Index: third_party/WebKit/Source/core/input/EventHandler.cpp |
diff --git a/third_party/WebKit/Source/core/input/EventHandler.cpp b/third_party/WebKit/Source/core/input/EventHandler.cpp |
index 22ff85faa4c717d09a7939f22de3bf7824bf75e5..bad5b0dc36e3628c3abf728963fe111b80484d2d 100644 |
--- a/third_party/WebKit/Source/core/input/EventHandler.cpp |
+++ b/third_party/WebKit/Source/core/input/EventHandler.cpp |
@@ -56,7 +56,6 @@ |
#include "core/frame/FrameView.h" |
#include "core/frame/LocalFrame.h" |
#include "core/frame/Settings.h" |
-#include "core/frame/TopControls.h" |
#include "core/frame/UseCounter.h" |
#include "core/frame/VisualViewport.h" |
#include "core/html/HTMLDialogElement.h" |
@@ -83,8 +82,6 @@ |
#include "core/page/Page.h" |
#include "core/page/SpatialNavigation.h" |
#include "core/page/TouchAdjustment.h" |
-#include "core/page/scrolling/OverscrollController.h" |
-#include "core/page/scrolling/RootScroller.h" |
#include "core/page/scrolling/ScrollState.h" |
#include "core/paint/PaintLayer.h" |
#include "core/style/ComputedStyle.h" |
@@ -143,47 +140,6 @@ bool shouldRefetchEventTarget(const MouseEventWithHitTestResults& mev) |
return targetNode->isShadowRoot() && isHTMLInputElement(toShadowRoot(targetNode)->host()); |
} |
-// TODO(bokan): This method can go away once all scrolls happen through the |
-// scroll customization path. |
-void computeScrollChainForSingleNode(Node& node, std::deque<int>& scrollChain) |
-{ |
- scrollChain.clear(); |
- |
- ASSERT(node.layoutObject()); |
- Element* element = toElement(&node); |
- |
- scrollChain.push_front(DOMNodeIds::idForNode(element)); |
-} |
- |
-void recomputeScrollChain(const LocalFrame& frame, const Node& startNode, |
- std::deque<int>& scrollChain) |
-{ |
- scrollChain.clear(); |
- |
- ASSERT(startNode.layoutObject()); |
- LayoutBox* curBox = startNode.layoutObject()->enclosingBox(); |
- |
- // Scrolling propagates along the containing block chain. |
- while (curBox && !curBox->isLayoutView()) { |
- Node* curNode = curBox->node(); |
- // FIXME: this should reject more elements, as part of crbug.com/410974. |
- if (curNode && curNode->isElementNode()) { |
- Element* curElement = toElement(curNode); |
- if (curElement == frame.document()->scrollingElement()) |
- break; |
- scrollChain.push_front(DOMNodeIds::idForNode(curElement)); |
- } |
- curBox = curBox->containingBlock(); |
- } |
- // TODO(tdresser): this should sometimes be excluded, as part of crbug.com/410974. |
- // We need to ensure that the scrollingElement is always part of |
- // the scroll chain. In quirks mode, when the scrollingElement is |
- // the body, some elements may use the documentElement as their |
- // containingBlock, so we ensure the scrollingElement is added |
- // here. |
- scrollChain.push_front(DOMNodeIds::idForNode(frame.document()->scrollingElement())); |
-} |
- |
} // namespace |
using namespace HTMLNames; |
@@ -249,19 +205,16 @@ EventHandler::EventHandler(LocalFrame* frame) |
, m_mouseDownMayStartAutoscroll(false) |
, m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired) |
, m_svgPan(false) |
- , m_resizeScrollableArea(nullptr) |
, m_eventHandlerWillResetCapturingMouseEventsNode(0) |
, m_clickCount(0) |
, m_shouldOnlyFireDragOverEvent(false) |
, m_mousePositionIsUnknown(true) |
, m_mouseDownTimestamp(0) |
, m_pointerEventManager(frame) |
- , m_scrollGestureHandlingNode(nullptr) |
- , m_lastGestureScrollOverWidget(false) |
+ , m_scrollManager(frame) |
, m_longTapShouldInvokeContextMenu(false) |
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
, m_lastShowPressTimestamp(0) |
- , m_deltaConsumedForScrollSequence(false) |
{ |
} |
@@ -274,7 +227,6 @@ DEFINE_TRACE(EventHandler) |
{ |
visitor->trace(m_frame); |
visitor->trace(m_mousePressNode); |
- visitor->trace(m_resizeScrollableArea); |
visitor->trace(m_capturingMouseEventsNode); |
visitor->trace(m_nodeUnderMouse); |
visitor->trace(m_lastMouseMoveEventSubframe); |
@@ -282,12 +234,10 @@ DEFINE_TRACE(EventHandler) |
visitor->trace(m_clickNode); |
visitor->trace(m_dragTarget); |
visitor->trace(m_frameSetBeingResized); |
- visitor->trace(m_scrollbarHandlingScrollGesture); |
- visitor->trace(m_scrollGestureHandlingNode); |
- visitor->trace(m_previousGestureScrolledNode); |
visitor->trace(m_lastDeferredTapElement); |
visitor->trace(m_selectionController); |
visitor->trace(m_pointerEventManager); |
+ visitor->trace(m_scrollManager); |
} |
DragState& EventHandler::dragState() |
@@ -302,7 +252,6 @@ void EventHandler::clear() |
m_cursorUpdateTimer.stop(); |
m_fakeMouseMoveEventTimer.stop(); |
m_activeIntervalTimer.stop(); |
- m_resizeScrollableArea = nullptr; |
m_nodeUnderMouse = nullptr; |
m_lastMouseMoveEventSubframe = nullptr; |
m_lastScrollbarUnderMouse = nullptr; |
@@ -319,10 +268,8 @@ void EventHandler::clear() |
m_mousePressed = false; |
m_capturesDragging = false; |
m_capturingMouseEventsNode = nullptr; |
- clearGestureScrollState(); |
- m_lastGestureScrollOverWidget = false; |
- m_scrollbarHandlingScrollGesture = nullptr; |
m_pointerEventManager.clear(); |
+ m_scrollManager.clear(); |
m_mouseDownMayStartDrag = false; |
m_lastShowPressTimestamp = 0; |
m_lastDeferredTapElement = nullptr; |
@@ -333,7 +280,6 @@ void EventHandler::clear() |
m_mouseDownTimestamp = 0; |
m_longTapShouldInvokeContextMenu = false; |
m_dragStartPos = LayoutPoint(); |
- m_offsetFromResizeCorner = LayoutSize(); |
m_mouseDown = PlatformMouseEvent(); |
} |
@@ -483,8 +429,8 @@ WebInputEventResult EventHandler::handleMouseDraggedEvent(const MouseEventWithHi |
m_mouseDownMayStartDrag = false; |
- if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) { |
- if (AutoscrollController* controller = autoscrollController()) { |
+ if (m_mouseDownMayStartAutoscroll && !m_scrollManager.panScrollInProgress()) { |
+ if (AutoscrollController* controller = m_scrollManager.autoscrollController()) { |
controller->startAutoscrollForSelection(layoutObject); |
m_mouseDownMayStartAutoscroll = false; |
} |
@@ -501,9 +447,9 @@ void EventHandler::updateSelectionForMouseDrag() |
WebInputEventResult EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event) |
{ |
- AutoscrollController* controller = autoscrollController(); |
+ AutoscrollController* controller = m_scrollManager.autoscrollController(); |
if (controller && controller->autoscrollInProgress()) |
- stopAutoscroll(); |
+ m_scrollManager.stopAutoscroll(); |
// Used to prevent mouseMoveEvent from initiating a drag before |
// the mouse is pressed again. |
@@ -521,7 +467,7 @@ void EventHandler::startPanScrolling(LayoutObject* layoutObject) |
{ |
if (!layoutObject->isBox()) |
return; |
- AutoscrollController* controller = autoscrollController(); |
+ AutoscrollController* controller = m_scrollManager.autoscrollController(); |
if (!controller) |
return; |
controller->startPanScrolling(toLayoutBox(layoutObject), lastKnownMousePosition()); |
@@ -530,18 +476,6 @@ void EventHandler::startPanScrolling(LayoutObject* layoutObject) |
#endif // OS(WIN) |
-AutoscrollController* EventHandler::autoscrollController() const |
-{ |
- if (Page* page = m_frame->page()) |
- return &page->autoscrollController(); |
- return nullptr; |
-} |
- |
-bool EventHandler::panScrollInProgress() const |
-{ |
- return autoscrollController() && autoscrollController()->panScrollInProgress(); |
-} |
- |
HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding) |
{ |
TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint"); |
@@ -584,186 +518,14 @@ HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTe |
void EventHandler::stopAutoscroll() |
{ |
- if (AutoscrollController* controller = autoscrollController()) |
- controller->stopAutoscroll(); |
-} |
- |
-ScrollResult EventHandler::scrollBox(LayoutBox* box, |
- ScrollGranularity granularity, const FloatSize& delta, |
- const FloatPoint& position, const FloatSize& velocity, |
- bool* wasRootScroller) |
-{ |
- ASSERT(box); |
- Node* node = box->node(); |
- |
- // If there's no ApplyScroll callback on the element, scroll as usuall in |
- // the non-scroll-customization case. |
- if (!node || !node->isElementNode() || !toElement(node)->getApplyScroll()) { |
- *wasRootScroller = false; |
- return box->scroll(granularity, delta); |
- } |
- |
- // Viewport actions should only happen when scrolling an element in the |
- // main frame. |
- ASSERT(m_frame->isMainFrame()); |
- |
- // If there is an ApplyScroll callback, its because we placed one on the |
- // root scroller to control top controls and overscroll. Invoke a scroll |
- // using parts of the scroll customization framework on just this element. |
- computeScrollChainForSingleNode(*node, m_currentScrollChain); |
- |
- OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData()); |
- scrollStateData->delta_x = delta.width(); |
- scrollStateData->delta_y = delta.height(); |
- scrollStateData->position_x = position.x(); |
- scrollStateData->position_y = position.y(); |
- // TODO(bokan): delta_granularity is meant to be the number of pixels per |
- // unit of delta but we can't determine that until we get to the area we'll |
- // scroll. This is a hack, we stuff the enum into the double value for |
- // now. |
- scrollStateData->delta_granularity = static_cast<double>(granularity); |
- scrollStateData->velocity_x = velocity.width(); |
- scrollStateData->velocity_y = velocity.height(); |
- scrollStateData->should_propagate = false; |
- scrollStateData->is_in_inertial_phase = false; |
- scrollStateData->from_user_input = true; |
- scrollStateData->delta_consumed_for_scroll_sequence = false; |
- ScrollState* scrollState = |
- ScrollState::create(std::move(scrollStateData)); |
- |
- customizedScroll(*node, *scrollState); |
- |
- ScrollResult result( |
- scrollState->deltaX() != delta.width(), |
- scrollState->deltaY() != delta.height(), |
- scrollState->deltaX(), |
- scrollState->deltaY()); |
- |
- *wasRootScroller = true; |
- m_currentScrollChain.clear(); |
- |
- return result; |
-} |
- |
-ScrollResult EventHandler::physicalScroll(ScrollGranularity granularity, |
- const FloatSize& delta, const FloatPoint& position, |
- const FloatSize& velocity, Node* startNode, Node** stopNode, bool* consumed) |
-{ |
- if (consumed) |
- *consumed = false; |
- if (delta.isZero()) |
- return ScrollResult(); |
- |
- Node* node = startNode; |
- ASSERT(node && node->layoutObject()); |
- |
- m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
- |
- ScrollResult result; |
- |
- LayoutBox* curBox = node->layoutObject()->enclosingBox(); |
- while (curBox) { |
- // If we're at the stopNode, we should try to scroll it but we shouldn't |
- // chain past it. |
- bool shouldStopChaining = |
- stopNode && *stopNode && curBox->node() == *stopNode; |
- bool wasRootScroller = false; |
- |
- result = scrollBox( |
- curBox, |
- granularity, |
- delta, |
- position, |
- velocity, |
- &wasRootScroller); |
- |
- if (result.didScroll() && stopNode) |
- *stopNode = curBox->node(); |
- |
- if (result.didScroll() || shouldStopChaining) { |
- setFrameWasScrolledByUser(); |
- if (consumed) |
- *consumed = true; |
- return result; |
- } else if (wasRootScroller) { |
- // Don't try to chain past the root scroller, even if there's |
- // eligible ancestors. |
- break; |
- } |
- |
- curBox = curBox->containingBlock(); |
- } |
- |
- return result; |
-} |
- |
-bool EventHandler::logicalScroll(ScrollDirection direction, ScrollGranularity granularity, Node* startNode) |
-{ |
- Node* node = startNode; |
- |
- if (!node) |
- node = m_frame->document()->focusedElement(); |
- |
- if (!node) |
- node = m_mousePressNode.get(); |
- |
- if ((!node || !node->layoutObject()) && m_frame->view() && !m_frame->view()->layoutViewItem().isNull()) |
- node = m_frame->view()->layoutViewItem().node(); |
- |
- if (!node) |
- return false; |
- |
- m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
- |
- LayoutBox* curBox = node->layoutObject()->enclosingBox(); |
- while (curBox) { |
- ScrollDirectionPhysical physicalDirection = toPhysicalDirection( |
- direction, curBox->isHorizontalWritingMode(), curBox->style()->isFlippedBlocksWritingMode()); |
- |
- ScrollResult result = curBox->scroll(granularity, toScrollDelta(physicalDirection, 1)); |
- |
- if (result.didScroll()) { |
- setFrameWasScrolledByUser(); |
- return true; |
- } |
- |
- curBox = curBox->containingBlock(); |
- } |
- |
- return false; |
-} |
- |
-void EventHandler::customizedScroll(const Node& startNode, ScrollState& scrollState) |
-{ |
- if (scrollState.fullyConsumed()) |
- return; |
- |
- if (scrollState.deltaX() || scrollState.deltaY()) |
- m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
- |
- if (m_currentScrollChain.empty()) |
- recomputeScrollChain(*m_frame, startNode, m_currentScrollChain); |
- scrollState.setScrollChain(m_currentScrollChain); |
- |
- scrollState.distributeToScrollChainDescendant(); |
+ m_scrollManager.stopAutoscroll(); |
} |
// TODO(bokan): This should be merged with logicalScroll assuming |
// defaultSpaceEventHandler's chaining scroll can be done crossing frames. |
bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode) |
{ |
- // The layout needs to be up to date to determine if we can scroll. We may be |
- // here because of an onLoad event, in which case the final layout hasn't been performed yet. |
- m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
- // FIXME: enable scroll customization in this case. See crbug.com/410974. |
- if (logicalScroll(direction, granularity, startingNode)) |
- return true; |
- |
- Frame* parentFrame = m_frame->tree().parent(); |
- if (!parentFrame || !parentFrame->isLocalFrame()) |
- return false; |
- // FIXME: Broken for OOPI. |
- return toLocalFrame(parentFrame)->eventHandler().bubblingScroll(direction, granularity, m_frame->deprecatedLocalOwner()); |
+ return m_scrollManager.bubblingScroll(direction, granularity, startingNode, m_mousePressNode); |
} |
IntPoint EventHandler::lastKnownMousePosition() const |
@@ -858,13 +620,13 @@ void EventHandler::updateCursor() |
OptionalCursor EventHandler::selectCursor(const HitTestResult& result) |
{ |
- if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) |
+ if (m_scrollManager.inResizeMode()) |
return NoCursorChange; |
Page* page = m_frame->page(); |
if (!page) |
return NoCursorChange; |
- if (panScrollInProgress()) |
+ if (m_scrollManager.panScrollInProgress()) |
return NoCursorChange; |
Node* node = result.innerPossiblyPseudoNode(); |
@@ -1097,8 +859,8 @@ WebInputEventResult EventHandler::handleMousePressEvent(const PlatformMouseEvent |
#if OS(WIN) |
// We store whether pan scrolling is in progress before calling stopAutoscroll() |
// because it will set m_autoscrollType to NoAutoscroll on return. |
- bool isPanScrollInProgress = panScrollInProgress(); |
- stopAutoscroll(); |
+ bool isPanScrollInProgress = m_scrollManager.panScrollInProgress(); |
+ m_scrollManager.stopAutoscroll(); |
if (isPanScrollInProgress) { |
// We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate |
// away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>. |
@@ -1119,9 +881,7 @@ WebInputEventResult EventHandler::handleMousePressEvent(const PlatformMouseEvent |
PaintLayer* layer = mev.innerNode()->layoutObject() ? mev.innerNode()->layoutObject()->enclosingLayer() : nullptr; |
IntPoint p = view->rootFrameToContents(mouseEvent.position()); |
if (layer && layer->getScrollableArea() && layer->getScrollableArea()->isPointInResizeControl(p, ResizerForPointer)) { |
- m_resizeScrollableArea = layer->getScrollableArea(); |
- m_resizeScrollableArea->setInResizeMode(true); |
- m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offsetFromResizeCorner(p)); |
+ m_scrollManager.setResizeScrollableArea(layer, p); |
return WebInputEventResult::HandledSystem; |
} |
} |
@@ -1292,8 +1052,8 @@ WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous |
Scrollbar* scrollbar = nullptr; |
- if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { |
- m_resizeScrollableArea->resize(mev.event(), m_offsetFromResizeCorner); |
+ if (m_scrollManager.inResizeMode()) { |
+ m_scrollManager.resize(mev.event()); |
} else { |
if (!scrollbar) |
scrollbar = mev.scrollbar(); |
@@ -1461,10 +1221,7 @@ WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve |
} |
} |
- if (m_resizeScrollableArea) { |
- m_resizeScrollableArea->setInResizeMode(false); |
- m_resizeScrollableArea = nullptr; |
- } |
+ m_scrollManager.clearResizeScrollableArea(false); |
if (eventResult == WebInputEventResult::NotHandled) |
eventResult = handleMouseReleaseEvent(mev); |
@@ -1559,7 +1316,7 @@ WebInputEventResult EventHandler::updateDragAndDrop(const PlatformMouseEvent& ev |
if (newTarget && newTarget->isTextNode()) |
newTarget = FlatTreeTraversal::parent(*newTarget); |
- if (AutoscrollController* controller = autoscrollController()) |
+ if (AutoscrollController* controller = m_scrollManager.autoscrollController()) |
controller->updateDragAndDrop(newTarget, event.position(), event.timestamp()); |
if (m_dragTarget != newTarget) { |
@@ -1647,7 +1404,7 @@ WebInputEventResult EventHandler::performDragAndDrop(const PlatformMouseEvent& e |
void EventHandler::clearDragState() |
{ |
- stopAutoscroll(); |
+ m_scrollManager.stopAutoscroll(); |
m_dragTarget = nullptr; |
m_capturingMouseEventsNode = nullptr; |
m_shouldOnlyFireDragOverEvent = false; |
@@ -1889,7 +1646,7 @@ WebInputEventResult EventHandler::handleWheelEvent(const PlatformWheelEvent& eve |
if (subframe) { |
WebInputEventResult result = subframe->eventHandler().handleWheelEvent(event); |
if (result != WebInputEventResult::NotHandled) { |
- setFrameWasScrolledByUser(); |
+ m_scrollManager.setFrameWasScrolledByUser(); |
return result; |
} |
// TODO(dtapuska): Remove this once wheel gesture scroll has |
@@ -1957,7 +1714,7 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv |
// FIXME: enable scroll customization in this case. See crbug.com/410974. |
bool consumed = false; |
- physicalScroll( |
+ m_scrollManager.physicalScroll( |
granularity, |
delta, |
FloatPoint(), |
@@ -2035,17 +1792,10 @@ WebInputEventResult EventHandler::handleGestureEventInFrame(const GestureEventWi |
ASSERT(!targetedEvent.event().isScrollEvent()); |
Node* eventTarget = targetedEvent.hitTestResult().innerNode(); |
- Scrollbar* scrollbar = targetedEvent.hitTestResult().scrollbar(); |
const PlatformGestureEvent& gestureEvent = targetedEvent.event(); |
- if (scrollbar) { |
- bool shouldUpdateCapture = false; |
- if (scrollbar->gestureEvent(gestureEvent, &shouldUpdateCapture)) { |
- if (shouldUpdateCapture) |
- m_scrollbarHandlingScrollGesture = scrollbar; |
- return WebInputEventResult::HandledSuppressed; |
- } |
- } |
+ if (m_scrollManager.canHandleGestureEvent(targetedEvent)) |
+ return WebInputEventResult::HandledSuppressed; |
if (eventTarget) { |
GestureEvent* gestureDomEvent = GestureEvent::create(eventTarget->document().domWindow(), gestureEvent); |
@@ -2087,74 +1837,7 @@ WebInputEventResult EventHandler::handleGestureScrollEvent(const PlatformGesture |
{ |
TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); |
- Node* eventTarget = nullptr; |
- Scrollbar* scrollbar = nullptr; |
- if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) { |
- scrollbar = m_scrollbarHandlingScrollGesture.get(); |
- eventTarget = m_scrollGestureHandlingNode.get(); |
- } |
- |
- if (!eventTarget) { |
- Document* document = m_frame->document(); |
- if (document->layoutViewItem().isNull()) |
- return WebInputEventResult::NotHandled; |
- |
- FrameView* view = m_frame->view(); |
- LayoutPoint viewPoint = view->rootFrameToContents(gestureEvent.position()); |
- HitTestRequest request(HitTestRequest::ReadOnly); |
- HitTestResult result(request, viewPoint); |
- document->layoutViewItem().hitTest(result); |
- |
- eventTarget = result.innerNode(); |
- |
- m_lastGestureScrollOverWidget = result.isOverWidget(); |
- m_scrollGestureHandlingNode = eventTarget; |
- m_previousGestureScrolledNode = nullptr; |
- |
- if (!scrollbar) |
- scrollbar = result.scrollbar(); |
- } |
- |
- if (scrollbar) { |
- bool shouldUpdateCapture = false; |
- if (scrollbar->gestureEvent(gestureEvent, &shouldUpdateCapture)) { |
- if (shouldUpdateCapture) |
- m_scrollbarHandlingScrollGesture = scrollbar; |
- return WebInputEventResult::HandledSuppressed; |
- } |
- m_scrollbarHandlingScrollGesture = nullptr; |
- } |
- |
- if (eventTarget) { |
- if (handleScrollGestureOnResizer(eventTarget, gestureEvent)) |
- return WebInputEventResult::HandledSuppressed; |
- |
- GestureEvent* gestureDomEvent = GestureEvent::create(eventTarget->document().domWindow(), gestureEvent); |
- if (gestureDomEvent) { |
- DispatchEventResult gestureDomEventResult = eventTarget->dispatchEvent(gestureDomEvent); |
- if (gestureDomEventResult != DispatchEventResult::NotCanceled) { |
- ASSERT(gestureDomEventResult != DispatchEventResult::CanceledByEventHandler); |
- return toWebInputEventResult(gestureDomEventResult); |
- } |
- } |
- } |
- |
- switch (gestureEvent.type()) { |
- case PlatformEvent::GestureScrollBegin: |
- return handleGestureScrollBegin(gestureEvent); |
- case PlatformEvent::GestureScrollUpdate: |
- return handleGestureScrollUpdate(gestureEvent); |
- case PlatformEvent::GestureScrollEnd: |
- return handleGestureScrollEnd(gestureEvent); |
- case PlatformEvent::GestureFlingStart: |
- case PlatformEvent::GesturePinchBegin: |
- case PlatformEvent::GesturePinchEnd: |
- case PlatformEvent::GesturePinchUpdate: |
- return WebInputEventResult::NotHandled; |
- default: |
- ASSERT_NOT_REACHED(); |
- return WebInputEventResult::NotHandled; |
- } |
+ return m_scrollManager.handleGestureScrollEvent(gestureEvent); |
} |
WebInputEventResult EventHandler::handleGestureTap(const GestureEventWithHitTestResults& targetedEvent) |
@@ -2317,235 +2000,14 @@ WebInputEventResult EventHandler::handleGestureLongTap(const GestureEventWithHit |
return WebInputEventResult::NotHandled; |
} |
-bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const PlatformGestureEvent& gestureEvent) |
-{ |
- if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) { |
- PaintLayer* layer = eventTarget->layoutObject() ? eventTarget->layoutObject()->enclosingLayer() : nullptr; |
- IntPoint p = m_frame->view()->rootFrameToContents(gestureEvent.position()); |
- if (layer && layer->getScrollableArea() && layer->getScrollableArea()->isPointInResizeControl(p, ResizerForTouch)) { |
- m_resizeScrollableArea = layer->getScrollableArea(); |
- m_resizeScrollableArea->setInResizeMode(true); |
- m_offsetFromResizeCorner = LayoutSize(m_resizeScrollableArea->offsetFromResizeCorner(p)); |
- return true; |
- } |
- } else if (gestureEvent.type() == PlatformEvent::GestureScrollUpdate) { |
- if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { |
- m_resizeScrollableArea->resize(gestureEvent, m_offsetFromResizeCorner); |
- return true; |
- } |
- } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd) { |
- if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) { |
- m_resizeScrollableArea->setInResizeMode(false); |
- m_resizeScrollableArea = nullptr; |
- return false; |
- } |
- } |
- |
- return false; |
-} |
- |
-WebInputEventResult EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& gestureEvent, LayoutObject* layoutObject) |
-{ |
- ASSERT(gestureEvent.isScrollEvent()); |
- |
- if (!m_lastGestureScrollOverWidget || !layoutObject || !layoutObject->isLayoutPart()) |
- return WebInputEventResult::NotHandled; |
- |
- Widget* widget = toLayoutPart(layoutObject)->widget(); |
- |
- if (!widget || !widget->isFrameView()) |
- return WebInputEventResult::NotHandled; |
- |
- return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent(gestureEvent); |
-} |
- |
WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEvent) |
{ |
- Node* node = m_scrollGestureHandlingNode; |
- |
- if (node) { |
- passScrollGestureEventToWidget(gestureEvent, node->layoutObject()); |
- if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) { |
- OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData()); |
- scrollStateData->is_ending = true; |
- scrollStateData->is_in_inertial_phase = gestureEvent.inertialPhase() == ScrollInertialPhaseMomentum; |
- scrollStateData->from_user_input = true; |
- scrollStateData->is_direct_manipulation = true; |
- scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsumedForScrollSequence; |
- ScrollState* scrollState = ScrollState::create(std::move(scrollStateData)); |
- customizedScroll(*node, *scrollState); |
- } |
- } |
- |
- clearGestureScrollState(); |
- return WebInputEventResult::NotHandled; |
-} |
- |
-WebInputEventResult EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureEvent) |
-{ |
- Document* document = m_frame->document(); |
- if (document->layoutViewItem().isNull()) |
- return WebInputEventResult::NotHandled; |
- |
- FrameView* view = m_frame->view(); |
- if (!view) |
- return WebInputEventResult::NotHandled; |
- |
- // If there's no layoutObject on the node, send the event to the nearest ancestor with a layoutObject. |
- // Needed for <option> and <optgroup> elements so we can touch scroll <select>s |
- while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->layoutObject()) |
- m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShadowHostNode(); |
- |
- if (!m_scrollGestureHandlingNode) { |
- if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) |
- m_scrollGestureHandlingNode = m_frame->document()->documentElement(); |
- else |
- return WebInputEventResult::NotHandled; |
- } |
- ASSERT(m_scrollGestureHandlingNode); |
- |
- passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->layoutObject()); |
- if (RuntimeEnabledFeatures::scrollCustomizationEnabled()) { |
- m_currentScrollChain.clear(); |
- OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData()); |
- scrollStateData->position_x = gestureEvent.position().x(); |
- scrollStateData->position_y = gestureEvent.position().y(); |
- scrollStateData->is_beginning = true; |
- scrollStateData->from_user_input = true; |
- scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsumedForScrollSequence; |
- ScrollState* scrollState = ScrollState::create(std::move(scrollStateData)); |
- customizedScroll(*m_scrollGestureHandlingNode.get(), *scrollState); |
- } else { |
- if (m_frame->isMainFrame()) |
- m_frame->host()->topControls().scrollBegin(); |
- } |
- return WebInputEventResult::HandledSystem; |
-} |
- |
-bool EventHandler::isRootScroller(const Node& node) const |
-{ |
- // The root scroller is the one Element on the page designated to perform |
- // "viewport actions" like top controls movement and overscroll glow. |
- if (!frameHost() || !frameHost()->rootScroller()) |
- return false; |
- |
- return frameHost()->rootScroller()->get() == &node; |
-} |
- |
-WebInputEventResult EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent) |
-{ |
- ASSERT(gestureEvent.type() == PlatformEvent::GestureScrollUpdate); |
- |
- // Negate the deltas since the gesture event stores finger movement and |
- // scrolling occurs in the direction opposite the finger's movement |
- // direction. e.g. Finger moving up has negative event delta but causes the |
- // page to scroll down causing positive scroll delta. |
- FloatSize delta(-gestureEvent.deltaX(), -gestureEvent.deltaY()); |
- FloatSize velocity(-gestureEvent.velocityX(), -gestureEvent.velocityY()); |
- if (delta.isZero()) |
- return WebInputEventResult::NotHandled; |
- |
- ScrollGranularity granularity = gestureEvent.deltaUnits(); |
- Node* node = m_scrollGestureHandlingNode.get(); |
- |
- // Scroll customization is only available for touch. |
- bool handleScrollCustomization = RuntimeEnabledFeatures::scrollCustomizationEnabled() && gestureEvent.source() == PlatformGestureSourceTouchscreen; |
- if (node) { |
- LayoutObject* layoutObject = node->layoutObject(); |
- if (!layoutObject) |
- return WebInputEventResult::NotHandled; |
- |
- // Try to send the event to the correct view. |
- WebInputEventResult result = passScrollGestureEventToWidget(gestureEvent, layoutObject); |
- if (result != WebInputEventResult::NotHandled) { |
- if (gestureEvent.preventPropagation() |
- && !RuntimeEnabledFeatures::scrollCustomizationEnabled()) { |
- // This is an optimization which doesn't apply with |
- // scroll customization enabled. |
- m_previousGestureScrolledNode = m_scrollGestureHandlingNode; |
- } |
- // FIXME: we should allow simultaneous scrolling of nested |
- // iframes along perpendicular axes. See crbug.com/466991. |
- m_deltaConsumedForScrollSequence = true; |
- return result; |
- } |
- |
- if (handleScrollCustomization) { |
- OwnPtr<ScrollStateData> scrollStateData = adoptPtr(new ScrollStateData()); |
- scrollStateData->delta_x = delta.width(); |
- scrollStateData->delta_y = delta.height(); |
- scrollStateData->delta_granularity = ScrollByPrecisePixel; |
- scrollStateData->velocity_x = velocity.width(); |
- scrollStateData->velocity_y = velocity.height(); |
- scrollStateData->should_propagate = !gestureEvent.preventPropagation(); |
- scrollStateData->is_in_inertial_phase = gestureEvent.inertialPhase() == ScrollInertialPhaseMomentum; |
- scrollStateData->from_user_input = true; |
- scrollStateData->delta_consumed_for_scroll_sequence = m_deltaConsumedForScrollSequence; |
- ScrollState* scrollState = ScrollState::create(std::move(scrollStateData)); |
- if (m_previousGestureScrolledNode) { |
- // The ScrollState needs to know what the current |
- // native scrolling element is, so that for an |
- // inertial scroll that shouldn't propagate, only the |
- // currently scrolling element responds. |
- ASSERT(m_previousGestureScrolledNode->isElementNode()); |
- scrollState->setCurrentNativeScrollingElement(toElement(m_previousGestureScrolledNode.get())); |
- } |
- customizedScroll(*node, *scrollState); |
- m_previousGestureScrolledNode = scrollState->currentNativeScrollingElement(); |
- m_deltaConsumedForScrollSequence = scrollState->deltaConsumedForScrollSequence(); |
- if (scrollState->deltaX() != delta.width() |
- || scrollState->deltaY() != delta.height()) { |
- setFrameWasScrolledByUser(); |
- return WebInputEventResult::HandledSystem; |
- } |
- } else { |
- Node* stopNode = nullptr; |
- if (gestureEvent.preventPropagation()) |
- stopNode = m_previousGestureScrolledNode.get(); |
- |
- bool consumed = false; |
- ScrollResult result = physicalScroll( |
- granularity, |
- delta, |
- FloatPoint(gestureEvent.position()), |
- velocity, |
- node, |
- &stopNode, |
- &consumed); |
- |
- if (gestureEvent.preventPropagation()) |
- m_previousGestureScrolledNode = stopNode; |
- |
- if ((!stopNode || !isRootScroller(*stopNode)) && frameHost()) { |
- frameHost()->overscrollController().resetAccumulated( |
- result.didScrollX, result.didScrollY); |
- } |
- |
- if (consumed) |
- return WebInputEventResult::HandledSystem; |
- } |
- } |
- |
- return WebInputEventResult::NotHandled; |
-} |
- |
-void EventHandler::clearGestureScrollState() |
-{ |
- m_scrollGestureHandlingNode = nullptr; |
- m_previousGestureScrolledNode = nullptr; |
- m_deltaConsumedForScrollSequence = false; |
- m_currentScrollChain.clear(); |
- |
- if (FrameHost* host = frameHost()) { |
- bool resetX = true; |
- bool resetY = true; |
- host->overscrollController().resetAccumulated(resetX, resetY); |
- } |
+ return m_scrollManager.handleGestureScrollEnd(gestureEvent); |
} |
bool EventHandler::isScrollbarHandlingGestures() const |
{ |
- return m_scrollbarHandlingScrollGesture.get(); |
+ return m_scrollManager.isScrollbarHandlingGestures(); |
} |
bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const |
@@ -3084,8 +2546,7 @@ void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) |
void EventHandler::resizeScrollableAreaDestroyed() |
{ |
- ASSERT(m_resizeScrollableArea); |
- m_resizeScrollableArea = nullptr; |
+ m_scrollManager.clearResizeScrollableArea(true); |
} |
void EventHandler::hoverTimerFired(Timer<EventHandler>*) |
@@ -3155,10 +2616,10 @@ WebInputEventResult EventHandler::keyEvent(const PlatformKeyboardEvent& initialK |
capsLockStateMayHaveChanged(); |
#if OS(WIN) |
- if (panScrollInProgress()) { |
+ if (m_scrollManager.panScrollInProgress()) { |
// If a key is pressed while the panScroll is in progress then we want to stop |
if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown) |
- stopAutoscroll(); |
+ m_scrollManager.stopAutoscroll(); |
// If we were in panscroll mode, we swallow the key event |
return WebInputEventResult::HandledSuppressed; |
@@ -3485,7 +2946,7 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event) |
ScrollDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward; |
// FIXME: enable scroll customization in this case. See crbug.com/410974. |
- if (logicalScroll(direction, ScrollByPage)) { |
+ if (m_scrollManager.logicalScroll(direction, ScrollByPage, nullptr, m_mousePressNode)) { |
event->setDefaultHandled(); |
return; |
} |
@@ -3581,12 +3042,6 @@ void EventHandler::capsLockStateMayHaveChanged() |
} |
} |
-void EventHandler::setFrameWasScrolledByUser() |
-{ |
- if (DocumentLoader* documentLoader = m_frame->loader().documentLoader()) |
- documentLoader->initialScrollState().wasScrolledByUser = true; |
-} |
- |
bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev) |
{ |
Scrollbar* scrollbar = mev.scrollbar(); |
@@ -3594,7 +3049,7 @@ bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& |
if (!scrollbar || !scrollbar->enabled()) |
return false; |
- setFrameWasScrolledByUser(); |
+ m_scrollManager.setFrameWasScrolledByUser(); |
scrollbar->mouseDown(mev.event()); |
return true; |
} |