Index: mozilla/layout/generic/nsTextFrame.cpp =================================================================== RCS file: /cvsroot/mozilla/layout/generic/nsTextFrame.cpp,v retrieving revision 1.575 diff -pU30 -r1.575 mozilla/layout/generic/nsTextFrame.cpp --- mozilla/layout/generic/nsTextFrame.cpp +++ mozilla/layout/generic/nsTextFrame.cpp @@ -4476,111 +4476,111 @@ nsTextFrame::GetChildFrameContainingOffs } else { if (contentOffset != mContentLength) //that condition was only for when there is a choice return NS_ERROR_FAILURE; } } if (inContentOffset < mContentOffset) //could happen with floats! { *outChildFrame = GetPrevInFlow(); if (*outChildFrame) return (*outChildFrame)->GetChildFrameContainingOffset(inContentOffset, inHint, outFrameContentOffset,outChildFrame); else return NS_OK; //this can't be the right thing to do? } *outFrameContentOffset = contentOffset; *outChildFrame = this; return NS_OK; } NS_IMETHODIMP nsTextFrame::PeekOffset(nsPresContext* aPresContext, nsPeekOffsetStruct *aPos) { DEBUG_VERIFY_NOT_DIRTY(mState); if (mState & NS_FRAME_IS_DIRTY) return NS_ERROR_UNEXPECTED; + if (!aPos || !mContent) + return NS_ERROR_NULL_POINTER; + #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 if (aPos->mStartOffset < 0 ) aPos->mStartOffset = mContentLength + mContentOffset; if (aPos->mStartOffset < mContentOffset){ aPos->mStartOffset = mContentOffset; } if (aPos->mStartOffset > (mContentOffset + mContentLength)){ nsIFrame *nextContinuation = GetNextContinuation();