void AutoscrollController::updateDragAndDrop(Node* dropTargetNode, const IntPoint& eventPosition, double eventTime) { if (!dropTargetNode || !dropTargetNode->layoutObject()) { stopAutoscroll(); return; } if (m_autoscrollLayoutObject && m_autoscrollLayoutObject->frame() != dropTargetNode->layoutObject()->frame()) return; dropTargetNode->layoutObject() ->frameView() ->updateAllLifecyclePhasesExceptPaint(); LayoutBox* scrollable = LayoutBox::findAutoscrollable(dropTargetNode->layoutObject()); if (!scrollable) { stopAutoscroll(); return; } Page* page = scrollable->frame() ? scrollable->frame()->page() : nullptr; if (!page) { stopAutoscroll(); return; } IntSize offset = scrollable->calculateAutoscrollDirection(eventPosition); if (offset.isZero()) { stopAutoscroll(); return; } m_dragAndDropAutoscrollReferencePosition = eventPosition + offset; if (m_autoscrollType == NoAutoscroll) { m_autoscrollType = AutoscrollForDragAndDrop; m_autoscrollLayoutObject = scrollable; m_dragAndDropAutoscrollStartTime = eventTime; UseCounter::count(m_page->mainFrame(), UseCounter::DragAndDropScrollStart); startAutoscroll(); } else if (m_autoscrollLayoutObject != scrollable) { m_dragAndDropAutoscrollStartTime = eventTime; m_autoscrollLayoutObject = scrollable; } }
void AutoscrollController::updateDragAndDrop(Node* dropTargetNode, const IntPoint& eventPosition, double eventTime) { if (!dropTargetNode || !dropTargetNode->renderer()) { stopAutoscroll(); return; } if (m_autoscrollRenderer && m_autoscrollRenderer->frame() != dropTargetNode->renderer()->frame()) return; RenderBox* scrollable = RenderBox::findAutoscrollable(dropTargetNode->renderer()); if (!scrollable) { stopAutoscroll(); return; } Page* page = scrollable->frame() ? scrollable->frame()->page() : 0; if (!page) { stopAutoscroll(); return; } IntSize offset = scrollable->calculateAutoscrollDirection(eventPosition); if (offset.isZero()) { stopAutoscroll(); return; } m_dragAndDropAutoscrollReferencePosition = eventPosition + offset; if (m_autoscrollType == NoAutoscroll) { m_autoscrollType = AutoscrollForDragAndDrop; m_autoscrollRenderer = scrollable; m_dragAndDropAutoscrollStartTime = eventTime; startAutoscroll(); } else if (m_autoscrollRenderer != scrollable) { m_dragAndDropAutoscrollStartTime = eventTime; m_autoscrollRenderer = scrollable; } }
// FIXME: This would get get better animation fidelity if it used the monotonicFrameBeginTime instead // of WTF::currentTime(). void AutoscrollController::animate(double) { if (!m_autoscrollLayoutObject) { stopAutoscroll(); return; } EventHandler& eventHandler = m_autoscrollLayoutObject->frame()->eventHandler(); switch (m_autoscrollType) { case AutoscrollForDragAndDrop: if (WTF::currentTime() - m_dragAndDropAutoscrollStartTime > autoscrollDelay) m_autoscrollLayoutObject->autoscroll(m_dragAndDropAutoscrollReferencePosition); break; case AutoscrollForSelection: if (!eventHandler.mousePressed()) { stopAutoscroll(); return; } eventHandler.updateSelectionForMouseDrag(); m_autoscrollLayoutObject->autoscroll(eventHandler.lastKnownMousePosition()); break; case NoAutoscroll: break; #if OS(WIN) case AutoscrollForPanCanStop: case AutoscrollForPan: if (!panScrollInProgress()) { stopAutoscroll(); return; } if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) updatePanScrollState(view, eventHandler.lastKnownMousePosition()); m_autoscrollLayoutObject->panScroll(m_panScrollStartPos); break; #endif } if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) m_page->chromeClient().scheduleAnimation(m_autoscrollLayoutObject->frame()->view()); }
void AutoscrollController::handleMouseReleaseForPanScrolling(LocalFrame* frame, const PlatformMouseEvent& mouseEvent) { if (!frame->isMainFrame()) return; switch (m_autoscrollType) { case AutoscrollForPan: if (mouseEvent.button() == MiddleButton) m_autoscrollType = AutoscrollForPanCanStop; break; case AutoscrollForPanCanStop: stopAutoscroll(); break; } }
void AutoscrollController::handleMouseReleaseForMiddleClickAutoscroll( LocalFrame* frame, const PlatformMouseEvent& mouseEvent) { DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); if (!frame->isMainFrame()) return; switch (m_autoscrollType) { case AutoscrollForMiddleClick: if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::Middle) m_autoscrollType = AutoscrollForMiddleClickCanStop; break; case AutoscrollForMiddleClickCanStop: stopAutoscroll(); break; case AutoscrollForDragAndDrop: case AutoscrollForSelection: case NoAutoscroll: // Nothing to do. break; } }
void AutoscrollController::animate(double) { if (!m_autoscrollLayoutObject || !m_autoscrollLayoutObject->frame()) { stopAutoscroll(); return; } EventHandler& eventHandler = m_autoscrollLayoutObject->frame()->eventHandler(); IntSize offset = m_autoscrollLayoutObject->calculateAutoscrollDirection( eventHandler.lastKnownMousePosition()); IntPoint selectionPoint = eventHandler.lastKnownMousePosition() + offset; switch (m_autoscrollType) { case AutoscrollForDragAndDrop: if (WTF::monotonicallyIncreasingTime() - m_dragAndDropAutoscrollStartTime > autoscrollDelay) m_autoscrollLayoutObject->autoscroll( m_dragAndDropAutoscrollReferencePosition); break; case AutoscrollForSelection: if (!eventHandler.mousePressed()) { stopAutoscroll(); return; } eventHandler.updateSelectionForMouseDrag(); m_autoscrollLayoutObject->autoscroll(selectionPoint); break; case NoAutoscroll: break; case AutoscrollForMiddleClickCanStop: case AutoscrollForMiddleClick: DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); if (!middleClickAutoscrollInProgress()) { stopAutoscroll(); return; } if (FrameView* view = m_autoscrollLayoutObject->frame()->view()) updateMiddleClickAutoscrollState(view, eventHandler.lastKnownMousePosition()); FloatSize delta = calculateAutoscrollDelta(); if (delta.isZero()) break; ScrollResult result = m_autoscrollLayoutObject->scroll(ScrollByPixel, delta); LayoutObject* layoutObject = m_autoscrollLayoutObject; while (!m_didLatchForMiddleClickAutoscroll && !result.didScroll()) { if (layoutObject->node() && layoutObject->node()->isDocumentNode()) { Element* owner = toDocument(layoutObject->node())->localOwner(); layoutObject = owner ? owner->layoutObject() : nullptr; } else { layoutObject = layoutObject->parent(); } if (!layoutObject) { break; } if (layoutObject && layoutObject->isBox() && toLayoutBox(layoutObject)->canBeScrolledAndHasScrollableArea()) result = toLayoutBox(layoutObject)->scroll(ScrollByPixel, delta); } if (result.didScroll()) { m_didLatchForMiddleClickAutoscroll = true; m_autoscrollLayoutObject = toLayoutBox(layoutObject); } break; } if (m_autoscrollType != NoAutoscroll && m_autoscrollLayoutObject) m_page->chromeClient().scheduleAnimation( m_autoscrollLayoutObject->frame()->view()); }