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