Title: [173784] trunk
Revision
173784
Author
[email protected]
Date
2014-09-19 18:10:50 -0700 (Fri, 19 Sep 2014)

Log Message

Latching in iframes is not working as expected
https://bugs.webkit.org/show_bug.cgi?id=136729
<rdar://problem/18370549>

Reviewed by Simon Fraser.

Source/WebCore:

Test: platform/mac/fast/scrolling/scrolling-iframe-100pct.html

Correct latching behavior by moving the concept of latching from the event handler to the main frame.
The event handlers are per-document, and can improperly latch to the iframe element (rather than the
scrollable content of the iframe) resulting in incorrect behavior.

Also move the wheel event delta tracking to the main frame, as this is similarly "top-level" in nature.

* WebCore.vcxproj/WebCore.vcxproj: Add new LatchedState class.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* page/EventHandler.cpp:
(WebCore::EventHandler::EventHandler): Update constructor after moving some members to the new
LatchedState object.
(WebCore::EventHandler::clear): Call 'clear' on the LatchedState class.
(WebCore::EventHandler::platformRecordWheelEvent):  Update for new LatchedState class.
(WebCore::EventHandler::handleWheelEvent): Ditto.
(WebCore::EventHandler::clearLatchedState): Ditto.
(WebCore::EventHandler::defaultWheelEventHandler): Ditto.
* page/EventHandler.h:
* page/LatchedState.cpp: Added.
(WebCore::LatchedState::LatchedState):
(WebCore::LatchedState::~LatchedState):
(WebCore::LatchedState::clear):
(WebCore::LatchedState::setWheelEventElement):
(WebCore::LatchedState::setWidgetIsLatched):
(WebCore::LatchedState::setPreviousWheelScrolledElement):
(WebCore::LatchedState::setScrollableContainer):
* page/LatchedState.h: Added.
(WebCore::LatchedState::wheelEventElement):
(WebCore::LatchedState::frame):
(WebCore::LatchedState::setFrame):
(WebCore::LatchedState::widgetIsLatched):
(WebCore::LatchedState::previousWheelScrolledElement):
(WebCore::LatchedState::scrollableContainer):
(WebCore::LatchedState::startedGestureAtScrollLimit):
(WebCore::LatchedState::setStartedGestureAtScrollLimit):
* page/MainFrame.cpp:
(WebCore::MainFrame::MainFrame): Update for new members (LatchedState and WheelEventDeltaTracker)
* page/MainFrame.h:
* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::platformPrepareForWheelEvents): Use mainFrame-located latching information.
(WebCore::EventHandler::platformRecordWheelEvent): Use mainFrame-located wheel event delta tracking.
(WebCore::EventHandler::platformCompleteWheelEvent): Make sure to use the latched frame as well as
the latched element so that events get routed properly.
(WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): Update for new mainFrame
location for latched state information.

LayoutTests:

* platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug-expected.txt: Added.
* platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (173783 => 173784)


--- trunk/LayoutTests/ChangeLog	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/LayoutTests/ChangeLog	2014-09-20 01:10:50 UTC (rev 173784)
@@ -1,3 +1,14 @@
+2014-09-19  Brent Fulgham  <[email protected]>
+
+        Latching in iframes is not working as expected
+        https://bugs.webkit.org/show_bug.cgi?id=136729
+        <rdar://problem/18370549>
+
+        Reviewed by Simon Fraser.
+
+        * platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug-expected.txt: Added.
+        * platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug.html: Added.
+
 2014-09-19  Jer Noble  <[email protected]>
 
         Videos with controls enabled never receive 'dragstart' events.

Added: trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug-expected.txt (0 => 173784)


--- trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug-expected.txt	2014-09-20 01:10:50 UTC (rev 173784)
@@ -0,0 +1,13 @@
+
+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 = 150
+Mouse moved to (28, 116)
+PASS iframe received wheel events.
+

Added: trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug.html (0 => 173784)


--- trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/scrolling/scroll-iframe-webkit1-latching-bug.html	2014-09-20 01:10:50 UTC (rev 173784)
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <link rel="help" href=""
+        <script src=""
+    </head>
+    <body id="parent" style="height: 2000px">
+        <script>
+        var iframeTarget;
+        var pageScrollPositionBefore;
+        var iframeScrollPositionBefore;
+        var continueCount = 5;
+
+        function checkForScroll() {
+
+            // The iframe should have scrolled, but not the main page.
+            var pageScrollPositionAfter = document.body.scrollTop;
+            var iframeScrollPositionAfter = window.frames['target'].document.body.scrollTop;
+
+            if (iframeScrollPositionBefore != iframeScrollPositionAfter)
+                testPassed("iframe received wheel events.");
+            else
+                testFailed("iframe 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.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>
+        <iframe id="target" name="target" style="border:solid 1px green; height: 150px; width: 300px;" 
+            src= ""
+                <html style='height: 100%'>
+                    <body style='height: 100%'>
+                        <div style='height: 100px; width: 200px'>
+                            <div style='overflow-y: auto; overflow-x: hidden;'>
+                            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>
+                        </div>
+                    </body>
+                </html>"
+            _onload_="setupTopLevel();">
+        </iframe>
+        <div id="console"></div>
+        <script>
+        description("Tests that iframe doesn't pass wheel events to main frame when scrolling at bottom");
+        </script>
+        <script src=""
+    </body>
+</html>

Modified: trunk/Source/WebCore/CMakeLists.txt (173783 => 173784)


--- trunk/Source/WebCore/CMakeLists.txt	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/CMakeLists.txt	2014-09-20 01:10:50 UTC (rev 173784)
@@ -1972,6 +1972,7 @@
     page/animation/ImplicitAnimation.cpp
     page/animation/KeyframeAnimation.cpp
 
+    page/scrolling/ScrollLatchingState.cpp
     page/scrolling/ScrollingConstraints.cpp
     page/scrolling/ScrollingCoordinator.cpp
     page/scrolling/ScrollingStateFixedNode.cpp

Modified: trunk/Source/WebCore/ChangeLog (173783 => 173784)


--- trunk/Source/WebCore/ChangeLog	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/ChangeLog	2014-09-20 01:10:50 UTC (rev 173784)
@@ -1,3 +1,59 @@
+2014-09-19  Brent Fulgham  <[email protected]>
+
+        Latching in iframes is not working as expected
+        https://bugs.webkit.org/show_bug.cgi?id=136729
+        <rdar://problem/18370549>
+
+        Reviewed by Simon Fraser.
+
+        Test: platform/mac/fast/scrolling/scrolling-iframe-100pct.html
+
+        Correct latching behavior by moving the concept of latching from the event handler to the main frame.
+        The event handlers are per-document, and can improperly latch to the iframe element (rather than the
+        scrollable content of the iframe) resulting in incorrect behavior.
+
+        Also move the wheel event delta tracking to the main frame, as this is similarly "top-level" in nature.
+
+        * WebCore.vcxproj/WebCore.vcxproj: Add new LatchedState class.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::EventHandler): Update constructor after moving some members to the new
+        LatchedState object.
+        (WebCore::EventHandler::clear): Call 'clear' on the LatchedState class.
+        (WebCore::EventHandler::platformRecordWheelEvent):  Update for new LatchedState class.
+        (WebCore::EventHandler::handleWheelEvent): Ditto.
+        (WebCore::EventHandler::clearLatchedState): Ditto.
+        (WebCore::EventHandler::defaultWheelEventHandler): Ditto.
+        * page/EventHandler.h:
+        * page/LatchedState.cpp: Added.
+        (WebCore::LatchedState::LatchedState):
+        (WebCore::LatchedState::~LatchedState):
+        (WebCore::LatchedState::clear):
+        (WebCore::LatchedState::setWheelEventElement):
+        (WebCore::LatchedState::setWidgetIsLatched):
+        (WebCore::LatchedState::setPreviousWheelScrolledElement):
+        (WebCore::LatchedState::setScrollableContainer):
+        * page/LatchedState.h: Added.
+        (WebCore::LatchedState::wheelEventElement):
+        (WebCore::LatchedState::frame):
+        (WebCore::LatchedState::setFrame):
+        (WebCore::LatchedState::widgetIsLatched):
+        (WebCore::LatchedState::previousWheelScrolledElement):
+        (WebCore::LatchedState::scrollableContainer):
+        (WebCore::LatchedState::startedGestureAtScrollLimit):
+        (WebCore::LatchedState::setStartedGestureAtScrollLimit):
+        * page/MainFrame.cpp:
+        (WebCore::MainFrame::MainFrame): Update for new members (LatchedState and WheelEventDeltaTracker)
+        * page/MainFrame.h:
+        * page/mac/EventHandlerMac.mm:
+        (WebCore::EventHandler::platformPrepareForWheelEvents): Use mainFrame-located latching information.
+        (WebCore::EventHandler::platformRecordWheelEvent): Use mainFrame-located wheel event delta tracking.
+        (WebCore::EventHandler::platformCompleteWheelEvent): Make sure to use the latched frame as well as
+        the latched element so that events get routed properly.
+        (WebCore::EventHandler::platformCompletePlatformWidgetWheelEvent): Update for new mainFrame
+        location for latched state information.
+
 2014-09-19  Chris Dumez  <[email protected]>
 
         Minimize virtual function calls in MarkupAccumulator

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (173783 => 173784)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-09-20 01:10:50 UTC (rev 173784)
@@ -7191,6 +7191,7 @@
     <ClCompile Include="..\page\PerformanceTiming.cpp" />
     <ClCompile Include="..\page\PrintContext.cpp" />
     <ClCompile Include="..\page\Screen.cpp" />
+    <ClCompile Include="..\page\scrolling\ScrollLatchingState.cpp" />
     <ClCompile Include="..\page\scrolling\ScrollingConstraints.cpp" />
     <ClCompile Include="..\page\scrolling\ScrollingCoordinator.cpp" />
     <ClCompile Include="..\page\SecurityOrigin.cpp" />
@@ -19173,6 +19174,7 @@
     <ClInclude Include="..\page\PrintContext.h" />
     <ClInclude Include="..\page\Screen.h" />
     <ClInclude Include="..\page\scrolling\coordinatedgraphics\ScrollingCoordinatorCoordinatedGraphics.h" />
+    <ClInclude Include="..\page\scrolling\ScrollLatchingState.h" />
     <ClInclude Include="..\page\scrolling\ScrollingConstraints.h" />
     <ClInclude Include="..\page\scrolling\ScrollingCoordinator.h" />
     <ClInclude Include="..\page\scrolling\ScrollingStateFixedNode.h" />

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (173783 => 173784)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters	2014-09-20 01:10:50 UTC (rev 173784)
@@ -789,6 +789,9 @@
     <ClCompile Include="..\page\Screen.cpp">
       <Filter>page</Filter>
     </ClCompile>
+    <ClCompile Include="..\page\scrolling\ScrollLatchingState.cpp">
+      <Filter>page</Filter>
+    </ClCompile>
     <ClCompile Include="..\page\scrolling\ScrollingConstraints.cpp">
       <Filter>page</Filter>
     </ClCompile>
@@ -7773,6 +7776,9 @@
     <ClInclude Include="..\page\Screen.h">
       <Filter>page</Filter>
     </ClInclude>
+    <ClInclude Include="..\page\scrolling\ScrollLatchingState.h">
+      <Filter>page</Filter>
+    </ClInclude>
     <ClInclude Include="..\page\scrolling\ScrollingConstraints.h">
       <Filter>page</Filter>
     </ClInclude>

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (173783 => 173784)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-09-20 01:10:50 UTC (rev 173784)
@@ -2364,6 +2364,8 @@
 		7AA3A6A4194B5C22001CBD24 /* TileCoverageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AA3A6A2194B5C22001CBD24 /* TileCoverageMap.h */; };
 		7AABA25914BC613300AA9A11 /* DOMEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AABA25714BC613300AA9A11 /* DOMEditor.cpp */; };
 		7AABA25A14BC613300AA9A11 /* DOMEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AABA25814BC613300AA9A11 /* DOMEditor.h */; };
+		7AAFE8CF19CB8672000F56D8 /* ScrollLatchingState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AAFE8CD19CB8672000F56D8 /* ScrollLatchingState.cpp */; };
+		7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */; };
 		7AB0B1C01211A62200A76940 /* InspectorDatabaseAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AB0B1BE1211A62200A76940 /* InspectorDatabaseAgent.cpp */; };
 		7AB0B1C11211A62200A76940 /* InspectorDatabaseAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AB0B1BF1211A62200A76940 /* InspectorDatabaseAgent.h */; };
 		7ACD88D314C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */; };
@@ -9498,6 +9500,8 @@
 		7AA3A6A2194B5C22001CBD24 /* TileCoverageMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TileCoverageMap.h; path = ca/TileCoverageMap.h; sourceTree = "<group>"; };
 		7AABA25714BC613300AA9A11 /* DOMEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMEditor.cpp; sourceTree = "<group>"; };
 		7AABA25814BC613300AA9A11 /* DOMEditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMEditor.h; sourceTree = "<group>"; };
+		7AAFE8CD19CB8672000F56D8 /* ScrollLatchingState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollLatchingState.cpp; sourceTree = "<group>"; };
+		7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollLatchingState.h; sourceTree = "<group>"; };
 		7AB0B1BE1211A62200A76940 /* InspectorDatabaseAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseAgent.cpp; sourceTree = "<group>"; };
 		7AB0B1BF1211A62200A76940 /* InspectorDatabaseAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseAgent.h; sourceTree = "<group>"; };
 		7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorIndexedDBAgent.cpp; sourceTree = "<group>"; };
@@ -15084,6 +15088,8 @@
 				1AF62EE214DA22A70041556C /* mac */,
 				0FFD4D5E18651FA300512F6E /* AsyncScrollingCoordinator.cpp */,
 				0FFD4D5F18651FA300512F6E /* AsyncScrollingCoordinator.h */,
+				7AAFE8CD19CB8672000F56D8 /* ScrollLatchingState.cpp */,
+				7AAFE8CE19CB8672000F56D8 /* ScrollLatchingState.h */,
 				0F605AEA15F94848004DF0C0 /* ScrollingConstraints.cpp */,
 				0F605AEB15F94848004DF0C0 /* ScrollingConstraints.h */,
 				1AF62EE414DA22A70041556C /* ScrollingCoordinator.cpp */,
@@ -24913,6 +24919,7 @@
 				BCEC01C30C274DDD009F4EC9 /* JSScreen.h in Headers */,
 				FDA15ECE12B03F61003A583A /* JSScriptProcessorNode.h in Headers */,
 				9FA37EFB1172FDA600C4CD55 /* JSScriptProfile.h in Headers */,
+				7AAFE8D019CB8672000F56D8 /* ScrollLatchingState.h in Headers */,
 				9FA37EFD1172FDA600C4CD55 /* JSScriptProfileNode.h in Headers */,
 				41D07A7F0FF935CA0095EDCE /* JSSharedWorker.h in Headers */,
 				41D1690610238B66009BC827 /* JSSharedWorkerGlobalScope.h in Headers */,
@@ -28952,6 +28959,7 @@
 				B27535630B053814002CE64F /* PathCG.cpp in Sources */,
 				A88DD4890B4629B000C02990 /* PathTraversalState.cpp in Sources */,
 				A8FA6E5E0E4CFDED00D5CF49 /* Pattern.cpp in Sources */,
+				7AAFE8CF19CB8672000F56D8 /* ScrollLatchingState.cpp in Sources */,
 				A80A38FE0E50CC8200A25EBC /* PatternCG.cpp in Sources */,
 				B27535640B053814002CE64F /* PDFDocumentImage.cpp in Sources */,
 				2D6E468417D660F500ECF8BB /* PDFDocumentImageMac.mm in Sources */,

Modified: trunk/Source/WebCore/page/EventHandler.cpp (173783 => 173784)


--- trunk/Source/WebCore/page/EventHandler.cpp	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2014-09-20 01:10:50 UTC (rev 173784)
@@ -83,6 +83,7 @@
 #include "SVGNames.h"
 #include "SVGUseElement.h"
 #include "ScrollAnimator.h"
+#include "ScrollLatchingState.h"
 #include "Scrollbar.h"
 #include "Settings.h"
 #include "ShadowRoot.h"
@@ -401,12 +402,9 @@
 #endif
     , m_mousePositionIsUnknown(true)
     , m_mouseDownTimestamp(0)
-    , m_recentWheelEventDeltaTracker(std::make_unique<WheelEventDeltaTracker>())
-    , m_widgetIsLatched(false)
 #if PLATFORM(COCOA)
     , m_mouseDownView(nil)
     , m_sendingEventToSubview(false)
-    , m_startedGestureAtScrollLimit(false)
 #if !PLATFORM(IOS)
     , m_activationEventNumber(-1)
 #endif // !PLATFORM(IOS)
@@ -490,11 +488,9 @@
     m_mousePressed = false;
     m_capturesDragging = false;
     m_capturingMouseEventsElement = nullptr;
-    m_latchedWheelEventElement = nullptr;
-#if PLATFORM(COCOA)
-    m_latchedScrollableContainer = nullptr;
+#if PLATFORM(MAC)
+    m_frame.mainFrame().resetLatchingState();
 #endif
-    m_previousWheelScrolledElement = nullptr;
 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
     m_originatingTouchPointTargets.clear();
     m_originatingTouchPointDocument.clear();
@@ -2644,7 +2640,7 @@
 
 void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
 {
-    m_recentWheelEventDeltaTracker->recordWheelEventDelta(event);
+    m_frame.mainFrame().wheelEventDeltaTracker()->recordWheelEventDelta(event);
 }
 
 bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, Element*, ContainerNode*, ScrollableArea*)
@@ -2689,13 +2685,12 @@
     bool isOverWidget = result.isOverWidget();
     platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
 
-#if PLATFORM(COCOA)
+#if PLATFORM(MAC)
     if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone)
-#endif
     {
-        m_latchedWheelEventElement = nullptr;
-        m_previousWheelScrolledElement = nullptr;
+        m_frame.mainFrame().latchingState()->clear();
     }
+#endif
 
     // FIXME: It should not be necessary to do this mutation here.
     // Instead, the handlers should know convert vertical scrolls appropriately.
@@ -2740,12 +2735,10 @@
 
 void EventHandler::clearLatchedState()
 {
-    m_latchedWheelEventElement = nullptr;
-#if PLATFORM(COCOA)
-    m_latchedScrollableContainer = nullptr;
+#if PLATFORM(MAC)
+    m_frame.mainFrame().latchingState()->clear();
 #endif
-    m_widgetIsLatched = false;
-    m_previousWheelScrolledElement = nullptr;
+    m_frame.mainFrame().wheelEventDeltaTracker()->endTrackingDeltas();
 }
 
 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
@@ -2753,13 +2746,18 @@
     if (!startNode || !wheelEvent)
         return;
     
-    Element* stopElement = m_previousWheelScrolledElement.get();
     DominantScrollGestureDirection dominantDirection = DominantScrollGestureDirection::None;
 
+#if PLATFORM(MAC)
+    ScrollLatchingState* latchedState = m_frame.mainFrame().latchingState();
+    ASSERT(latchedState);
+    Element* stopElement = latchedState->previousWheelScrolledElement();
+
     // Workaround for scrolling issues <rdar://problem/14758615>.
-#if PLATFORM(COCOA)
-    if (m_recentWheelEventDeltaTracker->isTrackingDeltas())
-        dominantDirection = m_recentWheelEventDeltaTracker->dominantScrollGestureDirection();
+    if (m_frame.mainFrame().wheelEventDeltaTracker()->isTrackingDeltas())
+        dominantDirection = m_frame.mainFrame().wheelEventDeltaTracker()->dominantScrollGestureDirection();
+#else
+    Element* stopElement = nullptr;
 #endif
     
     // Break up into two scrolls if we need to.  Diagonal movement on 
@@ -2770,8 +2768,10 @@
     if (dominantDirection != DominantScrollGestureDirection::Horizontal && handleWheelEventInAppropriateEnclosingBoxForSingleAxis(startNode, wheelEvent, &stopElement, ScrollEventAxis::Vertical))
         wheelEvent->setDefaultHandled();
     
-    if (!m_latchedWheelEventElement)
-        m_previousWheelScrolledElement = stopElement;
+#if PLATFORM(MAC)
+    if (!latchedState->wheelEventElement())
+        latchedState->setPreviousWheelScrolledElement(stopElement);
+#endif
 }
 
 #if ENABLE(CONTEXT_MENUS)

Modified: trunk/Source/WebCore/page/EventHandler.h (173783 => 173784)


--- trunk/Source/WebCore/page/EventHandler.h	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/page/EventHandler.h	2014-09-20 01:10:50 UTC (rev 173784)
@@ -535,15 +535,8 @@
     double m_mouseDownTimestamp;
     PlatformMouseEvent m_mouseDown;
 
-    std::unique_ptr<WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
-    RefPtr<Element> m_latchedWheelEventElement;
-    bool m_widgetIsLatched;
-
-    RefPtr<Element> m_previousWheelScrolledElement;
-
 #if PLATFORM(COCOA)
     NSView *m_mouseDownView;
-    RefPtr<ContainerNode> m_latchedScrollableContainer;
     bool m_sendingEventToSubview;
     bool m_startedGestureAtScrollLimit;
 #if !PLATFORM(IOS)

Modified: trunk/Source/WebCore/page/MainFrame.cpp (173783 => 173784)


--- trunk/Source/WebCore/page/MainFrame.cpp	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/page/MainFrame.cpp	2014-09-20 01:10:50 UTC (rev 173784)
@@ -1,40 +1,50 @@
 /*
+ * Copyright (C) 2013-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
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
 
-Copyright (C) 2013 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.
-
-THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "MainFrame.h"
 
+#include "ScrollLatchingState.h"
+#include "WheelEventDeltaTracker.h"
+
 namespace WebCore {
 
 inline MainFrame::MainFrame(Page& page, FrameLoaderClient& client)
     : Frame(page, nullptr, client)
     , m_selfOnlyRefCount(0)
+#if PLATFORM(MAC)
+    , m_latchingState(std::make_unique<ScrollLatchingState>())
+#endif
+    , m_recentWheelEventDeltaTracker(std::make_unique<WheelEventDeltaTracker>())
 {
 }
 
+MainFrame::~MainFrame()
+{
+}
+
 RefPtr<MainFrame> MainFrame::create(Page& page, FrameLoaderClient& client)
 {
     return adoptRef(new MainFrame(page, client));
@@ -66,4 +76,14 @@
         tree().removeChild(child);
 }
 
+#if PLATFORM(MAC)
+void MainFrame::resetLatchingState()
+{
+    if (!m_latchingState)
+        return;
+
+    m_latchingState->clear();
 }
+#endif
+
+}

Modified: trunk/Source/WebCore/page/MainFrame.h (173783 => 173784)


--- trunk/Source/WebCore/page/MainFrame.h	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/page/MainFrame.h	2014-09-20 01:10:50 UTC (rev 173784)
@@ -1,29 +1,28 @@
 /*
+ * Copyright (C) 2013-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
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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.
+ */
 
-Copyright (C) 2013 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.
-
-THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 MainFrame_h
 #define MainFrame_h
 
@@ -31,19 +30,36 @@
 
 namespace WebCore {
 
+class ScrollLatchingState;
+class WheelEventDeltaTracker;
+
 class MainFrame final : public Frame {
 public:
     static RefPtr<MainFrame> create(Page&, FrameLoaderClient&);
 
+    virtual ~MainFrame();
+
     void selfOnlyRef();
     void selfOnlyDeref();
 
+    WheelEventDeltaTracker* wheelEventDeltaTracker() { return m_recentWheelEventDeltaTracker.get(); }
+
+#if PLATFORM(MAC)
+    ScrollLatchingState* latchingState() { return m_latchingState.get(); }
+    void resetLatchingState();
+#endif
+
 private:
     MainFrame(Page&, FrameLoaderClient&);
 
     void dropChildren();
 
     unsigned m_selfOnlyRefCount;
+
+#if PLATFORM(MAC)
+    std::unique_ptr<ScrollLatchingState> m_latchingState;
+#endif
+    std::unique_ptr<WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
 };
 
 inline bool Frame::isMainFrame() const

Modified: trunk/Source/WebCore/page/mac/EventHandlerMac.mm (173783 => 173784)


--- trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2014-09-20 00:11:47 UTC (rev 173783)
+++ trunk/Source/WebCore/page/mac/EventHandlerMac.mm	2014-09-20 01:10:50 UTC (rev 173784)
@@ -47,6 +47,7 @@
 #include "RenderListBox.h"
 #include "RenderWidget.h"
 #include "RuntimeApplicationChecks.h"
+#include "ScrollLatchingState.h"
 #include "ScrollableArea.h"
 #include "Scrollbar.h"
 #include "Settings.h"
@@ -815,6 +816,18 @@
     return widget->platformWidget();
 }
 
+static bool latchingIsLockedToPlatformFrame(const Frame& frame)
+{
+    ScrollLatchingState* latchedState = frame.mainFrame().latchingState();
+    if (!latchedState)
+        return false;
+
+    if (frameHasPlatformWidget(frame) && &frame != latchedState->frame())
+        return true;
+
+    return false;
+}
+    
 void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, RefPtr<Element>& wheelEventTarget, RefPtr<ContainerNode>& scrollableContainer, ScrollableArea*& scrollableArea, bool& isOverWidget)
 {
     FrameView* view = m_frame.view();
@@ -841,56 +854,73 @@
         }
     }
     
+    ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
+    ASSERT(latchingState);
     if (wheelEvent.shouldConsiderLatching()) {
         if (scrollableArea && scrollableContainer)
-            m_startedGestureAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea, wheelEvent.deltaX(), wheelEvent.deltaY());
+            latchingState->setStartedGestureAtScrollLimit(scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea, wheelEvent.deltaX(), wheelEvent.deltaY()));
         else
-            m_startedGestureAtScrollLimit = false;
-        m_latchedWheelEventElement = wheelEventTarget;
+            latchingState->setStartedGestureAtScrollLimit(false);
+        latchingState->setWheelEventElement(wheelEventTarget);
+        latchingState->setFrame(&m_frame);
         // FIXME: What prevents us from deleting this scrollable container while still holding a pointer to it?
-        m_latchedScrollableContainer = scrollableContainer;
-        m_widgetIsLatched = result.isOverWidget();
-        isOverWidget = m_widgetIsLatched;
-        m_recentWheelEventDeltaTracker->beginTrackingDeltas();
-    } else if (wheelEvent.shouldResetLatching()) {
+        latchingState->setScrollableContainer(scrollableContainer);
+        latchingState->setWidgetIsLatched(result.isOverWidget());
+        isOverWidget = latchingState->widgetIsLatched();
+        m_frame.mainFrame().wheelEventDeltaTracker()->beginTrackingDeltas();
+    } else if (wheelEvent.shouldResetLatching())
         clearLatchedState();
-        m_recentWheelEventDeltaTracker->endTrackingDeltas();
+
+    if (!wheelEvent.shouldResetLatching() && latchingState->wheelEventElement()) {
+        if (latchingIsLockedToPlatformFrame(m_frame))
+            return;
+
+        wheelEventTarget = latchingState->wheelEventElement();
+        isOverWidget = latchingState->widgetIsLatched();
     }
-    
-    if (!wheelEvent.shouldResetLatching() && m_latchedWheelEventElement) {
-        wheelEventTarget = m_latchedWheelEventElement.get();
-        isOverWidget = m_widgetIsLatched;
-    }
 }
 
 void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& wheelEvent)
 {
     switch (wheelEvent.phase()) {
         case PlatformWheelEventPhaseBegan:
-            m_recentWheelEventDeltaTracker->beginTrackingDeltas();
+            m_frame.mainFrame().wheelEventDeltaTracker()->beginTrackingDeltas();
             break;
         case PlatformWheelEventPhaseEnded:
-            m_recentWheelEventDeltaTracker->endTrackingDeltas();
+            m_frame.mainFrame().wheelEventDeltaTracker()->endTrackingDeltas();
             break;
         default:
             break;
     }
 
-    m_recentWheelEventDeltaTracker->recordWheelEventDelta(wheelEvent);
+    m_frame.mainFrame().wheelEventDeltaTracker()->recordWheelEventDelta(wheelEvent);
 }
 
+static FrameView* frameViewForLatchingState(Frame& frame, ScrollLatchingState* latchingState)
+{
+    if (latchingIsLockedToPlatformFrame(frame))
+        return frame.view();
+
+    return latchingState->frame() ? latchingState->frame()->view() : frame.view();
+}
+
 bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& wheelEvent, Element* wheelEventTarget, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea)
 {
     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     FrameView* view = m_frame.view();
 
-    if (wheelEvent.useLatchedEventElement() && m_latchedScrollableContainer) {
+    ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
+    ASSERT(latchingState);
+    if (wheelEvent.useLatchedEventElement() && latchingState->scrollableContainer()) {
+        view = frameViewForLatchingState(m_frame, latchingState);
         if (!view || !view->frame().isMainFrame()) {
             bool didHandleWheelEvent = view && view->wheelEvent(wheelEvent);
-            if (!didHandleWheelEvent && scrollableContainer == m_latchedScrollableContainer) {
+            if (!didHandleWheelEvent && scrollableContainer == latchingState->scrollableContainer()) {
                 // If we are just starting a scroll event, and have nowhere left to scroll, allow
                 // the enclosing frame to handle the scroll.
-                didHandleWheelEvent = !m_startedGestureAtScrollLimit;
+                didHandleWheelEvent = !latchingState->startedGestureAtScrollLimit();
+                if (!didHandleWheelEvent)
+                    latchingState->setFrame(nullptr);
             }
 
             // If the platform widget is handling the event, we always want to return false
@@ -901,11 +931,11 @@
             return didHandleWheelEvent;
         }
         
-        if (scrollableArea && !m_startedGestureAtScrollLimit && scrollableContainer == m_latchedScrollableContainer) {
+        if (scrollableArea && !latchingState->startedGestureAtScrollLimit() && scrollableContainer == latchingState->scrollableContainer()) {
             m_isHandlingWheelEvent = false;
 
             if (eventTargetIsPlatformWidget(wheelEventTarget))
-                return !m_startedGestureAtScrollLimit;
+                return !latchingState->startedGestureAtScrollLimit();
 
             return true;
         }
@@ -922,8 +952,10 @@
     if (frameHasPlatformWidget(m_frame) && widget.isFrameView())
         return true;
 
-    if (wheelEvent.useLatchedEventElement() && m_latchedScrollableContainer && scrollableContainer == m_latchedScrollableContainer)
-        return !m_startedGestureAtScrollLimit;
+    ScrollLatchingState* latchingState = m_frame.mainFrame().latchingState();
+    ASSERT(latchingState);
+    if (wheelEvent.useLatchedEventElement() && latchingState->scrollableContainer() && scrollableContainer == latchingState->scrollableContainer())
+        return !latchingState->startedGestureAtScrollLimit();
 
     return false;
 }

Added: trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp (0 => 173784)


--- trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp	                        (rev 0)
+++ trunk/Source/WebCore/page/scrolling/ScrollLatchingState.cpp	2014-09-20 01:10:50 UTC (rev 173784)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "ScrollLatchingState.h"
+
+#include "Element.h"
+
+namespace WebCore {
+
+ScrollLatchingState::ScrollLatchingState()
+    : m_frame(nullptr)
+    , m_widgetIsLatched(false)
+    , m_startedGestureAtScrollLimit(false)
+{
+}
+    
+ScrollLatchingState::~ScrollLatchingState()
+{
+}
+
+void ScrollLatchingState::clear()
+{
+    m_wheelEventElement = nullptr;
+    m_frame = nullptr;
+    m_scrollableContainer = nullptr;
+    m_widgetIsLatched = false;
+    m_previousWheelScrolledElement = nullptr;
+}
+
+void ScrollLatchingState::setWheelEventElement(PassRefPtr<Element> element)
+{
+    m_wheelEventElement = element;
+}
+
+void ScrollLatchingState::setWidgetIsLatched(bool isOverWidget)
+{
+    m_widgetIsLatched = isOverWidget;
+}
+
+void ScrollLatchingState::setPreviousWheelScrolledElement(PassRefPtr<Element> element)
+{
+    m_previousWheelScrolledElement = element;
+}
+
+void ScrollLatchingState::setScrollableContainer(PassRefPtr<ContainerNode> node)
+{
+    m_scrollableContainer = node;
+}
+
+}

Added: trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h (0 => 173784)


--- trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h	                        (rev 0)
+++ trunk/Source/WebCore/page/scrolling/ScrollLatchingState.h	2014-09-20 01:10:50 UTC (rev 173784)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 ScrollLatchingState_h
+#define ScrollLatchingState_h
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class ContainerNode;
+class Element;
+class Frame;
+
+class ScrollLatchingState {
+public:
+    ScrollLatchingState();
+    virtual ~ScrollLatchingState();
+
+    void clear();
+
+    Element* wheelEventElement() { return m_wheelEventElement.get(); }
+    void setWheelEventElement(PassRefPtr<Element>);
+    Frame* frame() { return m_frame; }
+    void setFrame(Frame* frame) { m_frame = frame; }
+
+    bool widgetIsLatched() const { return m_widgetIsLatched; }
+    void setWidgetIsLatched(bool isOverWidget);
+
+    Element* previousWheelScrolledElement() { return m_previousWheelScrolledElement.get(); }
+    void setPreviousWheelScrolledElement(PassRefPtr<Element>);
+    
+    ContainerNode* scrollableContainer() { return m_scrollableContainer.get(); }
+    void setScrollableContainer(PassRefPtr<ContainerNode>);
+    bool startedGestureAtScrollLimit() const { return m_startedGestureAtScrollLimit; }
+    void setStartedGestureAtScrollLimit(bool startedAtLimit) { m_startedGestureAtScrollLimit = startedAtLimit; }
+
+private:
+    RefPtr<Element> m_wheelEventElement;
+    RefPtr<Element> m_previousWheelScrolledElement;
+    RefPtr<ContainerNode> m_scrollableContainer;
+
+    Frame* m_frame;
+    
+    bool m_widgetIsLatched;
+    bool m_startedGestureAtScrollLimit;
+};
+    
+}
+
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to