eventhandler.cpp

来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,735 行 · 第 1/5 页

CPP
1,735
字号
#if ENABLE(SVG)    if (m_frame->document()->isSVGDocument() &&       static_cast<SVGDocument*>(m_frame->document())->zoomAndPanEnabled()) {        if (event.event().shiftKey() && singleClick) {            m_svgPan = true;            static_cast<SVGDocument*>(m_frame->document())->startPan(event.event().pos());            return true;        }    }#endif    // We don't do this at the start of mouse down handling,    // because we don't want to do it until we know we didn't hit a widget.    if (singleClick)        focusDocumentView();    Node* innerNode = event.targetNode();    m_mousePressNode = innerNode;    m_dragStartPos = event.event().pos();    bool swallowEvent = false;    if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {        m_frame->selection()->setCaretBlinkingSuspended(true);        m_mousePressed = true;        m_beganSelectingText = false;        if (event.event().clickCount() == 2)            swallowEvent = handleMousePressEventDoubleClick(event);        else if (event.event().clickCount() >= 3)            swallowEvent = handleMousePressEventTripleClick(event);        else            swallowEvent = handleMousePressEventSingleClick(event);    }        m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect ||         (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled(true));   return swallowEvent;}bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event){    if (handleDrag(event))        return true;    if (!m_mousePressed)        return false;    Node* targetNode = event.targetNode();    if (event.event().button() != LeftButton || !targetNode || !targetNode->renderer())        return false;#if PLATFORM(MAC) // FIXME: Why does this assertion fire on other platforms?    ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);#endif    m_mouseDownMayStartDrag = false;    if (m_mouseDownMayStartAutoscroll && !m_panScrollInProgress) {                    // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll        // Otherwise, let the bridge handle it so the view can scroll itself.        RenderObject* renderer = targetNode->renderer();        while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {            if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())                renderer = renderer->document()->ownerElement()->renderer();            else                renderer = renderer->parent();        }                if (renderer) {            m_autoscrollInProgress = true;            handleAutoscroll(renderer);        }                m_mouseDownMayStartAutoscroll = false;    }        updateSelectionForMouseDrag(targetNode, event.localPoint());    return true;}    bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const{    // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful    // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag    // in handleMousePressEvent        if (!m_frame->contentRenderer() || !m_frame->contentRenderer()->hasLayer()        || event.button() != LeftButton || event.clickCount() != 1)        return false;        bool DHTMLFlag;    bool UAFlag;    allowDHTMLDrag(DHTMLFlag, UAFlag);    if (!DHTMLFlag && !UAFlag)        return false;        HitTestRequest request(HitTestRequest::ReadOnly);    HitTestResult result(m_frame->view()->windowToContents(event.pos()));    m_frame->contentRenderer()->layer()->hitTest(request, result);    bool srcIsDHTML;    return result.innerNode() && result.innerNode()->renderer()->draggableNode(DHTMLFlag, UAFlag, result.point().x(), result.point().y(), srcIsDHTML);}void EventHandler::updateSelectionForMouseDrag(){    FrameView* view = m_frame->view();    if (!view)        return;    RenderView* renderer = m_frame->contentRenderer();    if (!renderer)        return;    RenderLayer* layer = renderer->layer();    if (!layer)        return;    HitTestRequest request(HitTestRequest::ReadOnly |                           HitTestRequest::Active |                           HitTestRequest::MouseMove);    HitTestResult result(view->windowToContents(m_currentMousePosition));    layer->hitTest(request, result);    updateSelectionForMouseDrag(result.innerNode(), result.localPoint());}void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint){    if (!m_mouseDownMayStartSelect)        return;    if (!targetNode)        return;    RenderObject* targetRenderer = targetNode->renderer();    if (!targetRenderer)        return;            if (!canMouseDragExtendSelect(targetNode))        return;    VisiblePosition targetPosition(targetRenderer->positionForPoint(localPoint));    // Don't modify the selection if we're not on a node.    if (targetPosition.isNull())        return;    // Restart the selection if this is the first mouse move. This work is usually    // done in handleMousePressEvent, but not if the mouse press was on an existing selection.    VisibleSelection newSelection = m_frame->selection()->selection();#if ENABLE(SVG)    // Special case to limit selection to the containing block for SVG text.    // FIXME: Isn't there a better non-SVG-specific way to do this?    if (Node* selectionBaseNode = newSelection.base().node())        if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())            if (selectionBaseRenderer->isSVGText())                if (targetNode->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())                    return;#endif    if (!m_beganSelectingText) {        m_beganSelectingText = true;        newSelection = VisibleSelection(targetPosition);    }    newSelection.setExtent(targetPosition);    if (m_frame->selectionGranularity() != CharacterGranularity)        newSelection.expandUsingGranularity(m_frame->selectionGranularity());    if (m_frame->shouldChangeSelection(newSelection)) {        m_frame->selection()->setLastChangeWasHorizontalExtension(false);        m_frame->selection()->setSelection(newSelection);    }}    bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event){    if (eventLoopHandleMouseUp(event))        return true;        // If this was the first click in the window, we don't even want to clear the selection.    // This case occurs when the user clicks on a draggable element, since we have to process    // the mouse down and drag events to see if we might start a drag.  For other first clicks    // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets    // ignored upstream of this layer.    return eventActivatedView(event.event());}    bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event){    if (m_autoscrollInProgress)        stopAutoscrollTimer();    if (handleMouseUp(event))        return true;    // Used to prevent mouseMoveEvent from initiating a drag before    // the mouse is pressed again.    m_frame->selection()->setCaretBlinkingSuspended(false);    m_mousePressed = false;    m_capturesDragging = false;    m_mouseDownMayStartDrag = false;    m_mouseDownMayStartSelect = false;    m_mouseDownMayStartAutoscroll = false;    m_mouseDownWasInSubframe = false;      bool handled = false;    // Clear the selection if the mouse didn't move after the last mouse press.    // We do this so when clicking on the selection, the selection goes away.    // However, if we are editing, place the caret.    if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText            && m_dragStartPos == event.event().pos()            && m_frame->selection()->isRange()) {        VisibleSelection newSelection;        Node *node = event.targetNode();        if (node && node->isContentEditable() && node->renderer()) {            VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());            newSelection = VisibleSelection(pos);        }        if (m_frame->shouldChangeSelection(newSelection))            m_frame->selection()->setSelection(newSelection);        handled = true;    }    m_frame->notifyRendererOfSelectionChange(true);    m_frame->selection()->selectFrameElementInParentIfFullySelected();    return handled;}void EventHandler::handleAutoscroll(RenderObject* renderer){    // We don't want to trigger the autoscroll or the panScroll if it's already active    if (m_autoscrollTimer.isActive())        return;         setAutoscrollRenderer(renderer);#if ENABLE(PAN_SCROLLING)    if (m_panScrollInProgress) {        m_panScrollStartPos = currentMousePosition();        m_frame->view()->addPanScrollIcon(m_panScrollStartPos);        // If we're not in the top frame we notify it that we are using the panScroll        if (m_frame != m_frame->page()->mainFrame())            m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(true);    }#endif    startAutoscrollTimer();}void EventHandler::autoscrollTimerFired(Timer<EventHandler>*){    RenderObject* r = autoscrollRenderer();    if (!r || !r->isBox()) {        stopAutoscrollTimer();        return;    }    if (m_autoscrollInProgress) {        if (!m_mousePressed) {            stopAutoscrollTimer();            return;        }        toRenderBox(r)->autoscroll();    } else {        // we verify that the main frame hasn't received the order to stop the panScroll        if (!m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress()) {            stopAutoscrollTimer();            return;        }#if ENABLE(PAN_SCROLLING)        setPanScrollCursor();        toRenderBox(r)->panScroll(m_panScrollStartPos);#endif    }}#if ENABLE(PAN_SCROLLING)void EventHandler::setPanScrollCursor(){    // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll    // So we don't want to change the cursor over this area    const int noScrollRadius = 9;    bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - noScrollRadius);    bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + noScrollRadius);    bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + noScrollRadius);    bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - noScrollRadius);             if (north) {        if (east)            m_frame->view()->setCursor(northEastPanningCursor());        else if (west)            m_frame->view()->setCursor(northWestPanningCursor());        else            m_frame->view()->setCursor(northPanningCursor());    } else if (south) {        if (east)            m_frame->view()->setCursor(southEastPanningCursor());        else if (west)            m_frame->view()->setCursor(southWestPanningCursor());        else            m_frame->view()->setCursor(southPanningCursor());    } else if (east)        m_frame->view()->setCursor(eastPanningCursor());    else if (west)        m_frame->view()->setCursor(westPanningCursor());    else        m_frame->view()->setCursor(middlePanningCursor());}#endif  // ENABLE(PAN_SCROLLING)RenderObject* EventHandler::autoscrollRenderer() const{    return m_autoscrollRenderer;}void EventHandler::updateAutoscrollRenderer(){    if (!m_autoscrollRenderer)        return;    HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, true);    if (Node* nodeAtPoint = hitTest.innerNode())        m_autoscrollRenderer = nodeAtPoint->renderer();    while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeProgramaticallyScrolled(false)))        m_autoscrollRenderer = m_autoscrollRenderer->parent();}void EventHandler::setAutoscrollRenderer(RenderObject* renderer){    m_autoscrollRenderer = renderer;}void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const{    if (!m_frame) {        flagDHTML = false;        flagUA = false;        return;    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?