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 @@
+
+
+
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 @@ + + +
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 @@ + + +
ABC+