# HG changeset patch # Parent 30916c9ca768c83720a32fa8ff4904e60c5af9ed # User Jorg K Bug 756984 - Editor: Changing location in editor doesn't preserve the font when returning to end of text/line. r=ehsan diff --git a/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js b/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js --- a/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js +++ b/editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js @@ -517,25 +517,19 @@ const knownFailures = { "S-Proposed-SM:e.b.w_TEXT-1_SI-5-body": true, "S-Proposed-SM:e.b.w_TEXT-1_SI-5-div": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-1-dM": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-1-body": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-1-div": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-3-dM": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-3-body": true, "S-Proposed-SM:e.f.w_TEXT-1_SIR-3-div": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SC-1-dM": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SC-1-body": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SC-1-div": true, "S-Proposed-SM:e.f.lb_BR.BR-1_SI-1-dM": true, "S-Proposed-SM:e.f.lb_BR.BR-1_SI-1-body": true, "S-Proposed-SM:e.f.lb_BR.BR-1_SI-1-div": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SM-1-dM": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SM-1-body": true, - "S-Proposed-SM:e.f.lb_BR.BR-1_SM-1-div": true, "S-Proposed-SM:e.f.lb_P.P.P-1_SI-1-dM": true, "S-Proposed-SM:e.f.lb_P.P.P-1_SI-1-body": true, "S-Proposed-SM:e.f.lb_P.P.P-1_SI-1-div": true, "S-Proposed-SM:e.b.lb_BR.BR-1_SIR-2-dM": true, "S-Proposed-SM:e.b.lb_BR.BR-1_SIR-2-body": true, "S-Proposed-SM:e.b.lb_BR.BR-1_SIR-2-div": true, "S-Proposed-SM:e.b.lb_P.P.P-1_SIR-2-dM": true, "S-Proposed-SM:e.b.lb_P.P.P-1_SIR-2-body": true, diff --git a/editor/libeditor/tests/test_selection_move_commands.xul b/editor/libeditor/tests/test_selection_move_commands.xul --- a/editor/libeditor/tests/test_selection_move_commands.xul +++ b/editor/libeditor/tests/test_selection_move_commands.xul @@ -166,19 +166,19 @@ function execTests() { doCommand("cmd_moveBottom"); testMoveCommand("cmd_charPrevious", node(22), 1); testMoveCommand("cmd_charNext", node(22), 2); testSelectCommand("cmd_selectCharPrevious", node(22), 1); doCommand("cmd_moveTop"); testSelectCommand("cmd_selectCharNext", node(0), 1); doCommand("cmd_moveTop"); - testMoveCommand("cmd_endLine", body, 1); + testMoveCommand("cmd_endLine", node(0), 1); testMoveCommand("cmd_beginLine", node(0), 0); - testSelectCommand("cmd_selectEndLine", body, 1); + testSelectCommand("cmd_selectEndLine", node(0), 1); doCommand("cmd_moveBottom"); testSelectCommand("cmd_selectBeginLine", node(22), 0); doCommand("cmd_moveBottom"); testMoveCommand("cmd_wordPrevious", node(22), 0); testMoveCommand("cmd_wordNext", body, 23); testSelectCommand("cmd_selectWordPrevious", node(22), 0); doCommand("cmd_moveTop"); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -3546,20 +3546,26 @@ static FrameTarget GetSelectionClosestFr nsIFrame *frame = aLine->mFirstChild; // Account for end of lines (any iterator from the block is valid) if (aLine == aParent->end_lines()) return DrillDownToSelectionFrame(aParent, true, aFlags); nsIFrame *closestFromIStart = nullptr, *closestFromIEnd = nullptr; nscoord closestIStart = aLine->IStart(), closestIEnd = aLine->IEnd(); WritingMode wm = aLine->mWritingMode; LogicalPoint pt(wm, aPoint, aLine->mContainerWidth); + bool canSkipBr = false; for (int32_t n = aLine->GetChildCount(); n; --n, frame = frame->GetNextSibling()) { - if (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty()) + // Skip brFrames. Can only skip if the line contains at least + // one selectable and non-empty frame before + if (!SelfIsSelectable(frame, aFlags) || frame->IsEmpty() || + (canSkipBr && frame->GetType() == nsGkAtoms::brFrame)) { continue; + } + canSkipBr = true; LogicalRect frameRect = LogicalRect(wm, frame->GetRect(), aLine->mContainerWidth); if (pt.I(wm) >= frameRect.IStart(wm)) { if (pt.I(wm) < frameRect.IEnd(wm)) { return GetSelectionClosestFrameForChild(frame, aPoint, aFlags); } if (frameRect.IEnd(wm) >= closestIStart) { closestFromIStart = frame; @@ -6793,16 +6799,22 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* } } else { it->GetLine(thisLine, &firstFrame, &lineFrameCount, usedRect); nsIFrame* frame = firstFrame; for (int32_t count = lineFrameCount; count; --count, frame = frame->GetNextSibling()) { if (!frame->IsGeneratedContentFrame()) { + // When jumping to the end of the line with the "end" key, + // skip over brFrames + if (endOfLine && lineFrameCount > 1 && + frame->GetType() == nsGkAtoms::brFrame) { + continue; + } baseFrame = frame; if (!endOfLine) break; } } } if (!baseFrame) return NS_ERROR_FAILURE; @@ -7074,16 +7086,33 @@ nsIFrame::GetFrameFromDirection(nsDirect // Skip anonymous elements, but watch out for generated content if (!traversedFrame || (!traversedFrame->IsGeneratedContentFrame() && traversedFrame->GetContent()->IsRootOfNativeAnonymousSubtree())) { return NS_ERROR_FAILURE; } + // Skip brFrames, but only if they are not the only frame in the line + if (atLineEdge && aDirection == eDirPrevious && + traversedFrame->GetType() == nsGkAtoms::brFrame) { + int32_t lineFrameCount; + nsIFrame *currentBlockFrame, *currentFirstFrame; + nsRect usedRect; + int32_t currentLine = nsFrame::GetLineNumber(traversedFrame, aScrollViewStop, ¤tBlockFrame); + nsAutoLineIterator iter = currentBlockFrame->GetLineIterator(); + result = iter->GetLine(currentLine, ¤tFirstFrame, &lineFrameCount, usedRect); + if (NS_FAILED(result)) { + return result; + } + if (lineFrameCount > 1) { + continue; + } + } + traversedFrame->IsSelectable(&selectable, nullptr); if (!selectable) { *aOutMovedOverNonSelectableText = true; } } // while (!selectable) *aOutOffset = (aDirection == eDirNext) ? 0 : -1; diff --git a/layout/generic/test/mochitest.ini b/layout/generic/test/mochitest.ini --- a/layout/generic/test/mochitest.ini +++ b/layout/generic/test/mochitest.ini @@ -77,16 +77,17 @@ support-files = bug633762_iframe.html [test_bug666225.html] [test_bug719503.html] [test_bug719515.html] [test_bug719518.html] [test_bug719523.html] [test_bug735641.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage [test_bug748961.html] +[test_bug756984.html] [test_bug784410.html] skip-if = buildapp == 'b2g' #Bug 931116, 1129060 no wheel events on b2g [test_bug785324.html] [test_bug791616.html] skip-if = buildapp == 'b2g' # b2g(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438) b2g-debug(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438) b2g-desktop(Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438) [test_bug831780.html] [test_bug841361.html] [test_bug904810.html] diff --git a/layout/generic/test/test_bug756984.html b/layout/generic/test/test_bug756984.html new file mode 100644 --- /dev/null +++ b/layout/generic/test/test_bug756984.html @@ -0,0 +1,66 @@ + + + + + + Test for Bug 756984 + + + + + +Mozilla Bug 756984 +

+ + +
123
45678
+

45678
+ +
+
+ 
+
+
+ + diff --git a/layout/generic/test/test_movement_by_characters.html b/layout/generic/test/test_movement_by_characters.html --- a/layout/generic/test/test_movement_by_characters.html +++ b/layout/generic/test/test_movement_by_characters.html @@ -65,17 +65,17 @@ function test() { editor.innerHTML = "H
K"; sel.collapse(editor.firstChild, 0); testRight(editor.firstChild, 1); testRight(editor.firstChild, 2); testRight(editor.firstChild.nextSibling.nextSibling, 0); testRight(editor.firstChild.nextSibling.nextSibling, 1); testLeft(editor.firstChild.nextSibling.nextSibling, 0); - testLeft(editor, 1); + testLeft(editor.firstChild, 2); testLeft(editor.firstChild, 1); testLeft(editor.firstChild, 0); editor.innerHTML = "
aa\nbb
"; sel.collapse(editor.firstChild.firstChild, 0); testRight(editor.firstChild.firstChild, 1); // at the end of the first line, before the \n testRight(editor.firstChild.firstChild, 2);