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