eventhandler.cpp
来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 1,735 行 · 第 1/5 页
CPP
1,735 行
/* * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "EventHandler.h"#include "AXObjectCache.h"#include "CachedImage.h"#include "ChromeClient.h"#include "Cursor.h"#include "Document.h"#include "DragController.h"#include "Editor.h"#include "EventNames.h"#include "FloatPoint.h"#include "FloatRect.h"#include "FocusController.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameTree.h"#include "FrameView.h"#include "HitTestRequest.h"#include "HitTestResult.h"#include "HTMLFrameSetElement.h"#include "HTMLFrameElementBase.h"#include "HTMLInputElement.h"#include "HTMLNames.h"#include "Image.h"#include "InspectorController.h"#include "KeyboardEvent.h"#include "MouseEvent.h"#include "MouseEventWithHitTestResults.h"#include "Page.h"#include "PlatformKeyboardEvent.h"#include "PlatformWheelEvent.h"#include "RenderFrameSet.h"#include "RenderTextControlSingleLine.h"#include "RenderWidget.h"#include "RenderView.h"#include "Scrollbar.h"#include "SelectionController.h"#include "Settings.h"#include "TextEvent.h"#include <wtf/StdLibExtras.h>#if ENABLE(SVG)#include "SVGDocument.h"#include "SVGElementInstance.h"#include "SVGNames.h"#include "SVGUseElement.h"#endifnamespace WebCore {using namespace HTMLNames;// The link drag hysteresis is much larger than the others because there// needs to be enough space to cancel the link press without starting a link drag,// and because dragging links is rare.const int LinkDragHysteresis = 40;const int ImageDragHysteresis = 5;const int TextDragHysteresis = 3;const int GeneralDragHysteresis = 3;// Match key code of composition keydown event on windows.// IE sends VK_PROCESSKEY which has value 229;const int CompositionEventKeyCode = 229;#if ENABLE(SVG)using namespace SVGNames;#endif// When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smoothconst double autoscrollInterval = 0.05;static Frame* subframeForTargetNode(Node*);static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node){ if (!delta) return; // Find the nearest enclosing box. RenderBox* enclosingBox = node->renderer()->enclosingBox(); if (e.granularity() == ScrollByPageWheelEvent) { if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1)) e.accept(); return; } float pixelsToScroll = delta > 0 ? delta : -delta; if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll)) e.accept();}EventHandler::EventHandler(Frame* frame) : m_frame(frame) , m_mousePressed(false) , m_capturesDragging(false) , m_mouseDownMayStartSelect(false) , m_mouseDownMayStartDrag(false) , m_mouseDownWasSingleClickInSelection(false) , m_beganSelectingText(false) , m_panScrollInProgress(false) , m_hoverTimer(this, &EventHandler::hoverTimerFired) , m_autoscrollTimer(this, &EventHandler::autoscrollTimerFired) , m_autoscrollRenderer(0) , m_autoscrollInProgress(false) , m_mouseDownMayStartAutoscroll(false) , m_mouseDownWasInSubframe(false)#if ENABLE(SVG) , m_svgPan(false)#endif , m_resizeLayer(0) , m_capturingMouseEventsNode(0) , m_clickCount(0) , m_mouseDownTimestamp(0) , m_pendingFrameUnloadEventCount(0) , m_pendingFrameBeforeUnloadEventCount(0)#if PLATFORM(MAC) , m_mouseDownView(nil) , m_sendingEventToSubview(false) , m_activationEventNumber(0)#endif{}EventHandler::~EventHandler(){} EventHandler::EventHandlerDragState& EventHandler::dragState(){ DEFINE_STATIC_LOCAL(EventHandlerDragState, state, ()); return state;} void EventHandler::clear(){ m_hoverTimer.stop(); m_resizeLayer = 0; m_nodeUnderMouse = 0; m_lastNodeUnderMouse = 0;#if ENABLE(SVG) m_instanceUnderMouse = 0; m_lastInstanceUnderMouse = 0;#endif m_lastMouseMoveEventSubframe = 0; m_lastScrollbarUnderMouse = 0; m_clickCount = 0; m_clickNode = 0; m_frameSetBeingResized = 0; m_dragTarget = 0; m_currentMousePosition = IntPoint(); m_mousePressNode = 0; m_mousePressed = false; m_capturesDragging = false; m_capturingMouseEventsNode = 0;}void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result){ Node* innerNode = result.targetNode(); VisibleSelection newSelection; if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) { VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint())); if (pos.isNotNull()) { newSelection = VisibleSelection(pos); newSelection.expandUsingGranularity(WordGranularity); } if (newSelection.isRange()) { m_frame->setSelectionGranularity(WordGranularity); m_beganSelectingText = true; if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled()) newSelection.appendTrailingWhitespace(); } if (m_frame->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection); }}void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result){ if (!result.hitTestResult().isLiveLink()) return selectClosestWordFromMouseEvent(result); Node* innerNode = result.targetNode(); if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) { VisibleSelection newSelection; Element* URLElement = result.hitTestResult().URLElement(); VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint())); if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement)) newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement); if (newSelection.isRange()) { m_frame->setSelectionGranularity(WordGranularity); m_beganSelectingText = true; } if (m_frame->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection); }}bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event){ if (event.event().button() != LeftButton) return false; if (m_frame->selection()->isRange()) // A double-click when range is already selected // should not change the selection. So, do not call // selectClosestWordFromMouseEvent, but do set // m_beganSelectingText to prevent handleMouseReleaseEvent // from setting caret selection. m_beganSelectingText = true; else selectClosestWordFromMouseEvent(event); return true;}bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event){ if (event.event().button() != LeftButton) return false; Node* innerNode = event.targetNode(); if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect)) return false; VisibleSelection newSelection; VisiblePosition pos(innerNode->renderer()->positionForPoint(event.localPoint())); if (pos.isNotNull()) { newSelection = VisibleSelection(pos); newSelection.expandUsingGranularity(ParagraphGranularity); } if (newSelection.isRange()) { m_frame->setSelectionGranularity(ParagraphGranularity); m_beganSelectingText = true; } if (m_frame->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection); return true;}bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event){ if (event.event().button() != LeftButton) return false; Node* innerNode = event.targetNode(); if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect)) return false; // Extend the selection if the Shift key is down, unless the click is in a link. bool extendSelection = event.event().shiftKey() && !event.isOverLink(); // Don't restart the selection when the mouse is pressed on an // existing selection so we can allow for text dragging. IntPoint vPoint = m_frame->view()->windowToContents(event.event().pos()); if (!extendSelection && m_frame->selection()->contains(vPoint)) { m_mouseDownWasSingleClickInSelection = true; return false; } VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(event.localPoint())); if (visiblePos.isNull()) visiblePos = VisiblePosition(innerNode, 0, DOWNSTREAM); Position pos = visiblePos.deepEquivalent(); VisibleSelection newSelection = m_frame->selection()->selection(); if (extendSelection && newSelection.isCaretOrRange()) { m_frame->selection()->setLastChangeWasHorizontalExtension(false); // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection // was created right-to-left Position start = newSelection.start(); Position end = newSelection.end(); short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset()); if (before <= 0) newSelection = VisibleSelection(pos, end); else newSelection = VisibleSelection(start, pos); if (m_frame->selectionGranularity() != CharacterGranularity) newSelection.expandUsingGranularity(m_frame->selectionGranularity()); m_beganSelectingText = true; } else { newSelection = VisibleSelection(visiblePos); m_frame->setSelectionGranularity(CharacterGranularity); } if (m_frame->shouldChangeSelection(newSelection)) m_frame->selection()->setSelection(newSelection); return true;}bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event){ // Reset drag state. dragState().m_dragSrc = 0; bool singleClick = event.event().clickCount() <= 1; // If we got the event back, that must mean it wasn't prevented, // so it's allowed to start a drag or selection. m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()); // Careful that the drag starting logic stays in sync with eventMayStartDrag() m_mouseDownMayStartDrag = singleClick; m_mouseDownWasSingleClickInSelection = false; if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event)) return true;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?