eventhandler.cpp

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

CPP
1,735
字号
                accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);    }    m_dragTarget = newTarget;    return accept;}void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard){    if (m_dragTarget) {        Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))                         ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;        if (frame)            frame->eventHandler()->cancelDragAndDrop(event, clipboard);        else            dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);    }    clearDragState();}bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard){    bool accept = false;    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()->performDragAndDrop(event, clipboard);        else            accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);    }    clearDragState();    return accept;}void EventHandler::clearDragState(){    m_dragTarget = 0;    m_capturingMouseEventsNode = 0;#if PLATFORM(MAC)    m_sendingEventToSubview = false;#endif}void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n){    m_capturingMouseEventsNode = n;}MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev){    ASSERT(m_frame);    ASSERT(m_frame->document());        IntPoint documentPoint = m_frame->view()->windowToContents(mev.pos());    return m_frame->document()->prepareMouseEvent(request, documentPoint, mev);}#if ENABLE(SVG)static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode){    if (!referenceNode || !referenceNode->isSVGElement())        return 0;    Node* shadowTreeElement = referenceNode->shadowTreeRootNode();    if (!shadowTreeElement)        return 0;    Node* shadowTreeParentElement = shadowTreeElement->shadowParentNode();    if (!shadowTreeParentElement)        return 0;    ASSERT(shadowTreeParentElement->hasTagName(useTag));    return static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);}#endifvoid EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut){    Node* result = targetNode;        // If we're capturing, we always go right to that node.    if (m_capturingMouseEventsNode)        result = m_capturingMouseEventsNode.get();    else {        // If the target node is a text node, dispatch on the parent node - rdar://4196646        if (result && result->isTextNode())            result = result->parentNode();        if (result)            result = result->shadowAncestorNode();    }    m_nodeUnderMouse = result;#if ENABLE(SVG)    m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(result);    // <use> shadow tree elements may have been recloned, update node under mouse in any case    if (m_lastInstanceUnderMouse) {        SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();        SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();        if (lastCorrespondingElement && lastCorrespondingUseElement) {            HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();            // Locate the recloned shadow tree element for our corresponding instance            HashSet<SVGElementInstance*>::iterator end = instances.end();            for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {                SVGElementInstance* instance = (*it);                ASSERT(instance->correspondingElement() == lastCorrespondingElement);                if (instance == m_lastInstanceUnderMouse)                    continue;                if (instance->correspondingUseElement() != lastCorrespondingUseElement)                    continue;                SVGElement* shadowTreeElement = instance->shadowTreeElement();                if (!shadowTreeElement->inDocument() || m_lastNodeUnderMouse == shadowTreeElement)                    continue;                m_lastNodeUnderMouse = shadowTreeElement;                m_lastInstanceUnderMouse = instance;                break;            }        }    }#endif    // Fire mouseout/mouseover if the mouse has shifted to a different node.    if (fireMouseOverOut) {        if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {            m_lastNodeUnderMouse = 0;            m_lastScrollbarUnderMouse = 0;#if ENABLE(SVG)            m_lastInstanceUnderMouse = 0;#endif        }        if (m_lastNodeUnderMouse != m_nodeUnderMouse) {            // send mouseout event to the old node            if (m_lastNodeUnderMouse)                m_lastNodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_nodeUnderMouse.get());            // send mouseover event to the new node            if (m_nodeUnderMouse)                m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastNodeUnderMouse.get());        }        m_lastNodeUnderMouse = m_nodeUnderMouse;#if ENABLE(SVG)        m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_nodeUnderMouse.get());#endif    }}bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder){    m_frame->view()->resetDeferredRepaintDelay();    updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);    bool swallowEvent = false;    if (m_nodeUnderMouse)        swallowEvent = m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);        if (!swallowEvent && eventType == eventNames().mousedownEvent) {        // Blur current focus node when a link/button is clicked; this        // is expected by some sites that rely on onChange handlers running        // from form fields before the button click is processed.        Node* node = m_nodeUnderMouse.get();        RenderObject* renderer = node ? node->renderer() : 0;                        // Walk up the render tree to search for a node to focus.        // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.        while (renderer) {            node = renderer->node();            if (node && node->isFocusable()) {                // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a                 // node on mouse down if it's selected and inside a focused node. It will be                 // focused if the user does a mouseup over it, however, because the mouseup                // will set a selection inside it, which will call setFocuseNodeIfNeeded.                ExceptionCode ec = 0;                Node* n = node->isShadowNode() ? node->shadowParentNode() : node;                if (m_frame->selection()->isRange() &&                     m_frame->selection()->toNormalizedRange()->compareNode(n, ec) == Range::NODE_INSIDE &&                    n->isDescendantOf(m_frame->document()->focusedNode()))                    return false;                                    break;            }                        renderer = renderer->parent();        }        // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent        // if the page already set it (e.g., by canceling default behavior).        if (node && node->isMouseFocusable()) {            if (!m_frame->page()->focusController()->setFocusedNode(node, m_frame))                swallowEvent = true;        } else if (!node || !node->focused()) {            if (!m_frame->page()->focusController()->setFocusedNode(0, m_frame))                swallowEvent = true;        }    }    return swallowEvent;}bool EventHandler::handleWheelEvent(PlatformWheelEvent& e){    Document* doc = m_frame->document();    RenderObject* docRenderer = doc->renderer();    if (!docRenderer)        return false;        RefPtr<FrameView> protector(m_frame->view());    IntPoint vPoint = m_frame->view()->windowToContents(e.pos());    HitTestRequest request(HitTestRequest::ReadOnly);    HitTestResult result(vPoint);    doc->renderView()->layer()->hitTest(request, result);    Node* node = result.innerNode();        if (node) {        // Figure out which view to send the event to.        RenderObject* target = node->renderer();                if (result.isOverWidget() && target && target->isWidget()) {            Widget* widget = static_cast<RenderWidget*>(target)->widget();            if (widget && passWheelEventToWidget(e, widget)) {                e.accept();                return true;            }        }        node = node->shadowAncestorNode();        node->dispatchWheelEvent(e);        if (e.isAccepted())            return true;                // If we don't have a renderer, send the wheel event to the first node we find with a renderer.        // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.        while (node && !node->renderer())            node = node->parent();                if (node && node->renderer()) {            // Just break up into two scrolls if we need to.  Diagonal movement on             // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).            scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node);            scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node);        }    }    if (!e.isAccepted())        m_frame->view()->wheelEvent(e);        return e.isAccepted();}bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event){    Document* doc = m_frame->document();    FrameView* v = m_frame->view();    if (!v)        return false;        bool swallowEvent;    IntPoint viewportPos = v->windowToContents(event.pos());    HitTestRequest request(HitTestRequest::Active);    MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);    // Context menu events shouldn't select text in GTK+ applications or in Chromium.    // FIXME: This should probably be configurable by embedders. Consider making it a WebPreferences setting.    // See: https://bugs.webkit.org/show_bug.cgi?id=15279#if !PLATFORM(GTK) && !PLATFORM(CHROMIUM)    if (!m_frame->selection()->contains(viewportPos) &&         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.        // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items        // available for text selections.  But only if we're above text.        (m_frame->selection()->isContentEditable() || mev.targetNode() && mev.targetNode()->isTextNode())) {        m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection        selectClosestWordOrLinkFromMouseEvent(mev);    }#endif    swallowEvent = dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, true);        return swallowEvent;}void EventHandler::scheduleHoverStateUpdate(){    if (!m_hoverTimer.isActive())        m_hoverTimer.startOneShot(0);}// Whether or not a mouse down can begin the creation of a selection.  Fires the selectStart event.bool EventHandler::canMouseDownStartSelect(Node* node){    if (!node || !node->renderer())        return true;        // Some controls and images can't start a select on a mouse down.    if (!node->canStartSelection())        return false;                for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {        if (Node* node = curr->node())            return node->dispatchEventForType(eventNames().selectstartEvent, true, true);    }    return true;}bool EventHandler::canMouseDragExtendSelect(Node* node){    if (!node || !node->renderer())        return true;                for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {        if (Node* node = curr->node())            return node->dispatchEventForType(eventNames().selectstartEvent, true, true);    }    return true;}void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet){    m_frameSetBeingResized = frameSet;}void EventHandler::resizeLayerDestroyed(){    ASSERT(m_resizeLayer);    m_resizeLayer = 0;}void EventHandler::hoverTimerFired(Timer<EventHandler>*){    m_hoverTimer.stop();    ASSERT(m_frame);    ASSERT(m_frame->document());    if (RenderView* renderer = m_frame->contentRenderer()) {        HitTestRequest requ

⌨️ 快捷键说明

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