diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 2824b2f9bcac..989ae08b918c 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -81,9 +81,37 @@ static nsLineBox* FindContainingLine(nsIFrame* aFrame) { return nullptr; } +static bool AdjustCaretFrameForLineStart(nsIFrame*& aFrame, + int32_t& aFrameOffset, + nsFrameSelection& aFrameSelection) { + if (!aFrame->HasSignificantTerminalNewline()) { + return false; + } + + int32_t start; + int32_t end; + aFrame->GetOffsets(start, end); + if (aFrameOffset != end) { + return false; + } + + nsIFrame* nextSibling = aFrame->GetNextSibling(); + if (!nextSibling) { + return false; + } + + aFrame = nextSibling; + aFrame->GetOffsets(start, end); + aFrameOffset = start; + aFrameSelection.SetHint(CARET_ASSOCIATE_AFTER); + return true; +} + static void AdjustCaretFrameForLineEnd(nsIFrame** aFrame, int32_t* aOffset) { nsLineBox* line = FindContainingLine(*aFrame); - if (!line) return; + if (!line) { + return; + } int32_t count = line->GetChildCount(); for (nsIFrame* f = line->mFirstChild; count > 0; --count, f = f->GetNextSibling()) { @@ -636,11 +664,16 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset( *aReturnUnadjustedFrame = theFrame; } - // if theFrame is after a text frame that's logically at the end of the line - // (e.g. if theFrame is a
frame), then put the caret at the end of - // that text frame instead. This way, the caret will be positioned as if - // trailing whitespace was not trimmed. - AdjustCaretFrameForLineEnd(&theFrame, &theFrameOffset); + // if theFrame is a text frame with a significant terminal character, use the + // next frame instead + if (!AdjustCaretFrameForLineStart(theFrame, theFrameOffset, + *aFrameSelection)) { + // if theFrame is after a text frame that's logically at the end of the line + // (e.g. if theFrame is a
frame), then put the caret at the end of + // that text frame instead. This way, the caret will be positioned as if + // trailing whitespace was not trimmed. + AdjustCaretFrameForLineEnd(&theFrame, &theFrameOffset); + }; // Mamdouh : modification of the caret to work at rtl and ltr with Bidi // diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index d66d584a6488..a773c4b3c38c 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -1028,16 +1028,8 @@ nsresult nsTextControlFrame::OffsetToDOMPoint(uint32_t aOffset, *aPosition = 0; } else if (textNode) { uint32_t textLength = textNode->Length(); - if (length == 2 && aOffset == textLength) { - // If we're at the end of the text node and we have a trailing BR node, - // set the selection on the BR node. - rootNode.forget(aResult); - *aPosition = 1; - } else { - // Otherwise, set the selection on the textnode itself. - firstNode.forget(aResult); - *aPosition = std::min(aOffset, textLength); - } + firstNode.forget(aResult); + *aPosition = std::min(aOffset, textLength); } else { rootNode.forget(aResult); *aPosition = 0; diff --git a/testing/web-platform/meta/selection/caret/__dir__.ini b/testing/web-platform/meta/selection/caret/__dir__.ini new file mode 100644 index 000000000000..1f02b291e181 --- /dev/null +++ b/testing/web-platform/meta/selection/caret/__dir__.ini @@ -0,0 +1 @@ +prefs: [ui.caretBlinkTime:-1] diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html new file mode 100644 index 000000000000..6863456f06e0 --- /dev/null +++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html @@ -0,0 +1,12 @@ + + +selection.collapse() to line start + + + + +
ABC
+
+ diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html new file mode 100644 index 000000000000..ac119cbb3167 --- /dev/null +++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html @@ -0,0 +1,13 @@ + + +selection.collapse() to line start + + + + +
ABC
+
+
+ diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html new file mode 100644 index 000000000000..2b25941ded7e --- /dev/null +++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html @@ -0,0 +1,8 @@ + + +selection.collapse() to line start +
ABC

+