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