Title: [123980] trunk
Revision
123980
Author
[email protected]
Date
2012-07-29 10:27:35 -0700 (Sun, 29 Jul 2012)

Log Message

In flipped blocks, a point on the top edge of a box is considered outside the box (and vice versa)
https://bugs.webkit.org/show_bug.cgi?id=92593

Reviewed by Simon Fraser.

Source/WebCore: 

With respect to hit testing, boxes should always behave as half-open intervals which include
the physical top and left edges and not the bottom and right edges.
RenderBlock::positionForPoint was not adhering to this, since it was comparing flipped
coordinates.

Tests: fast/writing-mode/flipped-blocks-hit-test-box-edges.html
       fast/writing-mode/flipped-blocks-hit-test-line-edges.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::positionForPointWithInlineChildren): When blocks are flipped, changed
strict inequalities of y coordinates into non-strict ones and non-strict inequalities into
strict ones.
(WebCore::RenderBlock::positionForPoint): Ditto, except for the test for being under the top
of the last candidate box, which was made non-strict in the unflipped case and remained
strict.

LayoutTests: 

* fast/writing-mode/flipped-blocks-hit-test-box-edges-expected.txt: Added.
* fast/writing-mode/flipped-blocks-hit-test-box-edges.html: Added.
* fast/writing-mode/flipped-blocks-hit-test-line-edges-expected.txt: Added.
* fast/writing-mode/flipped-blocks-hit-test-line-edges.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (123979 => 123980)


--- trunk/LayoutTests/ChangeLog	2012-07-29 14:49:07 UTC (rev 123979)
+++ trunk/LayoutTests/ChangeLog	2012-07-29 17:27:35 UTC (rev 123980)
@@ -1,3 +1,15 @@
+2012-07-29  Dan Bernstein  <[email protected]>
+
+        In flipped blocks, a point on the top edge of a box is considered outside the box (and vice versa)
+        https://bugs.webkit.org/show_bug.cgi?id=92593
+
+        Reviewed by Simon Fraser.
+
+        * fast/writing-mode/flipped-blocks-hit-test-box-edges-expected.txt: Added.
+        * fast/writing-mode/flipped-blocks-hit-test-box-edges.html: Added.
+        * fast/writing-mode/flipped-blocks-hit-test-line-edges-expected.txt: Added.
+        * fast/writing-mode/flipped-blocks-hit-test-line-edges.html: Added.
+
 2012-07-29  Mike West  <[email protected]>
 
         Extend `application/x-webkit-test-netscape` plugins to better support multiple frames.

Added: trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges-expected.txt (0 => 123980)


--- trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges-expected.txt	2012-07-29 17:27:35 UTC (rev 123980)
@@ -0,0 +1,13 @@
+y	x	element	range start container
+25	25	outer	after-after
+25	100	after-after	after-after
+49	25	outer	after
+49	100	after	after
+50	25	outer	middle
+50	100	middle	middle
+149	25	outer	middle
+149	100	middle	middle
+150	25	outer	before
+150	100	before	before
+165	25	outer	before-before
+165	100	before-before	before-before

Added: trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges.html (0 => 123980)


--- trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges.html	                        (rev 0)
+++ trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-box-edges.html	2012-07-29 17:27:35 UTC (rev 123980)
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<style>
+    #outer > div { margin: 0 25px; }
+</style>
+<div id="outer" style="
+    outline: dashed lightblue;
+    width: 150px;
+    padding: 25px;
+    -webkit-writing-mode: horizontal-bt;
+">
+    <div id="before-before" style="
+        background-color: purple;
+        height: 10px;
+    "></div>
+    <div id="before" style="
+        background-color: silver;
+        height: 15px;
+    "></div>
+    <div id="middle" style="
+        background-color: blue;
+        height: 100px;
+    "></div>
+    <div id="after" style="
+        background-color: silver;
+        height: 15px;
+    "></div>
+    <div id="after-after" style="
+        background-color: purple;
+        height: 10px;
+    "></div>
+</div>
+<table id="results">
+    <thead>
+        <tr>
+            <th>y</th>
+            <th>x</th>
+            <th>element</th>
+            <th>range start container</th>
+        </tr>
+    </thead>
+    <tbody id="table-body">
+    </tbody>
+</table>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+
+    function addCell(row, text)
+    {
+        row.appendChild(document.createElement("td")).appendChild(document.createTextNode(text));
+    }
+
+    function test(x, y)
+    {
+        var row = document.getElementById("table-body").appendChild(document.createElement("tr"));
+        addCell(row, y);
+        addCell(row, x);
+        addCell(row, document.elementFromPoint(8 + x, 8 + y).id);
+        addCell(row, document.caretRangeFromPoint(8 + x, 8 + y).startContainer.id);
+    }
+
+    test(25, 25);
+    test(100, 25);
+    test(25, 49);
+    test(100, 49);
+    test(25, 50);
+    test(100, 50);
+    test(25, 149);
+    test(100, 149);
+    test(25, 150);
+    test(100, 150);
+    test(25, 165);
+    test(100, 165);
+</script>

Added: trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges-expected.txt (0 => 123980)


--- trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges-expected.txt	2012-07-29 17:27:35 UTC (rev 123980)
@@ -0,0 +1,7 @@
+Lorem ipsum dolor sit amet
+PASS: offset at (160,105) was 5.
+PASS: offset at (160,104) was 11.
+PASS: offset at (160,26) was 26.
+PASS: offset at (160,25) was 26.
+PASS: offset at (160,24) was 26.
+

Added: trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges.html (0 => 123980)


--- trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges.html	                        (rev 0)
+++ trunk/LayoutTests/fast/writing-mode/flipped-blocks-hit-test-line-edges.html	2012-07-29 17:27:35 UTC (rev 123980)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<div id="target" style="
+    outline: dashed lightblue;
+    width: 150px;
+    padding: 25px;
+    font: 20px ahem;
+    -webkit-writing-mode: horizontal-bt;
+">Lorem ipsum dolor sit amet</div>
+<pre id="log"></pre>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+
+    function log(message)
+    {
+        document.getElementById("log").appendChild(document.createTextNode(message + "\n"));
+    }
+
+    function test(x, y, expectedOffset)
+    {
+        var actualOffset = document.caretRangeFromPoint(8 + x, 8 + y).startOffset;
+        if (actualOffset === expectedOffset)
+            log("PASS: offset at (" + x + "," + y + ") was " + actualOffset + ".");
+        else
+            log("FAIL: offset at (" + x + "," + y + ") was " + actualOffset + ". Expected " + expectedOffset + ".");
+    }
+
+    test(160, 105, 5);
+    test(160, 104, 11);
+    test(160, 26, 26);
+    test(160, 25, 26);
+    test(160, 24, 26);
+</script>

Modified: trunk/Source/WebCore/ChangeLog (123979 => 123980)


--- trunk/Source/WebCore/ChangeLog	2012-07-29 14:49:07 UTC (rev 123979)
+++ trunk/Source/WebCore/ChangeLog	2012-07-29 17:27:35 UTC (rev 123980)
@@ -1,3 +1,26 @@
+2012-07-29  Dan Bernstein  <[email protected]>
+
+        In flipped blocks, a point on the top edge of a box is considered outside the box (and vice versa)
+        https://bugs.webkit.org/show_bug.cgi?id=92593
+
+        Reviewed by Simon Fraser.
+
+        With respect to hit testing, boxes should always behave as half-open intervals which include
+        the physical top and left edges and not the bottom and right edges.
+        RenderBlock::positionForPoint was not adhering to this, since it was comparing flipped
+        coordinates.
+
+        Tests: fast/writing-mode/flipped-blocks-hit-test-box-edges.html
+               fast/writing-mode/flipped-blocks-hit-test-line-edges.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::positionForPointWithInlineChildren): When blocks are flipped, changed
+        strict inequalities of y coordinates into non-strict ones and non-strict inequalities into
+        strict ones.
+        (WebCore::RenderBlock::positionForPoint): Ditto, except for the test for being under the top
+        of the last candidate box, which was made non-strict in the unflipped case and remained
+        strict.
+
 2012-07-28  Dan Bernstein  <[email protected]>
 
         RenderBlock::offsetForContents() is wrong in flipped blocks writing modes

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (123979 => 123980)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-07-29 14:49:07 UTC (rev 123979)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-07-29 17:27:35 UTC (rev 123980)
@@ -4917,6 +4917,7 @@
         return createVisiblePosition(0, DOWNSTREAM);
 
     bool linesAreFlipped = style()->isFlippedLinesWritingMode();
+    bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
 
     // look for the closest line box in the root box which is at the passed-in y coordinate
     InlineBox* closestBox = 0;
@@ -4928,19 +4929,21 @@
         if (!firstRootBoxWithChildren)
             firstRootBoxWithChildren = root;
 
-        if (!linesAreFlipped && root->isFirstAfterPageBreak() && pointInLogicalContents.y() < root->lineTopWithLeading())
+        if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
+            || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
             break;
 
         lastRootBoxWithChildren = root;
 
         // check if this root line box is located at this y coordinate
-        if (pointInLogicalContents.y() < root->selectionBottom()) {
+        if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
             if (linesAreFlipped) {
                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
 
-                if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && pointInLogicalContents.y() >= nextRootBoxWithChildren->lineTopWithLeading())
+                if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
+                    || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
                     continue;
             }
             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
@@ -4957,15 +4960,18 @@
     }
 
     if (closestBox) {
-        if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()
-            && pointInLogicalContents.y() < firstRootBoxWithChildren->logicalTop()) {
-            InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
-            if (box->isLineBreak()) {
-                if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
-                    box = newBox;
+        if (moveCaretToBoundary) {
+            LayoutUnit firstRootBoxWithChildrenTop = min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
+            if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
+                || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
+                InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
+                if (box->isLineBreak()) {
+                    if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
+                        box = newBox;
+                }
+                // y coordinate is above first root line box, so return the start of the first
+                return VisiblePosition(positionForBox(box, true), DOWNSTREAM);
             }
-            // y coordinate is above first root line box, so return the start of the first
-            return VisiblePosition(positionForBox(box, true), DOWNSTREAM);
         }
 
         // pass the box a top position that is inside it
@@ -5025,13 +5031,19 @@
     while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox))
         lastCandidateBox = lastCandidateBox->previousSiblingBox();
 
+    bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
     if (lastCandidateBox) {
-        if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox))
+        if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox)
+            || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(lastCandidateBox)))
             return positionForPointRespectingEditingBoundaries(this, lastCandidateBox, pointInContents);
 
         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
+            if (!isChildHitTestCandidate(childBox))
+                continue;
+            LayoutUnit childLogicalBottom = logicalTopForChild(childBox) + logicalHeightForChild(childBox);
             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
-            if (isChildHitTestCandidate(childBox) && pointInLogicalContents.y() < logicalTopForChild(childBox) + logicalHeightForChild(childBox))
+            if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y() < childLogicalBottom
+                || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
         }
     }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to