void AutoscrollController::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
{
    RenderBox* scrollable = m_autoscrollRenderer;
    m_autoscrollTimer.stop();
    m_autoscrollRenderer = 0;

    if (!scrollable)
        return;

    Frame& frame = scrollable->frame();
    if (autoscrollInProgress() && frame.eventHandler().mouseDownWasInSubframe()) {
        if (Frame* subframe = frame.eventHandler().subframeForTargetNode(frame.eventHandler().mousePressNode()))
            subframe->eventHandler().stopAutoscrollTimer(rendererIsBeingDestroyed);
        return;
    }

    if (!rendererIsBeingDestroyed)
        scrollable->stopAutoscroll();
#if ENABLE(PAN_SCROLLING)
    if (panScrollInProgress()) {
        FrameView& frameView = scrollable->view().frameView();
        frameView.removePanScrollIcon();
        frameView.setCursor(pointerCursor());
    }
#endif

    m_autoscrollType = NoAutoscroll;

#if ENABLE(PAN_SCROLLING)
    // If we're not in the top frame we notify it that we are not doing a panScroll any more.
    if (!frame.isMainFrame())
        frame.mainFrame().eventHandler().didPanScrollStop();
#endif
}
void AutoscrollController::stopAutoscroll()
{
    LayoutBox* scrollable = m_autoscrollLayoutObject;
    m_autoscrollLayoutObject = nullptr;

    if (!scrollable)
        return;

    scrollable->stopAutoscroll();
#if OS(WIN)
    if (panScrollInProgress()) {
        if (FrameView* view = scrollable->frame()->view()) {
            view->setCursor(pointerCursor());
        }
    }
#endif

    m_autoscrollType = NoAutoscroll;
}
void AutoscrollController::stopAutoscroll()
{
    RenderBox* scrollable = m_autoscrollRenderer;
    m_autoscrollRenderer = 0;

    if (!scrollable)
        return;

    scrollable->stopAutoscroll();
#if OS(WIN)
    if (panScrollInProgress()) {
        if (FrameView* view = scrollable->frame()->view()) {
            view->removePanScrollIcon();
            view->setCursor(pointerCursor());
        }
    }
#endif

    m_autoscrollType = NoAutoscroll;
}
// 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::autoscrollTimerFired(Timer<AutoscrollController>*)
{
    if (!m_autoscrollRenderer) {
        stopAutoscrollTimer();
        return;
    }

    EventHandler* eventHandler = m_autoscrollRenderer->frame()->eventHandler();
    switch (m_autoscrollType) {
    case AutoscrollForDragAndDrop:
        if (WTF::currentTime() - m_dragAndDropAutoscrollStartTime > autoscrollDelay)
            m_autoscrollRenderer->autoscroll(m_dragAndDropAutoscrollReferencePosition);
        break;
    case AutoscrollForSelection:
        if (!eventHandler->mousePressed()) {
            stopAutoscrollTimer();
            return;
        }
        eventHandler->updateSelectionForMouseDrag();
        m_autoscrollRenderer->autoscroll(eventHandler->lastKnownMousePosition());
        break;
    case NoAutoscroll:
        break;
#if ENABLE(PAN_SCROLLING)
    case AutoscrollForPanCanStop:
    case AutoscrollForPan:
        if (!panScrollInProgress()) {
            stopAutoscrollTimer();
            return;
        }
        if (FrameView* view = m_autoscrollRenderer->frame()->view())
            updatePanScrollState(view, eventHandler->lastKnownMousePosition());
        m_autoscrollRenderer->panScroll(m_panScrollStartPos);
        break;
#endif
    }
}