OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) | 187 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire
d) |
188 , m_svgPan(false) | 188 , m_svgPan(false) |
189 , m_eventHandlerWillResetCapturingMouseEventsNode(0) | 189 , m_eventHandlerWillResetCapturingMouseEventsNode(0) |
190 , m_clickCount(0) | 190 , m_clickCount(0) |
191 , m_shouldOnlyFireDragOverEvent(false) | 191 , m_shouldOnlyFireDragOverEvent(false) |
192 , m_mousePositionIsUnknown(true) | 192 , m_mousePositionIsUnknown(true) |
193 , m_mouseDownTimestamp(0) | 193 , m_mouseDownTimestamp(0) |
194 , m_pointerEventManager(frame) | 194 , m_pointerEventManager(frame) |
195 , m_scrollManager(frame) | 195 , m_scrollManager(frame) |
196 , m_keyboardEventManager(frame, &m_scrollManager) | 196 , m_keyboardEventManager(frame, &m_scrollManager) |
197 , m_longTapShouldInvokeContextMenu(false) | 197 , m_gestureManager(frame, &m_scrollManager, &m_pointerEventManager, m_select
ionController) |
198 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 198 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
199 , m_lastShowPressTimestamp(0) | |
200 , m_suppressMouseEventsFromGestures(false) | |
201 { | 199 { |
202 } | 200 } |
203 | 201 |
204 EventHandler::~EventHandler() | 202 EventHandler::~EventHandler() |
205 { | 203 { |
206 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); | 204 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); |
207 } | 205 } |
208 | 206 |
209 DEFINE_TRACE(EventHandler) | 207 DEFINE_TRACE(EventHandler) |
210 { | 208 { |
211 visitor->trace(m_frame); | 209 visitor->trace(m_frame); |
212 visitor->trace(m_mousePressNode); | 210 visitor->trace(m_mousePressNode); |
213 visitor->trace(m_capturingMouseEventsNode); | 211 visitor->trace(m_capturingMouseEventsNode); |
214 visitor->trace(m_nodeUnderMouse); | 212 visitor->trace(m_nodeUnderMouse); |
215 visitor->trace(m_lastMouseMoveEventSubframe); | 213 visitor->trace(m_lastMouseMoveEventSubframe); |
216 visitor->trace(m_lastScrollbarUnderMouse); | 214 visitor->trace(m_lastScrollbarUnderMouse); |
217 visitor->trace(m_clickNode); | 215 visitor->trace(m_clickNode); |
218 visitor->trace(m_dragTarget); | 216 visitor->trace(m_dragTarget); |
219 visitor->trace(m_frameSetBeingResized); | 217 visitor->trace(m_frameSetBeingResized); |
220 visitor->trace(m_lastDeferredTapElement); | 218 visitor->trace(m_lastDeferredTapElement); |
221 visitor->trace(m_selectionController); | 219 visitor->trace(m_selectionController); |
222 visitor->trace(m_pointerEventManager); | 220 visitor->trace(m_pointerEventManager); |
223 visitor->trace(m_scrollManager); | 221 visitor->trace(m_scrollManager); |
224 visitor->trace(m_keyboardEventManager); | 222 visitor->trace(m_keyboardEventManager); |
| 223 visitor->trace(m_gestureManager); |
225 } | 224 } |
226 | 225 |
227 DragState& EventHandler::dragState() | 226 DragState& EventHandler::dragState() |
228 { | 227 { |
229 DEFINE_STATIC_LOCAL(DragState, state, (new DragState)); | 228 DEFINE_STATIC_LOCAL(DragState, state, (new DragState)); |
230 return state; | 229 return state; |
231 } | 230 } |
232 | 231 |
233 void EventHandler::clear() | 232 void EventHandler::clear() |
234 { | 233 { |
(...skipping 12 matching lines...) Expand all Loading... |
247 m_mousePositionIsUnknown = true; | 246 m_mousePositionIsUnknown = true; |
248 m_lastKnownMousePosition = IntPoint(); | 247 m_lastKnownMousePosition = IntPoint(); |
249 m_lastKnownMouseGlobalPosition = IntPoint(); | 248 m_lastKnownMouseGlobalPosition = IntPoint(); |
250 m_lastMouseDownUserGestureToken.clear(); | 249 m_lastMouseDownUserGestureToken.clear(); |
251 m_mousePressNode = nullptr; | 250 m_mousePressNode = nullptr; |
252 m_mousePressed = false; | 251 m_mousePressed = false; |
253 m_capturesDragging = false; | 252 m_capturesDragging = false; |
254 m_capturingMouseEventsNode = nullptr; | 253 m_capturingMouseEventsNode = nullptr; |
255 m_pointerEventManager.clear(); | 254 m_pointerEventManager.clear(); |
256 m_scrollManager.clear(); | 255 m_scrollManager.clear(); |
| 256 m_gestureManager.clear(); |
257 m_mouseDownMayStartDrag = false; | 257 m_mouseDownMayStartDrag = false; |
258 m_lastShowPressTimestamp = 0; | |
259 m_lastDeferredTapElement = nullptr; | 258 m_lastDeferredTapElement = nullptr; |
260 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 259 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
261 m_mouseDownMayStartAutoscroll = false; | 260 m_mouseDownMayStartAutoscroll = false; |
262 m_svgPan = false; | 261 m_svgPan = false; |
263 m_mouseDownPos = IntPoint(); | 262 m_mouseDownPos = IntPoint(); |
264 m_mouseDownTimestamp = 0; | 263 m_mouseDownTimestamp = 0; |
265 m_longTapShouldInvokeContextMenu = false; | |
266 m_dragStartPos = LayoutPoint(); | 264 m_dragStartPos = LayoutPoint(); |
267 m_mouseDown = PlatformMouseEvent(); | 265 m_mouseDown = PlatformMouseEvent(); |
268 m_suppressMouseEventsFromGestures = false; | |
269 } | 266 } |
270 | 267 |
271 WebInputEventResult EventHandler::mergeEventResult( | 268 WebInputEventResult EventHandler::mergeEventResult( |
272 WebInputEventResult resultA, WebInputEventResult resultB) | 269 WebInputEventResult resultA, WebInputEventResult resultB) |
273 { | 270 { |
274 // The ordering of the enumeration is specific. There are times that | 271 // The ordering of the enumeration is specific. There are times that |
275 // multiple events fire and we need to combine them into a single | 272 // multiple events fire and we need to combine them into a single |
276 // result code. The enumeration is based on the level of consumption that | 273 // result code. The enumeration is based on the level of consumption that |
277 // is most significant. The enumeration is ordered with smaller specified | 274 // is most significant. The enumeration is ordered with smaller specified |
278 // numbers first. Examples of merged results are: | 275 // numbers first. Examples of merged results are: |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 | 1076 |
1080 return handleMouseDraggedEvent(mev); | 1077 return handleMouseDraggedEvent(mev); |
1081 } | 1078 } |
1082 | 1079 |
1083 void EventHandler::invalidateClick() | 1080 void EventHandler::invalidateClick() |
1084 { | 1081 { |
1085 m_clickCount = 0; | 1082 m_clickCount = 0; |
1086 m_clickNode = nullptr; | 1083 m_clickNode = nullptr; |
1087 } | 1084 } |
1088 | 1085 |
1089 static ContainerNode* parentForClickEvent(const Node& node) | 1086 ContainerNode* EventHandler::parentForClickEvent(const Node& node) |
1090 { | 1087 { |
1091 // IE doesn't dispatch click events for mousedown/mouseup events across form | 1088 // IE doesn't dispatch click events for mousedown/mouseup events across form |
1092 // controls. | 1089 // controls. |
1093 if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent()) | 1090 if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent()) |
1094 return nullptr; | 1091 return nullptr; |
1095 | 1092 |
1096 return FlatTreeTraversal::parent(node); | 1093 return FlatTreeTraversal::parent(node); |
1097 } | 1094 } |
1098 | 1095 |
1099 WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve
nt& mouseEvent) | 1096 WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve
nt& mouseEvent) |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 || mouseEventType == EventTypeNames::mousemove | 1500 || mouseEventType == EventTypeNames::mousemove |
1504 || mouseEventType == EventTypeNames::mouseup); | 1501 || mouseEventType == EventTypeNames::mouseup); |
1505 | 1502 |
1506 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent
); | 1503 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent
); |
1507 | 1504 |
1508 return m_pointerEventManager.sendMousePointerEvent( | 1505 return m_pointerEventManager.sendMousePointerEvent( |
1509 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, nullptr, | 1506 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, nullptr, |
1510 lastNodeUnderMouse); | 1507 lastNodeUnderMouse); |
1511 } | 1508 } |
1512 | 1509 |
| 1510 void EventHandler::setClickNode(Node* node) |
| 1511 { |
| 1512 m_clickNode = node; |
| 1513 } |
| 1514 |
1513 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe
sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities) | 1515 WebInputEventResult EventHandler::handleMouseFocus(const MouseEventWithHitTestRe
sults& targetedEvent, InputDeviceCapabilities* sourceCapabilities) |
1514 { | 1516 { |
1515 // If clicking on a frame scrollbar, do not mess up with content focus. | 1517 // If clicking on a frame scrollbar, do not mess up with content focus. |
1516 if (targetedEvent.hitTestResult().scrollbar() && !m_frame->contentLayoutItem
().isNull()) { | 1518 if (targetedEvent.hitTestResult().scrollbar() && !m_frame->contentLayoutItem
().isNull()) { |
1517 if (targetedEvent.hitTestResult().scrollbar()->getScrollableArea() == m_
frame->contentLayoutItem().getScrollableArea()) | 1519 if (targetedEvent.hitTestResult().scrollbar()->getScrollableArea() == m_
frame->contentLayoutItem().getScrollableArea()) |
1518 return WebInputEventResult::NotHandled; | 1520 return WebInputEventResult::NotHandled; |
1519 } | 1521 } |
1520 | 1522 |
1521 // The layout needs to be up to date to determine if an element is focusable
. | 1523 // The layout needs to be up to date to determine if an element is focusable
. |
1522 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1524 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1640 if (node) { | 1642 if (node) { |
1641 WheelEvent* domEvent = WheelEvent::create(event, node->document().domWin
dow()); | 1643 WheelEvent* domEvent = WheelEvent::create(event, node->document().domWin
dow()); |
1642 DispatchEventResult domEventResult = node->dispatchEvent(domEvent); | 1644 DispatchEventResult domEventResult = node->dispatchEvent(domEvent); |
1643 if (domEventResult != DispatchEventResult::NotCanceled) | 1645 if (domEventResult != DispatchEventResult::NotCanceled) |
1644 return toWebInputEventResult(domEventResult); | 1646 return toWebInputEventResult(domEventResult); |
1645 } | 1647 } |
1646 | 1648 |
1647 return WebInputEventResult::NotHandled; | 1649 return WebInputEventResult::NotHandled; |
1648 } | 1650 } |
1649 | 1651 |
1650 WebInputEventResult EventHandler::handleGestureShowPress() | |
1651 { | |
1652 m_lastShowPressTimestamp = WTF::monotonicallyIncreasingTime(); | |
1653 | |
1654 FrameView* view = m_frame->view(); | |
1655 if (!view) | |
1656 return WebInputEventResult::NotHandled; | |
1657 if (ScrollAnimatorBase* scrollAnimator = view->existingScrollAnimator()) | |
1658 scrollAnimator->cancelAnimation(); | |
1659 const FrameView::ScrollableAreaSet* areas = view->scrollableAreas(); | |
1660 if (!areas) | |
1661 return WebInputEventResult::NotHandled; | |
1662 for (const ScrollableArea* scrollableArea : *areas) { | |
1663 ScrollAnimatorBase* animator = scrollableArea->existingScrollAnimator(); | |
1664 if (animator) | |
1665 animator->cancelAnimation(); | |
1666 } | |
1667 return WebInputEventResult::NotHandled; | |
1668 } | |
1669 | |
1670 WebInputEventResult EventHandler::handleGestureEvent(const PlatformGestureEvent&
gestureEvent) | 1652 WebInputEventResult EventHandler::handleGestureEvent(const PlatformGestureEvent&
gestureEvent) |
1671 { | 1653 { |
1672 // Propagation to inner frames is handled below this function. | 1654 // Propagation to inner frames is handled below this function. |
1673 ASSERT(m_frame == m_frame->localFrameRoot()); | 1655 ASSERT(m_frame == m_frame->localFrameRoot()); |
1674 | 1656 |
1675 // Scrolling-related gesture events invoke EventHandler recursively for each
frame down | 1657 // Scrolling-related gesture events invoke EventHandler recursively for each
frame down |
1676 // the chain, doing a single-frame hit-test per frame. This matches handleWh
eelEvent. | 1658 // the chain, doing a single-frame hit-test per frame. This matches handleWh
eelEvent. |
1677 // FIXME: Add a test that traverses this path, e.g. for devtools overlay. | 1659 // FIXME: Add a test that traverses this path, e.g. for devtools overlay. |
1678 if (gestureEvent.isScrollEvent()) | 1660 if (gestureEvent.isScrollEvent()) |
1679 return handleGestureScrollEvent(gestureEvent); | 1661 return handleGestureScrollEvent(gestureEvent); |
(...skipping 17 matching lines...) Expand all Loading... |
1697 | 1679 |
1698 // update mouseout/leave/over/enter events before jumping directly to the in
ner most frame | 1680 // update mouseout/leave/over/enter events before jumping directly to the in
ner most frame |
1699 if (targetedEvent.event().type() == PlatformEvent::GestureTap) | 1681 if (targetedEvent.event().type() == PlatformEvent::GestureTap) |
1700 updateGestureTargetNodeForMouseEvent(targetedEvent); | 1682 updateGestureTargetNodeForMouseEvent(targetedEvent); |
1701 | 1683 |
1702 // Route to the correct frame. | 1684 // Route to the correct frame. |
1703 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame()) | 1685 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame()) |
1704 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEven
t); | 1686 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEven
t); |
1705 | 1687 |
1706 // No hit test result, handle in root instance. Perhaps we should just retur
n false instead? | 1688 // No hit test result, handle in root instance. Perhaps we should just retur
n false instead? |
1707 return handleGestureEventInFrame(targetedEvent); | 1689 return m_gestureManager.handleGestureEventInFrame(targetedEvent); |
1708 } | 1690 } |
1709 | 1691 |
1710 WebInputEventResult EventHandler::handleGestureEventInFrame(const GestureEventWi
thHitTestResults& targetedEvent) | 1692 WebInputEventResult EventHandler::handleGestureEventInFrame(const GestureEventWi
thHitTestResults& targetedEvent) |
1711 { | 1693 { |
1712 ASSERT(!targetedEvent.event().isScrollEvent()); | 1694 return m_gestureManager.handleGestureEventInFrame(targetedEvent); |
1713 | |
1714 Node* eventTarget = targetedEvent.hitTestResult().innerNode(); | |
1715 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
1716 | |
1717 if (m_scrollManager.canHandleGestureEvent(targetedEvent)) | |
1718 return WebInputEventResult::HandledSuppressed; | |
1719 | |
1720 if (eventTarget) { | |
1721 GestureEvent* gestureDomEvent = GestureEvent::create(eventTarget->docume
nt().domWindow(), gestureEvent); | |
1722 if (gestureDomEvent) { | |
1723 DispatchEventResult gestureDomEventResult = eventTarget->dispatchEve
nt(gestureDomEvent); | |
1724 if (gestureDomEventResult != DispatchEventResult::NotCanceled) { | |
1725 ASSERT(gestureDomEventResult != DispatchEventResult::CanceledByE
ventHandler); | |
1726 return toWebInputEventResult(gestureDomEventResult); | |
1727 } | |
1728 } | |
1729 } | |
1730 | |
1731 switch (gestureEvent.type()) { | |
1732 case PlatformEvent::GestureTapDown: | |
1733 return handleGestureTapDown(targetedEvent); | |
1734 case PlatformEvent::GestureTap: | |
1735 return handleGestureTap(targetedEvent); | |
1736 case PlatformEvent::GestureShowPress: | |
1737 return handleGestureShowPress(); | |
1738 case PlatformEvent::GestureLongPress: | |
1739 return handleGestureLongPress(targetedEvent); | |
1740 case PlatformEvent::GestureLongTap: | |
1741 return handleGestureLongTap(targetedEvent); | |
1742 case PlatformEvent::GestureTwoFingerTap: | |
1743 return sendContextMenuEventForGesture(targetedEvent); | |
1744 case PlatformEvent::GesturePinchBegin: | |
1745 case PlatformEvent::GesturePinchEnd: | |
1746 case PlatformEvent::GesturePinchUpdate: | |
1747 case PlatformEvent::GestureTapDownCancel: | |
1748 case PlatformEvent::GestureTapUnconfirmed: | |
1749 break; | |
1750 default: | |
1751 ASSERT_NOT_REACHED(); | |
1752 } | |
1753 | |
1754 return WebInputEventResult::NotHandled; | |
1755 } | 1695 } |
1756 | 1696 |
1757 WebInputEventResult EventHandler::handleGestureScrollEvent(const PlatformGesture
Event& gestureEvent) | 1697 WebInputEventResult EventHandler::handleGestureScrollEvent(const PlatformGesture
Event& gestureEvent) |
1758 { | 1698 { |
1759 TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); | 1699 TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); |
1760 | 1700 |
1761 return m_scrollManager.handleGestureScrollEvent(gestureEvent); | 1701 return m_scrollManager.handleGestureScrollEvent(gestureEvent); |
1762 } | 1702 } |
1763 | 1703 |
1764 WebInputEventResult EventHandler::handleGestureTapDown(const GestureEventWithHit
TestResults& targetedEvent) | |
1765 { | |
1766 m_suppressMouseEventsFromGestures = | |
1767 m_pointerEventManager.primaryPointerdownCanceled(targetedEvent.event().u
niqueTouchEventId()); | |
1768 return WebInputEventResult::NotHandled; | |
1769 } | |
1770 | |
1771 WebInputEventResult EventHandler::handleGestureTap(const GestureEventWithHitTest
Results& targetedEvent) | |
1772 { | |
1773 FrameView* frameView(m_frame->view()); | |
1774 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
1775 HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestur
eEvent.type()); | |
1776 uint64_t preDispatchDomTreeVersion = m_frame->document()->domTreeVersion(); | |
1777 uint64_t preDispatchStyleVersion = m_frame->document()->styleVersion(); | |
1778 | |
1779 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); | |
1780 | |
1781 HitTestResult currentHitTest = targetedEvent.hitTestResult(); | |
1782 | |
1783 // We use the adjusted position so the application isn't surprised to see a
event with | |
1784 // co-ordinates outside the target's bounds. | |
1785 IntPoint adjustedPoint = frameView->rootFrameToContents(gestureEvent.positio
n()); | |
1786 | |
1787 const unsigned modifiers = gestureEvent.getModifiers(); | |
1788 | |
1789 if (!m_suppressMouseEventsFromGestures) { | |
1790 PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.g
lobalPosition(), | |
1791 NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0, | |
1792 static_cast<PlatformEvent::Modifiers>(modifiers), | |
1793 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerP
roperties::PointerType::Mouse); | |
1794 dispatchMouseEvent(EventTypeNames::mousemove, currentHitTest.innerNode()
, 0, fakeMouseMove); | |
1795 } | |
1796 | |
1797 // Do a new hit-test in case the mousemove event changed the DOM. | |
1798 // Note that if the original hit test wasn't over an element (eg. was over a
scrollbar) we | |
1799 // don't want to re-hit-test because it may be in the wrong frame (and there
's no way the page | |
1800 // could have seen the event anyway). | |
1801 // Also note that the position of the frame may have changed, so we need to
recompute the content | |
1802 // co-ordinates (updating layout/style as hitTestResultAtPoint normally woul
d). | |
1803 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.
com/398920 | |
1804 if (currentHitTest.innerNode()) { | |
1805 LocalFrame* mainFrame = m_frame->localFrameRoot(); | |
1806 if (mainFrame && mainFrame->view()) | |
1807 mainFrame->view()->updateLifecycleToCompositingCleanPlusScrolling(); | |
1808 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); | |
1809 currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType); | |
1810 } | |
1811 m_clickNode = currentHitTest.innerNode(); | |
1812 | |
1813 // Capture data for showUnhandledTapUIIfNeeded. | |
1814 Node* tappedNode = m_clickNode; | |
1815 IntPoint tappedPosition = gestureEvent.position(); | |
1816 | |
1817 if (m_clickNode && m_clickNode->isTextNode()) | |
1818 m_clickNode = FlatTreeTraversal::parent(*m_clickNode); | |
1819 | |
1820 PlatformMouseEvent fakeMouseDown(gestureEvent.position(), gestureEvent.globa
lPosition(), | |
1821 LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(), | |
1822 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::LeftBut
tonDown), | |
1823 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerPrope
rties::PointerType::Mouse); | |
1824 | |
1825 // TODO(mustaq): We suppress MEs plus all it's side effects. What would that | |
1826 // mean for for TEs? What's the right balance here? crbug.com/617255 | |
1827 WebInputEventResult mouseDownEventResult = WebInputEventResult::HandledSuppr
essed; | |
1828 if (!m_suppressMouseEventsFromGestures) { | |
1829 mouseDownEventResult = dispatchMouseEvent(EventTypeNames::mousedown, cur
rentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseDown); | |
1830 selectionController().initializeSelectionState(); | |
1831 if (mouseDownEventResult == WebInputEventResult::NotHandled) | |
1832 mouseDownEventResult = handleMouseFocus(MouseEventWithHitTestResults
(fakeMouseDown, currentHitTest), InputDeviceCapabilities::firesTouchEventsSource
Capabilities()); | |
1833 if (mouseDownEventResult == WebInputEventResult::NotHandled) | |
1834 mouseDownEventResult = handleMousePressEvent(MouseEventWithHitTestRe
sults(fakeMouseDown, currentHitTest)); | |
1835 } | |
1836 | |
1837 if (currentHitTest.innerNode()) { | |
1838 ASSERT(gestureEvent.type() == PlatformEvent::GestureTap); | |
1839 HitTestResult result = currentHitTest; | |
1840 result.setToShadowHostIfInUserAgentShadowRoot(); | |
1841 m_frame->chromeClient().onMouseDown(result.innerNode()); | |
1842 } | |
1843 | |
1844 // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.
com/398920 | |
1845 if (currentHitTest.innerNode()) { | |
1846 LocalFrame* mainFrame = m_frame->localFrameRoot(); | |
1847 if (mainFrame && mainFrame->view()) | |
1848 mainFrame->view()->updateAllLifecyclePhases(); | |
1849 adjustedPoint = frameView->rootFrameToContents(gestureEvent.position()); | |
1850 currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType); | |
1851 } | |
1852 | |
1853 PlatformMouseEvent fakeMouseUp(gestureEvent.position(), gestureEvent.globalP
osition(), | |
1854 LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(), | |
1855 static_cast<PlatformEvent::Modifiers>(modifiers), | |
1856 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerPrope
rties::PointerType::Mouse); | |
1857 WebInputEventResult mouseUpEventResult = m_suppressMouseEventsFromGestures | |
1858 ? WebInputEventResult::HandledSuppressed | |
1859 : dispatchMouseEvent(EventTypeNames::mouseup, currentHitTest.innerNode()
, gestureEvent.tapCount(), fakeMouseUp); | |
1860 | |
1861 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; | |
1862 if (m_clickNode) { | |
1863 if (currentHitTest.innerNode()) { | |
1864 // Updates distribution because a mouseup (or mousedown) event liste
ner can make the | |
1865 // tree dirty at dispatchMouseEvent() invocation above. | |
1866 // Unless distribution is updated, commonAncestor would hit ASSERT. | |
1867 // Both m_clickNode and currentHitTest.innerNode()) don't need to be
updated | |
1868 // because commonAncestor() will exit early if their documents are d
ifferent. | |
1869 m_clickNode->updateDistribution(); | |
1870 Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor(*
m_clickNode, parentForClickEvent); | |
1871 clickEventResult = dispatchMouseEvent(EventTypeNames::click, clickTa
rgetNode, gestureEvent.tapCount(), fakeMouseUp); | |
1872 } | |
1873 m_clickNode = nullptr; | |
1874 } | |
1875 | |
1876 if (mouseUpEventResult == WebInputEventResult::NotHandled) | |
1877 mouseUpEventResult = handleMouseReleaseEvent(MouseEventWithHitTestResult
s(fakeMouseUp, currentHitTest)); | |
1878 clearDragHeuristicState(); | |
1879 | |
1880 WebInputEventResult eventResult = mergeEventResult(mergeEventResult(mouseDow
nEventResult, mouseUpEventResult), clickEventResult); | |
1881 if (eventResult == WebInputEventResult::NotHandled && tappedNode && m_frame-
>page()) { | |
1882 bool domTreeChanged = preDispatchDomTreeVersion != m_frame->document()->
domTreeVersion(); | |
1883 bool styleChanged = preDispatchStyleVersion != m_frame->document()->styl
eVersion(); | |
1884 | |
1885 IntPoint tappedPositionInViewport = frameHost()->visualViewport().rootFr
ameToViewport(tappedPosition); | |
1886 m_frame->chromeClient().showUnhandledTapUIIfNeeded(tappedPositionInViewp
ort, tappedNode, domTreeChanged || styleChanged); | |
1887 } | |
1888 return eventResult; | |
1889 } | |
1890 | |
1891 WebInputEventResult EventHandler::handleGestureLongPress(const GestureEventWithH
itTestResults& targetedEvent) | |
1892 { | |
1893 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
1894 IntPoint adjustedPoint = gestureEvent.position(); | |
1895 | |
1896 unsigned modifiers = gestureEvent.getModifiers(); | |
1897 | |
1898 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests
here (re-using the | |
1899 // supplied HitTestResult), but that will require some overhaul of the touch
drag-and-drop code | |
1900 // and LongPress is such a special scenario that it's unlikely to matter muc
h in practice. | |
1901 | |
1902 m_longTapShouldInvokeContextMenu = false; | |
1903 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_
frame->view()) { | |
1904 // TODO(mustaq): Suppressing long-tap MouseEvents could break | |
1905 // drag-drop. Will do separately because of the risk. crbug.com/606938. | |
1906 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi
tion(), LeftButton, PlatformEvent::MousePressed, 1, | |
1907 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef
tButtonDown), | |
1908 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W
ebPointerProperties::PointerType::Mouse); | |
1909 m_mouseDown = mouseDownEvent; | |
1910 | |
1911 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi
tion(), LeftButton, PlatformEvent::MouseMoved, 1, | |
1912 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef
tButtonDown), | |
1913 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W
ebPointerProperties::PointerType::Mouse); | |
1914 HitTestRequest request(HitTestRequest::ReadOnly); | |
1915 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE
vent); | |
1916 m_mouseDownMayStartDrag = true; | |
1917 dragState().m_dragSrc = nullptr; | |
1918 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos
ition()); | |
1919 if (handleDrag(mev, DragInitiator::Touch)) { | |
1920 m_longTapShouldInvokeContextMenu = true; | |
1921 return WebInputEventResult::HandledSystem; | |
1922 } | |
1923 } | |
1924 | |
1925 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(gestureEvent.po
sition()); | |
1926 HitTestResult result = hitTestResultAtPoint(hitTestPoint); | |
1927 if (selectionController().handleGestureLongPress(gestureEvent, result)) { | |
1928 focusDocumentView(); | |
1929 return WebInputEventResult::HandledSystem; | |
1930 } | |
1931 | |
1932 return sendContextMenuEventForGesture(targetedEvent); | |
1933 } | |
1934 | |
1935 WebInputEventResult EventHandler::handleGestureLongTap(const GestureEventWithHit
TestResults& targetedEvent) | |
1936 { | |
1937 #if !OS(ANDROID) | |
1938 if (m_longTapShouldInvokeContextMenu) { | |
1939 m_longTapShouldInvokeContextMenu = false; | |
1940 return sendContextMenuEventForGesture(targetedEvent); | |
1941 } | |
1942 #endif | |
1943 return WebInputEventResult::NotHandled; | |
1944 } | |
1945 | |
1946 WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEv
ent& gestureEvent) | 1704 WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEv
ent& gestureEvent) |
1947 { | 1705 { |
1948 return m_scrollManager.handleGestureScrollEnd(gestureEvent); | 1706 return m_scrollManager.handleGestureScrollEnd(gestureEvent); |
1949 } | 1707 } |
1950 | 1708 |
1951 bool EventHandler::isScrollbarHandlingGestures() const | 1709 bool EventHandler::isScrollbarHandlingGestures() const |
1952 { | 1710 { |
1953 return m_scrollManager.isScrollbarHandlingGestures(); | 1711 return m_scrollManager.isScrollbarHandlingGestures(); |
1954 } | 1712 } |
1955 | 1713 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 } | 1899 } |
2142 | 1900 |
2143 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe
stureEvent& gestureEvent, bool readOnly) | 1901 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe
stureEvent& gestureEvent, bool readOnly) |
2144 { | 1902 { |
2145 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); | 1903 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); |
2146 | 1904 |
2147 ASSERT(m_frame == m_frame->localFrameRoot()); | 1905 ASSERT(m_frame == m_frame->localFrameRoot()); |
2148 // Scrolling events get hit tested per frame (like wheel events do). | 1906 // Scrolling events get hit tested per frame (like wheel events do). |
2149 ASSERT(!gestureEvent.isScrollEvent()); | 1907 ASSERT(!gestureEvent.isScrollEvent()); |
2150 | 1908 |
2151 HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestur
eEvent.type()); | 1909 HitTestRequest::HitTestRequestType hitType = m_gestureManager.getHitTypeForG
estureType(gestureEvent.type()); |
2152 double activeInterval = 0; | 1910 double activeInterval = 0; |
2153 bool shouldKeepActiveForMinInterval = false; | 1911 bool shouldKeepActiveForMinInterval = false; |
2154 if (readOnly) { | 1912 if (readOnly) { |
2155 hitType |= HitTestRequest::ReadOnly; | 1913 hitType |= HitTestRequest::ReadOnly; |
2156 } else if (gestureEvent.type() == PlatformEvent::GestureTap) { | 1914 } else if (gestureEvent.type() == PlatformEvent::GestureTap) { |
2157 // If the Tap is received very shortly after ShowPress, we want to | 1915 // If the Tap is received very shortly after ShowPress, we want to |
2158 // delay clearing of the active state so that it's visible to the user | 1916 // delay clearing of the active state so that it's visible to the user |
2159 // for at least a couple of frames. | 1917 // for at least a couple of frames. |
2160 activeInterval = WTF::monotonicallyIncreasingTime() - m_lastShowPressTim
estamp; | 1918 activeInterval = WTF::monotonicallyIncreasingTime() - m_gestureManager.g
etLastShowPressTimestamp(); |
2161 shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInter
val < minimumActiveInterval; | 1919 shouldKeepActiveForMinInterval = m_gestureManager.getLastShowPressTimest
amp() && activeInterval < minimumActiveInterval; |
2162 if (shouldKeepActiveForMinInterval) | 1920 if (shouldKeepActiveForMinInterval) |
2163 hitType |= HitTestRequest::ReadOnly; | 1921 hitType |= HitTestRequest::ReadOnly; |
2164 } | 1922 } |
2165 | 1923 |
2166 GestureEventWithHitTestResults eventWithHitTestResults = hitTestResultForGes
tureEvent(gestureEvent, hitType); | 1924 GestureEventWithHitTestResults eventWithHitTestResults = hitTestResultForGes
tureEvent(gestureEvent, hitType); |
2167 // Now apply hover/active state to the final target. | 1925 // Now apply hover/active state to the final target. |
2168 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); | 1926 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); |
2169 if (!request.readOnly()) | 1927 if (!request.readOnly()) |
2170 updateGestureHoverActiveState(request, eventWithHitTestResults.hitTestRe
sult().innerElement()); | 1928 updateGestureHoverActiveState(request, eventWithHitTestResults.hitTestRe
sult().innerElement()); |
2171 | 1929 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 hitTestResult = hitTestResultInFrame(hitFrame, hitFrame->view()->rootFra
meToContents(adjustedEvent.position()), (hitType | HitTestRequest::ReadOnly) & ~
HitTestRequest::ListBased); | 1967 hitTestResult = hitTestResultInFrame(hitFrame, hitFrame->view()->rootFra
meToContents(adjustedEvent.position()), (hitType | HitTestRequest::ReadOnly) & ~
HitTestRequest::ListBased); |
2210 } | 1968 } |
2211 | 1969 |
2212 // If we did a rect-based hit test it must be resolved to the best single no
de by now to | 1970 // If we did a rect-based hit test it must be resolved to the best single no
de by now to |
2213 // ensure consumers don't accidentally use one of the other candidates. | 1971 // ensure consumers don't accidentally use one of the other candidates. |
2214 ASSERT(!hitTestResult.isRectBasedTest()); | 1972 ASSERT(!hitTestResult.isRectBasedTest()); |
2215 | 1973 |
2216 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult); | 1974 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult); |
2217 } | 1975 } |
2218 | 1976 |
2219 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(Platfo
rmEvent::EventType type) | |
2220 { | |
2221 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; | |
2222 switch (type) { | |
2223 case PlatformEvent::GestureShowPress: | |
2224 case PlatformEvent::GestureTapUnconfirmed: | |
2225 return hitType | HitTestRequest::Active; | |
2226 case PlatformEvent::GestureTapDownCancel: | |
2227 // A TapDownCancel received when no element is active shouldn't really b
e changing hover state. | |
2228 if (!m_frame->document()->activeHoverElement()) | |
2229 hitType |= HitTestRequest::ReadOnly; | |
2230 return hitType | HitTestRequest::Release; | |
2231 case PlatformEvent::GestureTap: | |
2232 return hitType | HitTestRequest::Release; | |
2233 case PlatformEvent::GestureTapDown: | |
2234 case PlatformEvent::GestureLongPress: | |
2235 case PlatformEvent::GestureLongTap: | |
2236 case PlatformEvent::GestureTwoFingerTap: | |
2237 // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state? | |
2238 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly; | |
2239 default: | |
2240 ASSERT_NOT_REACHED(); | |
2241 return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly; | |
2242 } | |
2243 } | |
2244 | |
2245 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT
estResult* hitTestResult) | 1977 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitT
estResult* hitTestResult) |
2246 { | 1978 { |
2247 if (!shouldApplyTouchAdjustment(*gestureEvent)) | 1979 if (!shouldApplyTouchAdjustment(*gestureEvent)) |
2248 return; | 1980 return; |
2249 | 1981 |
2250 Node* adjustedNode = nullptr; | 1982 Node* adjustedNode = nullptr; |
2251 IntPoint adjustedPoint = gestureEvent->position(); | 1983 IntPoint adjustedPoint = gestureEvent->position(); |
2252 bool adjusted = false; | 1984 bool adjusted = false; |
2253 switch (gestureEvent->type()) { | 1985 switch (gestureEvent->type()) { |
2254 case PlatformEvent::GestureTap: | 1986 case PlatformEvent::GestureTap: |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 if (dragState().m_dragSrc && !dragState().m_dragSrc->inShadowIncludingDocume
nt()) | 2341 if (dragState().m_dragSrc && !dragState().m_dragSrc->inShadowIncludingDocume
nt()) |
2610 dragState().m_dragSrc = rootEditableElement; | 2342 dragState().m_dragSrc = rootEditableElement; |
2611 } | 2343 } |
2612 | 2344 |
2613 // returns if we should continue "default processing", i.e., whether eventhandle
r canceled | 2345 // returns if we should continue "default processing", i.e., whether eventhandle
r canceled |
2614 WebInputEventResult EventHandler::dispatchDragSrcEvent(const AtomicString& event
Type, const PlatformMouseEvent& event) | 2346 WebInputEventResult EventHandler::dispatchDragSrcEvent(const AtomicString& event
Type, const PlatformMouseEvent& event) |
2615 { | 2347 { |
2616 return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, drag
State().m_dragDataTransfer.get()); | 2348 return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, drag
State().m_dragDataTransfer.get()); |
2617 } | 2349 } |
2618 | 2350 |
| 2351 bool EventHandler::handleDragDropIfPossible(const GestureEventWithHitTestResults
& targetedEvent) |
| 2352 { |
| 2353 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_
frame->view()) { |
| 2354 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); |
| 2355 IntPoint adjustedPoint = gestureEvent.position(); |
| 2356 unsigned modifiers = gestureEvent.getModifiers(); |
| 2357 |
| 2358 // TODO(mustaq): Suppressing long-tap MouseEvents could break |
| 2359 // drag-drop. Will do separately because of the risk. crbug.com/606938. |
| 2360 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi
tion(), LeftButton, PlatformEvent::MousePressed, 1, |
| 2361 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef
tButtonDown), |
| 2362 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W
ebPointerProperties::PointerType::Mouse); |
| 2363 m_mouseDown = mouseDownEvent; |
| 2364 |
| 2365 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi
tion(), LeftButton, PlatformEvent::MouseMoved, 1, |
| 2366 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef
tButtonDown), |
| 2367 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W
ebPointerProperties::PointerType::Mouse); |
| 2368 HitTestRequest request(HitTestRequest::ReadOnly); |
| 2369 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE
vent); |
| 2370 m_mouseDownMayStartDrag = true; |
| 2371 dragState().m_dragSrc = nullptr; |
| 2372 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos
ition()); |
| 2373 return handleDrag(mev, DragInitiator::Touch); |
| 2374 } |
| 2375 return false; |
| 2376 } |
| 2377 |
2619 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, DragIni
tiator initiator) | 2378 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, DragIni
tiator initiator) |
2620 { | 2379 { |
2621 ASSERT(event.event().type() == PlatformEvent::MouseMoved); | 2380 ASSERT(event.event().type() == PlatformEvent::MouseMoved); |
2622 // Callers must protect the reference to FrameView, since this function may
dispatch DOM | 2381 // Callers must protect the reference to FrameView, since this function may
dispatch DOM |
2623 // events, causing page/FrameView to go away. | 2382 // events, causing page/FrameView to go away. |
2624 ASSERT(m_frame); | 2383 ASSERT(m_frame); |
2625 ASSERT(m_frame->view()); | 2384 ASSERT(m_frame->view()); |
2626 if (!m_frame->page()) | 2385 if (!m_frame->page()) |
2627 return false; | 2386 return false; |
2628 | 2387 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2852 | 2611 |
2853 FrameHost* EventHandler::frameHost() const | 2612 FrameHost* EventHandler::frameHost() const |
2854 { | 2613 { |
2855 if (!m_frame->page()) | 2614 if (!m_frame->page()) |
2856 return nullptr; | 2615 return nullptr; |
2857 | 2616 |
2858 return &m_frame->page()->frameHost(); | 2617 return &m_frame->page()->frameHost(); |
2859 } | 2618 } |
2860 | 2619 |
2861 } // namespace blink | 2620 } // namespace blink |
OLD | NEW |