diff --git a/mozilla/accessible/src/html/nsHyperTextAccessible.cpp b/mozilla/accessible/src/html/nsHyperTextAccessible.cpp
index f86f92fdd07..503a06c2657 100644
--- a/mozilla/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/mozilla/accessible/src/html/nsHyperTextAccessible.cpp
@@ -511,7 +511,7 @@ PRInt32 nsHyperTextAccessible::GetRelativeOffset(nsIPresShell *aPresShell, nsIFr
kIsJumpLinesOk,
kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi,
wordMovementType);
- nsresult rv = aFromFrame->PeekOffset(&pos);
+ nsresult rv = aFromFrame->PeekOffset(aPresShell->GetPresContext(), &pos);
PRInt32 resultOffset = pos.mContentOffset;
nsIContent *resultContent = nsnull;
diff --git a/mozilla/layout/base/nsCaret.cpp b/mozilla/layout/base/nsCaret.cpp
index c49625d116b..8cc85cd093a 100644
--- a/mozilla/layout/base/nsCaret.cpp
+++ b/mozilla/layout/base/nsCaret.cpp
@@ -719,7 +719,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode,
{
nsPeekOffsetStruct pos;
pos.SetData(eSelectBeginLine, eDirPrevious, 0, 0, PR_FALSE, PR_TRUE, PR_FALSE, PR_TRUE);
- if (NS_SUCCEEDED(frameAfter->PeekOffset(&pos))) {
+ if (NS_SUCCEEDED(frameAfter->PeekOffset(presContext, &pos))) {
theFrame = pos.mResultFrame;
theFrameOffset = pos.mContentOffset;
}
@@ -751,7 +751,7 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode,
{
nsPeekOffsetStruct pos;
pos.SetData(eSelectEndLine, eDirNext, 0, 0, PR_FALSE, PR_TRUE, PR_FALSE, PR_TRUE);
- if (NS_SUCCEEDED(frameBefore->PeekOffset(&pos))) {
+ if (NS_SUCCEEDED(frameBefore->PeekOffset(presContext, &pos))) {
theFrame = pos.mResultFrame;
theFrameOffset = pos.mContentOffset;
}
diff --git a/mozilla/layout/generic/nsBRFrame.cpp b/mozilla/layout/generic/nsBRFrame.cpp
index 004532ec300..9fa0e85bd62 100644
--- a/mozilla/layout/generic/nsBRFrame.cpp
+++ b/mozilla/layout/generic/nsBRFrame.cpp
@@ -66,10 +66,8 @@ public:
virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
- virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType);
+ NS_IMETHOD PeekOffset(nsPresContext* aPresContext,
+ nsPeekOffsetStruct *aPos);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -209,35 +207,42 @@ nsIFrame::ContentOffsets BRFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoin
return offsets;
}
-PRBool
-BRFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset)
+NS_IMETHODIMP BRFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- // If we hit the end of a BR going backwards, go to its beginning and stay there.
- if (!aForward && startOffset != 0) {
- *aOffset = 0;
- return PR_TRUE;
+ if (!aPos)
+ return NS_ERROR_NULL_POINTER;
+
+ //BR is also a whitespace, but sometimes GetNextWord() can't handle this
+ //See bug 304891
+ nsTextTransformer::Initialize();
+
+ if (aPos->mWordMovementType != eDefaultBehavior) {
+ // aPos->mWordMovementType possible values:
+ // eEndWord: eat the space if we're moving backwards
+ // eStartWord: eat the space if we're moving forwards
+ if ((aPos->mWordMovementType == eEndWord) == (aPos->mDirection == eDirPrevious)) {
+ aPos->mEatingWS = PR_TRUE;
+ }
+ }
+ else if (aPos->mDirection == eDirNext && nsTextTransformer::GetWordSelectEatSpaceAfter()) {
+ // Use the hidden preference which is based on operating system behavior.
+ // This pref only affects whether moving forward by word should go to the end of this word or start of the next word.
+ // When going backwards, the start of the word is always used, on every operating system.
+ aPos->mEatingWS = PR_TRUE;
}
- // Otherwise, stop if we hit the beginning, continue (forward) if we hit the end.
- return (startOffset == 0);
-}
-PRBool
-BRFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
-{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- // Keep going. The actual line jumping will stop us.
- return PR_FALSE;
-}
+ //offset of this content in its parents child list. base 0
+ PRInt32 offsetBegin = mContent->GetParent()->IndexOf(mContent);
-PRBool
-BRFrame::PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType)
-{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- // Keep going. The actual line jumping will stop us.
- return PR_FALSE;
+ if (aPos->mAmount != eSelectLine && aPos->mAmount != eSelectBeginLine
+ && aPos->mAmount != eSelectEndLine) //then we must do the adjustment to make sure we leave this frame
+ {
+ if (aPos->mDirection == eDirNext)
+ aPos->mStartOffset = offsetBegin +1;//go to end to make sure we jump to next node.
+ else
+ aPos->mStartOffset = offsetBegin; //we start at beginning to make sure we leave this frame.
+ }
+ return nsFrame::PeekOffset(aPresContext, aPos);//now we let the default take over.
}
#ifdef ACCESSIBILITY
diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp
index 63bc5c06d86..18c6c5aafe5 100644
--- a/mozilla/layout/generic/nsFrame.cpp
+++ b/mozilla/layout/generic/nsFrame.cpp
@@ -2010,7 +2010,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
PR_TRUE, //limit on scrolled views
PR_FALSE,
PR_FALSE);
- rv = PeekOffset(&startpos);
+ rv = PeekOffset(aPresContext, &startpos);
if (NS_FAILED(rv))
return rv;
nsPeekOffsetStruct endpos;
@@ -2022,7 +2022,7 @@ nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
PR_TRUE, //limit on scrolled views
PR_FALSE,
PR_FALSE);
- rv = PeekOffset(&endpos);
+ rv = PeekOffset(aPresContext, &endpos);
if (NS_FAILED(rv))
return rv;
@@ -3767,9 +3767,7 @@ nsFrame::GetPointFromOffset(nsPresContext* inPresContext, nsIRenderingContext* i
if (newContent){
PRInt32 newOffset = newContent->IndexOf(mContent);
- PRBool isRTL = (NS_GET_EMBEDDING_LEVEL(this) & 1) == 1;
- if (!isRTL && inOffset > newOffset ||
- isRTL && inOffset <= newOffset)
+ if (inOffset > newOffset)
bottomLeft.x = GetRect().width;
}
}
@@ -4058,10 +4056,11 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
//we need to jump to new block frame.
aPos->mAmount = eSelectLine;
aPos->mStartOffset = 0;
+ aPos->mEatingWS = PR_FALSE;
aPos->mAttachForward = !(aPos->mDirection == eDirNext);
if (aPos->mDirection == eDirPrevious)
aPos->mStartOffset = -1;//start from end
- return aBlockFrame->PeekOffset(aPos);
+ return aBlockFrame->PeekOffset(aPresContext, aPos);
}
}
return NS_OK;
@@ -4141,7 +4140,8 @@ FindBlockFrameOrBR(nsIFrame* aFrame, nsDirection aDirection)
}
nsresult
-nsIFrame::PeekOffsetParagraph(nsPeekOffsetStruct *aPos)
+nsFrame::PeekOffsetParagraph(nsPresContext* aPresContext,
+ nsPeekOffsetStruct *aPos)
{
nsIFrame* frame = this;
nsBlockFrame* bf; // used only for QI
@@ -4208,137 +4208,62 @@ nsIFrame::PeekOffsetParagraph(nsPeekOffsetStruct *aPos)
return NS_OK;
}
-// Determine movement direction relative to frame
-static PRBool IsMovingInFrameDirection(nsIFrame* frame, nsDirection aDirection, PRBool aVisual)
-{
- PRBool isReverseDirection = aVisual ?
- (NS_GET_EMBEDDING_LEVEL(frame) & 1) != (NS_GET_BASE_LEVEL(frame) & 1) : PR_FALSE;
- return aDirection == (isReverseDirection ? eDirPrevious : eDirNext);
-}
-
-NS_IMETHOD
-nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
+NS_IMETHODIMP
+nsFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{
if (!aPos)
return NS_ERROR_NULL_POINTER;
nsresult result = NS_ERROR_FAILURE;
-
- if (mState & NS_FRAME_IS_DIRTY)
- return NS_ERROR_UNEXPECTED;
-
- // Translate content offset to be relative to frame
- FrameContentRange range = GetRangeForFrame(this);
- PRInt32 offset = aPos->mStartOffset - range.start;
- nsIFrame* current = this;
-
- switch (aPos->mAmount) {
- case eSelectCharacter:
+ switch (aPos->mAmount){
+ case eSelectCharacter : case eSelectWord:
{
- PRBool eatingNonRenderableWS = PR_FALSE;
- PRBool done = PR_FALSE;
-
- while (!done) {
- PRBool movingInFrameDirection =
- IsMovingInFrameDirection(current, aPos->mDirection, aPos->mVisual);
+ if (mContent)
+ {
+ nsIContent* newContent = mContent->GetParent();
+ if (newContent){
+ aPos->mResultContent = newContent;
- if (eatingNonRenderableWS)
- done = current->PeekOffsetNoAmount(movingInFrameDirection, &offset);
- else
- done = current->PeekOffsetCharacter(movingInFrameDirection, &offset);
+ PRInt32 newOffset = newContent->IndexOf(mContent);
+
+ if (aPos->mDirection == eDirNext)
+ aPos->mContentOffset = newOffset + 1;
+ else
+ aPos->mContentOffset = newOffset;//to beginning of frame
+
+ nsTextTransformer::Initialize();
+ if (nsTextTransformer::GetWordSelectEatSpaceAfter() &&
+ aPos->mDirection == eDirNext && aPos->mEatingWS)
+ {
+ //If we want to stop at beginning of the next word
+ //GetFrameFromDirection should not return NS_ERROR_FAILURE
+ //at end of line
+ aPos->mEatingWS = PR_FALSE;
+ result = GetFrameFromDirection(aPresContext, aPos);
+ aPos->mEatingWS = PR_TRUE;
+ }
+ else
+ result = GetFrameFromDirection(aPresContext, aPos);
- if (!done) {
- PRBool jumpedLine;
- result =
- current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
- aPos->mJumpLines, aPos->mScrollViewStop,
- ¤t, &offset, &jumpedLine);
if (NS_FAILED(result))
return result;
-
- // If we jumped lines, it's as if we found a character, but we still need
- // to eat non-renderable content on the new line.
- if (jumpedLine)
- eatingNonRenderableWS = PR_TRUE;
+ PRBool selectable = PR_FALSE;
+ if (aPos->mResultFrame)
+ aPos->mResultFrame->IsSelectable(&selectable, nsnull);
+ if (NS_FAILED(result) || !aPos->mResultFrame || !selectable)
+ {
+ return result?result:NS_ERROR_FAILURE;
+ }
+ return aPos->mResultFrame->PeekOffset(aPresContext, aPos);
}
}
-
- // Set outputs
- range = GetRangeForFrame(current);
- aPos->mResultFrame = current;
- aPos->mResultContent = range.content;
- // Output offset is relative to content, not frame
- aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
-
break;
}
- case eSelectWord:
+ case eSelectNoAmount:
{
- // wordSelectEatSpace means "are we looking for a boundary between whitespace
- // and non-whitespace (in the direction we're moving in)".
- // It is true when moving forward and looking for a beginning of a word, or
- // when moving backwards and looking for an end of a word.
- PRBool wordSelectEatSpace;
- if (aPos->mWordMovementType != eDefaultBehavior) {
- // aPos->mWordMovementType possible values:
- // eEndWord: eat the space if we're moving backwards
- // eStartWord: eat the space if we're moving forwards
- wordSelectEatSpace = ((aPos->mWordMovementType == eEndWord) == (aPos->mDirection == eDirPrevious));
- }
- else {
- // Use the hidden preference which is based on operating system behavior.
- // This pref only affects whether moving forward by word should go to the end of this word or start of the next word.
- // When going backwards, the start of the word is always used, on every operating system.
- nsTextTransformer::Initialize();
- wordSelectEatSpace = aPos->mDirection == eDirNext && nsTextTransformer::GetWordSelectEatSpaceAfter();
- }
-
- // sawBeforeType means "we already saw characters of the type
- // before the boundary we're looking for". Examples:
- // 1. If we're moving forward, looking for a word beginning (i.e. a boundary
- // between whitespace and non-whitespace), then eatingWS==PR_TRUE means
- // "we already saw some whitespace".
- // 2. If we're moving backward, looking for a word beginning (i.e. a boundary
- // between non-whitespace and whitespace), then eatingWS==PR_TRUE means
- // "we already saw some non-whitespace".
- PRBool sawBeforeType = PR_FALSE;
-
- PRBool done = PR_FALSE;
- while (!done) {
- PRBool movingInFrameDirection =
- IsMovingInFrameDirection(current, aPos->mDirection, aPos->mVisual);
-
- done = current->PeekOffsetWord(movingInFrameDirection, wordSelectEatSpace, aPos->mIsKeyboardSelect,
- &offset, &sawBeforeType);
-
- if (!done) {
- nsIFrame* nextFrame;
- PRInt32 nextFrameOffset;
- PRBool jumpedLine;
- result =
- current->GetFrameFromDirection(aPos->mDirection, aPos->mVisual,
- aPos->mJumpLines, aPos->mScrollViewStop,
- &nextFrame, &nextFrameOffset, &jumpedLine);
- // We can't jump lines if we're looking for whitespace following
- // non-whitespace, and we already encountered non-whitespace.
- if (NS_FAILED(result) ||
- jumpedLine && !wordSelectEatSpace && sawBeforeType) {
- done = PR_TRUE;
- } else {
- current = nextFrame;
- offset = nextFrameOffset;
- // Jumping a line is equivalent to encountering whitespace
- if (wordSelectEatSpace && jumpedLine)
- sawBeforeType = PR_TRUE;
- }
- }
- }
-
- // Set outputs
- range = GetRangeForFrame(current);
- aPos->mResultFrame = current;
+ FrameContentRange range = GetRangeForFrame(this);
aPos->mResultContent = range.content;
- // Output offset is relative to content, not frame
- aPos->mContentOffset = offset < 0 ? range.end : range.start + offset;
+ aPos->mContentOffset = range.start;
+ result = range.content ? NS_OK : NS_ERROR_FAILURE;
break;
}
case eSelectLine :
@@ -4347,24 +4272,23 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
nsIFrame *blockFrame = this;
while (NS_FAILED(result)){
- PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, &blockFrame);
+ PRInt32 thisLine = GetLineNumber(blockFrame, &blockFrame);
if (thisLine < 0)
return NS_ERROR_FAILURE;
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter));
NS_ASSERTION(NS_SUCCEEDED(result) && iter, "GetLineNumber() succeeded but no block frame?");
int edgeCase = 0;//no edge case. this should look at thisLine
-
PRBool doneLooping = PR_FALSE;//tells us when no more block frames hit.
//this part will find a frame or a block frame. if it's a block frame
//it will "drill down" to find a viable frame or it will return an error.
nsIFrame *lastFrame = this;
do {
- result = nsFrame::GetNextPrevLineFromeBlockFrame(GetPresContext(),
- aPos,
- blockFrame,
- thisLine,
- edgeCase //start from thisLine
+ result = GetNextPrevLineFromeBlockFrame(aPresContext,
+ aPos,
+ blockFrame,
+ thisLine,
+ edgeCase //start from thisLine
);
if (NS_SUCCEEDED(result) && (!aPos->mResultFrame || aPos->mResultFrame == lastFrame))//we came back to same spot! keep going
{
@@ -4429,11 +4353,11 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
}
} while (!doneLooping);
}
- return result;
+ break;
}
case eSelectParagraph:
- return PeekOffsetParagraph(aPos);
+ return PeekOffsetParagraph(aPresContext, aPos);
case eSelectBeginLine:
case eSelectEndLine:
@@ -4441,7 +4365,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
nsCOMPtr it;
// Adjusted so that the caret can't get confused when content changes
nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this);
- PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, &blockFrame);
+ PRInt32 thisLine = GetLineNumber(blockFrame, &blockFrame);
if (thisLine < 0)
return NS_ERROR_FAILURE;
result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it));
@@ -4455,7 +4379,7 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
PRBool endOfLine = (eSelectEndLine == aPos->mAmount);
#ifdef IBMBIDI
- if (aPos->mVisual && GetPresContext()->BidiEnabled()) {
+ if (aPos->mVisual && aPresContext->BidiEnabled()) {
PRBool lineIsRTL;
it->GetDirection(&lineIsRTL);
PRBool isReordered;
@@ -4495,61 +4419,17 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos)
return NS_ERROR_FAILURE;
return NS_OK;
}
+ break;
default:
{
- NS_ASSERTION(PR_FALSE, "Invalid amount");
- return NS_ERROR_FAILURE;
+ if (NS_SUCCEEDED(result))
+ result = aPos->mResultFrame->PeekOffset(aPresContext, aPos);
}
- }
- return NS_OK;
+ }
+ return result;
}
-PRBool
-nsFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset)
-{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- // Sure, we can stop right here.
- return PR_TRUE;
-}
-
-PRBool
-nsFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
-{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- // A negative offset means "end of frame", which in our case means offset 1.
- if (startOffset < 0)
- startOffset = 1;
- if (aForward == (startOffset == 0)) {
- // We're before the frame and moving forward, or after it and moving backwards:
- // skip to the other side and we're done.
- *aOffset = 1 - startOffset;
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-PRBool
-nsFrame::PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType)
-{
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- if (startOffset < 0)
- startOffset = 1;
- if (aForward == (startOffset == 0)) {
- // We're before the frame and moving forward, or after it and moving backwards.
- // If we're looking for non-whitespace, we found it (without skipping this frame).
- if (aWordSelectEatSpace && *aSawBeforeType)
- return PR_TRUE;
- // Otherwise skip to the other side and note that we encountered non-whitespace.
- *aOffset = 1 - startOffset;
- if (!aWordSelectEatSpace)
- *aSawBeforeType = PR_TRUE;
- }
- return PR_FALSE;
-}
NS_IMETHODIMP
nsFrame::CheckVisibility(nsPresContext* , PRInt32 , PRInt32 , PRBool , PRBool *, PRBool *)
@@ -4596,18 +4476,8 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, nsIFrame** aContainingBlock)
}
nsresult
-nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
- PRBool aJumpLines, PRBool aScrollViewStop,
- nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine)
-{
- if (!aOutFrame || !aOutOffset || !aOutJumpedLine)
- return NS_ERROR_NULL_POINTER;
-
- nsPresContext* presContext = GetPresContext();
- *aOutFrame = nsnull;
- *aOutOffset = 0;
- *aOutJumpedLine = PR_FALSE;
-
+nsIFrame::GetFrameFromDirection(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
+{
// Find the prev/next selectable frame
PRBool selectable = PR_FALSE;
nsIFrame *traversedFrame = this;
@@ -4625,19 +4495,19 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
nsIFrame *firstFrame;
nsIFrame *lastFrame;
#ifdef IBMBIDI
- if (aVisual && presContext->BidiEnabled()) {
+ if (aPos->mVisual && aPresContext->BidiEnabled()) {
PRBool lineIsRTL;
it->GetDirection(&lineIsRTL);
PRBool isReordered;
result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame);
- nsIFrame** framePtr = aDirection == eDirPrevious ? &firstFrame : &lastFrame;
+ nsIFrame** framePtr = aPos->mDirection == eDirPrevious ? &firstFrame : &lastFrame;
if (*framePtr) {
nsBidiLevel embeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(*framePtr);
if (((embeddingLevel & 1) && lineIsRTL || !(embeddingLevel & 1) && !lineIsRTL) ==
- (aDirection == eDirPrevious)) {
- nsFrame::GetFirstLeaf(presContext, framePtr);
+ (aPos->mDirection == eDirPrevious)) {
+ nsFrame::GetFirstLeaf(aPresContext, framePtr);
} else {
- nsFrame::GetLastLeaf(presContext, framePtr);
+ nsFrame::GetLastLeaf(aPresContext, framePtr);
}
atLineEdge = *framePtr == traversedFrame;
} else {
@@ -4654,8 +4524,8 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
if (NS_FAILED(result))
return result;
- if (aDirection == eDirPrevious) {
- nsFrame::GetFirstLeaf(presContext, &firstFrame);
+ if (aPos->mDirection == eDirPrevious) {
+ nsFrame::GetFirstLeaf(aPresContext, &firstFrame);
atLineEdge = firstFrame == traversedFrame;
} else { // eDirNext
lastFrame = firstFrame;
@@ -4666,36 +4536,43 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
return NS_ERROR_FAILURE;
}
}
- nsFrame::GetLastLeaf(presContext, &lastFrame);
+ nsFrame::GetLastLeaf(aPresContext, &lastFrame);
atLineEdge = lastFrame == traversedFrame;
}
}
- if (atLineEdge) {
- *aOutJumpedLine = PR_TRUE;
- if (!aJumpLines)
- return NS_ERROR_FAILURE; //we are done. cannot jump lines
+ if (atLineEdge)
+ {
+ if (aPos->mJumpLines != PR_TRUE)
+ return NS_ERROR_FAILURE;//we are done. cannot jump lines
+ if (aPos->mAmount != eSelectWord)
+ {
+ aPos->mAmount = eSelectNoAmount;
+ }
+ else{
+ if (aPos->mEatingWS)//done finding what we wanted
+ return NS_ERROR_FAILURE;
+ }
}
-
nsCOMPtr frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
- presContext, traversedFrame,
+ aPresContext, traversedFrame,
eLeaf,
- aVisual && presContext->BidiEnabled(),
- aScrollViewStop,
+ aPos->mVisual && aPresContext->BidiEnabled(),
+ aPos->mScrollViewStop,
PR_TRUE // aFollowOOFs
);
if (NS_FAILED(result))
return result;
- if (aDirection == eDirNext)
+ nsISupports *isupports = nsnull;
+ if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
- else
+ else
result = frameTraversal->Prev();
+
if (NS_FAILED(result))
return result;
-
- nsISupports *isupports = nsnull;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result))
return result;
@@ -4706,18 +4583,20 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
traversedFrame = (nsIFrame *)isupports;
traversedFrame->IsSelectable(&selectable, nsnull);
} // while (!selectable)
-
- *aOutOffset = (aDirection == eDirNext) ? 0 : -1;
-
+
+ if (aPos->mDirection == eDirNext)
+ aPos->mStartOffset = 0;
+ else
+ aPos->mStartOffset = -1;
#ifdef IBMBIDI
- if (aVisual) {
+ if (aPos->mVisual) {
PRUint8 newLevel = NS_GET_EMBEDDING_LEVEL(traversedFrame);
PRUint8 newBaseLevel = NS_GET_BASE_LEVEL(traversedFrame);
if ((newLevel & 1) != (newBaseLevel & 1)) // The new frame is reverse-direction, go to the other end
- *aOutOffset = -1 - *aOutOffset;
+ aPos->mStartOffset = -1 - aPos->mStartOffset;
}
#endif
- *aOutFrame = traversedFrame;
+ aPos->mResultFrame = traversedFrame;
return NS_OK;
}
diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h
index 950891d386e..e9857ff1021 100644
--- a/mozilla/layout/generic/nsFrame.h
+++ b/mozilla/layout/generic/nsFrame.h
@@ -250,14 +250,11 @@ public:
NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle) const;
NS_IMETHOD GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon);
-
- virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType);
-
+ NS_IMETHOD PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos) ;
NS_IMETHOD CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval);
+ NS_IMETHOD PeekOffsetParagraph(nsPresContext* aPresContext,
+ nsPeekOffsetStruct *aPos);
NS_IMETHOD GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const;
NS_IMETHOD ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild);
diff --git a/mozilla/layout/generic/nsFrameSelection.h b/mozilla/layout/generic/nsFrameSelection.h
index 71123949414..8b4ce2ccb27 100644
--- a/mozilla/layout/generic/nsFrameSelection.h
+++ b/mozilla/layout/generic/nsFrameSelection.h
@@ -91,6 +91,7 @@ struct nsPeekOffsetStruct
mIsKeyboardSelect = aIsKeyboardSelect;
mVisual = aVisual;
mWordMovementType = aWordMovementType;
+ mEatingWS = PR_FALSE;
}
// Note: Most arguments (input and output) are only used with certain values
@@ -104,14 +105,6 @@ struct nsPeekOffsetStruct
nsSelectionAmount mAmount;
// mDirection: eDirPrevious or eDirNext.
- // * Note for visual bidi movement:
- // eDirPrevious means 'left-then-up' if the containing block is LTR,
- // 'right-then-up' if it is RTL.
- // eDirNext means 'right-then-down' if the containing block is LTR,
- // 'left-then-down' if it is RTL.
- // Between paragraphs, eDirPrevious means "go to the visual end of the
- // previous paragraph", and eDirNext means "go to the visual beginning
- // of the next paragraph".
// Used with: eSelectCharacter, eSelectWord, eSelectLine, eSelectParagraph.
nsDirection mDirection;
@@ -163,6 +156,14 @@ struct nsPeekOffsetStruct
// PR_TRUE means "the beginning of the frame logically after the caret".
// Used with: eSelectLine, eSelectBeginLine, eSelectEndLine.
PRBool mAttachForward;
+
+ /*** Arguments only used internally ***/
+
+ // mEatingWS: Used only internally, for recursive calls into PeekOffset.
+ // Shold be PR_FALSE upon initial call to PeekOffset.
+ // Used with: eSelectWord.
+ PRBool mEatingWS;
+
};
struct nsPrevNextBidiLevels
diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h
index b9808ea62bc..0df87d2ff20 100644
--- a/mozilla/layout/generic/nsIFrame.h
+++ b/mozilla/layout/generic/nsIFrame.h
@@ -100,10 +100,10 @@ struct nsMargin;
typedef class nsIFrame nsIBox;
// IID for the nsIFrame interface
-// 48813f12-5e55-46af-8527-c8f408bac999
+// b7f1e31d-0dc8-466f-a46c-76a718a805a3
#define NS_IFRAME_IID \
-{ 0x48813f12, 0x5e55, 0x46af, \
- { 0x85, 0x27, 0xc8, 0xf4, 0x08, 0xba, 0xc9, 0x99 } }
+{ 0xb7f1e31d, 0x0dc8, 0x466f, \
+ { 0xa4, 0x6c, 0x76, 0xa7, 0x18, 0xa8, 0x05, 0xa3 } }
/**
* Indication of how the frame can be split. This is used when doing runaround
@@ -1335,22 +1335,26 @@ public:
* return NS_ERROR_FAILURE
* @param aPOS is defined in nsFrameSelection
*/
- NS_IMETHOD PeekOffset(nsPeekOffsetStruct *aPos);
+ NS_IMETHOD PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos) = 0;
/**
* called to find the previous/next selectable leaf frame.
- * @param aDirection [in] the direction to move in (eDirPrevious or eDirNext)
- * @param aVisual [in] whether bidi caret behavior is visual (PR_TRUE) or logical (PR_FALSE)
- * @param aJumpLines [in] whether to allow jumping across line boundaries
- * @param aScrollViewStop [in] whether to stop when reaching a scroll frame boundary
- * @param aOutFrame [out] the previous/next selectable leaf frame
- * @param aOutOffset [out] 0 indicates that we arrived at the beginning of the output frame;
- * -1 indicates that we arrived at its end.
- * @param aOutJumpedLine [out] whether this frame and the returned frame are on different lines
+ * @param aPOS is defined in nsFrameSelection.
+ * Fields of aPos used as input are:
+ * mAmount: should be either eSelectWord or eSelectCharacter
+ * mDirection: eDirPrevious or eDirNext
+ * mJumpLines: whether to allow jumping across line boundaries
+ * mScrollViewStop: whether to stop when reaching a scroll view boundary
+ * mVisual: whether bidi caret behavior is visual (PR_TRUE) or logical (PR_FALSE)
+ * mEatingWS: indicates whether we're seeking a boundary between
+ * non-whitespace and whitespace.
+ * Fields of aPos set as output are:
+ * mResultFrame: the previous/next selectable leaf frame
+ * mAmount: might be set to eSelectNone after crossing a line boundary
+ * mStartOffset: set to 0 or -1 to indicate which edge of the result frame
+ * is closer to "this" frame.
*/
- nsresult GetFrameFromDirection(nsDirection aDirection, PRBool aVisual,
- PRBool aJumpLines, PRBool aScrollViewStop,
- nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine);
+ nsresult GetFrameFromDirection(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos);
/**
* called to see if the children of the frame are visible from indexstart to index end.
@@ -1700,60 +1704,7 @@ protected:
*/
void InvalidateRoot(const nsRect& aDamageRect,
nscoord aOffsetX, nscoord aOffsetY,
- PRBool aImmediate);
-
- /**
- * Can we stop inside this frame when we're skipping non-rendered whitespace?
- * @param aForward [in] Are we moving forward (or backward) in content order.
- * @param aOffset [in/out] At what offset into the frame to start looking.
- * on output - what offset was reached (whether or not we found a place to stop).
- * @return PR_TRUE: An appropriate offset was found within this frame,
- * and is given by aOffset.
- * PR_FALSE: Not found within this frame, need to try the next frame.
- */
- virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset) = 0;
-
- /**
- * Search the frame for the next character
- * @param aForward [in] Are we moving forward (or backward) in content order.
- * @param aOffset [in/out] At what offset into the frame to start looking.
- * on output - what offset was reached (whether or not we found a place to stop).
- * @return PR_TRUE: An appropriate offset was found within this frame,
- * and is given by aOffset.
- * PR_FALSE: Not found within this frame, need to try the next frame.
- */
- virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset) = 0;
-
- /**
- * Search the frame for the next word boundary
- * @param aForward [in] Are we moving forward (or backward) in content order.
- * @param aWordSelectEatSpace [in] PR_TRUE: look for non-whitespace following
- * whitespace (in the direction of movement).
- * PR_FALSE: look for whitespace following non-whitespace (in the
- * direction of movement).
- * @param aIsKeyboardSelect [in] Was the action initiated by a keyboard operation?
- * If PR_TRUE, punctuation immediately following a word is considered part
- * of that word. Otherwise, a sequence of punctuation is always considered
- * as a word on its own.
- * @param aOffset [in/out] At what offset into the frame to start looking.
- * on output - what offset was reached (whether or not we found a place to stop).
- * @param aSawBeforeType [in/out] Did we encounter a character of the pre-boundary type
- * (whitespace if aWordSelectEatSpace is true, non-whitespace otherwise).
- * @return PR_TRUE: An appropriate offset was found within this frame,
- * and is given by aOffset.
- * PR_FALSE: Not found within this frame, need to try the next frame.
- */
- virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType) = 0;
-
- /**
- * Search for the first paragraph boundary before or after the given position
- * @param aPos See description in nsFrameSelection.h. The following fields are
- * used by this method:
- * Input: mDirection
- * Output: mResultContent, mContentOffset
- */
- nsresult PeekOffsetParagraph(nsPeekOffsetStruct *aPos);
+ PRBool aImmediate);
private:
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp
index db2a2962ec8..e081517d446 100644
--- a/mozilla/layout/generic/nsInlineFrame.cpp
+++ b/mozilla/layout/generic/nsInlineFrame.cpp
@@ -175,22 +175,6 @@ nsInlineFrame::IsEmpty()
return PR_TRUE;
}
-PRBool
-nsInlineFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
-{
- // Override the implementation in nsFrame, to skip empty inline frames
- NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- if (startOffset < 0)
- startOffset = 1;
- if (aForward == (startOffset == 0)) {
- // We're before the frame and moving forward, or after it and moving backwards:
- // skip to the other side, but keep going.
- *aOffset = 1 - startOffset;
- }
- return PR_FALSE;
-}
-
NS_IMETHODIMP
nsInlineFrame::AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList)
diff --git a/mozilla/layout/generic/nsInlineFrame.h b/mozilla/layout/generic/nsInlineFrame.h
index 2f2aef8654b..4d88af07294 100644
--- a/mozilla/layout/generic/nsInlineFrame.h
+++ b/mozilla/layout/generic/nsInlineFrame.h
@@ -48,7 +48,7 @@
class nsAnonymousBlockFrame;
#define NS_INLINE_FRAME_CID \
- { 0x88b298af, 0x8b0e, 0x4592,{0x9e, 0xc6, 0xea, 0x4c, 0x4b, 0x3f, 0xf7, 0xa4}}
+ { 0xa6cf90e0, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
#define nsInlineFrameSuper nsHTMLContainerFrame
@@ -113,8 +113,6 @@ public:
virtual PRBool IsEmpty();
virtual PRBool IsSelfEmpty();
- virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
-
// nsIHTMLReflow overrides
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
diff --git a/mozilla/layout/generic/nsSelection.cpp b/mozilla/layout/generic/nsSelection.cpp
index cd1e013130e..b45ace73542 100644
--- a/mozilla/layout/generic/nsSelection.cpp
+++ b/mozilla/layout/generic/nsSelection.cpp
@@ -1287,6 +1287,9 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
}
}
+ offsetused = mDomSelections[index]->FetchFocusOffset();
+ weakNodeUsed = mDomSelections[index]->FetchFocusNode();
+
PRBool visualMovement =
(aKeycode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE ||
aKeycode == nsIDOMKeyEvent::DOM_VK_DELETE ||
@@ -1346,7 +1349,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
default :return NS_ERROR_FAILURE;
}
PostReason(nsISelectionListener::KEYPRESS_REASON);
- if (NS_SUCCEEDED(result = frame->PeekOffset(&pos)) && pos.mResultContent)
+ if (NS_SUCCEEDED(result = frame->PeekOffset(context, &pos)) && pos.mResultContent)
{
nsIFrame *theFrame;
PRInt32 currentOffset, frameStart, frameEnd;
@@ -1413,8 +1416,6 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode,
result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinueSelection, PR_FALSE);
} else if (aKeycode == nsIDOMKeyEvent::DOM_VK_RIGHT && !aContinueSelection) {
// Collapse selection if PeekOffset failed because we bumped into the BRFrame, bug 207623.
- weakNodeUsed = mDomSelections[index]->FetchFocusNode();
- offsetused = mDomSelections[index]->FetchFocusOffset();
mDomSelections[index]->Collapse(weakNodeUsed, offsetused);
tHint = mHint; // make the line below restore the original hint
result = NS_OK;
@@ -1547,8 +1548,10 @@ nsFrameSelection::VisualSequence(nsIFrame* aSelectFrame,
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
nsresult result = nsnull;
+ nsPresContext* presContext = mShell->GetPresContext();
+
PRUint8 currentLevel = NS_GET_EMBEDDING_LEVEL(aCurrentFrame);
- result = aSelectFrame->PeekOffset(aPos);
+ result = aSelectFrame->PeekOffset(presContext, aPos);
while (aCurrentFrame != (aSelectFrame = aPos->mResultFrame))
{
if (NS_FAILED(result))
@@ -1581,7 +1584,7 @@ nsFrameSelection::VisualSequence(nsIFrame* aSelectFrame,
aPos->mAmount = eSelectDir; // reset this because PeekOffset will have changed it to eSelectNoAmount
aPos->mContentOffset = 0;
- result = aSelectFrame->PeekOffset(aPos);
+ result = aSelectFrame->PeekOffset(presContext, aPos);
}
return NS_OK;
@@ -1651,17 +1654,19 @@ nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
endOffset = aAnchorOffset;
}
+ nsPresContext* presContext = mShell->GetPresContext();
+
aPos.mStartOffset = startOffset;
aPos.mDirection = eDirNext;
aPos.mAmount = eSelectLine;
- result = startFrame->PeekOffset(&aPos);
+ result = startFrame->PeekOffset(presContext, &aPos);
if (NS_FAILED(result))
return result;
startFrame = aPos.mResultFrame;
aPos.mStartOffset = aPos.mContentOffset;
aPos.mAmount = eSelectBeginLine;
- result = startFrame->PeekOffset(&aPos);
+ result = startFrame->PeekOffset(presContext, &aPos);
if (NS_FAILED(result))
return result;
@@ -1685,14 +1690,14 @@ nsFrameSelection::SelectLines(nsDirection aSelectionDirection,
aPos.mStartOffset = endOffset;
aPos.mDirection = eDirPrevious;
aPos.mAmount = eSelectLine;
- result = endFrame->PeekOffset(&aPos);
+ result = endFrame->PeekOffset(presContext, &aPos);
if (NS_FAILED(result))
return result;
endFrame = aPos.mResultFrame;
aPos.mStartOffset = aPos.mContentOffset;
aPos.mAmount = eSelectEndLine;
- result = endFrame->PeekOffset(&aPos);
+ result = endFrame->PeekOffset(presContext, &aPos);
if (NS_FAILED(result))
return result;
@@ -1736,6 +1741,8 @@ nsFrameSelection::VisualSelectFrames(nsIFrame* aCurrentFrame,
nsDirection selectionDirection;
PRInt8 index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
+ nsPresContext* presContext = mShell->GetPresContext();
+
result = mDomSelections[index]->GetOriginalAnchorPoint(getter_AddRefs(anchorNode), &anchorOffset);
if (NS_FAILED(result))
return result;
@@ -1811,7 +1818,7 @@ nsFrameSelection::VisualSelectFrames(nsIFrame* aCurrentFrame,
aPos.mStartOffset = anchorOffset;
aPos.mDirection = selectionDirection;
- result = anchorFrame->PeekOffset(&aPos);
+ result = anchorFrame->PeekOffset(presContext, &aPos);
if (NS_FAILED(result))
return result;
@@ -1963,14 +1970,20 @@ nsFrameSelection::GetPrevNextBidiLevels(nsIContent *aNode,
return levels;
}
- nsIFrame *newFrame;
- PRInt32 offset;
- PRBool jumpedLine;
- nsresult rv = currentFrame->GetFrameFromDirection(direction, PR_FALSE,
- aJumpLines, PR_TRUE,
- &newFrame, &offset, &jumpedLine);
- if (NS_FAILED(rv))
- newFrame = nsnull;
+ nsPeekOffsetStruct pos;
+ pos.SetData(eSelectCharacter,
+ direction,
+ currentOffset,
+ 0,
+ aJumpLines,
+ PR_TRUE, // aScrollViewStop
+ PR_FALSE, // aIsKeyboardSelect
+ PR_FALSE); // aVisual
+
+ nsresult rv = currentFrame->GetFrameFromDirection(mShell->GetPresContext(), &pos);
+ nsIFrame *newFrame = nsnull;
+ if (NS_SUCCEEDED(rv))
+ newFrame = pos.mResultFrame;
PRUint8 baseLevel = NS_GET_BASE_LEVEL(currentFrame);
PRUint8 currentLevel = NS_GET_EMBEDDING_LEVEL(currentFrame);
@@ -2286,7 +2299,7 @@ nsFrameSelection::HandleDrag(nsIFrame *aFrame, nsPoint aPoint)
pos.SetData(amount, direction, offset, 0,
PR_FALSE, mLimiter != nsnull, PR_FALSE, PR_FALSE);
- if (frame && NS_SUCCEEDED(frame->PeekOffset(&pos)) && pos.mResultContent) {
+ if (frame && NS_SUCCEEDED(frame->PeekOffset(mShell->GetPresContext(), &pos)) && pos.mResultContent) {
offsets.content = pos.mResultContent;
offsets.offset = pos.mContentOffset;
}
diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp
index 85b68c8ff52..235be480e58 100644
--- a/mozilla/layout/generic/nsTextFrame.cpp
+++ b/mozilla/layout/generic/nsTextFrame.cpp
@@ -345,11 +345,7 @@ public:
PRBool aSelected,
nsSpread aSpread);
- virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
- virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType);
-
+ NS_IMETHOD PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos);
NS_IMETHOD CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval);
NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const;
@@ -4467,273 +4463,480 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
return NS_OK;
}
-PRBool
-nsTextFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset)
-{
- NS_ASSERTION (aOffset && *aOffset <= mContentLength, "aOffset out of range");
- nsAutoTextBuffer paintBuffer;
- nsAutoIndexBuffer indexBuffer;
- nsresult rv = indexBuffer.GrowTo(mContentLength + 1);
- if (NS_FAILED(rv)) {
- return PR_FALSE;
- }
- PRInt32 textLength;
- nsTextTransformer tx(GetPresContext());
- PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
- return (textLength > 0);
-}
-PRBool
-nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset)
+NS_IMETHODIMP
+nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos)
{
- NS_ASSERTION (aOffset && *aOffset <= mContentLength, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- // A negative offset means "end of frame".
- if (startOffset < 0)
- startOffset = mContentLength;
+ DEBUG_VERIFY_NOT_DIRTY(mState);
+ if (mState & NS_FRAME_IS_DIRTY)
+ return NS_ERROR_UNEXPECTED;
- nsPresContext* presContext = GetPresContext();
+#ifdef IBMBIDI
+ // XXX TODO: - this explanation may not be accurate
+ // - need to better explain for what happens when you move
+ // from the end of a line to the beginning of the next
+ // despite not making a move logically within the text.
+ //
+ // When you move your caret by in some visual direction, and you find the
+ // new position is at the edge of a line (beginning or end), you usually
+ // want to stay on the current line rather than move to the next or the
+ // previous one; however, if you want to get to the edge of the next or
+ // the previous word (i.e. you're 'eating white space' when moving
+ // between words), and you couldn't find the word in the current line,
+ // you do _not_ want to stay on the current line - you want to get to that
+ // word.
+ //
+ // When your frames are ordered the same way logically as they are
+ // visually (e.g. when they're frames of LTR text displayed in
+ // left-then-down order), this translates to terms of 'prefer left' or
+ // 'prefer right', i.e. if you move to the left and hit the beginning of
+ // the line you have to choose between the frame "on the left" - the last
+ // frame on the previous line - and the frame "on the right" - the
+ // first frame of the current line.
+ //
+ // When the frames are displayed in right-then-down order (i.e. frames
+ // within an RTL line), the last sentence remains correct, but now
+ // the directions are reversed - if you're moving left, you hit the end
+ // of a line; the frame closer to your original position is the one
+ // "on the right" - the last frame on the current line - rather than the
+ // one "on the left" - the first frame on the next
+ // line.
+ //
+ // Note (for visual caret movement):
+ // eDirPrevious means 'left-then-up' if the containing block is LTR,
+ // 'right-then-up' if it is RTL.
+ // eDirNext means 'right-then-down' if the containing block is LTR,
+ // 'left-then-down' if it is RTL.
+ // Between paragraphs, eDirPrevious means "go to the visual end of the
+ // previous paragraph", and eDirNext means "go to the visual beginning of
+ // the next paragraph"
+
+ PRBool isReverseDirection = aPos->mVisual ?
+ (NS_GET_EMBEDDING_LEVEL(this) & 1) != (NS_GET_BASE_LEVEL(this) & 1) : PR_FALSE;
+ PRBool movementIsInFrameDirection =
+ ((aPos->mDirection == eDirNext) && !isReverseDirection) ||
+ ((aPos->mDirection == eDirPrevious) && isReverseDirection);
+
+#endif
+
+ if (!aPos || !mContent)
+ return NS_ERROR_NULL_POINTER;
+
+ // XXX TODO: explain this policy; why the assymetry between
+ // too high and too low start offsets?
+ //
+ // There are 4 possible ranges of aPos->mStartOffset:
+ //
+ // 0 mContentOffset mContentOffset+mContentLength
+ // | | |
+ // range #1 | range #2 | range #3 | range #4
+ // ***************
+ // our frame's part
+ // of the content
+ //
+ // Range Policy
+ // ------------------------------------------------------------------------
+ // #1 Assume the start position is at the end of the content of 'this'
+ // #2 Round up the position to the beginning of our frame
+ // #3 No change necessary
+ // #4 Delegate the PeekOffset() to the next frame (according
+ // to the direction, either to our left or our right)
+ //
+ // Note: the diagram above is drawn left-to-right, but advancing
+ // in the content may sometimes mean going right-to-left
- // Transform text from content into renderable form
+ if (aPos->mStartOffset < 0 )
+ aPos->mStartOffset = mContentLength + mContentOffset;
+ if (aPos->mStartOffset < mContentOffset){
+ aPos->mStartOffset = mContentOffset;
+ }
+ if (aPos->mStartOffset > (mContentOffset + mContentLength)){
+ nsIFrame *nextContinuation = GetNextContinuation();
+ if (!nextContinuation){
+ NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more continuation\n");
+ return NS_ERROR_INVALID_ARG;
+ }
+ return nextContinuation->PeekOffset(aPresContext, aPos);
+ }
+
+ // XXX TODO: explain the following:
+ // - if this frame is the first of the last in the line according
+ // to the content indices, why not handle the cases of
+ // eSelectBeginLine/eSelectEndLine
+ // - why can't we make the hand-off to the parent class' method
+ // before correcting aPos->mStartOffset?
+
+ if (aPos->mAmount == eSelectLine || aPos->mAmount == eSelectBeginLine
+ || aPos->mAmount == eSelectEndLine || aPos->mAmount == eSelectParagraph)
+ {
+ return nsFrame::PeekOffset(aPresContext, aPos);
+ }
+
nsAutoTextBuffer paintBuffer;
nsAutoIndexBuffer indexBuffer;
nsresult rv = indexBuffer.GrowTo(mContentLength + 1);
if (NS_FAILED(rv)) {
- return PR_FALSE;
- }
- PRInt32 textLength;
- nsTextTransformer tx(presContext);
- PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
+ return rv;
+ }
PRInt32* ip = indexBuffer.mBuffer;
- PRBool found = PR_TRUE;
-
- PRBool selectable;
- PRUint8 selectStyle;
-
- IsSelectable(&selectable, &selectStyle);
- if (selectStyle == NS_STYLE_USER_SELECT_ALL)
- return PR_FALSE;
-
- if (!aForward) {
- *aOffset = 0;
- PRInt32 i;
-
- nsAutoPRUint8Buffer clusterBuffer;
- rv = FillClusterBuffer(presContext, paintBuffer.mBuffer,
- (PRUint32)textLength, clusterBuffer);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (i = startOffset-1; i >= 0; i--){
- if ((ip[i] < ip[startOffset]) &&
- (clusterBuffer.mBuffer[ip[i] - mContentOffset]) &&
- (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))
+ PRInt32 textLength;
+ nsresult result(NS_ERROR_FAILURE);
+ aPos->mResultContent = mContent;//do this right off
+ switch (aPos->mAmount){
+ case eSelectNoAmount:
+ {
+ if (!IsEmpty()) //if no renderable length, you can't park here.
{
- *aOffset = i;
- break;
+ aPos->mContentOffset = aPos->mStartOffset;
+ result = NS_OK;
+ }
+ else
+ {
+ result = GetFrameFromDirection(aPresContext, aPos);
+ if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
+ return aPos->mResultFrame->PeekOffset(aPresContext, aPos);
+ else if (NS_FAILED(result))
+ return result;
}
}
-
-#ifdef SUNCTL
- static NS_DEFINE_CID(kLECID, NS_ULE_CID);
-
- nsCOMPtr ctlObj;
- ctlObj = do_CreateInstance(kLECID, &rv);
- if (NS_FAILED(rv)) {
- NS_WARNING("Cell based cursor movement will not be supported\n");
- ctlObj = nsnull;
- }
- else {
- PRBool needsCTL = PR_FALSE;
- PRInt32 previousOffset;
-
- ctlObj->NeedsCTLFix(NS_REINTERPRET_CAST(const PRUnichar*,
- paintBuffer.mBuffer),
- mContentOffset + startOffset, -1, &needsCTL);
-
- if (needsCTL) {
- ctlObj->PrevCluster(NS_REINTERPRET_CAST(const PRUnichar*,
- paintBuffer.mBuffer),
- textLength, mContentOffset + startOffset,
- &previousOffset);
- *aOffset = i = previousOffset - mContentOffset;
- }
- }
-#endif /* SUNCTL */
-
- if (i < 0)
- found = PR_FALSE;
- }
- else // aForward
- {
- PRInt32 i;
- *aOffset = mContentLength;
-
- nsAutoPRUint8Buffer clusterBuffer;
- rv = FillClusterBuffer(presContext, paintBuffer.mBuffer,
- (PRUint32)textLength, clusterBuffer);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (i = startOffset; i <= mContentLength; i++) {
- if ((ip[i] > ip[startOffset]) &&
- ((i == mContentLength) ||
- (!IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i] - mContentOffset])) &&
- (clusterBuffer.mBuffer[ip[i] - mContentOffset]))) {
- *aOffset = i;
- break;
- }
- }
-
-#ifdef SUNCTL
- static NS_DEFINE_CID(kLECID, NS_ULE_CID);
-
- nsCOMPtr ctlObj;
- ctlObj = do_CreateInstance(kLECID, &rv);
- if (NS_FAILED(rv)) {
- NS_WARNING("Cell based cursor movement will not be supported\n");
- ctlObj = nsnull;
- }
- else {
- PRBool needsCTL = PR_FALSE;
- PRInt32 nextOffset;
-
- ctlObj->NeedsCTLFix(NS_REINTERPRET_CAST(const PRUnichar*,
- paintBuffer.mBuffer),
- mContentOffset + startOffset, 0, &needsCTL);
-
- if (needsCTL) {
-
- ctlObj->NextCluster(NS_REINTERPRET_CAST(const PRUnichar*,
- paintBuffer.mBuffer),
- textLength, mContentOffset + startOffset,
- &nextOffset);
- *aOffset = i = nextOffset - mContentOffset;
- }
- }
-#endif /* SUNCTL */
-
- if (i > mContentLength)
- found = PR_FALSE;
- }
- return found;
-}
+ break;
-PRBool
-nsTextFrame::PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
- PRInt32* aOffset, PRBool* aSawBeforeType)
-{
- NS_ASSERTION (aOffset && *aOffset <= mContentLength, "aOffset out of range");
- PRInt32 startOffset = *aOffset;
- if (startOffset < 0)
- startOffset = mContentLength;
-
- nsTextTransformer tx(GetPresContext());
- PRBool keepSearching = PR_TRUE; //if you run out of chars before you hit the end of word, maybe next frame has more text to select?
- PRBool found = PR_FALSE;
- PRBool isWhitespace, wasTransformed;
- PRInt32 wordLen, contentLen;
-
- PRBool selectable;
- PRUint8 selectStyle;
- IsSelectable(&selectable, &selectStyle);
- if (selectStyle == NS_STYLE_USER_SELECT_ALL)
- found = PR_FALSE;
- else
- {
- tx.Init(this, mContent, mContentOffset + startOffset);
- if (!aForward) {
- *aOffset = 0; //initialize
+ case eSelectCharacter:
+ {
+ // Transform text from content into renderable form
+ nsIDocument* doc = mContent->GetDocument();
+ if (!doc) {
+ return NS_OK;
+ }
+ nsTextTransformer tx(aPresContext);
+ PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
+
+ PRBool found = PR_TRUE;
+
+ PRBool selectable;
+ PRUint8 selectStyle;
+
+ IsSelectable(&selectable, &selectStyle);
+ if ( selectStyle == NS_STYLE_USER_SELECT_ALL )
+ found = PR_FALSE;
+ else
+ {
+
+ #ifdef IBMBIDI
+ if (!movementIsInFrameDirection){
+ #else
+ if (aPos->mDirection == eDirPrevious){
+ #endif
+ aPos->mContentOffset = 0;
+ PRInt32 i;
+
+ nsAutoPRUint8Buffer clusterBuffer;
+ rv = FillClusterBuffer(aPresContext, paintBuffer.mBuffer,
+ (PRUint32)textLength, clusterBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (i = aPos->mStartOffset -1 - mContentOffset; i >=0; i--){
+ if ((ip[i] < ip[aPos->mStartOffset - mContentOffset]) &&
+ (clusterBuffer.mBuffer[ip[i] - mContentOffset]) &&
+ (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))
+ {
+ aPos->mContentOffset = i + mContentOffset;
+ break;
+ }
+ }
+
+ #ifdef SUNCTL
+ static NS_DEFINE_CID(kLECID, NS_ULE_CID);
+
+ nsCOMPtr ctlObj;
+ ctlObj = do_CreateInstance(kLECID, &rv);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Cell based cursor movement will not be supported\n");
+ ctlObj = nsnull;
+ }
+ else {
+ PRBool needsCTL = PR_FALSE;
+ PRInt32 previousOffset;
+
+ ctlObj->NeedsCTLFix(NS_REINTERPRET_CAST(const PRUnichar*,
+ paintBuffer.mBuffer),
+ aPos->mStartOffset, -1, &needsCTL);
+
+ if (needsCTL) {
+ ctlObj->PrevCluster(NS_REINTERPRET_CAST(const PRUnichar*,
+ paintBuffer.mBuffer),
+ textLength,aPos->mStartOffset,
+ &previousOffset);
+ aPos->mContentOffset = i = previousOffset;
+ }
+ }
+ #endif /* SUNCTL */
+
+ if (i <0){
+ found = PR_FALSE;
+ aPos->mContentOffset = mContentOffset;//in case next call fails we stop at this offset
+ }
+ }
+ #ifdef IBMBIDI
+ else if (movementIsInFrameDirection){
+ #else
+ else if (aPos->mDirection == eDirNext){
+ #endif
+ PRInt32 i;
+ aPos->mContentOffset = mContentLength;
+
+ nsAutoPRUint8Buffer clusterBuffer;
+ rv = FillClusterBuffer(aPresContext, paintBuffer.mBuffer,
+ (PRUint32)textLength, clusterBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (i = aPos->mStartOffset - mContentOffset; i <= mContentLength; i++) {
+ if ((ip[i] > ip[aPos->mStartOffset - mContentOffset]) &&
+ ((i == mContentLength) ||
+ (!IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i] - mContentOffset])) &&
+ (clusterBuffer.mBuffer[ip[i] - mContentOffset]))) {
+ aPos->mContentOffset = i + mContentOffset;
+ break;
+ }
+ }
+
+ #ifdef SUNCTL
+ static NS_DEFINE_CID(kLECID, NS_ULE_CID);
+
+ nsCOMPtr ctlObj;
+ ctlObj = do_CreateInstance(kLECID, &rv);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Cell based cursor movement will not be supported\n");
+ ctlObj = nsnull;
+ }
+ else {
+ PRBool needsCTL = PR_FALSE;
+ PRInt32 nextOffset;
+
+ ctlObj->NeedsCTLFix(NS_REINTERPRET_CAST(const PRUnichar*,
+ paintBuffer.mBuffer),
+ aPos->mStartOffset, 0, &needsCTL);
+
+ if (needsCTL) {
+
+ ctlObj->NextCluster(NS_REINTERPRET_CAST(const PRUnichar*,
+ paintBuffer.mBuffer),
+ textLength, aPos->mStartOffset,
+ &nextOffset);
+ aPos->mContentOffset = i = nextOffset;
+ }
+ }
+ #endif /* SUNCTL */
+
+ /* if (aStartOffset == 0 && (mState & TEXT_SKIP_LEADING_WS))
+ i--; //back up because we just skipped over some white space. why skip over the char also?
+ */
+ if (i > mContentLength){
+ found = PR_FALSE;
+ aPos->mContentOffset = mContentOffset + mContentLength;//in case next call fails we stop at this offset
+ }
+ }
+ }
+ if (!found)
+ {
+ result = GetFrameFromDirection(aPresContext, aPos);
+ if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
+ {
+ return aPos->mResultFrame->PeekOffset(aPresContext, aPos);
+ }
+ }
+ else
+ aPos->mResultContent = mContent;
+ }
+ break;
+
+ case eSelectWord:
+ {
+ // Transform text from content into renderable form
+ nsIDocument* doc = mContent->GetDocument();
+ if (!doc) {
+ return result;
+ }
+
+ nsTextTransformer tx(aPresContext);
+
+ PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);
+ PRBool keepSearching; //if you run out of chars before you hit the end of word, maybe next frame has more text to select?
+ PRBool found = PR_FALSE;
+ PRBool isWhitespace, wasTransformed;
+ PRInt32 wordLen, contentLen;
+ PRBool wordSelectEatSpace;
+ if (aPos->mWordMovementType != eDefaultBehavior) {
+ // aPos->mWordMovementType possible values:
+ // eEndWord: eat the space if we're moving backwards
+ // eStartWord: eat the space if we're moving forwards
+ wordSelectEatSpace = ((aPos->mWordMovementType == eEndWord) == (aPos->mDirection == eDirPrevious));
+ }
+ else {
+ // Use the hidden preference which is based on operating system behavior.
+ // This pref only affects whether moving forward by word should go to the end of this word or start of the next word.
+ // When going backwards, the start of the word is always used, on every operating system.
+ wordSelectEatSpace = aPos->mDirection == eDirNext && nsTextTransformer::GetWordSelectEatSpaceAfter();
+ }
+
+ PRBool selectable;
+ PRUint8 selectStyle;
+ IsSelectable(&selectable, &selectStyle);
+ if ( selectStyle == NS_STYLE_USER_SELECT_ALL )
+ found = PR_FALSE;
+ else
+ {
+
#ifdef IBMBIDI
- wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
-#endif // IBMBIDI
- if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,
- PR_FALSE, aIsKeyboardSelect) &&
- contentLen <= startOffset) {
- if ((aWordSelectEatSpace ? isWhitespace : !isWhitespace) || !*aSawBeforeType){
- *aOffset = startOffset - contentLen;
+ if (!movementIsInFrameDirection){
+#else
+ if (aPos->mDirection == eDirPrevious){
+#endif
keepSearching = PR_TRUE;
- if (aWordSelectEatSpace ? isWhitespace : !isWhitespace)
- *aSawBeforeType = PR_TRUE;
+ tx.Init(this, mContent, aPos->mStartOffset);
+ aPos->mContentOffset = mContentOffset;//initialize
#ifdef IBMBIDI
wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
#endif // IBMBIDI
- while (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen,
- &isWhitespace, PR_FALSE,
- aIsKeyboardSelect)){
- if (aWordSelectEatSpace ? !isWhitespace : *aSawBeforeType)
- break;
- if (contentLen >= startOffset)
- goto TryNextFrame;
- *aOffset -= contentLen;
- if (aWordSelectEatSpace ? isWhitespace : !isWhitespace)
- *aSawBeforeType = PR_TRUE;
+ if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,
+ PR_FALSE, aPos->mIsKeyboardSelect) &&
+ (aPos->mStartOffset - contentLen >= mContentOffset) ){
+ if ((wordSelectEatSpace ? isWhitespace : !isWhitespace) || !aPos->mEatingWS){
+ aPos->mContentOffset = aPos->mStartOffset - contentLen;
+ keepSearching = PR_TRUE;
+ if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
+ aPos->mEatingWS = PR_TRUE;
#ifdef IBMBIDI
- wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
+ wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
#endif // IBMBIDI
+ while (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen,
+ &isWhitespace, PR_FALSE,
+ aPos->mIsKeyboardSelect)){
+ if (wordSelectEatSpace ? !isWhitespace : aPos->mEatingWS)
+ break;
+ if (aPos->mStartOffset - contentLen <= mContentOffset)
+ goto TryNextFrame;
+ aPos->mContentOffset -= contentLen;
+ if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
+ aPos->mEatingWS = PR_TRUE;
+#ifdef IBMBIDI
+ wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;
+#endif // IBMBIDI
+ }
+ keepSearching = aPos->mContentOffset <= mContentOffset;
+ if (!keepSearching)
+ found = PR_TRUE;
+ }
+ else {
+ aPos->mContentOffset = mContentLength + mContentOffset;
+ found = PR_TRUE;
+ }
}
- keepSearching = *aOffset <= 0;
- if (!keepSearching)
- found = PR_TRUE;
}
- else {
- *aOffset = mContentLength;
- found = PR_TRUE;
- }
- }
- }
- else { // aForward
- *aOffset = mContentLength; //initialize
-
#ifdef IBMBIDI
- wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset + mContentLength : -1;
-#endif // IBMBIDI
- if (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aIsKeyboardSelect) &&
- (startOffset + contentLen <= mContentLength)) {
-
- if ((aWordSelectEatSpace ? isWhitespace : !isWhitespace) || !*aSawBeforeType) {
- *aOffset = startOffset + contentLen;
- keepSearching = PR_TRUE;
- if (aWordSelectEatSpace ? isWhitespace : !isWhitespace)
- *aSawBeforeType = PR_TRUE;
+ else if (movementIsInFrameDirection){
+#else
+ else if (aPos->mDirection == eDirNext) {
+#endif
+ tx.Init(this, mContent, aPos->mStartOffset );
+ aPos->mContentOffset = mContentOffset + mContentLength;//initialize
+
#ifdef IBMBIDI
wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset + mContentLength : -1;
#endif // IBMBIDI
- while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aIsKeyboardSelect))
- {
- if (aWordSelectEatSpace ? !isWhitespace : *aSawBeforeType)
- break;
- if (startOffset + contentLen >= mContentLength)
- goto TryNextFrame;
- if (aWordSelectEatSpace ? isWhitespace : !isWhitespace)
- *aSawBeforeType = PR_TRUE;
- *aOffset += contentLen;
+ if (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect) &&
+ (aPos->mStartOffset + contentLen <= (mContentLength + mContentOffset))){
+
+ // On some platforms (mac, unix), we want the selection to end
+ // at the end of the word (not the beginning of the next one).
+ if ((wordSelectEatSpace ? isWhitespace : !isWhitespace) || !aPos->mEatingWS) {
+ aPos->mContentOffset = aPos->mStartOffset + contentLen;
+ keepSearching = PR_TRUE;
+ if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
+ aPos->mEatingWS = PR_TRUE;
#ifdef IBMBIDI
- wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset + mContentLength : -1;
+ wordLen = (mState & NS_FRAME_IS_BIDI)
+ ? mContentOffset + mContentLength : -1;
#endif // IBMBIDI
- }
- keepSearching = *aOffset >= mContentLength;
- if (!keepSearching)
- found = PR_TRUE;
+ while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect))
+ {
+ if (wordSelectEatSpace ? !isWhitespace : aPos->mEatingWS)
+ break;
+ if (aPos->mStartOffset + contentLen >= (mContentLength + mContentOffset))
+ goto TryNextFrame;
+ if (wordSelectEatSpace ? isWhitespace : !isWhitespace)
+ aPos->mEatingWS = PR_TRUE;
+ aPos->mContentOffset += contentLen;
+#ifdef IBMBIDI
+ wordLen = (mState & NS_FRAME_IS_BIDI)
+ ? mContentOffset + mContentLength : -1;
+#endif // IBMBIDI
+ }
+ keepSearching = (mContentOffset + mContentLength) <= aPos->mContentOffset;
+ if (!keepSearching)
+ found = PR_TRUE;
+ }
+ else
+ {
+ aPos->mContentOffset = mContentOffset;
+ found = PR_TRUE;
+ }
+ }
+ }
+ }
+TryNextFrame:
+ if (!found ||
+ (aPos->mContentOffset > (mContentOffset + mContentLength)) ||
+ (aPos->mContentOffset < mContentOffset))
+ {
+ aPos->mContentOffset = PR_MIN(aPos->mContentOffset, mContentOffset + mContentLength);
+ aPos->mContentOffset = PR_MAX(aPos->mContentOffset, mContentOffset);
+ if (wordSelectEatSpace && aPos->mEatingWS) {
+ //If we want to stop at beginning of the next word
+ //GetFrameFromDirction should not return NS_ERROR_FAILURE at end of line
+ aPos->mEatingWS = PR_FALSE;
+ result = GetFrameFromDirection(aPresContext, aPos);
+ aPos->mEatingWS = PR_TRUE;
}
else
+ result = GetFrameFromDirection(aPresContext, aPos);
+ if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
{
- *aOffset = 0;
- found = PR_TRUE;
+ if (NS_SUCCEEDED(result = aPos->mResultFrame->PeekOffset(aPresContext, aPos)))
+ return NS_OK;//else fall through
+#ifdef IBMBIDI
+ else if (movementIsInFrameDirection)
+#else
+ else if (aPos->mDirection == eDirNext)
+#endif
+ aPos->mContentOffset = mContentOffset + mContentLength;
+ else
+ aPos->mContentOffset = mContentOffset;
}
- }
+ else
+ aPos->mResultContent = mContent;
+ }
+ else
+ {
+ aPos->mResultContent = mContent;
+ }
}
+ break;
+
+ default:
+ result = NS_ERROR_FAILURE; break;
}
-TryNextFrame:
- if (!found ||
- *aOffset > mContentLength ||
- *aOffset < 0)
- {
- found = PR_FALSE;
- *aOffset = PR_MIN(*aOffset, mContentLength);
- *aOffset = PR_MAX(*aOffset, 0);
+
+ if (NS_FAILED(result)){
+ aPos->mResultContent = mContent;
+ //aPos->mContentOffset = aPos->mStartOffset;
+ result = NS_OK;
}
- return found;
-}
+ aPos->mResultFrame = this;
+
+ return result;
+}
NS_IMETHODIMP
nsTextFrame::CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval)