From 4bb2e93aeb77356bfb1449faa0ef3914aaea9d0b Mon Sep 17 00:00:00 2001 From: "mjudge%netscape.com" Date: Wed, 3 Mar 1999 01:51:21 +0000 Subject: [PATCH] updates and fixes for CTRL left arrow and right arrow. also fixes for releasing the presshell correctly. the selection code was leaking it. updates for PREV and NEXT in nsFrameTraversal git-svn-id: svn://10.0.0.236/trunk@22673 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsFrameTraversal.cpp | 42 ++++++++++-- mozilla/layout/base/nsIPresShell.h | 2 + mozilla/layout/base/public/nsIFocusTracker.h | 2 + mozilla/layout/base/public/nsIPresShell.h | 2 + mozilla/layout/base/src/nsFrameTraversal.cpp | 42 ++++++++++-- mozilla/layout/base/src/nsRangeList.cpp | 2 + mozilla/layout/generic/nsFrame.cpp | 2 +- mozilla/layout/generic/nsTextFrame.cpp | 71 +++++++++++++++----- mozilla/layout/html/base/src/nsFrame.cpp | 2 +- mozilla/layout/html/base/src/nsTextFrame.cpp | 71 +++++++++++++++----- 10 files changed, 192 insertions(+), 46 deletions(-) diff --git a/mozilla/layout/base/nsFrameTraversal.cpp b/mozilla/layout/base/nsFrameTraversal.cpp index a346eaf390b..e13e2b7edba 100644 --- a/mozilla/layout/base/nsFrameTraversal.cpp +++ b/mozilla/layout/base/nsFrameTraversal.cpp @@ -171,6 +171,8 @@ nsFrameIterator::CurrentItem(nsISupports **aItem) if (!aItem) return NS_ERROR_NULL_POINTER; *aItem = mCurrent; + if (mOffEdge) + return NS_COMFALSE; return NS_OK; } @@ -254,7 +256,7 @@ nsLeafIterator::Next() setCurrent(result); if (!result) setOffEdge(1); - return nsnull; + return NS_OK; } @@ -267,10 +269,39 @@ nsLeafIterator::Prev() nsIFrame *result; nsIFrame *parent = getCurrent(); if (!parent) - return NS_ERROR_FAILURE; - - parent = getLast(); + parent = getLast(); while(parent){ + nsIFrame *grandParent; + if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent && + NS_SUCCEEDED(grandParent->FirstChild(nsnull,&result))){ + nsFrameList list(result); + if (result = list.GetPrevSiblingFor(parent)){ + parent = result; + while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){ + parent = result; + while(NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){ + parent = result; + } + } + result = parent; + break; + } + else if (NS_FAILED(parent->GetParent(&result)) || !result){ + result = nsnull; + break; + } + else + parent = result; + } + else{ + setLast(parent); + result = nsnull; + break; + } + } + + +/* while(parent){ nsIFrame *grandParent; if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent){ nsIFrame * grandFchild; @@ -297,8 +328,9 @@ nsLeafIterator::Prev() } } } + */ setCurrent(result); if (!result) setOffEdge(-1); - return nsnull; + return NS_OK; } diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index 34c44774bbc..b5d7c2f9d11 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -64,6 +64,8 @@ class nsISelectionMgr; */ class nsIPresShell : public nsISupports { public: + static const nsIID& IID() { static nsIID iid = NS_IPRESSHELL_IID; return iid; } + NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, diff --git a/mozilla/layout/base/public/nsIFocusTracker.h b/mozilla/layout/base/public/nsIFocusTracker.h index 8c99229cc87..c748808fa73 100644 --- a/mozilla/layout/base/public/nsIFocusTracker.h +++ b/mozilla/layout/base/public/nsIFocusTracker.h @@ -30,6 +30,8 @@ class nsIFocusTracker : public nsISupports { public: + static const nsIID& IID() { static nsIID iid = NS_IFOCUSTRACKER_IID; return iid; } + /** SetFocus will keep track of the new frame as the focus frame. * as well as keeping track of the anchor frame;
* @param aFrame will be the focus frame diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index 34c44774bbc..b5d7c2f9d11 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -64,6 +64,8 @@ class nsISelectionMgr; */ class nsIPresShell : public nsISupports { public: + static const nsIID& IID() { static nsIID iid = NS_IPRESSHELL_IID; return iid; } + NS_IMETHOD Init(nsIDocument* aDocument, nsIPresContext* aPresContext, nsIViewManager* aViewManager, diff --git a/mozilla/layout/base/src/nsFrameTraversal.cpp b/mozilla/layout/base/src/nsFrameTraversal.cpp index a346eaf390b..e13e2b7edba 100644 --- a/mozilla/layout/base/src/nsFrameTraversal.cpp +++ b/mozilla/layout/base/src/nsFrameTraversal.cpp @@ -171,6 +171,8 @@ nsFrameIterator::CurrentItem(nsISupports **aItem) if (!aItem) return NS_ERROR_NULL_POINTER; *aItem = mCurrent; + if (mOffEdge) + return NS_COMFALSE; return NS_OK; } @@ -254,7 +256,7 @@ nsLeafIterator::Next() setCurrent(result); if (!result) setOffEdge(1); - return nsnull; + return NS_OK; } @@ -267,10 +269,39 @@ nsLeafIterator::Prev() nsIFrame *result; nsIFrame *parent = getCurrent(); if (!parent) - return NS_ERROR_FAILURE; - - parent = getLast(); + parent = getLast(); while(parent){ + nsIFrame *grandParent; + if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent && + NS_SUCCEEDED(grandParent->FirstChild(nsnull,&result))){ + nsFrameList list(result); + if (result = list.GetPrevSiblingFor(parent)){ + parent = result; + while(NS_SUCCEEDED(parent->FirstChild(nsnull,&result)) && result){ + parent = result; + while(NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){ + parent = result; + } + } + result = parent; + break; + } + else if (NS_FAILED(parent->GetParent(&result)) || !result){ + result = nsnull; + break; + } + else + parent = result; + } + else{ + setLast(parent); + result = nsnull; + break; + } + } + + +/* while(parent){ nsIFrame *grandParent; if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent){ nsIFrame * grandFchild; @@ -297,8 +328,9 @@ nsLeafIterator::Prev() } } } + */ setCurrent(result); if (!result) setOffEdge(-1); - return nsnull; + return NS_OK; } diff --git a/mozilla/layout/base/src/nsRangeList.cpp b/mozilla/layout/base/src/nsRangeList.cpp index 438edc75721..a25e3219add 100644 --- a/mozilla/layout/base/src/nsRangeList.cpp +++ b/mozilla/layout/base/src/nsRangeList.cpp @@ -606,6 +606,7 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent) if (NS_SUCCEEDED(frameused->PeekOffset(amount, eDirNext, offsetused, &resultFrame, &frameOffset, &contentOffset, PR_FALSE)) && resultFrame){ result = TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, keyEvent->isShift); } + break; case nsIDOMEvent::VK_UP : printf("debug vk up\n"); break; @@ -1035,6 +1036,7 @@ nsRangeList::ResetSelection(nsIFocusTracker *aTracker, nsIFrame *aStartFrame) res = ScrollIntoView(aTracker); } } + printf("debug reset selection has been called\n"); return res; } diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index a10db05114d..e6e83abff25 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -1601,7 +1601,7 @@ nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 a nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this); if (NS_FAILED(result)) return result; - nsISupports *isupports; + nsISupports *isupports = nsnull; if (aDirection == eDirNext) result = frameTraversal->Next(); else diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 73b3b7d16f0..2f644e9e13a 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -160,12 +160,13 @@ public: nsIRenderingContext& aRC, nscoord& aDeltaWidth); - // TextFrame methods +/* // TextFrame methods struct SelectionInfo { PRInt32 mStartOffset; PRInt32 mEndOffset; PRBool mEmptySelection; }; + */ /* void ComputeSelectionInfo(nsIRenderingContext& aRenderingContext, nsIDocument* aDocument, @@ -1823,7 +1824,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 i; for (i = aStartOffset -1; i >=0; i--){ if (ip[i] < ip[aStartOffset]){ - *aResultFrame = this; *aFrameOffset = i; break; } @@ -1838,7 +1838,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 i; for (i = aStartOffset +1; i <= mContentLength; i++){ if (ip[i] > ip[aStartOffset]){ - *aResultFrame = this; *aFrameOffset = i; break; } @@ -1853,32 +1852,53 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 } if (!found){ if (frameUsed){ - return frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, + result = frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } else {//reached end ask the frame for help - return nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, + result = nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } } - *aContentOffset = mContentOffset; + else{ + *aResultFrame = this; + *aContentOffset = mContentOffset; + } } break; case eSelectWord : { nsIFrame *frameUsed = nsnull; + PRBool keepSearching; //if you run out of chars before you hit the end of word, maybe next frame has more text to select? PRInt32 start; PRBool found = PR_FALSE; PRBool isWhitespace; PRInt32 wordLen, contentLen; if (aDirection == eDirPrevious){ + keepSearching = PR_TRUE; tx.Init(this, mContentOffset + aStartOffset); if (tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){ - *aFrameOffset = aStartOffset - contentLen; - //check for whitespace next. - while (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)) - *aFrameOffset -= contentLen; - if (!isWhitespace) + if ((aEatingWS && !isWhitespace) || !aEatingWS){ + *aFrameOffset = aStartOffset - contentLen; + //check for whitespace next. + if (*aFrameOffset > 0) + keepSearching = PR_FALSE;//reached the beginning of a word + aEatingWS = !isWhitespace;//nowhite space, just eat chars. + while (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){ + *aFrameOffset -= contentLen; + aEatingWS = PR_FALSE; + } + keepSearching = *aFrameOffset <= 0; + if (!isWhitespace){ + if (!keepSearching) + found = PR_TRUE; + else + aEatingWS = PR_TRUE; + } + } + else { + *aFrameOffset = mContentLength; found = PR_TRUE; + } } frameUsed = GetPrevInFlow(); start = -1; //start at end @@ -1889,8 +1909,12 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 if ((aEatingWS && isWhitespace) || !aEatingWS){ *aFrameOffset = aStartOffset + contentLen; //check for whitespace next. - while (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace) + keepSearching = PR_TRUE; + isWhitespace = PR_TRUE; + while (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace){ *aFrameOffset += contentLen; + keepSearching = PR_FALSE; + } } else if (aEatingWS) *aFrameOffset = mContentOffset; @@ -1899,7 +1923,7 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 found = PR_TRUE; aEatingWS = PR_FALSE; } - else + else if (!keepSearching) //we have found the "whole" word so just looking for WS aEatingWS = PR_TRUE; } frameUsed = GetNextInFlow(); @@ -1907,16 +1931,18 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 } if (!found || (*aFrameOffset > mContentLength) || (*aFrameOffset < 0)){ //gone too far if (frameUsed){ - return frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame, + result = frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } else {//reached end ask the frame for help - return nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame, + result = nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } } - *aContentOffset = mContentOffset; - *aResultFrame = this; + else { + *aContentOffset = mContentOffset; + *aResultFrame = this; + } } break; case eSelectLine : @@ -1929,6 +1955,17 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 if (ip != indicies) { delete [] ip; } + if (NS_FAILED(result)){ + *aResultFrame = this; + *aContentOffset = mContentOffset; + if (aDirection = eDirNext){ + *aFrameOffset = mContentLength; + } + else if (aDirection = eDirPrevious){ + *aFrameOffset = 0; + } + result = NS_OK; + } return result; } diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index a10db05114d..e6e83abff25 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -1601,7 +1601,7 @@ nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 a nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this); if (NS_FAILED(result)) return result; - nsISupports *isupports; + nsISupports *isupports = nsnull; if (aDirection == eDirNext) result = frameTraversal->Next(); else diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 73b3b7d16f0..2f644e9e13a 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -160,12 +160,13 @@ public: nsIRenderingContext& aRC, nscoord& aDeltaWidth); - // TextFrame methods +/* // TextFrame methods struct SelectionInfo { PRInt32 mStartOffset; PRInt32 mEndOffset; PRBool mEmptySelection; }; + */ /* void ComputeSelectionInfo(nsIRenderingContext& aRenderingContext, nsIDocument* aDocument, @@ -1823,7 +1824,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 i; for (i = aStartOffset -1; i >=0; i--){ if (ip[i] < ip[aStartOffset]){ - *aResultFrame = this; *aFrameOffset = i; break; } @@ -1838,7 +1838,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 i; for (i = aStartOffset +1; i <= mContentLength; i++){ if (ip[i] > ip[aStartOffset]){ - *aResultFrame = this; *aFrameOffset = i; break; } @@ -1853,32 +1852,53 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 } if (!found){ if (frameUsed){ - return frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, + result = frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } else {//reached end ask the frame for help - return nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, + result = nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } } - *aContentOffset = mContentOffset; + else{ + *aResultFrame = this; + *aContentOffset = mContentOffset; + } } break; case eSelectWord : { nsIFrame *frameUsed = nsnull; + PRBool keepSearching; //if you run out of chars before you hit the end of word, maybe next frame has more text to select? PRInt32 start; PRBool found = PR_FALSE; PRBool isWhitespace; PRInt32 wordLen, contentLen; if (aDirection == eDirPrevious){ + keepSearching = PR_TRUE; tx.Init(this, mContentOffset + aStartOffset); if (tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){ - *aFrameOffset = aStartOffset - contentLen; - //check for whitespace next. - while (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)) - *aFrameOffset -= contentLen; - if (!isWhitespace) + if ((aEatingWS && !isWhitespace) || !aEatingWS){ + *aFrameOffset = aStartOffset - contentLen; + //check for whitespace next. + if (*aFrameOffset > 0) + keepSearching = PR_FALSE;//reached the beginning of a word + aEatingWS = !isWhitespace;//nowhite space, just eat chars. + while (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){ + *aFrameOffset -= contentLen; + aEatingWS = PR_FALSE; + } + keepSearching = *aFrameOffset <= 0; + if (!isWhitespace){ + if (!keepSearching) + found = PR_TRUE; + else + aEatingWS = PR_TRUE; + } + } + else { + *aFrameOffset = mContentLength; found = PR_TRUE; + } } frameUsed = GetPrevInFlow(); start = -1; //start at end @@ -1889,8 +1909,12 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 if ((aEatingWS && isWhitespace) || !aEatingWS){ *aFrameOffset = aStartOffset + contentLen; //check for whitespace next. - while (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace) + keepSearching = PR_TRUE; + isWhitespace = PR_TRUE; + while (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace){ *aFrameOffset += contentLen; + keepSearching = PR_FALSE; + } } else if (aEatingWS) *aFrameOffset = mContentOffset; @@ -1899,7 +1923,7 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 found = PR_TRUE; aEatingWS = PR_FALSE; } - else + else if (!keepSearching) //we have found the "whole" word so just looking for WS aEatingWS = PR_TRUE; } frameUsed = GetNextInFlow(); @@ -1907,16 +1931,18 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 } if (!found || (*aFrameOffset > mContentLength) || (*aFrameOffset < 0)){ //gone too far if (frameUsed){ - return frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame, + result = frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } else {//reached end ask the frame for help - return nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame, + result = nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame, aFrameOffset, aContentOffset, aEatingWS); } } - *aContentOffset = mContentOffset; - *aResultFrame = this; + else { + *aContentOffset = mContentOffset; + *aResultFrame = this; + } } break; case eSelectLine : @@ -1929,6 +1955,17 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 if (ip != indicies) { delete [] ip; } + if (NS_FAILED(result)){ + *aResultFrame = this; + *aContentOffset = mContentOffset; + if (aDirection = eDirNext){ + *aFrameOffset = mContentLength; + } + else if (aDirection = eDirPrevious){ + *aFrameOffset = 0; + } + result = NS_OK; + } return result; }