Bug 1025815 - caretPositionFromPoint needs to account for CSS transforms. draft
authorKestrel <ke5trel@protonmail.com>
Tue, 08 May 2018 18:09:32 +0800
changeset 792382 037163bedde44f53e36df508d84aa576f9e761e5
parent 788379 ac371c7f3ebc64f0d490a983ec995d784a2d0b0f
push id109101
push userbmo:ke5trel@protonmail.com
push dateTue, 08 May 2018 10:10:11 +0000
bugs1025815
milestone61.0a1
Bug 1025815 - caretPositionFromPoint needs to account for CSS transforms. MozReview-Commit-ID: 1cTUyd0x6xy
dom/base/nsDocument.cpp
dom/base/test/test_caretPositionFromPoint.html
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -9990,20 +9990,23 @@ nsIDocument::CaretPositionFromPoint(floa
   }
 
   nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt,
       nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC);
   if (!ptFrame) {
     return nullptr;
   }
 
-  // GetContentOffsetsFromPoint requires frame-relative coordinates, so we need
-  // to adjust to frame-relative coordinates before we can perform this call.
-  // It should also not take into account the padding of the frame.
-  nsPoint adjustedPoint = pt - ptFrame->GetOffsetTo(rootFrame);
+  // We require frame-relative coordinates for GetContentOffsetsFromPoint.
+  nsPoint aOffset;
+  nsCOMPtr<nsIWidget> widget = nsContentUtils::GetWidget(ps, &aOffset);
+  LayoutDeviceIntPoint refPoint =
+    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), aOffset, GetPresContext());
+  nsPoint adjustedPoint =
+    nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, refPoint, ptFrame);
 
   nsFrame::ContentOffsets offsets =
     ptFrame->GetContentOffsetsFromPoint(adjustedPoint);
 
   nsCOMPtr<nsIContent> node = offsets.content;
   uint32_t offset = offsets.offset;
   nsCOMPtr<nsIContent> anonNode = node;
   bool nodeIsAnonymous = node && node->IsInNativeAnonymousSubtree();
--- a/dom/base/test/test_caretPositionFromPoint.html
+++ b/dom/base/test/test_caretPositionFromPoint.html
@@ -100,24 +100,32 @@
     var test6Rect = test6Element.getBoundingClientRect();
     checkOffsetsFromPoint(Math.round(test6Rect.left + 4),
                           Math.round(test6Rect.top + (test6Rect.height / 2)),
                           0, "test6");
     checkOffsetsFromPoint(Math.round(test6Rect.left + test6Rect.width - 30),
                           Math.round(test6Rect.top + (test6Rect.height / 2)),
                           5, "test6");
 
+    // Check the first and last characters of the transformed div.
+    var test7Element = document.getElementById('test7');
+    var test7Rect = test7Element.getBoundingClientRect();
+    checkOffsetsFromPoint(Math.round(test7Rect.left + 1), Math.round(test7Rect.top + 1), 0, 'test7');
+    checkOffsetsFromPoint(Math.round(test7Rect.right - 1), Math.round(test7Rect.top + 1), 13, 'test7');
+
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
 </script>
 </head>
 <body onload="doTesting();">
 <div id="a" contenteditable><span id="test1">abc, abc, abc</span><br>
 <span id="test2" style="color: blue;">abc, abc, abc</span><br>
 <textarea id="test3">abc</textarea><input id="test4" value="abcdef"><br><br>
 <marquee>marquee</marquee>
+<!-- Translate test7 while staying within confines of the test viewport -->
+<div id="test7" style="transform: translate(140px, -20px); display: inline-block;">abc, abc, abc</div>
 </div>
 <input id="test5" value="The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down a very deep well. Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything; then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves; here and there she saw maps and pictures hung upon pegs. She took down a jar from one of the shelves as she passed; it was labelled `ORANGE MARMALADE', but to her great disappointment it was empty: she did not like to drop the jar for fear of killing somebody, so managed to put it into one of the cupboards as she fell past it." type="text">
 <input id="test6" type="number" style="width:150px; height:57px;" value="31415"><br>
 </body>
 </html>