Title: [90800] trunk
Revision
90800
Author
rn...@webkit.org
Date
2011-07-11 18:10:32 -0700 (Mon, 11 Jul 2011)

Log Message

positionForPoint is broken when a block is positioned relatively inside the parent
https://bugs.webkit.org/show_bug.cgi?id=64298

Reviewed by Simon Fraser.

Source/WebCore: 

The bug was caused by positionForPointRespectingEditingBoundaries's not taking relativePositionOffset
into account when computing the point in child coordinates. Fixed the bug by adding the offset to
childLocation as needed.

Test: fast/block/positioning/hittest-on-relative-positioned-children.html

* rendering/RenderBlock.cpp:
(WebCore::positionForPointRespectingEditingBoundaries): Fixed the bug; also replaced all instances of
IntPoint by LayoutPoint.

LayoutTests: 

Added a test for hit testing on relatively positioned children.

* fast/block/positioning/hittest-on-relative-positioned-children-expected.txt: Added.
* fast/block/positioning/hittest-on-relative-positioned-children.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (90799 => 90800)


--- trunk/LayoutTests/ChangeLog	2011-07-12 01:10:07 UTC (rev 90799)
+++ trunk/LayoutTests/ChangeLog	2011-07-12 01:10:32 UTC (rev 90800)
@@ -1,3 +1,15 @@
+2011-07-11  Ryosuke Niwa  <rn...@webkit.org>
+
+        positionForPoint is broken when a block is positioned relatively inside the parent
+        https://bugs.webkit.org/show_bug.cgi?id=64298
+
+        Reviewed by Simon Fraser.
+
+        Added a test for hit testing on relatively positioned children.
+
+        * fast/block/positioning/hittest-on-relative-positioned-children-expected.txt: Added.
+        * fast/block/positioning/hittest-on-relative-positioned-children.html: Added.
+
 2011-07-11  Dan Bernstein  <m...@apple.com>
 
         Excessive expansion of justified text when rounding hacks are enabled

Added: trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children-expected.txt (0 => 90800)


--- trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children-expected.txt	2011-07-12 01:10:32 UTC (rev 90800)
@@ -0,0 +1,16 @@
+This tests hit testing on relative positioned children. To manually test, select text by a mouse drag starting in the blue box but outside red boxes and ending inside a red box.
+
+PASS Selecting line 1 of box 1 selected "first line"
+PASS Selecting line 2 of box 1 selected "second line"
+PASS Selecting line 3 of box 1 selected "third line"
+PASS Selecting line 1 of box 2 selected "first line"
+PASS Selecting line 2 of box 2 selected "second line"
+PASS Selecting line 3 of box 2 selected "third line"
+PASS Selecting line 1 of box 3 selected "first line"
+PASS Selecting line 2 of box 3 selected "second line"
+PASS Selecting line 3 of box 3 selected "third line"
+PASS Selecting line 1 of box 4 selected "first line"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children.html (0 => 90800)


--- trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/positioning/hittest-on-relative-positioned-children.html	2011-07-12 01:10:32 UTC (rev 90800)
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description">This tests hit testing on relative positioned children. To manually test, select text by a mouse drag
+starting in the blue box but outside red boxes and ending inside a red box.</p>
+<div id="tests" style="margin-bottom: 200px; width: 300px; border: solid 5px #ccf;">
+<div style="position: relative; left: 50px; width: 200px; border: solid 5px #f66;">
+first line<br>
+second line<br>
+third line<br>
+</div>
+<div style="position: relative; left: 300px; width: 200px; border: solid 5px #f66;">
+first line<br>
+second line<br>
+third line<br>
+</div>
+<div style="position: relative; left: 250px; width: 200px; border: solid 5px #f66;">
+first line<br>
+second line<br>
+third line<br>
+</div>
+<div class="testVerticalSelection" style="position: relative; top: 4em; width: 200px; border: solid 5px #f66;">
+first line<br>
+second line<br>
+third line<br>
+</div>
+</div>
+<div id="console"></div>
+<script>
+
+function runTest(boxName, testDiv) {
+    var testVerticalSelection = testDiv.className == 'testVerticalSelection';
+
+    var expectedString = [null, "first line", "second line", "third line"];
+    for (var line = 1; line <= 3; line++) {
+        var y = testDiv.offsetTop + testDiv.offsetHeight * (line - 1) / 3 + 5;
+        if (testVerticalSelection)
+            eventSender.mouseMoveTo(testDiv.offsetLeft, y - 20);
+        else
+            eventSender.mouseMoveTo(testDiv.offsetLeft - 10, y);
+        eventSender.mouseDown();
+
+        eventSender.leapForward(200);
+
+        eventSender.mouseMoveTo(testDiv.offsetLeft + testDiv.offsetWidth - 20, y);
+        eventSender.mouseUp();
+
+        var actual = window.getSelection().toString();
+        var action = "" line " + line + ' of ' + boxName + ' selected "' + actual + '"';
+        if (actual == expectedString[line])
+            testPassed(action);
+        else
+            testFailed(action + ', expected "' + expectedString[line] + '"')
+
+        if (testVerticalSelection)
+            break;
+    }
+}
+
+if (window.layoutTestController) {
+    var tests = document.getElementById('tests').getElementsByTagName('div');
+    for (var i = 0; i < tests.length; i++)
+        runTest("box " + (i + 1), tests[i]);
+    document.getElementById('tests').style.display = 'none';
+}
+
+var successfullyParsed = true;
+
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (90799 => 90800)


--- trunk/Source/WebCore/ChangeLog	2011-07-12 01:10:07 UTC (rev 90799)
+++ trunk/Source/WebCore/ChangeLog	2011-07-12 01:10:32 UTC (rev 90800)
@@ -1,3 +1,20 @@
+2011-07-11  Ryosuke Niwa  <rn...@webkit.org>
+
+        positionForPoint is broken when a block is positioned relatively inside the parent
+        https://bugs.webkit.org/show_bug.cgi?id=64298
+
+        Reviewed by Simon Fraser.
+
+        The bug was caused by positionForPointRespectingEditingBoundaries's not taking relativePositionOffset
+        into account when computing the point in child coordinates. Fixed the bug by adding the offset to
+        childLocation as needed.
+
+        Test: fast/block/positioning/hittest-on-relative-positioned-children.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::positionForPointRespectingEditingBoundaries): Fixed the bug; also replaced all instances of
+        IntPoint by LayoutPoint.
+
 2011-07-11  Dan Bernstein  <m...@apple.com>
 
         Excessive expansion of justified text when rounding hacks are enabled

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (90799 => 90800)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2011-07-12 01:10:07 UTC (rev 90799)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2011-07-12 01:10:32 UTC (rev 90800)
@@ -4117,10 +4117,13 @@
 // FIXME: This function should go on RenderObject as an instance method. Then
 // all cases in which positionForPoint recurs could call this instead to
 // prevent crossing editable boundaries. This would require many tests.
-static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
+static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
 {
+    LayoutPoint childLocation = child->location();
+    if (child->isRelPositioned())
+        childLocation += child->relativePositionOffset();
     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
-    IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
+    LayoutPoint pointInChildCoordinates(pointInParentCoordinates - childLocation);
 
     // If this is an anonymous renderer, we just recur normally
     Node* childNode = child->node();
@@ -4138,8 +4141,8 @@
         return child->positionForPoint(pointInChildCoordinates);
 
     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
-    int childMiddle = parent->logicalWidthForChild(child) / 2;
-    int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
+    LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2;
+    LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
     if (logicalLeft < childMiddle)
         return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
     return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to