eventhandler.cpp

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

CPP
1,735
字号
    }#if ENABLE(PAN_SCROLLING)    if (m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {        stopAutoscrollTimer();        invalidateClick();        return true;    }        if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {        RenderObject* renderer = mev.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_panScrollInProgress = true;            handleAutoscroll(renderer);            invalidateClick();            return true;        }   }#endif    m_clickCount = mouseEvent.clickCount();    m_clickNode = mev.targetNode();        RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;    IntPoint p = m_frame->view()->windowToContents(mouseEvent.pos());    if (layer && layer->isPointInResizeControl(p)) {        layer->setInResizeMode(true);        m_resizeLayer = layer;        m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);        invalidateClick();        return true;    }    bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);    m_capturesDragging = !swallowEvent;    // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults    // in case the scrollbar widget was destroyed when the mouse event was handled.    if (mev.scrollbar()) {        const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();        HitTestRequest request(HitTestRequest::ReadOnly |                               HitTestRequest::Active);        mev = prepareMouseEvent(request, mouseEvent);        if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())            m_lastScrollbarUnderMouse = 0;    }    if (swallowEvent) {        // scrollbars should get events anyway, even disabled controls might be scrollable        if (mev.scrollbar())            passMousePressEventToScrollbar(mev, mev.scrollbar());    } else {        // Refetch the event target node if it currently is the shadow node inside an <input> element.        // If a mouse event handler changes the input element type to one that has a widget associated,        // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the        // event target node can't still be the shadow node.        if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag)) {            HitTestRequest request(HitTestRequest::ReadOnly |                                   HitTestRequest::Active);            mev = prepareMouseEvent(request, mouseEvent);        }        Scrollbar* scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);        if (!scrollbar)            scrollbar = mev.scrollbar();        if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))            swallowEvent = true;        else            swallowEvent = handleMousePressEvent(mev);    }    return swallowEvent;}// This method only exists for platforms that don't know how to deliver bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent){    RefPtr<FrameView> protector(m_frame->view());    // We get this instead of a second mouse-up     m_mousePressed = false;    m_currentMousePosition = mouseEvent.pos();    HitTestRequest request(HitTestRequest::Active);    MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);    Frame* subframe = subframeForHitTestResult(mev);    if (subframe && passMousePressEventToSubframe(mev, subframe)) {        m_capturingMouseEventsNode = 0;        return true;    }    m_clickCount = mouseEvent.clickCount();    bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);    bool swallowClickEvent = false;    // Don't ever dispatch click events for right clicks    if (mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)        swallowClickEvent = dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);    if (m_lastScrollbarUnderMouse)        swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp();                bool swallowMouseReleaseEvent = false;    if (!swallowMouseUpEvent)        swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);    invalidateClick();    return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;}bool EventHandler::mouseMoved(const PlatformMouseEvent& event){    HitTestResult hoveredNode = HitTestResult(IntPoint());    bool result = handleMouseMoveEvent(event, &hoveredNode);    Page* page = m_frame->page();    if (!page)        return result;    hoveredNode.setToNonShadowAncestor();    page->chrome()->mouseDidMoveOverElement(hoveredNode, event.modifierFlags());    page->chrome()->setToolTip(hoveredNode);    return result;}bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, HitTestResult* hoveredNode){    // in Radar 3703768 we saw frequent crashes apparently due to the    // part being null here, which seems impossible, so check for nil    // but also assert so that we can try to figure this out in debug    // builds, if it happens.    ASSERT(m_frame);    if (!m_frame)        return false;    RefPtr<FrameView> protector(m_frame->view());    m_currentMousePosition = mouseEvent.pos();    if (m_hoverTimer.isActive())        m_hoverTimer.stop();#if ENABLE(SVG)    if (m_svgPan) {        static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);        return true;    }#endif    if (m_frameSetBeingResized)        return dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);    // Send events right to a scrollbar if the mouse is pressed.    if (m_lastScrollbarUnderMouse && m_mousePressed)        return m_lastScrollbarUnderMouse->mouseMoved(m_lastScrollbarUnderMouse->transformEvent(mouseEvent));    // Treat mouse move events while the mouse is pressed as "read-only" in prepareMouseEvent    // if we are allowed to select.    // This means that :hover and :active freeze in the state they were in when the mouse    // was pressed, rather than updating for nodes the mouse moves over as you hold the mouse down.    int hitType = HitTestRequest::MouseMove;    if (m_mousePressed && m_mouseDownMayStartSelect)        hitType |= HitTestRequest::ReadOnly;    if (m_mousePressed)        hitType |= HitTestRequest::Active;    HitTestRequest request(hitType);    MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);    if (hoveredNode)        *hoveredNode = mev.hitTestResult();    Scrollbar* scrollbar = 0;    if (m_resizeLayer && m_resizeLayer->inResizeMode())        m_resizeLayer->resize(mouseEvent, m_offsetFromResizeCorner);    else {        if (m_frame->view())            scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);        if (!scrollbar)            scrollbar = mev.scrollbar();        if (m_lastScrollbarUnderMouse != scrollbar) {            // Send mouse exited to the old scrollbar.            if (m_lastScrollbarUnderMouse)                m_lastScrollbarUnderMouse->mouseExited();            m_lastScrollbarUnderMouse = m_mousePressed ? 0 : scrollbar;        }    }    bool swallowEvent = false;    RefPtr<Frame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);     // We want mouseouts to happen first, from the inside out.  First send a move event to the last subframe so that it will fire mouseouts.    if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree()->isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)        passMouseMoveEventToSubframe(mev, m_lastMouseMoveEventSubframe.get());    if (newSubframe) {        // Update over/out state before passing the event to the subframe.        updateMouseEventTargetNode(mev.targetNode(), mouseEvent, true);                // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target        // node to be detached from its FrameView, in which case the event should not be passed.        if (newSubframe->view())            swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);    } else {        if (scrollbar && !m_mousePressed)            scrollbar->mouseMoved(scrollbar->transformEvent(mouseEvent)); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.        if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() && m_frame->view())            m_frame->view()->setCursor(selectCursor(mev, scrollbar));    }        m_lastMouseMoveEventSubframe = newSubframe;    if (swallowEvent)        return true;        swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);    if (!swallowEvent)        swallowEvent = handleMouseDraggedEvent(mev);    return swallowEvent;}void EventHandler::invalidateClick(){    m_clickCount = 0;    m_clickNode = 0;}bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent){    RefPtr<FrameView> protector(m_frame->view());    m_mousePressed = false;    m_currentMousePosition = mouseEvent.pos();#if ENABLE(SVG)    if (m_svgPan) {        m_svgPan = false;        static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);        return true;    }#endif    if (m_frameSetBeingResized)        return dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);    if (m_lastScrollbarUnderMouse) {        invalidateClick();        return m_lastScrollbarUnderMouse->mouseUp();    }    HitTestRequest request(HitTestRequest::MouseUp);    MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);    Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);    if (subframe && passMouseReleaseEventToSubframe(mev, subframe)) {        m_capturingMouseEventsNode = 0;        return true;    }    bool swallowMouseUpEvent = dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);    // Don't ever dispatch click events for right clicks    bool swallowClickEvent = false;    if (m_clickCount > 0 && mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)        swallowClickEvent = dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);    if (m_resizeLayer) {        m_resizeLayer->setInResizeMode(false);        m_resizeLayer = 0;    }    bool swallowMouseReleaseEvent = false;    if (!swallowMouseUpEvent)        swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);    invalidateClick();    return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;}bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard){    m_frame->view()->resetDeferredRepaintDelay();    IntPoint contentsPos = m_frame->view()->windowToContents(event.pos());        RefPtr<MouseEvent> me = MouseEvent::create(eventType,        true, true, m_frame->document()->defaultView(),        0, event.globalX(), event.globalY(), contentsPos.x(), contentsPos.y(),        event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),        0, 0, clipboard);    ExceptionCode ec = 0;    dragTarget->dispatchEvent(me.get(), ec);    return me->defaultPrevented();}bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard){    bool accept = false;    if (!m_frame->view())        return false;    HitTestRequest request(HitTestRequest::ReadOnly);    MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);    // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)    Node* newTarget = mev.targetNode();    if (newTarget && newTarget->isTextNode())        newTarget = newTarget->parentNode();    if (newTarget)        newTarget = newTarget->shadowAncestorNode();    if (m_dragTarget != newTarget) {        // FIXME: this ordering was explicitly chosen to match WinIE. However,        // it is sometimes incorrect when dragging within subframes, as seen with        // LayoutTests/fast/events/drag-in-frames.html.        if (newTarget)            if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))                accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);            else                accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);                if (m_dragTarget) {            Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))                             ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;            if (frame)                accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);            else                dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);        }    } else {        if (newTarget)            if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))                accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);            else

⌨️ 快捷键说明

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