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 + -
显示快捷键?