Expand test infrastructure to support scrolling tests
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Apr 2015 00:05:17 +0000 (00:05 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Apr 2015 00:05:17 +0000 (00:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=143286
<rdar://problem/20375516>

Reviewed by Simon Fraser.

Source/WebCore:

No new functionality.

This series of changes adds a new singleton class, 'WheelEventTestTrigger', which encapsulates a
function object to be fired when scroll events are finished. The object also keeps track of reasons
why the test should not yet fire (e.g., 'rubberbanding' is active) so that tests do not incorrectly
check rendering state in the middle of an animation.

This code is not yet hooked up to the rendering system, and so does not have any effect on behavior.

* CMakeLists.txt: Add new WheelEventTestTrigger files.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* page/MainFrame.cpp:
(WebCore::MainFrame::MainFrame): Add new member to constructor.
(WebCore::MainFrame::testTrigger): Added.
(WebCore::MainFrame::ensureTestTrigger): Added.
(WebCore::MainFrame::clearTrigger): Added.
* page/MainFrame.h:
* page/WheelEventTestTrigger.cpp: Added.
(WebCore::WheelEventTestTrigger::WheelEventTestTrigger):
(WebCore::WheelEventTestTrigger::createWeakPtr):
(WebCore::WheelEventTestTrigger::clearAllTestDeferrals):
(WebCore::WheelEventTestTrigger::setTestNotificationCallback):
(WebCore::WheelEventTestTrigger::deferTestsForReason):
(WebCore::WheelEventTestTrigger::removeTestDeferralForReason):
(WebCore::WheelEventTestTrigger::triggerTestTimerFired):
* page/WheelEventTestTrigger.h: Added.

Source/WebKit2:

Extend the WK2 testing API to include a method for setting a JSC callback function to be triggered
by the new WebCore::WheelEventTestTrigger singleton.

* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageStartMonitoringScrollOperations): WK2 method that causes the testing system to begin tracking wheel events.
(WKBundlePageRegisterScrollOperationCompletionCallback): WK2 method to set the callback function for testing.
* WebProcess/InjectedBundle/API/c/WKBundlePage.h:

Tools:

Extend the WK1 and WK2 test programs to support two new EventSender commands:
(1) monitorWheelEvents: Tells DRT and WKTR to track the wheel event and animation state, so that we can
block executing tests until WebKit has completed any rubberband, scroll, or scroll-snap animations.
(2) callAfterScrollingCompletes: Provide a callback method to be executed when WebKit determines that
relevant rubberband, scroll, and scroll-snap animations are finished.

* DumpRenderTree/mac/EventSendingController.mm:
(+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize 'callAfterScrollingCompletes:'
and 'monitorWheelEvents'.
(+[EventSendingController webScriptNameForSelector:]): Ditto.
(-[EventSendingController mouseScrollByX:andY:continuously:]): Add some stderr logging to help when
debugging test failures.
(-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Ditto.
(-[EventSendingController callAfterScrollingCompletes:]): Added. Protects the JSObject representing the callback
function, then passes it to WebCore to be called once the test deferrals have been cleared.
(-[EventSendingController monitorWheelEvents:]): Added. Activates the wheel event tracking used by the
'callAfterScrollingCompletes' method.
* WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Added signatures for 'callAfterScrollingCompletes'
and 'monitorWheelEvents'.
* WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
(WTR::EventSendingController::callAfterScrollingCompletes): Added. Protects the JSObject representing the
callback function, then passes it to WebCore to be called once the test deferrals have been cleared
(WTR::EventSendingController::monitorWheelEvents): Added. Activates the wheel event tracking used by the
'callAfterScrollingComplates' method.
* WebKitTestRunner/InjectedBundle/EventSendingController.h:

LayoutTests:

Correct a scrolling test that had not been issuing wheel events to a valid
view. This was found by some new logging in this patch.

* platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt:
* platform/mac/fast/scrolling/scroll-div-latched-div.html:
* platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt: Added.*

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

24 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt
LayoutTests/platform/mac/fast/scrolling/scroll-div-latched-div.html
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/MainFrame.cpp
Source/WebCore/page/MainFrame.h
Source/WebCore/page/WheelEventTestTrigger.cpp [new file with mode: 0644]
Source/WebCore/page/WheelEventTestTrigger.h [new file with mode: 0644]
Source/WebCore/platform/PlatformExportMacros.h
Source/WebCore/platform/spi/mac/NSSharingServicePickerSPI.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
Tools/ChangeLog
Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj
Tools/DumpRenderTree/mac/EventSendingController.mm
Tools/WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl
Tools/WebKitTestRunner/InjectedBundle/EventSendingController.cpp
Tools/WebKitTestRunner/InjectedBundle/EventSendingController.h

index 6a4db04..d940dad 100644 (file)
@@ -1,3 +1,18 @@
+2015-04-10  Brent Fulgham  <bfulgham@apple.com>
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        <rdar://problem/20375516>
+
+        Reviewed by Simon Fraser.
+
+        Correct a scrolling test that had not been issuing wheel events to a valid
+        view. This was found by some new logging in this patch.
+
+        * platform/mac/fast/scrolling/scroll-div-latched-div-expected.txt:
+        * platform/mac/fast/scrolling/scroll-div-latched-div.html:
+        * platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt: Added.*
+
 2015-04-13  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         Fix LayoutTests/http/tests/canvas/canvas-tainted-after-draw-image.html on all bots
diff --git a/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt b/LayoutTests/platform/mac-wk1/scrollbars/scrollevent-iframe-no-scrolling-wheel-expected.txt
new file mode 100644 (file)
index 0000000..a8c0575
--- /dev/null
@@ -0,0 +1,3 @@
+mouseScrollByXandYContinuously: Unable to locate target view for current mouse location.Content-Type: text/plain
+Not scrolled by WheelEvent: SUCCESS
+
index fc39377..c1b1c35 100644 (file)
@@ -52,7 +52,5 @@ 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)
 PASS Page did not receive wheel events.
 
index f64711b..92a4fcf 100644 (file)
@@ -40,15 +40,12 @@ var pageScrollPositionBefore;
 var divScrollPositionBefore;
 var continueCount = 5;
 
-function checkForScroll() {
-
+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
@@ -57,8 +54,8 @@ function checkForScroll() {
     testRunner.notifyDone();
 }
 
-function scrollTest() {
-    // See where our IFrame lives:
+function scrollTest()
+{
     pageScrollPositionBefore = document.body.scrollTop;
 
     divTarget = document.getElementById('target');
@@ -67,11 +64,9 @@ function scrollTest() {
     divScrollPositionBefore = divTarget.scrollTop;
 
     // Scroll the #source until we reach the #target.
-    var startPosX = divTarget.offsetLeft + 20;
-    debug("div display height = " + divTarget.clientHeight);
-    var startPosY = Math.round(divTarget.offsetTop) + Math.round(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 + ")");
+    var startPosX = Math.round(divTarget.offsetLeft) + 20;
+    var startPosY = Math.round(divTarget.offsetTop) + 100; // One wheel turn before end.
+    eventSender.mouseMoveTo(startPosX, startPosY);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'began', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
     eventSender.mouseScrollByWithWheelAndMomentumPhases(0, -1, 'changed', 'none', true);
@@ -85,9 +80,10 @@ function scrollTest() {
     setTimeout(checkForScroll, 100);
 }
 
-function setupTopLevel() {
-
+function setupTopLevel()
+{
     if (window.eventSender) {
+        testRunner.dumpAsText();
         testRunner.waitUntilDone();
 
         setTimeout(scrollTest, 1000);
@@ -109,7 +105,7 @@ function setupTopLevel() {
     </div>
     <div class="scrollable_region">
         <h3>Scrollable Region</h3>
-        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 485px;'>
+        <div id="target" style='overflow-y: auto; overflow-x: hidden; max-height: 350px;'>
             <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>
index 469dc66..290b331 100644 (file)
@@ -1968,6 +1968,7 @@ set(WebCore_SOURCES
     page/UserContentURLPattern.cpp
     page/VisitedLinkStore.cpp
     page/WheelEventDeltaTracker.cpp
+    page/WheelEventTestTrigger.cpp
     page/WindowFeatures.cpp
     page/WindowFocusAllowedIndicator.cpp
     page/WorkerNavigator.cpp
index 5510510..86217ad 100644 (file)
@@ -1,3 +1,40 @@
+2015-04-10  Brent Fulgham  <bfulgham@apple.com>
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        <rdar://problem/20375516>
+
+        Reviewed by Simon Fraser.
+
+        No new functionality.
+
+        This series of changes adds a new singleton class, 'WheelEventTestTrigger', which encapsulates a
+        function object to be fired when scroll events are finished. The object also keeps track of reasons
+        why the test should not yet fire (e.g., 'rubberbanding' is active) so that tests do not incorrectly
+        check rendering state in the middle of an animation.
+
+        This code is not yet hooked up to the rendering system, and so does not have any effect on behavior.
+
+        * CMakeLists.txt: Add new WheelEventTestTrigger files.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * page/MainFrame.cpp:
+        (WebCore::MainFrame::MainFrame): Add new member to constructor.
+        (WebCore::MainFrame::testTrigger): Added.
+        (WebCore::MainFrame::ensureTestTrigger): Added.
+        (WebCore::MainFrame::clearTrigger): Added.
+        * page/MainFrame.h:
+        * page/WheelEventTestTrigger.cpp: Added.
+        (WebCore::WheelEventTestTrigger::WheelEventTestTrigger):
+        (WebCore::WheelEventTestTrigger::createWeakPtr):
+        (WebCore::WheelEventTestTrigger::clearAllTestDeferrals):
+        (WebCore::WheelEventTestTrigger::setTestNotificationCallback):
+        (WebCore::WheelEventTestTrigger::deferTestsForReason):
+        (WebCore::WheelEventTestTrigger::removeTestDeferralForReason):
+        (WebCore::WheelEventTestTrigger::triggerTestTimerFired):
+        * page/WheelEventTestTrigger.h: Added.
+
 2015-04-13  Jer Noble  <jer.noble@apple.com>
 
         [iOS] When entering optimized fullscreen, standard fullscreen view should exit.
         3. Remove a number of unneeded null checks in EventHandler.
         4. ScrollController must always have a client, so hold a reference instead of using a pointer.
 
+        * WebCore.vcxproj/WebCore.vcxproj: Add new WheelEventTestTrigger files.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
         * page/EventHandler.cpp:
         (WebCore::EventHandler::platformNotifyIfEndGesture): Renamed from 'platformNotifySnapIfNecessary'.
         (WebCore::EventHandler::handleWheelEvent): Call 'platformNotifySnapIfNecessary' at method exit points.
index 04d47c6..d077a02 100644 (file)
     <ClCompile Include="..\page\VisitedLinkStore.cpp" />
     <ClCompile Include="..\fileapi\WebKitBlobBuilder.cpp" />
     <ClCompile Include="..\page\WheelEventDeltaTracker.cpp" />
+    <ClCompile Include="..\page\WheelEventTestTrigger.cpp" />
     <ClCompile Include="..\page\WindowFeatures.cpp" />
     <ClCompile Include="..\page\WindowFocusAllowedIndicator.cpp" />
     <ClCompile Include="..\page\WorkerNavigator.cpp" />
     <ClInclude Include="..\fileapi\WebKitBlobBuilder.h" />
     <ClInclude Include="..\page\WebKitPoint.h" />
     <ClInclude Include="..\page\WheelEventDeltaTracker.h" />
+    <ClInclude Include="..\page\WheelEventTestTrigger.h" />
     <ClInclude Include="..\page\WindowFeatures.h" />
     <ClInclude Include="..\page\WindowFocusAllowedIndicator.h" />
     <ClInclude Include="..\page\WorkerNavigator.h" />
index 8b4af32..e446087 100644 (file)
     <ClCompile Include="..\page\WheelEventDeltaTracker.cpp">
       <Filter>page</Filter>
     </ClCompile>
+    <ClCompile Include="..\page\WheelEventTestTrigger.cpp">
+      <Filter>page</Filter>
+    </ClCompile>
     <ClCompile Include="..\page\WindowFeatures.cpp">
       <Filter>page</Filter>
     </ClCompile>
     <ClInclude Include="..\page\WheelEventDeltaTracker.h">
       <Filter>page</Filter>
     </ClInclude>
+    <ClInclude Include="..\page\WheelEventTestTrigger.h">
+      <Filter>page</Filter>
+    </ClInclude>
     <ClInclude Include="..\page\WindowFeatures.h">
       <Filter>page</Filter>
     </ClInclude>
index f25b003..bb3ebaf 100644 (file)
                7ACD88D314C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */; };
                7ACD88D414C08BD60084EDD2 /* InspectorIndexedDBAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */; };
                7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               7AE335F11ACB09E200E401EF /* WheelEventTestTrigger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */; };
+               7AE335F21ACB09E200E401EF /* WheelEventTestTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7AF9B20218CFB2DF00C64BEF /* VTTRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9B1FC18CFB2DF00C64BEF /* VTTRegion.cpp */; };
                7AF9B20318CFB2DF00C64BEF /* VTTRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B1FD18CFB2DF00C64BEF /* VTTRegion.h */; };
                7AF9B20518CFB2DF00C64BEF /* VTTRegionList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9B1FF18CFB2DF00C64BEF /* VTTRegionList.cpp */; };
                7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorIndexedDBAgent.cpp; sourceTree = "<group>"; };
                7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorIndexedDBAgent.h; sourceTree = "<group>"; };
                7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuProvider.h; sourceTree = "<group>"; };
+               7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WheelEventTestTrigger.cpp; sourceTree = "<group>"; };
+               7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WheelEventTestTrigger.h; sourceTree = "<group>"; };
                7AF9B1FC18CFB2DF00C64BEF /* VTTRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTTRegion.cpp; sourceTree = "<group>"; };
                7AF9B1FD18CFB2DF00C64BEF /* VTTRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTTRegion.h; sourceTree = "<group>"; };
                7AF9B1FE18CFB2DF00C64BEF /* VTTRegion.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VTTRegion.idl; sourceTree = "<group>"; };
                                494BD7940F55C8EE00747828 /* WebKitPoint.idl */,
                                93EC449F188F4BB800661DF1 /* WheelEventDeltaTracker.cpp */,
                                93EC44A0188F4BB800661DF1 /* WheelEventDeltaTracker.h */,
+                               7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */,
+                               7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */,
                                BC8243E60D0CFD7500460C8F /* WindowFeatures.cpp */,
                                BC8243E70D0CFD7500460C8F /* WindowFeatures.h */,
                                7E99AF520B13846468FB01A5 /* WindowFocusAllowedIndicator.cpp */,
                        buildActionMask = 2147483647;
                        files = (
                                FE115FAB167988CD00249134 /* AbstractDatabaseServer.h in Headers */,
+                               7AE335F21ACB09E200E401EF /* WheelEventTestTrigger.h in Headers */,
                                41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */,
                                29A8122E0FBB9C1D00510293 /* AccessibilityARIAGridCell.h in Headers */,
                                29A812330FBB9C1D00510293 /* AccessibilityARIAGridRow.h in Headers */,
                                7728694E14F8882500F484DC /* EXTTextureFilterAnisotropic.cpp in Sources */,
                                A75E8B880E1DE2D6007F2481 /* FEBlend.cpp in Sources */,
                                A75E8B8A0E1DE2D6007F2481 /* FEColorMatrix.cpp in Sources */,
+                               7AE335F11ACB09E200E401EF /* WheelEventTestTrigger.cpp in Sources */,
                                A75E8B8C0E1DE2D6007F2481 /* FEComponentTransfer.cpp in Sources */,
                                A75E8B8E0E1DE2D6007F2481 /* FEComposite.cpp in Sources */,
                                84730D781248F0B300D3A9C9 /* FEConvolveMatrix.cpp in Sources */,
index 8732301..866d5b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@
 #include "ScrollLatchingState.h"
 #include "Settings.h"
 #include "WheelEventDeltaTracker.h"
+#include "WheelEventTestTrigger.h"
 #include <wtf/NeverDestroyed.h>
 
 #if PLATFORM(MAC)
@@ -122,7 +123,24 @@ void MainFrame::popLatchingState()
 {
     m_latchingState.removeLast();
 }
-
 #endif
 
+WheelEventTestTrigger* MainFrame::testTrigger() const
+{
+    return m_testTrigger.get();
+}
+
+WheelEventTestTrigger* MainFrame::ensureTestTrigger()
+{
+    if (!m_testTrigger)
+        m_testTrigger = std::make_unique<WheelEventTestTrigger>();
+
+    return m_testTrigger.get();
+}
+
+void MainFrame::clearTrigger()
+{
+    m_testTrigger = nullptr;
+}
+
 }
index 5da3a24..4f5d139 100644 (file)
@@ -37,6 +37,7 @@ class PageOverlayController;
 class ScrollLatchingState;
 class ServicesOverlayController;
 class WheelEventDeltaTracker;
+class WheelEventTestTrigger;
 
 class MainFrame final : public Frame {
 public:
@@ -63,6 +64,10 @@ public:
 
     WEBCORE_EXPORT DiagnosticLoggingClient& diagnosticLoggingClient() const;
 
+    WEBCORE_EXPORT WheelEventTestTrigger* testTrigger() const;
+    WEBCORE_EXPORT WheelEventTestTrigger* ensureTestTrigger();
+    WEBCORE_EXPORT void clearTrigger();
+
 private:
     MainFrame(Page&, PageConfiguration&);
 
@@ -76,6 +81,8 @@ private:
     std::unique_ptr<ServicesOverlayController> m_servicesOverlayController;
 #endif
 #endif
+    std::unique_ptr<WheelEventTestTrigger> m_testTrigger;
+
     std::unique_ptr<WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
     std::unique_ptr<PageOverlayController> m_pageOverlayController;
     DiagnosticLoggingClient* m_diagnosticLoggingClient;
diff --git a/Source/WebCore/page/WheelEventTestTrigger.cpp b/Source/WebCore/page/WheelEventTestTrigger.cpp
new file mode 100644 (file)
index 0000000..5f90ae7
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WheelEventTestTrigger.h"
+
+namespace WebCore {
+
+WheelEventTestTrigger::WheelEventTestTrigger()
+    : m_testTriggerTimer(RunLoop::current(), this, &WheelEventTestTrigger::triggerTestTimerFired)
+    , m_weakPtrFactory(this)
+{
+}
+
+WeakPtr<WheelEventTestTrigger> WheelEventTestTrigger::createWeakPtr()
+{
+    return m_weakPtrFactory.createWeakPtr();
+}
+
+void WheelEventTestTrigger::clearAllTestDeferrals()
+{
+    std::lock_guard<std::mutex> lock(m_testTriggerMutex);
+    m_deferTestTriggerReasons.clear();
+    m_testNotificationCallback = std::function<void()>();
+    m_testTriggerTimer.stop();
+}
+
+void WheelEventTestTrigger::setTestCallbackAndStartNotificationTimer(std::function<void()> functionCallback)
+{
+    {
+        std::lock_guard<std::mutex> lock(m_testTriggerMutex);
+        m_testNotificationCallback = WTF::move(functionCallback);
+    }
+    
+    if (!m_testTriggerTimer.isActive())
+        m_testTriggerTimer.startRepeating(1.0 / 60.0);
+}
+
+void WheelEventTestTrigger::deferTestsForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
+{
+    std::lock_guard<std::mutex> lock(m_testTriggerMutex);
+    auto it = m_deferTestTriggerReasons.find(identifier);
+    if (it == m_deferTestTriggerReasons.end())
+        it = m_deferTestTriggerReasons.add(identifier, std::set<DeferTestTriggerReason>()).iterator;
+    
+    it->value.insert(reason);
+}
+
+void WheelEventTestTrigger::removeTestDeferralForReason(ScrollableAreaIdentifier identifier, DeferTestTriggerReason reason)
+{
+    std::lock_guard<std::mutex> lock(m_testTriggerMutex);
+    auto it = m_deferTestTriggerReasons.find(identifier);
+    if (it == m_deferTestTriggerReasons.end())
+        return;
+
+    it->value.erase(reason);
+    
+    if (it->value.empty())
+        m_deferTestTriggerReasons.remove(it);
+}
+
+void WheelEventTestTrigger::triggerTestTimerFired()
+{
+    std::function<void()> functionCallback;
+
+    {
+        std::lock_guard<std::mutex> lock(m_testTriggerMutex);
+        if (!m_deferTestTriggerReasons.isEmpty())
+            return;
+
+        functionCallback = WTF::move(m_testNotificationCallback);
+        m_testNotificationCallback = std::function<void()>();
+    }
+
+    m_testTriggerTimer.stop();
+
+    if (functionCallback)
+        functionCallback();
+}
+
+}
diff --git a/Source/WebCore/page/WheelEventTestTrigger.h b/Source/WebCore/page/WheelEventTestTrigger.h
new file mode 100644 (file)
index 0000000..30b3030
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WheelEventTestTrigger_h
+#define WheelEventTestTrigger_h
+
+#include <mutex>
+#include <set>
+#include <wtf/HashMap.h>
+#include <wtf/RunLoop.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class WheelEventTestTrigger {
+    WTF_MAKE_NONCOPYABLE(WheelEventTestTrigger); WTF_MAKE_FAST_ALLOCATED;
+public:
+    WheelEventTestTrigger();
+
+    WEBCORE_EXPORT void setTestCallbackAndStartNotificationTimer(std::function<void()>);
+    WEBCORE_EXPORT void clearAllTestDeferrals();
+    
+    enum DeferTestTriggerReason {
+        RubberbandInProgress,
+        ScrollSnapInProgress,
+        ScrollingThreadSyncNeeded,
+        ContentScrollInProgress
+    };
+    typedef void* ScrollableAreaIdentifier;
+    void deferTestsForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
+    void removeTestDeferralForReason(ScrollableAreaIdentifier, DeferTestTriggerReason);
+    void triggerTestTimerFired();
+
+    WeakPtr<WheelEventTestTrigger> createWeakPtr();
+
+private:
+    std::function<void()> m_testNotificationCallback;
+    RunLoop::Timer<WheelEventTestTrigger> m_testTriggerTimer;
+    mutable std::mutex m_testTriggerMutex;
+    WTF::HashMap<void*, std::set<DeferTestTriggerReason>> m_deferTestTriggerReasons;
+
+    WeakPtrFactory<WheelEventTestTrigger> m_weakPtrFactory;
+};
+
+}
+
+#endif
index 1f0496a..cc63fae 100644 (file)
@@ -43,7 +43,6 @@
 #endif
 
 #else // !USE(EXPORT_MACROS)
-
 #define WEBCORE_EXPORT
 #define WEBCORE_TESTSUPPORT_EXPORT
 
index 8518fde..7b226b4 100644 (file)
@@ -43,6 +43,7 @@ typedef NS_ENUM(NSInteger, NSSharingServicePickerStyle) {
 @interface NSSharingServicePicker (Private)
 @property NSSharingServicePickerStyle style;
 - (NSMenu *)menu;
+- (void)hide;
 @end
 
 #endif
index 71f9fe4..152f520 100644 (file)
@@ -1,3 +1,19 @@
+2015-04-10  Brent Fulgham  <bfulgham@apple.com>
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        <rdar://problem/20375516>
+
+        Reviewed by Simon Fraser.
+
+        Extend the WK2 testing API to include a method for setting a JSC callback function to be triggered
+        by the new WebCore::WheelEventTestTrigger singleton.
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageStartMonitoringScrollOperations): WK2 method that causes the testing system to begin tracking wheel events.
+        (WKBundlePageRegisterScrollOperationCompletionCallback): WK2 method to set the callback function for testing.
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+
 2015-04-13  Enrica Casucci  <enrica@apple.com>
 
         Clients of WKWebView should be able to override drag functions.
index ae27fd5..ebe0898 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,6 +59,7 @@
 #include <WebCore/PageOverlay.h>
 #include <WebCore/PageOverlayController.h>
 #include <WebCore/URL.h>
+#include <WebCore/WheelEventTestTrigger.h>
 #include <wtf/StdLibExtras.h>
 
 using namespace WebKit;
@@ -573,6 +574,34 @@ void WKBundlePageSetUseTestingViewportConfiguration(WKBundlePageRef pageRef, boo
 }
 #endif
 
+void WKBundlePageStartMonitoringScrollOperations(WKBundlePageRef pageRef)
+{
+    WebKit::WebPage* webPage = toImpl(pageRef);
+    WebCore::Page* page = webPage ? webPage->corePage() : nullptr;
+    
+    if (!page)
+        return;
+
+    page->mainFrame().ensureTestTrigger();
+}
+
+void WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef pageRef, WKBundlePageTestNotificationCallback callback, void* context)
+{
+    if (!callback)
+        return;
+    
+    WebKit::WebPage* webPage = toImpl(pageRef);
+    WebCore::Page* page = webPage ? webPage->corePage() : nullptr;
+    
+    if (!page)
+        return;
+    
+    WebCore::WheelEventTestTrigger* trigger = page->mainFrame().ensureTestTrigger();
+    trigger->setTestCallbackAndStartNotificationTimer([=]() {
+        callback(context);
+    });
+}
+
 void WKBundlePagePostMessage(WKBundlePageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef)
 {
     toImpl(pageRef)->postMessage(toWTFString(messageNameRef), toImpl(messageBodyRef));
index 829b6a3..5c85149 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -109,6 +109,11 @@ WK_EXPORT WKBundleInspectorRef WKBundlePageGetInspector(WKBundlePageRef page);
 
 WK_EXPORT bool WKBundlePageIsUsingEphemeralSession(WKBundlePageRef page);
 
+WK_EXPORT void WKBundlePageStartMonitoringScrollOperations(WKBundlePageRef);
+
+typedef void (*WKBundlePageTestNotificationCallback)(void* context);
+WK_EXPORT void WKBundlePageRegisterScrollOperationCompletionCallback(WKBundlePageRef, WKBundlePageTestNotificationCallback, void* context);
+
 WK_EXPORT void WKBundlePagePostMessage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody);
 WK_EXPORT void WKBundlePagePostSynchronousMessage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData);
 
index 0e1c544..ddfc456 100644 (file)
@@ -1,3 +1,37 @@
+2015-04-10  Brent Fulgham  <bfulgham@apple.com>
+
+        Expand test infrastructure to support scrolling tests
+        https://bugs.webkit.org/show_bug.cgi?id=143286
+        <rdar://problem/20375516>
+
+        Reviewed by Simon Fraser.
+
+        Extend the WK1 and WK2 test programs to support two new EventSender commands:
+        (1) monitorWheelEvents: Tells DRT and WKTR to track the wheel event and animation state, so that we can
+        block executing tests until WebKit has completed any rubberband, scroll, or scroll-snap animations.
+        (2) callAfterScrollingCompletes: Provide a callback method to be executed when WebKit determines that
+        relevant rubberband, scroll, and scroll-snap animations are finished.
+
+        * DumpRenderTree/mac/EventSendingController.mm:
+        (+[EventSendingController isSelectorExcludedFromWebScript:]): Update to recognize 'callAfterScrollingCompletes:'
+        and 'monitorWheelEvents'.
+        (+[EventSendingController webScriptNameForSelector:]): Ditto.
+        (-[EventSendingController mouseScrollByX:andY:continuously:]): Add some stderr logging to help when
+        debugging test failures.
+        (-[EventSendingController mouseScrollByX:andY:withWheel:andMomentumPhases:]): Ditto.
+        (-[EventSendingController callAfterScrollingCompletes:]): Added. Protects the JSObject representing the callback
+        function, then passes it to WebCore to be called once the test deferrals have been cleared.
+        (-[EventSendingController monitorWheelEvents:]): Added. Activates the wheel event tracking used by the
+        'callAfterScrollingCompletes' method.
+        * WebKitTestRunner/InjectedBundle/Bindings/EventSendingController.idl: Added signatures for 'callAfterScrollingCompletes'
+        and 'monitorWheelEvents'.
+        * WebKitTestRunner/InjectedBundle/EventSendingController.cpp:
+        (WTR::EventSendingController::callAfterScrollingCompletes): Added. Protects the JSObject representing the
+        callback function, then passes it to WebCore to be called once the test deferrals have been cleared
+        (WTR::EventSendingController::monitorWheelEvents): Added. Activates the wheel event tracking used by the
+        'callAfterScrollingComplates' method.
+        * WebKitTestRunner/InjectedBundle/EventSendingController.h:
+
 2015-04-13  Alexey Proskuryakov  <ap@apple.com>
 
         build.webkit.org/dashboard: Crash-only queues should show failure when testing fails to start
index 525a283..b392145 100644 (file)
                        buildSettings = {
                                INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks/$(WEBKIT_FRAMEWORK_RESOURCES_PATH)";
                                PRODUCT_NAME = All;
+                               WTF_USE_EXPORT_MACROS = 0;
                        };
                        name = Production;
                };
                                        "-Wno-four-char-constants",
                                        "-Wno-unknown-pragmas",
                                );
+                               WTF_USE_EXPORT_MACROS = 0;
                        };
                        name = Debug;
                };
                                        "-Wno-four-char-constants",
                                        "-Wno-unknown-pragmas",
                                );
+                               WTF_USE_EXPORT_MACROS = 0;
                        };
                        name = Release;
                };
index 06d18bb..8bc7a89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2014-2015 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>
 #import "DumpRenderTree.h"
 #import "DumpRenderTreeDraggingInfo.h"
 #import "DumpRenderTreeFileDraggingSource.h"
-
 #import <WebKit/DOMPrivate.h>
 #import <WebKit/WebKit.h>
 #import <WebKit/WebViewPrivate.h>
+#import <functional>
 
 #if !PLATFORM(IOS)
 #import <Carbon/Carbon.h> // for GetCurrentEventTime()
+#import <JavaScriptCore/JSRetainPtr.h>
+#import <WebCore/MainFrame.h>
+#import <WebCore/Page.h>
+#import <WebCore/WheelEventTestTrigger.h>
 #endif
 
 #if PLATFORM(IOS)
@@ -128,6 +132,12 @@ BOOL replayingSavedEvents;
 @end // SyntheticTouch
 #endif
 
+#if !PLATFORM(IOS)
+@interface WebView (WebViewInternalForTesting)
+- (WebCore::Frame*)_mainCoreFrame;
+@end
+#endif
+
 @implementation EventSendingController
 
 + (void)initialize
@@ -204,6 +214,8 @@ BOOL replayingSavedEvents;
             || aSelector == @selector(mouseScrollByX:andY:)
             || aSelector == @selector(mouseScrollByX:andY:withWheel:andMomentumPhases:)
             || aSelector == @selector(continuousMouseScrollByX:andY:)
+            || aSelector == @selector(monitorWheelEvents)
+            || aSelector == @selector(callAfterScrollingCompletes:)
 #if PLATFORM(IOS)
             || aSelector == @selector(addTouchAtX:y:)
             || aSelector == @selector(updateTouchAtIndex:x:y:)
@@ -261,6 +273,10 @@ BOOL replayingSavedEvents;
         return @"continuousMouseScrollBy";
     if (aSelector == @selector(scalePageBy:atX:andY:))
         return @"scalePageBy";
+    if (aSelector == @selector(monitorWheelEvents))
+        return @"monitorWheelEvents";
+    if (aSelector == @selector(callAfterScrollingCompletes:))
+        return @"callAfterScrollingCompletes";
 #if PLATFORM(IOS)
     if (aSelector == @selector(addTouchAtX:y:))
         return @"addTouchPoint";
@@ -687,7 +703,8 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
         [NSApp _setCurrentEvent:scrollEvent];
         [subView scrollWheel:scrollEvent];
         [NSApp _setCurrentEvent:nil];
-    }
+    } else
+        printf("mouseScrollByXandYContinuously: Unable to locate target view for current mouse location.");
 #endif
 }
 
@@ -746,7 +763,8 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
         [NSApp _setCurrentEvent:scrollEvent];
         [targetView scrollWheel:scrollEvent];
         [NSApp _setCurrentEvent:nil];
-    }
+    } else
+        printf("mouseScrollByX...andMomentumPhases: Unable to locate target view for current mouse location.");
 #endif
 }
 
@@ -1243,6 +1261,39 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
     
 }
 
+- (void)monitorWheelEvents
+{
+#if PLATFORM(MAC)
+    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
+    if (!frame)
+        return;
+    
+    frame->mainFrame().ensureTestTrigger();
+#endif
+}
+
+- (void)callAfterScrollingCompletes:(WebScriptObject*)callback
+{
+#if PLATFORM(MAC)
+    JSObjectRef jsCallbackFunction = [callback JSObject];
+    if (!jsCallbackFunction)
+        return;
+
+    WebCore::Frame* frame = [[mainFrame webView] _mainCoreFrame];
+    if (!frame)
+        return;
+
+    WebCore::WheelEventTestTrigger* trigger = frame->mainFrame().ensureTestTrigger();
+    JSGlobalContextRef globalContext = [mainFrame globalContext];
+    JSValueProtect(globalContext, jsCallbackFunction);
+
+    trigger->setTestCallbackAndStartNotificationTimer([=](void) {
+        JSObjectCallAsFunction(globalContext, jsCallbackFunction, nullptr, 0, nullptr, nullptr);
+        JSValueUnprotect(globalContext, jsCallbackFunction);
+    });
+#endif
+}
+
 #if PLATFORM(IOS)
 - (void)addTouchAtX:(int)x y:(int)y
 {
index d67794c..249ecb1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +45,9 @@ interface EventSendingController {
     void zoomPageOut();
     void scalePageBy(double scale, double x, double y);
 
+    void monitorWheelEvents();
+    void callAfterScrollingCompletes(object functionCallback);
+
 #if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
     // Touch events.
     void addTouchPoint(long x, long y);
index 89c5a6c..9fc549b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -501,6 +501,54 @@ void EventSendingController::scalePageBy(double scale, double x, double y)
     WKBundlePageSetScaleAtOrigin(InjectedBundle::singleton().page()->page(), scale, origin);
 }
 
+void EventSendingController::monitorWheelEvents()
+{
+    WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+    
+    WKBundlePageStartMonitoringScrollOperations(page);
+}
+
+struct ScrollCompletionCallbackData {
+    JSContextRef m_context;
+    JSObjectRef m_function;
+
+    ScrollCompletionCallbackData(JSContextRef context, JSObjectRef function)
+        : m_context(context), m_function(function)
+    {
+    }
+};
+
+static void executeCallback(void* context)
+{
+    if (!context)
+        return;
+
+    std::unique_ptr<ScrollCompletionCallbackData> callBackData(reinterpret_cast<ScrollCompletionCallbackData*>(context));
+
+    JSObjectCallAsFunction(callBackData->m_context, callBackData->m_function, nullptr, 0, nullptr, nullptr);
+    JSValueUnprotect(callBackData->m_context, callBackData->m_function);
+}
+
+void EventSendingController::callAfterScrollingCompletes(JSValueRef functionCallback)
+{
+    if (!functionCallback)
+        return;
+
+    WKBundlePageRef page = InjectedBundle::singleton().page()->page();
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(page);
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+    
+    JSObjectRef functionCallbackObject = JSValueToObject(context, functionCallback, nullptr);
+    if (!functionCallbackObject)
+        return;
+    
+    JSValueProtect(context, functionCallbackObject);
+
+    auto scrollCompletionCallbackData = std::make_unique<ScrollCompletionCallbackData>(context, functionCallbackObject);
+
+    WKBundlePageRegisterScrollOperationCompletionCallback(page, executeCallback, scrollCompletionCallbackData.release());
+}
+
 #if ENABLE(TOUCH_EVENTS)
 void EventSendingController::addTouchPoint(int x, int y)
 {
index 359f541..e635f5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2011, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -52,6 +52,8 @@ public:
     JSValueRef contextClick();
     void leapForward(int milliseconds);
     void scheduleAsynchronousClick();
+    void monitorWheelEvents();
+    void callAfterScrollingCompletes(JSValueRef functionCallback);
 
     void keyDown(JSStringRef key, JSValueRef modifierArray, int location);
     void scheduleAsynchronousKeyDown(JSStringRef key);