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