eventhandler.cpp
来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,735 行 · 第 1/5 页
CPP
1,735 行
unsigned mask = m_frame->page()->dragController()->delegateDragSourceAction(m_frame->view()->contentsToWindow(m_mouseDownPos)); flagDHTML = (mask & DragSourceActionDHTML) != DragSourceActionNone; flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));} HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping){ HitTestResult result(point); if (!m_frame->contentRenderer()) return result; int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; if (ignoreClipping) hitType |= HitTestRequest::IgnoreClipping; m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), result); while (true) { Node* n = result.innerNode(); if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget()) break; RenderWidget* renderWidget = static_cast<RenderWidget*>(n->renderer()); Widget* widget = renderWidget->widget(); if (!widget || !widget->isFrameView()) break; Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame(); if (!frame || !frame->contentRenderer()) break; FrameView* view = static_cast<FrameView*>(widget); IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(), result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop()); HitTestResult widgetHitTestResult(widgetPoint); frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), widgetHitTestResult); result = widgetHitTestResult; } // If our HitTestResult is not visible, then we started hit testing too far down the frame chain. // Another hit test at the main frame level should get us the correct visible result. Frame* resultFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : 0; Frame* mainFrame = m_frame->page()->mainFrame(); if (m_frame != mainFrame && resultFrame && resultFrame != mainFrame && !resultFrame->editor()->insideVisibleArea(result.point())) { IntPoint windowPoint = resultFrame->view()->contentsToWindow(result.point()); IntPoint mainFramePoint = mainFrame->view()->windowToContents(windowPoint); result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent, ignoreClipping); } if (!allowShadowContent) result.setToNonShadowAncestor(); return result;}void EventHandler::startAutoscrollTimer(){ m_autoscrollTimer.startRepeating(autoscrollInterval);}void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed){ if (m_autoscrollInProgress) { if (m_mouseDownWasInSubframe) { if (Frame* subframe = subframeForTargetNode(m_mousePressNode.get())) subframe->eventHandler()->stopAutoscrollTimer(rendererIsBeingDestroyed); return; } } if (autoscrollRenderer()) { if (!rendererIsBeingDestroyed && (m_autoscrollInProgress || m_panScrollInProgress)) toRenderBox(autoscrollRenderer())->stopAutoscroll();#if ENABLE(PAN_SCROLLING) if (m_panScrollInProgress) { m_frame->view()->removePanScrollIcon(); m_frame->view()->setCursor(pointerCursor()); }#endif setAutoscrollRenderer(0); } m_autoscrollTimer.stop(); m_panScrollInProgress = false; // If we're not in the top frame we notify it that we are not using the panScroll anymore if (m_frame->page() && m_frame != m_frame->page()->mainFrame()) m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(false); m_autoscrollInProgress = false;}Node* EventHandler::mousePressNode() const{ return m_mousePressNode.get();}void EventHandler::setMousePressNode(PassRefPtr<Node> node){ m_mousePressNode = node;}bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity){ Node* node = m_frame->document()->focusedNode(); if (!node) node = m_mousePressNode.get(); if (node) { RenderObject* r = node->renderer(); if (r && !r->isListBox()) return r->enclosingBox()->scroll(direction, granularity); } return false;}IntPoint EventHandler::currentMousePosition() const{ return m_currentMousePosition;}Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult){ if (!hitTestResult.isOverWidget()) return 0; return subframeForTargetNode(hitTestResult.targetNode());}Frame* subframeForTargetNode(Node* node){ if (!node) return 0; RenderObject* renderer = node->renderer(); if (!renderer || !renderer->isWidget()) return 0; Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); if (!widget || !widget->isFrameView()) return 0; return static_cast<FrameView*>(widget)->frame();}static bool isSubmitImage(Node* node){ return node && node->hasTagName(inputTag) && static_cast<HTMLInputElement*>(node)->inputType() == HTMLInputElement::IMAGE;}// Returns true if the node's editable block is not current focused for editingstatic bool nodeIsNotBeingEdited(Node* node, Frame* frame){ return frame->selection()->rootEditableElement() != node->rootEditableElement();}Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar){ // During selection, use an I-beam no matter what we're over. // If you're capturing mouse events for a particular node, don't treat this as a selection. if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode) return iBeamCursor(); Node* node = event.targetNode(); RenderObject* renderer = node ? node->renderer() : 0; RenderStyle* style = renderer ? renderer->style() : 0; if (renderer && renderer->isFrameSet()) { RenderFrameSet* fs = static_cast<RenderFrameSet*>(renderer); if (fs->canResizeRow(event.localPoint())) return rowResizeCursor(); if (fs->canResizeColumn(event.localPoint())) return columnResizeCursor(); } if (style && style->cursors()) { const CursorList* cursors = style->cursors(); for (unsigned i = 0; i < cursors->size(); ++i) { CachedImage* cimage = (*cursors)[i].cursorImage.get(); IntPoint hotSpot = (*cursors)[i].hotSpot; if (!cimage) continue; // Limit the size of cursors so that they cannot be used to cover UI elements in chrome. IntSize size = cimage->image()->size(); if (size.width() > 128 || size.height() > 128) continue; // Do not let the hotspot be outside the bounds of the image. if (hotSpot.x() < 0 || hotSpot.y() < 0 || hotSpot.x() > size.width() || hotSpot.y() > size.height()) continue; if (cimage->image()->isNull()) break; if (!cimage->errorOccurred()) return Cursor(cimage->image(), hotSpot); } } switch (style ? style->cursor() : CURSOR_AUTO) { case CURSOR_AUTO: { bool editable = (node && node->isContentEditable()); bool editableLinkEnabled = false; // If the link is editable, then we need to check the settings to see whether or not the link should be followed if (editable) { ASSERT(m_frame->settings()); switch(m_frame->settings()->editableLinkBehavior()) { default: case EditableLinkDefaultBehavior: case EditableLinkAlwaysLive: editableLinkEnabled = true; break; case EditableLinkNeverLive: editableLinkEnabled = false; break; case EditableLinkLiveWhenNotFocused: editableLinkEnabled = nodeIsNotBeingEdited(node, m_frame) || event.event().shiftKey(); break; case EditableLinkOnlyLiveWithShiftKey: editableLinkEnabled = event.event().shiftKey(); break; } } if ((event.isOverLink() || isSubmitImage(node)) && (!editable || editableLinkEnabled)) return handCursor(); RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0; bool inResizer = false; if (m_frame->view() && layer && layer->isPointInResizeControl(m_frame->view()->windowToContents(event.event().pos()))) inResizer = true; if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !scrollbar) return iBeamCursor(); return pointerCursor(); } case CURSOR_CROSS: return crossCursor(); case CURSOR_POINTER: return handCursor(); case CURSOR_MOVE: return moveCursor(); case CURSOR_ALL_SCROLL: return moveCursor(); case CURSOR_E_RESIZE: return eastResizeCursor(); case CURSOR_W_RESIZE: return westResizeCursor(); case CURSOR_N_RESIZE: return northResizeCursor(); case CURSOR_S_RESIZE: return southResizeCursor(); case CURSOR_NE_RESIZE: return northEastResizeCursor(); case CURSOR_SW_RESIZE: return southWestResizeCursor(); case CURSOR_NW_RESIZE: return northWestResizeCursor(); case CURSOR_SE_RESIZE: return southEastResizeCursor(); case CURSOR_NS_RESIZE: return northSouthResizeCursor(); case CURSOR_EW_RESIZE: return eastWestResizeCursor(); case CURSOR_NESW_RESIZE: return northEastSouthWestResizeCursor(); case CURSOR_NWSE_RESIZE: return northWestSouthEastResizeCursor(); case CURSOR_COL_RESIZE: return columnResizeCursor(); case CURSOR_ROW_RESIZE: return rowResizeCursor(); case CURSOR_TEXT: return iBeamCursor(); case CURSOR_WAIT: return waitCursor(); case CURSOR_HELP: return helpCursor(); case CURSOR_VERTICAL_TEXT: return verticalTextCursor(); case CURSOR_CELL: return cellCursor(); case CURSOR_CONTEXT_MENU: return contextMenuCursor(); case CURSOR_PROGRESS: return progressCursor(); case CURSOR_NO_DROP: return noDropCursor(); case CURSOR_ALIAS: return aliasCursor(); case CURSOR_COPY: return copyCursor(); case CURSOR_NONE: return noneCursor(); case CURSOR_NOT_ALLOWED: return notAllowedCursor(); case CURSOR_DEFAULT: return pointerCursor(); case CURSOR_WEBKIT_ZOOM_IN: return zoomInCursor(); case CURSOR_WEBKIT_ZOOM_OUT: return zoomOutCursor(); case CURSOR_WEBKIT_GRAB: return grabCursor(); case CURSOR_WEBKIT_GRABBING: return grabbingCursor(); } return pointerCursor();}bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent){ RefPtr<FrameView> protector(m_frame->view()); m_mousePressed = true; m_capturesDragging = true; m_currentMousePosition = mouseEvent.pos(); m_mouseDownTimestamp = mouseEvent.timestamp(); m_mouseDownMayStartDrag = false; m_mouseDownMayStartSelect = false; m_mouseDownMayStartAutoscroll = false; m_mouseDownPos = m_frame->view()->windowToContents(mouseEvent.pos()); m_mouseDownWasInSubframe = false; HitTestRequest request(HitTestRequest::Active); MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); if (!mev.targetNode()) { invalidateClick(); return false; } m_mousePressNode = mev.targetNode(); InspectorController* inspector = m_frame->page()->inspectorController(); if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) { inspector->handleMousePressOnNode(m_mousePressNode.get()); invalidateClick(); return true; } Frame* subframe = subframeForHitTestResult(mev); if (subframe && passMousePressEventToSubframe(mev, subframe)) { // Start capturing future events for this frame. We only do this if we didn't clear // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop. m_capturesDragging = subframe->eventHandler()->capturesDragging(); if (m_mousePressed && m_capturesDragging) m_capturingMouseEventsNode = mev.targetNode(); invalidateClick(); return true;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?