REGRESSION (r209299): Selection is broken when you zoom in webpage using trackpad
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 Dec 2016 23:57:40 +0000 (23:57 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 Dec 2016 23:57:40 +0000 (23:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=166472
rdar://problem/29675551

Reviewed by Tim Horton.

Source/WebCore:

r209299 broke autoscroll in zoomed pages because it changed RenderLayer::scrollRectToVisible()
to shrink viewRect by page scale. This is incorrect for all callers of scrollRectToVisible, since
the "absoluteRect" passed in is actually in zoomed document coordinates for all the callers I tested.

This code is also fixed to account for headers and footers. getRectToExpose() takes rectangles
in "scroll view contents" coordinates (i.e. including header, and zoomed document), so doesn't need
the separate visibleRectRelativeToDocument parameter.

Tests: fast/events/autoscroll-main-document.html
       fast/events/autoscroll-when-zoomed.html
       fast/events/drag-select-when-zoomed-with-header.html
       fast/events/drag-select-when-zoomed.html
       fast/scrolling/scroll-to-anchor-zoomed-header.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::scrollRectToVisible):
(WebCore::RenderLayer::getRectToExpose):
* rendering/RenderLayer.h:

Tools:

These changes are necessary to allow the mouse to leave the WTR window while
drag-scrolling, to test autoscroll. Previously, we were never calling -mouseDragged
(which DRT does); we'd always go through mouseMoved, which hits an early return
in WebViewImpl::mouseMoved() when the point is outside the view.

* WebKitTestRunner/mac/EventSenderProxy.mm:
(WTR::EventSenderProxy::mouseMoveTo):

LayoutTests:

Add some test coverage for autoscroll of the main document. I could only get this
working in WebKitTestRunner, not DumpRenderTree.

* TestExpectations:
* fast/events/autoscroll-main-document-expected.txt: Added.
* fast/events/autoscroll-main-document.html: Added.
* fast/events/autoscroll-when-zoomed-expected.txt: Added.
* fast/events/autoscroll-when-zoomed.html: Added.
* fast/events/drag-select-when-zoomed-expected.txt: Added.
* fast/events/drag-select-when-zoomed-with-header-expected.txt: Added.
* fast/events/drag-select-when-zoomed-with-header.html: Added.
* fast/events/drag-select-when-zoomed.html: Added.
* fast/scrolling/scroll-to-anchor-zoomed-header-expected.txt: Added.
* fast/scrolling/scroll-to-anchor-zoomed-header.html: Added.
* fast/transforms/selection-bounds-in-transformed-view.html: Revert the target scroll position to what it was
before r209299, and improve the failure output.
* platform/ios-simulator/TestExpectations:
* platform/mac-wk2/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210147 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/events/autoscroll-main-document-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/autoscroll-main-document.html [new file with mode: 0644]
LayoutTests/fast/events/autoscroll-when-zoomed-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/autoscroll-when-zoomed.html [new file with mode: 0644]
LayoutTests/fast/events/drag-select-when-zoomed-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/drag-select-when-zoomed-with-header-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/drag-select-when-zoomed-with-header.html [new file with mode: 0644]
LayoutTests/fast/events/drag-select-when-zoomed.html [new file with mode: 0644]
LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header-expected.txt [new file with mode: 0644]
LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header.html [new file with mode: 0644]
LayoutTests/fast/transforms/selection-bounds-in-transformed-view.html
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Tools/ChangeLog
Tools/WebKitTestRunner/mac/EventSenderProxy.mm

index de7b6e1..e7e3d18 100644 (file)
@@ -1,3 +1,30 @@
+2016-12-23  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r209299): Selection is broken when you zoom in webpage using trackpad
+        https://bugs.webkit.org/show_bug.cgi?id=166472
+        rdar://problem/29675551
+
+        Reviewed by Tim Horton.
+
+        Add some test coverage for autoscroll of the main document. I could only get this
+        working in WebKitTestRunner, not DumpRenderTree.
+
+        * TestExpectations:
+        * fast/events/autoscroll-main-document-expected.txt: Added.
+        * fast/events/autoscroll-main-document.html: Added.
+        * fast/events/autoscroll-when-zoomed-expected.txt: Added.
+        * fast/events/autoscroll-when-zoomed.html: Added.
+        * fast/events/drag-select-when-zoomed-expected.txt: Added.
+        * fast/events/drag-select-when-zoomed-with-header-expected.txt: Added.
+        * fast/events/drag-select-when-zoomed-with-header.html: Added.
+        * fast/events/drag-select-when-zoomed.html: Added.
+        * fast/scrolling/scroll-to-anchor-zoomed-header-expected.txt: Added.
+        * fast/scrolling/scroll-to-anchor-zoomed-header.html: Added.
+        * fast/transforms/selection-bounds-in-transformed-view.html: Revert the target scroll position to what it was
+        before r209299, and improve the failure output.
+        * platform/ios-simulator/TestExpectations:
+        * platform/mac-wk2/TestExpectations:
+
 2016-12-23  Andy Estes  <aestes@apple.com>
 
         [iOS] Fix some crashing webarchive tests
index bf9b135..930fcd3 100644 (file)
@@ -51,6 +51,10 @@ fast/events/mouse-force-changed.html [ Skip ]
 fast/events/mouse-force-down.html [ Skip ]
 fast/events/mouse-force-up.html [ Skip ]
 
+# Document autoscroll tests only work on Mac WK2
+fast/events/autoscroll-when-zoomed.html [ Skip ]
+fast/events/autoscroll-main-document.html [ Skip ]
+
 # Only iOS supports QuickLook
 quicklook [ Skip ]
 http/tests/quicklook [ Skip ]
diff --git a/LayoutTests/fast/events/autoscroll-main-document-expected.txt b/LayoutTests/fast/events/autoscroll-main-document-expected.txt
new file mode 100644 (file)
index 0000000..4ebda84
--- /dev/null
@@ -0,0 +1,9 @@
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+This test ensures that drag-selecting works correctly in the main frame.
+
+PASS firstRange.startOffset is 18
+PASS firstRange.endOffset is 425
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/autoscroll-main-document.html b/LayoutTests/fast/events/autoscroll-main-document.html
new file mode 100644 (file)
index 0000000..1c34628
--- /dev/null
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+        #container {
+            position: relative;
+            top: -10px;
+            left: 50px;
+            width: 400px;
+            outline: 1px solid black;
+            font-family: monospace;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+        
+        const eventCount = 50;
+        var scrollCount = 0;
+
+        var start;
+        var end;
+        var firstRange;
+        
+        function testComplete()
+        {
+            eventSender.mouseMoveTo(end.x, 0);
+            eventSender.mouseUp();
+
+            firstRange = window.getSelection().getRangeAt(0);
+            shouldBe('firstRange.startOffset', '18');
+            shouldBe('firstRange.endOffset', '425');
+
+            finishJSTest();
+        }
+        
+        function waitForScrolledToTop()
+        {
+            if (window.scrollY == 0) {
+                testComplete();
+                return;
+            }
+            
+            window.setTimeout(waitForScrolledToTop, 2);
+        }
+        
+        function doOneScroll()
+        {
+            if (++scrollCount == eventCount) {
+                waitForScrolledToTop();
+                return;
+            }
+
+            eventSender.mouseMoveTo(end.x, end.y - scrollCount);
+            window.setTimeout(doOneScroll, 2);
+        }
+
+        function doTest()
+        {
+            if (!window.testRunner || !window.eventSender) {
+                debug('This test requires testRunner and eventSender');
+                return;
+            }
+
+            var containerRect = document.getElementById('container').getBoundingClientRect();
+            var lineHeight = containerRect.height / 3;
+            
+            window.scrollTo(0, containerRect.bottom - lineHeight);
+
+            containerRect = document.getElementById('container').getBoundingClientRect(); // Scrolling changed it.
+
+            start = { x: containerRect.left + containerRect.width / 2, y: containerRect.bottom - lineHeight / 3 };
+            end = { x: containerRect.left + containerRect.width / 3, y: 16 };
+            
+            eventSender.mouseMoveTo(start.x, start.y);
+            eventSender.mouseDown();
+
+            doOneScroll();
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<div id="container">
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</div>
+
+<p>This test ensures that drag-selecting works correctly in the main frame.</p>
+
+<div id="console"></div>
+
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/events/autoscroll-when-zoomed-expected.txt b/LayoutTests/fast/events/autoscroll-when-zoomed-expected.txt
new file mode 100644 (file)
index 0000000..17f79fb
--- /dev/null
@@ -0,0 +1,9 @@
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+This test ensures that drag-selecting works correctly in the main frame.
+
+PASS firstRange.startOffset is 51
+PASS firstRange.endOffset is 400
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/autoscroll-when-zoomed.html b/LayoutTests/fast/events/autoscroll-when-zoomed.html
new file mode 100644 (file)
index 0000000..da5a835
--- /dev/null
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            height: 1000px;
+        }
+        #container {
+            position: relative;
+            top: -10px;
+            left: 50px;
+            width: 400px;
+            outline: 1px solid black;
+            font-family: monospace;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+        
+        const pageScale = 1.5;
+        const eventCount = 50;
+        var scrollCount = 0;
+
+        var start;
+        var end;
+        var firstRange;
+        
+        function testComplete()
+        {
+            eventSender.mouseMoveTo(pageScale * end.x, 0);
+            eventSender.mouseUp();
+
+            firstRange = window.getSelection().getRangeAt(0);
+            shouldBe('firstRange.startOffset', '51');
+            shouldBe('firstRange.endOffset', '400');
+
+            finishJSTest();
+        }
+        
+        function waitForScrolledToTop()
+        {
+            if (window.scrollY == 0) {
+                testComplete();
+                return;
+            }
+            
+            window.setTimeout(waitForScrolledToTop, 2);
+        }
+        
+        function doOneScroll()
+        {
+            if (++scrollCount == eventCount) {
+                waitForScrolledToTop();
+                return;
+            }
+
+            eventSender.mouseMoveTo(pageScale * end.x, pageScale * (end.y - scrollCount));
+            window.setTimeout(doOneScroll, 2);
+        }
+
+        function doTest()
+        {
+            if (!window.testRunner || !window.eventSender) {
+                debug('This test requires testRunner and eventSender');
+                return;
+            }
+            
+            window.internals.setPageScaleFactor(pageScale, 0, 0);
+
+            var containerRect = document.getElementById('container').getBoundingClientRect();
+            var lineHeight = containerRect.height / 3;
+            
+            window.scrollTo(0, containerRect.bottom - lineHeight);
+
+            containerRect = document.getElementById('container').getBoundingClientRect(); // Scrolling changed it.
+
+            start = { x: containerRect.left + 10, y: containerRect.bottom - lineHeight / 3 };
+            end = { x: containerRect.right - 10, y: 16 };
+            
+            eventSender.mouseMoveTo(pageScale * start.x, pageScale * start.y);
+            eventSender.mouseDown();
+
+            doOneScroll();
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<div id="container">
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</div>
+
+<p>This test ensures that drag-selecting works correctly in the main frame.</p>
+
+<div id="console"></div>
+
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/events/drag-select-when-zoomed-expected.txt b/LayoutTests/fast/events/drag-select-when-zoomed-expected.txt
new file mode 100644 (file)
index 0000000..f95eaa6
--- /dev/null
@@ -0,0 +1,9 @@
+This test ensures that drag-selecting works correctly in scaled pages.
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+PASS firstRange.startOffset is 79
+PASS firstRange.endOffset is 103
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/drag-select-when-zoomed-with-header-expected.txt b/LayoutTests/fast/events/drag-select-when-zoomed-with-header-expected.txt
new file mode 100644 (file)
index 0000000..f95eaa6
--- /dev/null
@@ -0,0 +1,9 @@
+This test ensures that drag-selecting works correctly in scaled pages.
+
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+PASS firstRange.startOffset is 79
+PASS firstRange.endOffset is 103
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/drag-select-when-zoomed-with-header.html b/LayoutTests/fast/events/drag-select-when-zoomed-with-header.html
new file mode 100644 (file)
index 0000000..8799470
--- /dev/null
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        #container {
+            position: absolute;
+            top: 100px;
+            left: 10px;
+            width: 400px;
+            outline: 1px solid black;
+            font-family: monospace;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+
+        const headerHeight = 32;
+        const pageScale = 1.8;
+        var mouseXStart;
+        var mouseXEnd;
+        var mouseY;
+        var currMouseX;
+        var firstRange;
+
+        if (window.internals)
+            internals.setHeaderHeight(headerHeight);
+
+        function testComplete()
+        {
+            eventSender.mouseMoveTo(mouseXEnd, mouseY);
+            eventSender.mouseUp();
+
+            firstRange = window.getSelection().getRangeAt(0);
+            shouldBe('firstRange.startOffset', '79');
+            shouldBe('firstRange.endOffset', '103');
+
+            finishJSTest();
+        }
+
+        function doOneMouseMove()
+        {
+            if (currMouseX >= mouseXEnd) {
+                testComplete();
+                return;
+            }
+
+            eventSender.mouseMoveTo(currMouseX, mouseY);
+            currMouseX += 2;
+            window.setTimeout(doOneMouseMove, 2);
+        }
+
+        function doTest()
+        {
+            if (!window.testRunner || !window.eventSender) {
+                debug('This test requires testRunner and eventSender');
+                return;
+            }
+            
+            window.internals.setPageScaleFactor(pageScale, 0, 0);
+            
+            var containerRect = document.getElementById('container').getBoundingClientRect();
+            var lineHeight = containerRect.height / 3;
+
+            mouseXStart = pageScale * (containerRect.left + containerRect.width / 2);
+            mouseY = headerHeight + pageScale * (containerRect.top + lineHeight / 2);
+            mouseXEnd = pageScale * (containerRect.right - 10);
+            
+            currMouseX = mouseXStart;
+            eventSender.mouseMoveTo(currMouseX, mouseY);
+            eventSender.mouseDown();
+
+            doOneMouseMove();
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<p>This test ensures that drag-selecting works correctly in scaled pages.</p>
+
+<div id="container">
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+</div>
+
+<div id="console"></div>
+
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/events/drag-select-when-zoomed.html b/LayoutTests/fast/events/drag-select-when-zoomed.html
new file mode 100644 (file)
index 0000000..f2b4ce5
--- /dev/null
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        #container {
+            position: absolute;
+            top: 100px;
+            left: 10px;
+            width: 400px;
+            outline: 1px solid black;
+            font-family: monospace;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+        window.jsTestIsAsync = true;
+
+        const pageScale = 1.8;
+        var mouseXStart;
+        var mouseXEnd;
+        var mouseY;
+        var currMouseX;
+        var firstRange;
+
+        function testComplete()
+        {
+            eventSender.mouseMoveTo(mouseXEnd, mouseY);
+            eventSender.mouseUp();
+
+            firstRange = window.getSelection().getRangeAt(0);
+            shouldBe('firstRange.startOffset', '79');
+            shouldBe('firstRange.endOffset', '103');
+
+            finishJSTest();
+        }
+
+        function doOneMouseMove()
+        {
+            if (currMouseX >= mouseXEnd) {
+                testComplete();
+                return;
+            }
+
+            eventSender.mouseMoveTo(currMouseX, mouseY);
+            currMouseX += 2;
+            window.setTimeout(doOneMouseMove, 2);
+        }
+
+        function doTest()
+        {
+            if (!window.testRunner || !window.eventSender) {
+                debug('This test requires testRunner and eventSender');
+                return;
+            }
+            
+            window.internals.setPageScaleFactor(pageScale, 0, 0);
+            
+            var containerRect = document.getElementById('container').getBoundingClientRect();
+            var lineHeight = containerRect.height / 3;
+
+            mouseXStart = pageScale * (containerRect.left + containerRect.width / 2);
+            mouseY = pageScale * (containerRect.top + lineHeight / 2);
+            mouseXEnd = pageScale * (containerRect.right - 10);
+            
+            currMouseX = mouseXStart;
+            eventSender.mouseMoveTo(currMouseX, mouseY);
+            eventSender.mouseDown();
+
+            doOneMouseMove();
+        }
+
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<p>This test ensures that drag-selecting works correctly in scaled pages.</p>
+
+<div id="container">
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+</div>
+
+<div id="console"></div>
+
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header-expected.txt b/LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header-expected.txt
new file mode 100644 (file)
index 0000000..9461918
--- /dev/null
@@ -0,0 +1,11 @@
+Tests scrolling to an anchor in a zoomed page with a header scrolls to the correct location.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.scrollingElement.scrollTop is 1019
+PASS document.scrollingElement.scrollLeft is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Anchor is here
diff --git a/LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header.html b/LayoutTests/fast/scrolling/scroll-to-anchor-zoomed-header.html
new file mode 100644 (file)
index 0000000..3b4560d
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        body {
+            height: 2000px;
+            width: 2000px;
+        }
+        
+        .anchor {
+            position: absolute;
+            top: 1000px;
+            left: 40px;
+            border: 1px solid black;
+        }
+    </style>
+    <script src="../../resources/js-test-pre.js"></script>
+    <script>
+    description("Tests scrolling to an anchor in a zoomed page with a header scrolls to the correct location.");
+    window.jsTestIsAsync = true;
+
+    const headerHeight = 32;
+    const pageScale = 1.8;
+
+    if (window.internals) {
+        internals.setHeaderHeight(headerHeight);
+        internals.setPageScaleFactor(pageScale, 0, 0);
+    }
+
+    function runTest()
+    {
+        setTimeout(function() {
+            window.location='#anchor';
+            setTimeout(finishTest, 0);
+        }, 0);
+    }
+
+    function finishTest()
+    {
+        if (window.location.toString().indexOf("#") == -1) {
+            setTimeout(finishTest, 0);
+            return;
+        }
+        
+        shouldBe('document.scrollingElement.scrollTop', '1019');
+        shouldBe('document.scrollingElement.scrollLeft', '0');
+
+        finishJSTest();
+    }
+    </script>
+</head>
+<body onload="runTest()">
+
+<div class="anchor">
+    <a name="anchor">Anchor is here</a>
+</div>
+
+<script src="../../resources/js-test-post.js"></script>
+
+</body></html>
index 01d9c39..64d2520 100644 (file)
@@ -10,6 +10,8 @@
         }
 
         document.execCommand("FindString", false, "target");
-        document.getElementById("result").innerText = document.body.scrollTop === 937 ? "PASS" : "FAIL";
+        var scrollTop = document.body.scrollTop;
+        var expectedScrollTop = 864;
+        document.getElementById("result").innerText = scrollTop === expectedScrollTop ? "PASS" : "FAIL: document.body.scrollTop was " + scrollTop + ", should be " + expectedScrollTop;
     </script>
 </body>
index 76e5b27..f7010ba 100644 (file)
@@ -1292,6 +1292,12 @@ fast/events/show-modal-dialog-onblur-onfocus.html [ Failure ]
 fast/events/tab-focus-link-in-canvas.html [ Failure ]
 fast/events/tabindex-focus-blur-all.html [ Failure ]
 
+# Tests that depend on mouse input
+fast/events/autoscroll-main-document.html [ Skip ]
+fast/events/autoscroll-when-zoomed.html [ Skip ]
+fast/events/drag-select-when-zoomed-with-header.html [ Skip ]
+fast/events/drag-select-when-zoomed.html [ Skip ]
+
 # Ref-test imported from W3C that is failing because type=image input elements have rounded corners on iOS.
 imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/image01.html [ ImageOnlyFailure ]
 # Ref-test imported form W3C that is failing because the test is off by a couple of pixels on iOS.
@@ -2747,6 +2753,7 @@ webkit.org/b/163046 js/regress-141098.html [ Pass Failure ]
 fast/zooming/client-rect-in-fixed-zoomed.html [ Skip ]
 fast/visual-viewport/zoomed-scroll-to-anchor-in-position-fixed.html [ Skip ]
 fast/visual-viewport/zoomed-scroll-into-view-fixed.html [ Skip ]
+fast/scrolling/scroll-to-anchor-zoomed-header.html [ Skip ]
 
 # This test relies on Arial being used to draw Arabic. However, on iOS,
 # we explicitly disallow this because this font is too slow.
index 4e843ee..eb10819 100644 (file)
@@ -13,6 +13,8 @@ fast/events/cancelled-force-click-link-navigation.html [ Pass ]
 fast/events/force-click-link-selection-behavior.html [ Pass ]
 fast/events/force-click-on-link-navigation.html [ Pass ]
 fast/events/force-click-text-selection-behavior.html [ Failure ]
+fast/events/autoscroll-when-zoomed.html [ Pass ]
+fast/events/autoscroll-main-document.html [ Pass ]
 
 fast/media/mq-inverted-colors-live-update.html [ Pass ]
 fast/media/mq-inverted-colors-live-update-in-subframes.html [ Pass ]
@@ -40,7 +42,7 @@ pointer-lock/lock-lost-on-esc-in-fullscreen.html [ Pass ]
 ########################################
 ### START OF (1) Classified failures with bug reports
 
-# WebKitTestRunner needs an implementation of eventSender
+# WebKitTestRunner needs a more complete implementation of eventSender
 # <https://bugs.webkit.org/show_bug.cgi?id=42194>
 editing/pasteboard/4947130.html
 editing/pasteboard/cleanup-on-move.html
index f423df5..847e2c1 100644 (file)
@@ -1,3 +1,30 @@
+2016-12-23  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r209299): Selection is broken when you zoom in webpage using trackpad
+        https://bugs.webkit.org/show_bug.cgi?id=166472
+        rdar://problem/29675551
+
+        Reviewed by Tim Horton.
+
+        r209299 broke autoscroll in zoomed pages because it changed RenderLayer::scrollRectToVisible()
+        to shrink viewRect by page scale. This is incorrect for all callers of scrollRectToVisible, since
+        the "absoluteRect" passed in is actually in zoomed document coordinates for all the callers I tested.
+
+        This code is also fixed to account for headers and footers. getRectToExpose() takes rectangles
+        in "scroll view contents" coordinates (i.e. including header, and zoomed document), so doesn't need
+        the separate visibleRectRelativeToDocument parameter.
+
+        Tests: fast/events/autoscroll-main-document.html
+               fast/events/autoscroll-when-zoomed.html
+               fast/events/drag-select-when-zoomed-with-header.html
+               fast/events/drag-select-when-zoomed.html
+               fast/scrolling/scroll-to-anchor-zoomed-header.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::scrollRectToVisible):
+        (WebCore::RenderLayer::getRectToExpose):
+        * rendering/RenderLayer.h:
+
 2016-12-24  Zalan Bujtas  <zalan@apple.com>
 
         RenderBlockFlow::moveFloatsTo does not move floats.
index 530d7ba..f4f6f7c 100644 (file)
@@ -2527,7 +2527,7 @@ void RenderLayer::scrollRectToVisible(SelectionRevealMode revealMode, const Layo
         ASSERT(box);
         LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(absoluteRect))).boundingBox());
         LayoutRect layerBounds(0, 0, box->clientWidth(), box->clientHeight());
-        LayoutRect revealRect = getRectToExpose(layerBounds, layerBounds, localExposeRect, insideFixed, alignX, alignY);
+        LayoutRect revealRect = getRectToExpose(layerBounds, localExposeRect, insideFixed, alignX, alignY);
 
         ScrollOffset clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(revealRect).location()));
         if (clampedScrollOffset != scrollOffset()) {
@@ -2551,7 +2551,7 @@ void RenderLayer::scrollRectToVisible(SelectionRevealMode revealMode, const Layo
                 NoEventDispatchAssertion assertNoEventDispatch;
 
                 LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
-                LayoutRect exposeRect = getRectToExpose(viewRect, viewRect, absoluteRect, insideFixed, alignX, alignY);
+                LayoutRect exposeRect = getRectToExpose(viewRect, absoluteRect, insideFixed, alignX, alignY);
 
                 IntPoint scrollOffset(roundedIntPoint(exposeRect.location()));
                 // Adjust offsets if they're outside of the allowable range.
@@ -2572,16 +2572,15 @@ void RenderLayer::scrollRectToVisible(SelectionRevealMode revealMode, const Layo
 
 #if !PLATFORM(IOS)
             LayoutRect viewRect = frameView.visibleContentRect();
-            viewRect.scale(1 / frameView.frameScaleFactor());
-
-            LayoutRect visibleRectRelativeToDocument = viewRect;
-            visibleRectRelativeToDocument.setLocation(frameView.documentScrollPositionRelativeToScrollableAreaOrigin());
 #else
             LayoutRect viewRect = frameView.unobscuredContentRect();
-            LayoutRect visibleRectRelativeToDocument = viewRect;
 #endif
-            LayoutRect revealRect = getRectToExpose(viewRect, visibleRectRelativeToDocument, absoluteRect, insideFixed, alignX, alignY);
-                
+            // Move the target rect into "scrollView contents" coordinates.
+            LayoutRect targetRect = absoluteRect;
+            targetRect.move(0, frameView.headerHeight());
+
+            LayoutRect revealRect = getRectToExpose(viewRect, targetRect, insideFixed, alignX, alignY);
+            
             frameView.setScrollPosition(roundedIntPoint(revealRect.location()));
 
             // This is the outermost view of a web page, so after scrolling this view we
@@ -2612,7 +2611,7 @@ void RenderLayer::updateCompositingLayersAfterScroll()
     }
 }
 
-LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &visibleRectRelativeToDocument, const LayoutRect &exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY) const
 {
     FrameView& frameView = renderer().view().frameView();
     if (insideFixed) {
@@ -2624,6 +2623,8 @@ LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const Lay
             // exposeRect is in absolute coords, affected by page scale. Unscale it.
             LayoutRect unscaledExposeRect = exposeRect;
             unscaledExposeRect.scale(1 / frameView.frameScaleFactor());
+            unscaledExposeRect.move(0, -frameView.headerHeight());
+
             // These are both in unscaled coordinates.
             LayoutRect layoutViewport = frameView.layoutViewportRect();
             LayoutRect visualViewport = frameView.visualViewportRect();
@@ -2634,9 +2635,10 @@ LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const Lay
             unscaledExposeRect.setSize(unscaledExposeRect.size().shrunkTo(visualViewport.size()));
 
             // Compute how much we have to move the visualViewport to reveal the part of the layoutViewport that contains exposeRect.
-            LayoutRect requiredVisualViewport = getRectToExpose(visualViewport, visualViewport, unscaledExposeRect, false, alignX, alignY);
+            LayoutRect requiredVisualViewport = getRectToExpose(visualViewport, unscaledExposeRect, false, alignX, alignY);
             // Scale it back up.
             requiredVisualViewport.scale(frameView.frameScaleFactor());
+            requiredVisualViewport.move(0, frameView.headerHeight());
             return requiredVisualViewport;
         }
     }
@@ -2679,7 +2681,7 @@ LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const Lay
     // Determine the appropriate Y behavior.
     ScrollAlignment::Behavior scrollY;
     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
-    LayoutUnit intersectHeight = intersection(visibleRectRelativeToDocument, exposeRectY).height();
+    LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
     if (intersectHeight == exposeRect.height())
         // If the rectangle is fully visible, use the specified visible behavior.
         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
index 0797455..fc5ee52 100644 (file)
@@ -204,10 +204,9 @@ public:
 
     void availableContentSizeChanged(AvailableSizeChangeReason) override;
 
+    // "absoluteRect" is in scaled document coordinates.
     void scrollRectToVisible(SelectionRevealMode, const LayoutRect& absoluteRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
 
-    LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& visibleRectRelativeToDocument, const LayoutRect& exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
-
     bool scrollsOverflow() const;
     bool hasScrollbars() const { return m_hBar || m_vBar; }
     void setHasHorizontalScrollbar(bool);
@@ -940,6 +939,8 @@ private:
 
     RenderLayer* enclosingTransformedAncestor() const;
 
+    LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, bool insideFixed, const ScrollAlignment& alignX, const ScrollAlignment& alignY) const;
+
     // Convert a point in absolute coords into layer coords, taking transforms into account
     LayoutPoint absoluteToContents(const LayoutPoint&) const;
 
index 1c3dc66..312ea36 100644 (file)
@@ -1,3 +1,19 @@
+2016-12-23  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r209299): Selection is broken when you zoom in webpage using trackpad
+        https://bugs.webkit.org/show_bug.cgi?id=166472
+        rdar://problem/29675551
+
+        Reviewed by Tim Horton.
+
+        These changes are necessary to allow the mouse to leave the WTR window while
+        drag-scrolling, to test autoscroll. Previously, we were never calling -mouseDragged
+        (which DRT does); we'd always go through mouseMoved, which hits an early return
+        in WebViewImpl::mouseMoved() when the point is outside the view.
+
+        * WebKitTestRunner/mac/EventSenderProxy.mm:
+        (WTR::EventSenderProxy::mouseMoveTo):
+
 2016-12-23  Andy Estes  <aestes@apple.com>
 
         [iOS] Fix some crashing webarchive tests
index 8029f94..4c19542 100644 (file)
@@ -603,7 +603,8 @@ void EventSenderProxy::mouseMoveTo(double x, double y)
     NSPoint position = [view convertPoint:NSMakePoint(x, y) toView:nil];
     m_position.x = position.x;
     m_position.y = position.y;
-    NSEvent *event = [NSEvent mouseEventWithType:(m_leftMouseButtonDown ? NSEventTypeLeftMouseDragged : NSEventTypeMouseMoved)
+    bool isDrag = m_leftMouseButtonDown;
+    NSEvent *event = [NSEvent mouseEventWithType:(isDrag ? NSEventTypeLeftMouseDragged : NSEventTypeMouseMoved)
                                         location:position
                                    modifierFlags:0 
                                        timestamp:absoluteTimeForEventTime(currentEventTime())
@@ -614,10 +615,14 @@ void EventSenderProxy::mouseMoveTo(double x, double y)
                                         pressure:0];
 
     NSPoint windowLocation = event.locationInWindow;
-    NSView *targetView = [m_testController->mainWebView()->platformView() hitTest:windowLocation];
+    // Always target drags at the WKWebView to allow for drag-scrolling outside the view.
+    NSView *targetView = isDrag ? m_testController->mainWebView()->platformView() : [m_testController->mainWebView()->platformView() hitTest:windowLocation];
     if (targetView) {
         [NSApp _setCurrentEvent:event];
-        [targetView mouseMoved:event];
+        if (isDrag)
+            [targetView mouseDragged:event];
+        else
+            [targetView mouseMoved:event];
         [NSApp _setCurrentEvent:nil];
     } else
         WTFLogAlways("mouseMoveTo failed to find a target view at %f,%f\n", windowLocation.x, windowLocation.y);