Create some latched scrolling tests.
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Feb 2014 17:48:55 +0000 (17:48 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Feb 2014 17:48:55 +0000 (17:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127606
<rdar://problem/15911348>

Reviewed by Simon Fraser.

Tools:

* DumpRenderTree/mac/EventSendingController.mm:
(+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize
the new "mouseScrollByX:andY:withWheel:andMomentumPhases:" selector.
(+[EventSendingController webScriptNameForSelector:]): Ditto.
(-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Implement
the new wheel event sender.
* WebKitTestRunner/EventSenderProxy.h:
* WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Add declaration
of new mouseScrollByWithWheelAndMomentumPhases method.
* WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases): Added
* WebKitTestRunner/InjectedBundle/EventSendingController.h:
* WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm:
(WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Add stub for iOS.
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::didReceiveMessageFromInjectedBundle): Handle the new
mouseScrollByWithWheelAndMomentumPhases message.
(WTR::TestController::didReceiveSynchronousMessageFromInjectedBundle): Handle the
new mouseScrollByWithWheelAndMomentumPhases.
* WebKitTestRunner/efl/EventSenderProxyEfl.cpp:
(WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Provide stub that
relays to the standard mouse wheel handler.
* WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
(WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Ditto.
* WebKitTestRunner/mac/EventSenderProxy.mm:
(WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Provide implementation
of mouse wheel gesture method.

LayoutTests:

Add a series of tests to cover desired behavior with wheel events (including momentum).
This behavior is specific to the Mac platform, so is limited to the platform/mac and
platform/mac-wk2 directories.

* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html: Added.
* platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html: Added.
* platform/mac/fast/scrolling: Added.
* platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-div-latched-div.html: Added.
* platform/mac/fast/scrolling/scroll-div-latched-mainframe-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-div-latched-mainframe.html: Added.
* platform/mac/fast/scrolling/scroll-iframe-latched-iframe-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-iframe-latched-iframe.html: Added.
* platform/mac/fast/scrolling/scroll-iframe-latched-mainframe-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-iframe-latched-mainframe.html: Added.
* platform/mac/fast/scrolling/scroll-select-latched-mainframe-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-select-latched-mainframe.html: Added.
* platform/mac/fast/scrolling/scroll-select-latched-select-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-select-latched-select.html: Added.

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

48 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select.html [new file with mode: 0644]
Tools/ChangeLog
Tools/DumpRenderTree/mac/EventSendingController.mm
Tools/WebKitTestRunner/EventSenderProxy.h
Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl
Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h
Tools/WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/efl/EventSenderProxyEfl.cpp
Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp
Tools/WebKitTestRunner/mac/EventSenderProxy.mm

index 6fe6edc..c34462c 100644 (file)
@@ -1,3 +1,53 @@
+2014-02-13  Brent Fulgham  <bfulgham@apple.com>
+
+        Create some latched scrolling tests.
+        https://bugs.webkit.org/show_bug.cgi?id=127606
+        <rdar://problem/15911348>
+
+        Reviewed by Simon Fraser.
+
+        Add a series of tests to cover desired behavior with wheel events (including momentum).
+        This behavior is specific to the Mac platform, so is limited to the platform/mac and
+        platform/mac-wk2 directories.
+
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html: Added.
+        * platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html: Added.
+        * platform/mac/fast/scrolling: Added.
+        * platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-div-latched-div.html: Added.
+        * platform/mac/fast/scrolling/scroll-div-latched-mainframe-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-div-latched-mainframe.html: Added.
+        * platform/mac/fast/scrolling/scroll-iframe-latched-iframe-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-iframe-latched-iframe.html: Added.
+        * platform/mac/fast/scrolling/scroll-iframe-latched-mainframe-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-iframe-latched-mainframe.html: Added.
+        * platform/mac/fast/scrolling/scroll-select-latched-mainframe-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-select-latched-mainframe.html: Added.
+        * platform/mac/fast/scrolling/scroll-select-latched-select-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-select-latched-select.html: Added.
+
 2014-02-14  Renata Hodovan  <rhodovan.u-szeged@partner.samsung.com>
 
         ASSERTION FAILED: comparePositions(newEnd, newStart) >= 0 in WebCore::ApplyStyleCommand::updateStartEnd
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-expected.txt
new file mode 100644 (file)
index 0000000..2871f64
--- /dev/null
@@ -0,0 +1,76 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 485
+Mouse moved to (28, 610)
+Page before: 0, div before: 451
+Page after:  0, div after: 451
+PASS Page did not receive wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2326.00)
+  (visible rect 0.00, 0.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..bb1a0f8
--- /dev/null
@@ -0,0 +1,77 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 485
+Mouse moved to (28, 610)
+Page before: 0, div before: 451
+Page after:  0, div after: 451
+PASS Page did not receive wheel events.
+Document was initial target for 0 of the wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2341.00)
+  (visible rect 0.00, 0.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2341.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div-with-handler.html
new file mode 100644 (file)
index 0000000..00baf89
--- /dev/null
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+    divTarget.scrollTop = divTarget.scrollHeight - divTarget.clientHeight - 100;
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    debug("div display height = " + divTarget.clientHeight);
+    var startPosY = divTarget.offsetTop + divTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-div.html
new file mode 100644 (file)
index 0000000..6f23c70
--- /dev/null
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+    divTarget.scrollTop = divTarget.scrollHeight - divTarget.clientHeight - 100;
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    debug("div display height = " + divTarget.clientHeight);
+    var startPosY = divTarget.offsetTop + divTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..091c212
--- /dev/null
@@ -0,0 +1,75 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 125)
+Page before: 0, div before: 0
+Page after:  280, div after: 0
+PASS Scrollable div did not receive wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2311.00)
+  (visible rect 0.00, 280.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2311.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..5b0210e
--- /dev/null
@@ -0,0 +1,76 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 125)
+Page before: 0, div before: 0
+Page after:  280, div after: 0
+PASS Scrollable div did not receive wheel events.
+Document was initial target for 4 of the wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2326.00)
+  (visible rect 0.00, 280.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe-with-handler.html
new file mode 100644 (file)
index 0000000..47ac6e1
--- /dev/null
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (divScrollPositionBefore != divScrollPositionAfter)
+        testFailed("Scrollable div consumed wheel events.");
+    else
+        testPassed("Scrollable div did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    var startPosY = divTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-div-latched-mainframe.html
new file mode 100644 (file)
index 0000000..c0136e3
--- /dev/null
@@ -0,0 +1,172 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (divScrollPositionBefore != divScrollPositionAfter)
+        testFailed("Scrollable div consumed wheel events.");
+    else
+        testPassed("Scrollable div did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    var startPosY = divTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-expected.txt
new file mode 100644 (file)
index 0000000..8d7a08f
--- /dev/null
@@ -0,0 +1,32 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+IFrame display height = 500
+Mouse moved to (28, 566)
+Page before: 0, IFrame before: 416
+Page after:  0, IFrame after: 531
+PASS Page did not receive wheel events.
+(GraphicsLayer
+  (bounds 785.00 2326.00)
+  (visible rect 0.00, 0.00 785.00 x 600.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 600.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 785 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..08775b9
--- /dev/null
@@ -0,0 +1,33 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+IFrame display height = 500
+Mouse moved to (28, 566)
+Page before: 0, IFrame before: 416
+Page after:  0, IFrame after: 531
+PASS Page did not receive wheel events.
+Document was initial target for 0 of the wheel events.
+(GraphicsLayer
+  (bounds 785.00 2341.00)
+  (visible rect 0.00, 0.00 785.00 x 600.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2341.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 600.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 785 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe-with-handler.html
new file mode 100644 (file)
index 0000000..4212f5a
--- /dev/null
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    var iFrameBody = window.frames['target'].document.body;
+    iFrameBody.scrollTop = iFrameBody.scrollHeight - iframeTarget.clientHeight - 100;
+
+    iFrameScrollPositionBefore = iFrameBody.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    debug("IFrame display height = " + iframeTarget.clientHeight);
+    var startPosY = iframeTarget.offsetTop + iframeTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the IFrame, then use the mouse wheel or a two-finger swipe to scroll the IFrame to the bottom (and beyond).<br/>"
+            + "<br/><br/>"
+            + "The test passes if you scroll far enough to see the row of END labels but the main page does not scroll.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-iframe.html
new file mode 100644 (file)
index 0000000..6856fa2
--- /dev/null
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    var iFrameBody = window.frames['target'].document.body;
+    iFrameBody.scrollTop = iFrameBody.scrollHeight - iframeTarget.clientHeight - 100;
+
+    iFrameScrollPositionBefore = iFrameBody.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    debug("IFrame display height = " + iframeTarget.clientHeight);
+    var startPosY = iframeTarget.offsetTop + iframeTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the IFrame, then use the mouse wheel or a two-finger swipe to scroll the IFrame to the bottom (and beyond).<br/>"
+            + "<br/><br/>"
+            + "The test passes if you scroll far enough to see the row of END labels but the main page does not scroll.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..525497a
--- /dev/null
@@ -0,0 +1,31 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't consume wheel events when scroll
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 66)
+Page before: 0, IFrame before: 0
+Page after:  280, IFrame after: 0
+PASS IFrame did not receive wheel events.
+(GraphicsLayer
+  (bounds 785.00 2311.00)
+  (visible rect 0.00, 280.00 785.00 x 600.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2311.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 600.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 785 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..aa76bb4
--- /dev/null
@@ -0,0 +1,32 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't consume wheel events when scroll
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 66)
+Page before: 0, IFrame before: 0
+Page after:  280, IFrame after: 0
+PASS IFrame did not receive wheel events.
+Document was initial target for 4 of the wheel events.
+(GraphicsLayer
+  (bounds 785.00 2326.00)
+  (visible rect 0.00, 280.00 785.00 x 600.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 600.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 785 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe-with-handler.html
new file mode 100644 (file)
index 0000000..89b47a7
--- /dev/null
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (iFrameScrollPositionBefore != iFrameScrollPositionAfter)
+        testFailed("IFrame consumed wheel events.");
+    else
+        testPassed("IFrame did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+    iFrameScrollPositionBefore = window.frames['target'].document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    var startPosY = iframeTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the IFrame.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't consume wheel events when scroll ");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-iframe-latched-mainframe.html
new file mode 100644 (file)
index 0000000..1dbd20a
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (iFrameScrollPositionBefore != iFrameScrollPositionAfter)
+        testFailed("IFrame consumed wheel events.");
+    else
+        testPassed("IFrame did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+    iFrameScrollPositionBefore = window.frames['target'].document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    var startPosY = iframeTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the IFrame.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't consume wheel events when scroll ");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..d5d72ac
--- /dev/null
@@ -0,0 +1,33 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (30, 127)
+Page before: 0, select before: 0
+Page after:  280, select after: 0
+PASS Select did not receive wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2311.00)
+  (visible rect 0.00, 280.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2311.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..d07bf50
--- /dev/null
@@ -0,0 +1,34 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (30, 127)
+Page before: 0, select before: 0
+Page after:  280, select after: 0
+PASS Select did not receive wheel events.
+Document was initial target for 4 of the wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2326.00)
+  (visible rect 0.00, 280.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 280.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe-with-handler.html
new file mode 100644 (file)
index 0000000..e97f257
--- /dev/null
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The select should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (selectScrollPositionBefore != selectScrollPositionAfter)
+        testFailed("Select consumed wheel events.");
+    else
+        testPassed("Select did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    var startPosY = selectTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll down<br/>"
+            + "past the selectTarget.<br/><br/>"
+            + "You should not see the 'content21' label if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-mainframe.html
new file mode 100644 (file)
index 0000000..c1064b6
--- /dev/null
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The select should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (selectScrollPositionBefore != selectScrollPositionAfter)
+        testFailed("Select consumed wheel events.");
+    else
+        testPassed("Select did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    var startPosY = selectTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll down<br/>"
+            + "past the selectTarget.<br/><br/>"
+            + "You should not see the 'content21' label if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-expected.txt
new file mode 100644 (file)
index 0000000..e48747b
--- /dev/null
@@ -0,0 +1,34 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 111
+Mouse moved to (30, 238)
+Page before: 0, select before: 70
+Page after:  0, select after: 182
+PASS Page did not receive wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2326.00)
+  (visible rect 0.00, 0.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2326.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler-expected.txt
new file mode 100644 (file)
index 0000000..46b224d
--- /dev/null
@@ -0,0 +1,35 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 111
+Mouse moved to (30, 238)
+Page before: 0, select before: 70
+Page after:  0, select after: 182
+PASS Page did not receive wheel events.
+Document was initial target for 4 of the wheel events.
+(GraphicsLayer
+  (bounds 2008.00 2341.00)
+  (visible rect 0.00, 0.00 785.00 x 585.00)
+  (contentsScale 1.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 2008.00 2341.00)
+      (contentsOpaque 1)
+      (visible rect 0.00, 0.00 785.00 x 585.00)
+      (contentsScale 1.00)
+      (tile cache coverage 0, 0 2008 x 2048)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 4 x 4)
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select-with-handler.html
new file mode 100644 (file)
index 0000000..f450898
--- /dev/null
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+var wheelCount = 0;
+function onScrollWheel(evt) {
+    wheelCount = wheelCount + 1;
+}
+
+function onLoad() {
+    document.addEventListener("mousewheel", onScrollWheel);
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The page should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    debug("Document was initial target for " + wheelCount + " of the wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+    selectTarget.scrollTop = selectTarget.scrollHeight - selectTarget.clientHeight - 100;
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    debug("div display height = " + selectTarget.clientHeight);
+    var startPosY = selectTarget.offsetTop + selectTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the select box, and scroll near (but not AT) the bottom of the range. Use the mouse wheel or a two-finger<br/>"
+            + "swipe to scroll through the rest of the select options.<br/><br/>"
+            + "You should not see the page position change if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html b/LayoutTests/platform/mac-wk2/tiled-drawing/fast-scroll-select-latched-select.html
new file mode 100644 (file)
index 0000000..d8df89b
--- /dev/null
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The page should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    if (window.internals) {
+        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
+            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+    }
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+    selectTarget.scrollTop = selectTarget.scrollHeight - selectTarget.clientHeight - 100;
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    debug("div display height = " + selectTarget.clientHeight);
+    var startPosY = selectTarget.offsetTop + selectTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the select box, and scroll near (but not AT) the bottom of the range. Use the mouse wheel or a two-finger<br/>"
+            + "swipe to scroll through the rest of the select options.<br/><br/>"
+            + "You should not see the page position change if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<pre id="layers">Layer tree goes here</p>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt
new file mode 100644 (file)
index 0000000..e4249d3
--- /dev/null
@@ -0,0 +1,60 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 485
+Mouse moved to (28, 610)
+Page before: 0, div before: 451
+Page after:  0, div after: 451
+PASS Page did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html b/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html
new file mode 100644 (file)
index 0000000..8704797
--- /dev/null
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+    divTarget.scrollTop = divTarget.scrollHeight - divTarget.clientHeight - 100;
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    debug("div display height = " + divTarget.clientHeight);
+    var startPosY = divTarget.offsetTop + divTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..4df6c44
--- /dev/null
@@ -0,0 +1,59 @@
+Put mouse here and flick downwards
+Scrollable Region
+
+Count  DATA    Rev Count
+TOP TOP TOP TOP TOP    TOP TOP TOP TOP TOP     TOP TOP TOP TOP TOP
+1      0.1100  40
+2      0.1155  39
+3      0.2200  38
+4      0.2255  37
+5      0.3300  36
+6      0.3355  35
+7      0.4400  34
+8      0.4455  33
+9      0.5500  32
+10     0.5555  31
+11     0.6600  30
+12     0.6655  29
+13     0.7700  28
+14     0.7755  27
+15     0.8800  26
+16     0.8855  25
+17     0.9900  24
+18     0.9955  23
+19     0.9999  22
+20     1.0000  21
+21     1.0000  20
+22     0.9999  19
+23     0.9955  18
+24     0.9900  17
+25     0.8855  16
+26     0.8800  15
+27     0.7755  14
+28     0.7700  13
+29     0.6655  12
+30     0.6600  11
+31     0.5555  10
+32     0.5500  9
+33     0.4455  8
+34     0.4400  7
+35     0.3355  6
+36     0.3300  5
+37     0.2255  4
+38     0.2200  3
+39     0.1155  2
+40     0.1100  1
+END END END END END    END END END END END     END END END END END
+Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 125)
+Page before: 0, div before: 0
+Page after:  320, div after: 0
+PASS Scrollable div did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe.html b/LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-mainframe.html
new file mode 100644 (file)
index 0000000..c611ad1
--- /dev/null
@@ -0,0 +1,166 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var divTarget;
+var pageScrollPositionBefore;
+var divScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The div should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var divScrollPositionAfter = divTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", div before: " + divScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", div after: " + divScrollPositionAfter);
+
+    if (divScrollPositionBefore != divScrollPositionAfter)
+        testFailed("Scrollable div consumed wheel events.");
+    else
+        testPassed("Scrollable div did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    divTarget = document.getElementById('target');
+
+    divScrollPositionBefore = divTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = divTarget.offsetLeft + 20;
+    var startPosY = divTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the div.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+    <div class="scrollable_region">
+        <h3>Scrollable Region</h3>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+            <table class="table" style='width: 99%'>
+                <tr><th>Count</th><th>DATA</th><th>Rev Count</th></tr>
+                <tr><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td><td>TOP TOP TOP TOP TOP</td></tr>
+                <tr><td>1</td><td>0.1100</td><td>40</td></tr>
+                <tr><td>2</td><td>0.1155</td><td>39</td></tr>
+                <tr><td>3</td><td>0.2200</td><td>38</td></tr>
+                <tr><td>4</td><td>0.2255</td><td>37</td></tr>
+                <tr><td>5</td><td>0.3300</td><td>36</td></tr>
+                <tr><td>6</td><td>0.3355</td><td>35</td></tr>
+                <tr><td>7</td><td>0.4400</td><td>34</td></tr>
+                <tr><td>8</td><td>0.4455</td><td>33</td></tr>
+                <tr><td>9</td><td>0.5500</td><td>32</td></tr>
+                <tr><td>10</td><td>0.5555</td><td>31</td></tr>
+                <tr><td>11</td><td>0.6600</td><td>30</td></tr>
+                <tr><td>12</td><td>0.6655</td><td>29</td></tr>
+                <tr><td>13</td><td>0.7700</td><td>28</td></tr>
+                <tr><td>14</td><td>0.7755</td><td>27</td></tr>
+                <tr><td>15</td><td>0.8800</td><td>26</td></tr>
+                <tr><td>16</td><td>0.8855</td><td>25</td></tr>
+                <tr><td>17</td><td>0.9900</td><td>24</td></tr>
+                <tr><td>18</td><td>0.9955</td><td>23</td></tr>
+                <tr><td>19</td><td>0.9999</td><td>22</td></tr>
+                <tr><td>20</td><td>1.0000</td><td>21</td></tr>
+                <tr><td>21</td><td>1.0000</td><td>20</td></tr>
+                <tr><td>22</td><td>0.9999</td><td>19</td></tr>
+                <tr><td>23</td><td>0.9955</td><td>18</td></tr>
+                <tr><td>24</td><td>0.9900</td><td>17</td></tr>
+                <tr><td>25</td><td>0.8855</td><td>16</td></tr>
+                <tr><td>26</td><td>0.8800</td><td>15</td></tr>
+                <tr><td>27</td><td>0.7755</td><td>14</td></tr>
+                <tr><td>28</td><td>0.7700</td><td>13</td></tr>
+                <tr><td>29</td><td>0.6655</td><td>12</td></tr>
+                <tr><td>30</td><td>0.6600</td><td>11</td></tr>
+                <tr><td>31</td><td>0.5555</td><td>10</td></tr>
+                <tr><td>32</td><td>0.5500</td><td>9</td></tr>
+                <tr><td>33</td><td>0.4455</td><td>8</td></tr>
+                <tr><td>34</td><td>0.4400</td><td>7</td></tr>
+                <tr><td>35</td><td>0.3355</td><td>6</td></tr>
+                <tr><td>36</td><td>0.3300</td><td>5</td></tr>
+                <tr><td>37</td><td>0.2255</td><td>4</td></tr>
+                <tr><td>38</td><td>0.2200</td><td>3</td></tr>
+                <tr><td>39</td><td>0.1155</td><td>2</td></tr>
+                <tr><td>40</td><td>0.1100</td><td>1</td></tr>
+                <tr><td>END END END END END</td><td>END END END END END</td><td>END END END END END</td></tr>
+            </table>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a scrollable div doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe-expected.txt
new file mode 100644 (file)
index 0000000..493f2f4
--- /dev/null
@@ -0,0 +1,16 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+IFrame display height = 500
+Mouse moved to (28, 566)
+Page before: 0, IFrame before: 416
+Page after:  0, IFrame after: 416
+PASS Page did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe.html b/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-iframe.html
new file mode 100644 (file)
index 0000000..2d86f2b
--- /dev/null
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    var iFrameBody = window.frames['target'].document.body;
+    iFrameBody.scrollTop = iFrameBody.scrollHeight - iframeTarget.clientHeight - 100;
+
+    iFrameScrollPositionBefore = iFrameBody.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    debug("IFrame display height = " + iframeTarget.clientHeight);
+    var startPosY = iframeTarget.offsetTop + iframeTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the IFrame, then use the mouse wheel or a two-finger swipe to scroll the IFrame to the bottom (and beyond).<br/>"
+            + "<br/><br/>"
+            + "The test passes if you scroll far enough to see the row of END labels but the main page does not scroll.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..8c66525
--- /dev/null
@@ -0,0 +1,15 @@
+Put mouse here and flick downwards
+
+Tests that iframe doesn't consume wheel events when scroll
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (28, 66)
+Page before: 0, IFrame before: 0
+Page after:  320, IFrame after: 0
+PASS IFrame did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe.html b/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-latched-mainframe.html
new file mode 100644 (file)
index 0000000..0206519
--- /dev/null
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-Events/#events-WheelEvent">
+<script src="../../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+var iframeTarget;
+var pageScrollPositionBefore;
+var iFrameScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The IFrame should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var iFrameScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", IFrame before: " + iFrameScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", IFrame after: " + iFrameScrollPositionAfter);
+
+    if (iFrameScrollPositionBefore != iFrameScrollPositionAfter)
+        testFailed("IFrame consumed wheel events.");
+    else
+        testPassed("IFrame did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+    iFrameScrollPositionBefore = window.frames['target'].document.body.scrollTop;
+
+    iframeTarget = document.getElementById('target');
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = iframeTarget.offsetLeft + 20;
+    var startPosY = iframeTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
+            + "down past the IFrame.<br/><br/>"
+            + "You should not see the row of END labels if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px">
+    <div id="source" style="height: 100px">
+        Put mouse here and flick downwards
+    </div>
+    <iframe id="target" name="target" style="border:solid 1px green; height: 500px; width: 500px;" 
+     src= "data:text/html,
+     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
+     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
+     This should still be visible inside the frame after you scroll down
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
+     This should NOT be visible inside the frame after you scroll down<br/>
+     <br/>
+     END END END END END END END END END END END END END
+     </div>
+     "
+     onload="setupTopLevel();"
+     >
+    </iframe>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that iframe doesn't consume wheel events when scroll ");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe-expected.txt
new file mode 100644 (file)
index 0000000..ebcd7d5
--- /dev/null
@@ -0,0 +1,17 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't consume wheel events when scroll is latched to main frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Mouse moved to (30, 127)
+Page before: 0, select before: 0
+Page after:  320, select after: 0
+PASS Select did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe.html b/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-mainframe.html
new file mode 100644 (file)
index 0000000..97d6841
--- /dev/null
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The select should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (selectScrollPositionBefore != selectScrollPositionAfter)
+        testFailed("Select consumed wheel events.");
+    else
+        testPassed("Select did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    var startPosY = selectTarget.offsetTop - 42; // Slightly more than one wheel scroll away from the IFrame
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll down<br/>"
+            + "past the selectTarget.<br/><br/>"
+            + "You should not see the 'content21' label if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't consume wheel events when scroll is latched to main frame.");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select-expected.txt b/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select-expected.txt
new file mode 100644 (file)
index 0000000..59cd29e
--- /dev/null
@@ -0,0 +1,18 @@
+Put mouse here and flick downwards
+Scrollable Select
+
+
+Tests that a select doesn't pass wheel events to main frame when scrolling at bottom
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+div display height = 111
+Mouse moved to (30, 238)
+Page before: 0, select before: 70
+Page after:  0, select after: 182
+PASS Page did not receive wheel events.
+
diff --git a/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select.html b/LayoutTests/platform/mac/fast/scrolling/scroll-select-latched-select.html
new file mode 100644 (file)
index 0000000..396d2d5
--- /dev/null
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.scrollable_region {
+    width: 680px;
+}
+
+.table td, .table th {
+    padding: 2px;
+}
+
+.table th {
+    height: 20px;
+    text-align: left;
+    font-weight: strong;
+}
+
+.table tr:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+.scrollable_select option:nth-child(odd) {
+    background: #f3f3f3;
+}
+
+</style>
+<script src="../../../../resources/js-test-pre.js"></script>
+<script>
+function onLoad() {
+    setupTopLevel();
+}
+</script>
+</head>
+<body onload="onLoad();">
+<script>
+
+var selectTarget;
+var pageScrollPositionBefore;
+var selectScrollPositionBefore;
+var continueCount = 5;
+
+function checkForScroll() {
+
+    // The page should not have scrolled at all.
+    var pageScrollPositionAfter = document.body.scrollTop;
+    var selectScrollPositionAfter = selectTarget.scrollTop;
+
+    debug("Page before: " + pageScrollPositionBefore + ", select before: " + selectScrollPositionBefore);
+    debug("Page after:  " + pageScrollPositionAfter + ", select after: " + selectScrollPositionAfter);
+
+    if (pageScrollPositionBefore != pageScrollPositionAfter)
+        testFailed("Page received wheel events.");
+    else
+        testPassed("Page did not receive wheel events.");
+
+    testRunner.notifyDone();
+}
+
+function scrollTest() {
+    // See where our IFrame lives:
+    pageScrollPositionBefore = document.body.scrollTop;
+
+    selectTarget = document.getElementById('target');
+    selectTarget.scrollTop = selectTarget.scrollHeight - selectTarget.clientHeight - 100;
+
+    selectScrollPositionBefore = selectTarget.scrollTop;
+
+    // Scroll the #source until we reach the #target.
+    var startPosX = selectTarget.offsetLeft + 20;
+    debug("div display height = " + selectTarget.clientHeight);
+    var startPosY = selectTarget.offsetTop + selectTarget.clientHeight - 42; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY); // Make sure we are just outside the iFrame
+    debug("Mouse moved to (" + startPosX + ", " + startPosY + ")");
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'ended', 'none', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'begin', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'none', 'continue', true);
+    eventSender.mouseScrollByWithWheelAndMomentumPhases(0, 0, 'none', 'end', true);
+    setTimeout(checkForScroll, 100);
+}
+
+function setupTopLevel() {
+
+    if (window.eventSender) {
+        testRunner.dumpAsText(true);
+        testRunner.waitUntilDone();
+
+        setTimeout(scrollTest, 1000);
+    } else {
+        var messageLocation = document.getElementById('parent');
+        var message = document.createElement('div');
+        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
+            + "inside the select box, and scroll near (but not AT) the bottom of the range. Use the mouse wheel or a two-finger<br/>"
+            + "swipe to scroll through the rest of the select options.<br/><br/>"
+            + "You should not see the page position change if this test is successful.</p>";
+        messageLocation.appendChild(message);
+    }
+}
+
+</script>
+<div id="parent" style="height: 2000px; width: 2000px;">
+    <div id="source" style="height: 100px; width: 500px;">
+        Put mouse here and flick downwards
+    </div>
+        <div class="scrollable_region">
+            <h3>Scrollable Select</h3>
+            <select id="target" class="scrollable_select" size="8">
+                <option>content1</option>
+                <option>content2</option>
+                <option>content3</option>
+                <option>content4</option>
+                <option>content5</option>
+                <option>content6</option>
+                <option>content7</option>
+                <option>content8</option>
+                <option>content9</option>
+                <option>content10</option>
+                <option>content11</option>
+                <option>content12</option>
+                <option>content13</option>
+                <option>content14</option>
+                <option>content15</option>
+                <option>content16</option>
+                <option>content17</option>
+                <option>content18</option>
+                <option>content19</option>
+                <option>content20</option>
+                <option>content21</option>
+            </select>
+        </div>
+    </div>
+</div>
+<div id="console"></div>
+<script>
+description("Tests that a select doesn't pass wheel events to main frame when scrolling at bottom");
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 15a0ee1..148543b 100644 (file)
@@ -1,3 +1,39 @@
+2014-02-13  Brent Fulgham  <bfulgham@apple.com>
+
+        Create some latched scrolling tests.
+        https://bugs.webkit.org/show_bug.cgi?id=127606
+        <rdar://problem/15911348>
+
+        Reviewed by Simon Fraser.
+
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize
+        the new "mouseScrollByX:andY:withWheel:andMomentumPhases:" selector.
+        (+[EventSendingController webScriptNameForSelector:]): Ditto.
+        (-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Implement
+        the new wheel event sender.
+        * WebKitTestRunner/EventSenderProxy.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Add declaration
+        of new mouseScrollByWithWheelAndMomentumPhases method.
+        * WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
+        (WTR::EventSendingController::mouseScrollByWithWheelAndMomentumPhases): Added
+        * WebKitTestRunner/InjectedBundle/EventSendingController.h:
+        * WebKitTestRunner/InjectedBundle/ios/EventSenderProxyIOS.mm:
+        (WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Add stub for iOS.
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::didReceiveMessageFromInjectedBundle): Handle the new
+        mouseScrollByWithWheelAndMomentumPhases message.
+        (WTR::TestController::didReceiveSynchronousMessageFromInjectedBundle): Handle the
+        new mouseScrollByWithWheelAndMomentumPhases.
+        * WebKitTestRunner/efl/EventSenderProxyEfl.cpp:
+        (WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Provide stub that
+        relays to the standard mouse wheel handler.
+        * WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
+        (WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Ditto.
+        * WebKitTestRunner/mac/EventSenderProxy.mm:
+        (WTR::EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases): Provide implementation
+        of mouse wheel gesture method.
+
 2014-02-13  David Farler  <dfarler@apple.com>
 
         DumpRenderTree fails to build: Perl support module building for OS X but linking for the simulator
index 5674e89..ac85731 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2006 Jonas Witt <jonas.witt@gmail.com>
  * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
  * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
@@ -202,6 +202,7 @@ BOOL replayingSavedEvents;
             || aSelector == @selector(zoomPageOut)
             || aSelector == @selector(scalePageBy:atX:andY:)
             || aSelector == @selector(mouseScrollByX:andY:)
+            || aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:)
             || aSelector == @selector(continuousMouseScrollByX:andY:)
 #if PLATFORM(IOS)
             || aSelector == @selector(addTouchAtX:y:)
@@ -254,6 +255,8 @@ BOOL replayingSavedEvents;
         return @"setDragMode";
     if (aSelector == @selector(mouseScrollByX:andY:))
         return @"mouseScrollBy";
+    if (aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:))
+        return @"mouseScrollByWithWheelAndMomentumPhases";
     if (aSelector == @selector(continuousMouseScrollByX:andY:))
         return @"continuousMouseScrollBy";
     if (aSelector == @selector(scalePageBy:atX:andY:))
@@ -699,6 +702,56 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
     [self mouseScrollByX:x andY:y continuously:NO];
 }
 
+#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+const uint32_t kCGScrollWheelEventMomentumPhase = 123;
+#endif
+
+- (void)mouseScrollByX:(int)x andY:(int)y withWheel:(NSString*)phaseName andMomentumPhases:(NSString*)momentumName
+{
+#if !PLATFORM(IOS)
+    uint32_t phase = 0;
+    if ([phaseName isEqualToString: @"none"])
+        phase = 0;
+    else if ([phaseName isEqualToString: @"began"])
+        phase = 1; // kCGScrollPhaseBegan
+    else if ([phaseName isEqualToString: @"changd"])
+        phase = 2; // kCGScrollPhaseChanged;
+    else if ([phaseName isEqualToString: @"ended"])
+        phase = 4; // kCGScrollPhaseEnded
+    else if ([phaseName isEqualToString: @"cancelled"])
+        phase = 8; // kCGScrollPhaseCancelled
+    else if ([phaseName isEqualToString: @"maybegin"])
+        phase = 128; // kCGScrollPhaseMayBegin
+
+    uint32_t momentum = 0;
+    if ([momentumName isEqualToString: @"none"])
+        momentum = 0; //kCGMomentumScrollPhaseNone;
+    else if ([momentumName isEqualToString:@"begin"])
+        momentum = 1; // kCGMomentumScrollPhaseBegin;
+    else if ([momentumName isEqualToString:@"continue"])
+        momentum = 2; // kCGMomentumScrollPhaseContinue;
+    else if ([momentumName isEqualToString:@"end"])
+        momentum = 3; // kCGMomentumScrollPhaseEnd;
+
+    CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, 2, y, x);
+
+    // CGEvent locations are in global display coordinates.
+    CGPoint lastGlobalMousePosition = CGPointMake(lastMousePosition.x, [[NSScreen mainScreen] frame].size.height - lastMousePosition.y);
+    CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition);
+    CGEventSetIntegerValueField(cgScrollEvent, kCGScrollWheelEventScrollPhase, phase);
+    CGEventSetIntegerValueField(cgScrollEvent, kCGScrollWheelEventMomentumPhase, momentum);
+    
+    NSEvent* scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent];
+    CFRelease(cgScrollEvent);
+
+    if (NSView* targetView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]]) {
+        [NSApp _setCurrentEvent:scrollEvent];
+        [targetView scrollWheel:scrollEvent];
+        [NSApp _setCurrentEvent:nil];
+    }
+#endif
+}
+
 - (NSArray *)contextClick
 {
 #if !PLATFORM(IOS)
index db2c58b..7ce5d9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,6 +60,7 @@ public:
     void mouseUp(unsigned button, WKEventModifiers);
     void mouseMoveTo(double x, double y);
     void mouseScrollBy(int x, int y);
+    void mouseScrollByWithWheelAndMomentumPhases(int x, int y, int phase, int momentum);
     void continuousMouseScrollBy(int x, int y, bool paged);
 
     void leapForward(int milliseconds);
index b3aa024..d67794c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@ interface EventSendingController {
     void mouseUp(long buttonNumber, object modifierArray);
     void mouseMoveTo(long x, long y);
     void mouseScrollBy(long x, long y);
+    void mouseScrollByWithWheelAndMomentumPhases(long x, long y, DOMString phase, DOMString momentum, optional boolean asyncScrolling);
     void continuousMouseScrollBy(long x, long y, optional boolean paged);
     object contextClick();
     void scheduleAsynchronousClick();
index 65e3556..d224d1e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -347,6 +347,61 @@ void EventSendingController::mouseScrollBy(int x, int y)
     WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
 }
 
+void EventSendingController::mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phaseStr, JSStringRef momentumStr, bool asyncScrolling)
+{
+    WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
+    WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate());
+    
+    WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage"));
+    WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("MouseScrollByWithWheelAndMomentumPhases"));
+    WKDictionarySetItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get());
+    
+    WKRetainPtr<WKStringRef> xKey(AdoptWK, WKStringCreateWithUTF8CString("X"));
+    WKRetainPtr<WKDoubleRef> xRef(AdoptWK, WKDoubleCreate(x));
+    WKDictionarySetItem(EventSenderMessageBody.get(), xKey.get(), xRef.get());
+    
+    WKRetainPtr<WKStringRef> yKey(AdoptWK, WKStringCreateWithUTF8CString("Y"));
+    WKRetainPtr<WKDoubleRef> yRef(AdoptWK, WKDoubleCreate(y));
+    WKDictionarySetItem(EventSenderMessageBody.get(), yKey.get(), yRef.get());
+
+    uint64_t phase = 0;
+    if (JSStringIsEqualToUTF8CString(phaseStr, "none"))
+        phase = 0;
+    else if (JSStringIsEqualToUTF8CString(phaseStr, "began"))
+        phase = 1; // kCGScrollPhaseBegan
+    else if (JSStringIsEqualToUTF8CString(phaseStr, "changed"))
+        phase = 2; // kCGScrollPhaseChanged
+    else if (JSStringIsEqualToUTF8CString(phaseStr, "ended"))
+        phase = 4; // kCGScrollPhaseEnded
+    else if (JSStringIsEqualToUTF8CString(phaseStr, "cancelled"))
+        phase = 8; // kCGScrollPhaseCancelled
+    else if (JSStringIsEqualToUTF8CString(phaseStr, "maybegin"))
+        phase = 128; // kCGScrollPhaseMayBegin
+
+    WKRetainPtr<WKStringRef> phaseKey(AdoptWK, WKStringCreateWithUTF8CString("Phase"));
+    WKRetainPtr<WKUInt64Ref> phaseRef(AdoptWK, WKUInt64Create(phase));
+    WKDictionarySetItem(EventSenderMessageBody.get(), phaseKey.get(), phaseRef.get());
+
+    uint64_t momentum = 0;
+    if (JSStringIsEqualToUTF8CString(momentumStr, "none"))
+        momentum = 0; // kCGMomentumScrollPhaseNone
+    else if (JSStringIsEqualToUTF8CString(momentumStr, "begin"))
+        momentum = 1; // kCGMomentumScrollPhaseBegin
+    else if (JSStringIsEqualToUTF8CString(momentumStr, "continue"))
+        momentum = 2; // kCGMomentumScrollPhaseContinue
+    else if (JSStringIsEqualToUTF8CString(momentumStr, "end"))
+        momentum = 3; // kCGMomentumScrollPhaseEnd
+
+    WKRetainPtr<WKStringRef> momentumKey(AdoptWK, WKStringCreateWithUTF8CString("Momentum"));
+    WKRetainPtr<WKUInt64Ref> momentumRef(AdoptWK, WKUInt64Create(momentum));
+    WKDictionarySetItem(EventSenderMessageBody.get(), momentumKey.get(), momentumRef.get());
+
+    if (asyncScrolling)
+        WKBundlePostMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get());
+    else
+        WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0);
+}
+
 void EventSendingController::continuousMouseScrollBy(int x, int y, bool paged)
 {
     WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender"));
index c6a9131..fd030b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -47,6 +47,7 @@ public:
     void mouseUp(int button, JSValueRef modifierArray);
     void mouseMoveTo(int x, int y);
     void mouseScrollBy(int x, int y);
+    void mouseScrollByWithWheelAndMomentumPhases(int x, int y, JSStringRef phase, JSStringRef momentum, bool asyncScrolling);
     void continuousMouseScrollBy(int x, int y, bool paged);
     JSValueRef contextClick();
     void leapForward(int milliseconds);
index cdb2f51..77c35b4 100644 (file)
@@ -98,6 +98,11 @@ void EventSenderProxy::mouseScrollBy(int x, int y)
     // Write me.
 }
 
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int phase, int momentum)
+{
+    // Write me.
+}
+
 void EventSenderProxy::continuousMouseScrollBy(int x, int y, bool paged)
 {
     // Write me.
index c653d8e..620e0df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -856,6 +856,25 @@ void TestController::didReceiveMessageFromInjectedBundle(WKStringRef messageName
             return;
         }
 
+        if (WKStringIsEqualToUTF8CString(subMessageName, "MouseScrollByWithWheelAndMomentumPhases")) {
+            WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
+            double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+            
+            WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
+            double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+            
+            WKRetainPtr<WKStringRef> phaseKey = adoptWK(WKStringCreateWithUTF8CString("Phase"));
+            int phase = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, phaseKey.get()))));
+            WKRetainPtr<WKStringRef> momentumKey = adoptWK(WKStringCreateWithUTF8CString("Momentum"));
+            int momentum = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, momentumKey.get()))));
+            
+            // Forward to WebProcess
+            WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
+            m_eventSenderProxy->mouseScrollByWithWheelAndMomentumPhases(x, y, phase, momentum);
+
+            return;
+        }
+
         ASSERT_NOT_REACHED();
     }
 
@@ -925,6 +944,25 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
             return 0;
         }
 
+        if (WKStringIsEqualToUTF8CString(subMessageName, "MouseScrollByWithWheelAndMomentumPhases")) {
+            WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
+            double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
+            
+            WKRetainPtr<WKStringRef> yKey = adoptWK(WKStringCreateWithUTF8CString("Y"));
+            double y = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, yKey.get())));
+            
+            WKRetainPtr<WKStringRef> phaseKey = adoptWK(WKStringCreateWithUTF8CString("Phase"));
+            int phase = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, phaseKey.get()))));
+            WKRetainPtr<WKStringRef> momentumKey = adoptWK(WKStringCreateWithUTF8CString("Momentum"));
+            int momentum = static_cast<int>(WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, momentumKey.get()))));
+
+            // Forward to WebProcess
+            WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), true);
+            m_eventSenderProxy->mouseScrollByWithWheelAndMomentumPhases(x, y, phase, momentum);
+            WKPageSetShouldSendEventsSynchronously(mainWebView()->page(), false);
+            return 0;
+        }
+        
         if (WKStringIsEqualToUTF8CString(subMessageName, "ContinuousMouseScrollBy")) {
             WKRetainPtr<WKStringRef> xKey = adoptWK(WKStringCreateWithUTF8CString("X"));
             double x = WKDoubleGetValue(static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, xKey.get())));
index 31d3c83..7a68c7f 100644 (file)
@@ -392,6 +392,13 @@ void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, boo
     notImplemented();
 }
 
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int /*phase*/, int /*momentum*/)
+{
+    // EFL does not have the concept of wheel gesture phases or momentum. Just relay to
+    // the mouse wheel handler.
+    mouseScrollBy(x, y);
+}
+
 void EventSenderProxy::leapForward(int milliseconds)
 {
     if (m_eventQueue.isEmpty())
index d253201..847980e 100644 (file)
@@ -433,6 +433,13 @@ void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, boo
     sendOrQueueEvent(event);
 }
 
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int /*phase*/, int /*momentum*/)
+{
+    // Gtk+ does not have the concept of wheel gesture phases or momentum. Just relay to
+    // the mouse wheel handler.
+    mouseScrollBy(x, y);
+}
+
 void EventSenderProxy::leapForward(int milliseconds)
 {
     if (m_eventQueue.isEmpty())
index 428b210..a09fcf1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Redistribution and use in source and binary forms, with or without
@@ -461,4 +461,29 @@ void EventSenderProxy::continuousMouseScrollBy(int x, int y, bool paged)
     return;
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+const uint32_t kCGScrollWheelEventMomentumPhase = 123;
+#endif
+
+void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int phase, int momentum)
+{
+    RetainPtr<CGEventRef> cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitLine, 2, y, x));
+
+    // CGEvent locations are in global display coordinates.
+    CGPoint lastGlobalMousePosition = CGPointMake(m_position.x, [[NSScreen mainScreen] frame].size.height - m_position.y);
+    CGEventSetLocation(cgScrollEvent.get(), lastGlobalMousePosition);
+
+    CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventScrollPhase, phase);
+    CGEventSetIntegerValueField(cgScrollEvent.get(), kCGScrollWheelEventMomentumPhase, momentum);
+
+    NSEvent* event = [NSEvent eventWithCGEvent: cgScrollEvent.get()];
+
+    // Our event should have the correct settings:
+    if (NSView *targetView = [m_testController->mainWebView()->platformView() hitTest: [event locationInWindow]]) {
+        [NSApp _setCurrentEvent: event];
+        [targetView scrollWheel: event];
+        [NSApp _setCurrentEvent: nil];
+    }
+}
+
 } // namespace WTR