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 |
| 3 * reserved. |
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 5 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
5 * | 6 * |
6 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
8 * are met: | 9 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 11 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 12 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 13 * notice, this list of conditions and the following disclaimer in the |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 #include "wtf/Assertions.h" | 101 #include "wtf/Assertions.h" |
101 #include "wtf/CurrentTime.h" | 102 #include "wtf/CurrentTime.h" |
102 #include "wtf/PtrUtil.h" | 103 #include "wtf/PtrUtil.h" |
103 #include "wtf/StdLibExtras.h" | 104 #include "wtf/StdLibExtras.h" |
104 #include <memory> | 105 #include <memory> |
105 | 106 |
106 namespace blink { | 107 namespace blink { |
107 | 108 |
108 namespace { | 109 namespace { |
109 | 110 |
110 // Refetch the event target node if it is removed or currently is the shadow nod
e inside an <input> element. | 111 // Refetch the event target node if it is removed or currently is the shadow |
111 // If a mouse event handler changes the input element type to one that has a wid
get associated, | 112 // node inside an <input> element. If a mouse event handler changes the input |
112 // we'd like to EventHandler::handleMousePressEvent to pass the event to the wid
get and thus the | 113 // element type to one that has a widget associated, we'd like to |
113 // event target node can't still be the shadow node. | 114 // EventHandler::handleMousePressEvent to pass the event to the widget and thus |
| 115 // the event target node can't still be the shadow node. |
114 bool shouldRefetchEventTarget(const MouseEventWithHitTestResults& mev) { | 116 bool shouldRefetchEventTarget(const MouseEventWithHitTestResults& mev) { |
115 Node* targetNode = mev.innerNode(); | 117 Node* targetNode = mev.innerNode(); |
116 if (!targetNode || !targetNode->parentNode()) | 118 if (!targetNode || !targetNode->parentNode()) |
117 return true; | 119 return true; |
118 return targetNode->isShadowRoot() && | 120 return targetNode->isShadowRoot() && |
119 isHTMLInputElement(toShadowRoot(targetNode)->host()); | 121 isHTMLInputElement(toShadowRoot(targetNode)->host()); |
120 } | 122 } |
121 | 123 |
122 } // namespace | 124 } // namespace |
123 | 125 |
124 using namespace HTMLNames; | 126 using namespace HTMLNames; |
125 | 127 |
126 // The amount of time to wait for a cursor update on style and layout changes | 128 // The amount of time to wait for a cursor update on style and layout changes |
127 // Set to 50Hz, no need to be faster than common screen refresh rate | 129 // Set to 50Hz, no need to be faster than common screen refresh rate |
128 static const double cursorUpdateInterval = 0.02; | 130 static const double cursorUpdateInterval = 0.02; |
129 | 131 |
130 static const int maximumCursorSize = 128; | 132 static const int maximumCursorSize = 128; |
131 | 133 |
132 // It's pretty unlikely that a scale of less than one would ever be used. But al
l we really | 134 // It's pretty unlikely that a scale of less than one would ever be used. But |
133 // need to ensure here is that the scale isn't so small that integer overflow ca
n occur when | 135 // all we really need to ensure here is that the scale isn't so small that |
134 // dividing cursor sizes (limited above) by the scale. | 136 // integer overflow can occur when dividing cursor sizes (limited above) by the |
| 137 // scale. |
135 static const double minimumCursorScale = 0.001; | 138 static const double minimumCursorScale = 0.001; |
136 | 139 |
137 // The minimum amount of time an element stays active after a ShowPress | 140 // The minimum amount of time an element stays active after a ShowPress |
138 // This is roughly 9 frames, which should be long enough to be noticeable. | 141 // This is roughly 9 frames, which should be long enough to be noticeable. |
139 static const double minimumActiveInterval = 0.15; | 142 static const double minimumActiveInterval = 0.15; |
140 | 143 |
141 enum NoCursorChangeType { NoCursorChange }; | 144 enum NoCursorChangeType { NoCursorChange }; |
142 | 145 |
143 class OptionalCursor { | 146 class OptionalCursor { |
144 public: | 147 public: |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 FrameView* mainView = mainFrame->view(); | 251 FrameView* mainView = mainFrame->view(); |
249 if (frameView && mainView) { | 252 if (frameView && mainView) { |
250 IntPoint mainFramePoint = mainView->rootFrameToContents( | 253 IntPoint mainFramePoint = mainView->rootFrameToContents( |
251 frameView->contentsToRootFrame(roundedIntPoint(point))); | 254 frameView->contentsToRootFrame(roundedIntPoint(point))); |
252 return mainFrame->eventHandler().hitTestResultAtPoint(mainFramePoint, | 255 return mainFrame->eventHandler().hitTestResultAtPoint(mainFramePoint, |
253 hitType, padding); | 256 hitType, padding); |
254 } | 257 } |
255 } | 258 } |
256 } | 259 } |
257 | 260 |
258 // hitTestResultAtPoint is specifically used to hitTest into all frames, thus
it always allows child frame content. | 261 // hitTestResultAtPoint is specifically used to hitTest into all frames, thus |
| 262 // it always allows child frame content. |
259 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); | 263 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); |
260 HitTestResult result(request, point, padding.height().toUnsigned(), | 264 HitTestResult result(request, point, padding.height().toUnsigned(), |
261 padding.width().toUnsigned(), | 265 padding.width().toUnsigned(), |
262 padding.height().toUnsigned(), | 266 padding.height().toUnsigned(), |
263 padding.width().toUnsigned()); | 267 padding.width().toUnsigned()); |
264 | 268 |
265 // LayoutView::hitTest causes a layout, and we don't want to hit that until th
e first | 269 // LayoutView::hitTest causes a layout, and we don't want to hit that until |
266 // layout because until then, there is nothing shown on the screen - the user
can't | 270 // the first layout because until then, there is nothing shown on the screen - |
267 // have intentionally clicked on something belonging to this page. Furthermore
, | 271 // the user can't have intentionally clicked on something belonging to this |
268 // mousemove events before the first layout should not lead to a premature lay
out() | 272 // page. Furthermore, mousemove events before the first layout should not |
269 // happening, which could show a flash of white. | 273 // lead to a premature layout() happening, which could show a flash of white. |
270 // See also the similar code in Document::performMouseEventHitTest. | 274 // See also the similar code in Document::performMouseEventHitTest. |
271 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || | 275 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || |
272 !m_frame->view()->didFirstLayout()) | 276 !m_frame->view()->didFirstLayout()) |
273 return result; | 277 return result; |
274 | 278 |
275 m_frame->contentLayoutItem().hitTest(result); | 279 m_frame->contentLayoutItem().hitTest(result); |
276 if (!request.readOnly()) | 280 if (!request.readOnly()) |
277 m_frame->document()->updateHoverActiveState(request, result.innerElement()); | 281 m_frame->document()->updateHoverActiveState(request, result.innerElement()); |
278 | 282 |
279 return result; | 283 return result; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 void EventHandler::cursorUpdateTimerFired(TimerBase*) { | 344 void EventHandler::cursorUpdateTimerFired(TimerBase*) { |
341 ASSERT(m_frame); | 345 ASSERT(m_frame); |
342 ASSERT(m_frame->document()); | 346 ASSERT(m_frame->document()); |
343 | 347 |
344 updateCursor(); | 348 updateCursor(); |
345 } | 349 } |
346 | 350 |
347 void EventHandler::updateCursor() { | 351 void EventHandler::updateCursor() { |
348 TRACE_EVENT0("input", "EventHandler::updateCursor"); | 352 TRACE_EVENT0("input", "EventHandler::updateCursor"); |
349 | 353 |
350 // We must do a cross-frame hit test because the frame that triggered the curs
or | 354 // We must do a cross-frame hit test because the frame that triggered the |
351 // update could be occluded by a different frame. | 355 // cursor update could be occluded by a different frame. |
352 ASSERT(m_frame == m_frame->localFrameRoot()); | 356 ASSERT(m_frame == m_frame->localFrameRoot()); |
353 | 357 |
354 if (m_mouseEventManager->isMousePositionUnknown()) | 358 if (m_mouseEventManager->isMousePositionUnknown()) |
355 return; | 359 return; |
356 | 360 |
357 FrameView* view = m_frame->view(); | 361 FrameView* view = m_frame->view(); |
358 if (!view || !view->shouldSetCursor()) | 362 if (!view || !view->shouldSetCursor()) |
359 return; | 363 return; |
360 | 364 |
361 LayoutViewItem layoutViewItem = view->layoutViewItem(); | 365 LayoutViewItem layoutViewItem = view->layoutViewItem(); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 bool inResizer = false; | 538 bool inResizer = false; |
535 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; | 539 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; |
536 if (layoutObject && m_frame->view()) { | 540 if (layoutObject && m_frame->view()) { |
537 PaintLayer* layer = layoutObject->enclosingLayer(); | 541 PaintLayer* layer = layoutObject->enclosingLayer(); |
538 inResizer = layer->getScrollableArea() && | 542 inResizer = layer->getScrollableArea() && |
539 layer->getScrollableArea()->isPointInResizeControl( | 543 layer->getScrollableArea()->isPointInResizeControl( |
540 result.roundedPointInMainFrame(), ResizerForPointer); | 544 result.roundedPointInMainFrame(), ResizerForPointer); |
541 } | 545 } |
542 | 546 |
543 // During selection, use an I-beam no matter what we're over. | 547 // During selection, use an I-beam no matter what we're over. |
544 // If a drag may be starting or we're capturing mouse events for a particular
node, don't treat this as a selection. | 548 // If a drag may be starting or we're capturing mouse events for a particular |
| 549 // node, don't treat this as a selection. |
545 if (m_mouseEventManager->mousePressed() && | 550 if (m_mouseEventManager->mousePressed() && |
546 selectionController().mouseDownMayStartSelect() && | 551 selectionController().mouseDownMayStartSelect() && |
547 !m_mouseEventManager->mouseDownMayStartDrag() && | 552 !m_mouseEventManager->mouseDownMayStartDrag() && |
548 !m_frame->selection().isNone() && !m_capturingMouseEventsNode) { | 553 !m_frame->selection().isNone() && !m_capturingMouseEventsNode) { |
549 return iBeam; | 554 return iBeam; |
550 } | 555 } |
551 | 556 |
552 if ((editable || | 557 if ((editable || |
553 (layoutObject && layoutObject->isText() && node->canStartSelection())) && | 558 (layoutObject && layoutObject->isText() && node->canStartSelection())) && |
554 !inResizer && !result.scrollbar()) | 559 !inResizer && !result.scrollbar()) |
(...skipping 17 matching lines...) Expand all Loading... |
572 UserGestureIndicator::currentToken(); | 577 UserGestureIndicator::currentToken(); |
573 | 578 |
574 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 579 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
575 m_capturingMouseEventsNode = nullptr; | 580 m_capturingMouseEventsNode = nullptr; |
576 m_mouseEventManager->handleMousePressEventUpdateStates(mouseEvent); | 581 m_mouseEventManager->handleMousePressEventUpdateStates(mouseEvent); |
577 selectionController().setMouseDownMayStartSelect(false); | 582 selectionController().setMouseDownMayStartSelect(false); |
578 if (!m_frame->view()) | 583 if (!m_frame->view()) |
579 return WebInputEventResult::NotHandled; | 584 return WebInputEventResult::NotHandled; |
580 | 585 |
581 HitTestRequest request(HitTestRequest::Active); | 586 HitTestRequest request(HitTestRequest::Active); |
582 // Save the document point we generate in case the window coordinate is invali
dated by what happens | 587 // Save the document point we generate in case the window coordinate is |
583 // when we dispatch the event. | 588 // invalidated by what happens when we dispatch the event. |
584 LayoutPoint documentPoint = | 589 LayoutPoint documentPoint = |
585 m_frame->view()->rootFrameToContents(mouseEvent.position()); | 590 m_frame->view()->rootFrameToContents(mouseEvent.position()); |
586 MouseEventWithHitTestResults mev = | 591 MouseEventWithHitTestResults mev = |
587 m_frame->document()->performMouseEventHitTest(request, documentPoint, | 592 m_frame->document()->performMouseEventHitTest(request, documentPoint, |
588 mouseEvent); | 593 mouseEvent); |
589 | 594 |
590 if (!mev.innerNode()) { | 595 if (!mev.innerNode()) { |
591 m_mouseEventManager->invalidateClick(); | 596 m_mouseEventManager->invalidateClick(); |
592 return WebInputEventResult::NotHandled; | 597 return WebInputEventResult::NotHandled; |
593 } | 598 } |
594 | 599 |
595 m_mouseEventManager->setMousePressNode(mev.innerNode()); | 600 m_mouseEventManager->setMousePressNode(mev.innerNode()); |
596 m_frame->document()->setSequentialFocusNavigationStartingPoint( | 601 m_frame->document()->setSequentialFocusNavigationStartingPoint( |
597 mev.innerNode()); | 602 mev.innerNode()); |
598 | 603 |
599 LocalFrame* subframe = subframeForHitTestResult(mev); | 604 LocalFrame* subframe = subframeForHitTestResult(mev); |
600 if (subframe) { | 605 if (subframe) { |
601 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe); | 606 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe); |
602 // Start capturing future events for this frame. We only do this if we didn
't clear | 607 // Start capturing future events for this frame. We only do this if we |
603 // the m_mousePressed flag, which may happen if an AppKit widget entered a m
odal event loop. | 608 // didn't clear the m_mousePressed flag, which may happen if an AppKit |
604 // The capturing should be done only when the result indicates it | 609 // widget entered a modal event loop. The capturing should be done only |
605 // has been handled. See crbug.com/269917 | 610 // when the result indicates it has been handled. See crbug.com/269917 |
606 m_mouseEventManager->setCapturesDragging( | 611 m_mouseEventManager->setCapturesDragging( |
607 subframe->eventHandler().m_mouseEventManager->capturesDragging()); | 612 subframe->eventHandler().m_mouseEventManager->capturesDragging()); |
608 if (m_mouseEventManager->mousePressed() && | 613 if (m_mouseEventManager->mousePressed() && |
609 m_mouseEventManager->capturesDragging()) { | 614 m_mouseEventManager->capturesDragging()) { |
610 m_capturingMouseEventsNode = mev.innerNode(); | 615 m_capturingMouseEventsNode = mev.innerNode(); |
611 m_eventHandlerWillResetCapturingMouseEventsNode = true; | 616 m_eventHandlerWillResetCapturingMouseEventsNode = true; |
612 } | 617 } |
613 m_mouseEventManager->invalidateClick(); | 618 m_mouseEventManager->invalidateClick(); |
614 return result; | 619 return result; |
615 } | 620 } |
616 | 621 |
617 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { | 622 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { |
618 // We store whether middle click autoscroll is in progress before calling st
opAutoscroll() | 623 // We store whether middle click autoscroll is in progress before calling |
619 // because it will set m_autoscrollType to NoAutoscroll on return. | 624 // stopAutoscroll() because it will set m_autoscrollType to NoAutoscroll on |
| 625 // return. |
620 bool isMiddleClickAutoscrollInProgress = | 626 bool isMiddleClickAutoscrollInProgress = |
621 m_scrollManager->middleClickAutoscrollInProgress(); | 627 m_scrollManager->middleClickAutoscrollInProgress(); |
622 m_scrollManager->stopAutoscroll(); | 628 m_scrollManager->stopAutoscroll(); |
623 if (isMiddleClickAutoscrollInProgress) { | 629 if (isMiddleClickAutoscrollInProgress) { |
624 // We invalidate the click when exiting middle click auto scroll so that w
e don't inadvertently navigate | 630 // We invalidate the click when exiting middle click auto scroll so that |
625 // away from the current page (e.g. the click was on a hyperlink). See <rd
ar://problem/6095023>. | 631 // we don't inadvertently navigate away from the current page (e.g. the |
| 632 // click was on a hyperlink). See <rdar://problem/6095023>. |
626 m_mouseEventManager->invalidateClick(); | 633 m_mouseEventManager->invalidateClick(); |
627 return WebInputEventResult::HandledSuppressed; | 634 return WebInputEventResult::HandledSuppressed; |
628 } | 635 } |
629 } | 636 } |
630 | 637 |
631 m_mouseEventManager->setClickCount(mouseEvent.clickCount()); | 638 m_mouseEventManager->setClickCount(mouseEvent.clickCount()); |
632 m_mouseEventManager->setClickNode( | 639 m_mouseEventManager->setClickNode( |
633 mev.innerNode()->isTextNode() | 640 mev.innerNode()->isTextNode() |
634 ? FlatTreeTraversal::parent(*mev.innerNode()) | 641 ? FlatTreeTraversal::parent(*mev.innerNode()) |
635 : mev.innerNode()); | 642 : mev.innerNode()); |
(...skipping 30 matching lines...) Expand all Loading... |
666 mouseEvent.getSyntheticEventType() == PlatformMouseEvent::FromTouch | 673 mouseEvent.getSyntheticEventType() == PlatformMouseEvent::FromTouch |
667 ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities() | 674 ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities() |
668 : InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); | 675 : InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); |
669 if (eventResult == WebInputEventResult::NotHandled) { | 676 if (eventResult == WebInputEventResult::NotHandled) { |
670 eventResult = m_mouseEventManager->handleMouseFocus(hitTestResult, | 677 eventResult = m_mouseEventManager->handleMouseFocus(hitTestResult, |
671 sourceCapabilities); | 678 sourceCapabilities); |
672 } | 679 } |
673 m_mouseEventManager->setCapturesDragging( | 680 m_mouseEventManager->setCapturesDragging( |
674 eventResult == WebInputEventResult::NotHandled || mev.scrollbar()); | 681 eventResult == WebInputEventResult::NotHandled || mev.scrollbar()); |
675 | 682 |
676 // If the hit testing originally determined the event was in a scrollbar, refe
tch the MouseEventWithHitTestResults | 683 // If the hit testing originally determined the event was in a scrollbar, |
677 // in case the scrollbar widget was destroyed when the mouse event was handled
. | 684 // refetch the MouseEventWithHitTestResults in case the scrollbar widget was |
| 685 // destroyed when the mouse event was handled. |
678 if (mev.scrollbar()) { | 686 if (mev.scrollbar()) { |
679 const bool wasLastScrollBar = | 687 const bool wasLastScrollBar = |
680 mev.scrollbar() == m_lastScrollbarUnderMouse.get(); | 688 mev.scrollbar() == m_lastScrollbarUnderMouse.get(); |
681 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); | 689 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); |
682 mev = m_frame->document()->performMouseEventHitTest(request, documentPoint, | 690 mev = m_frame->document()->performMouseEventHitTest(request, documentPoint, |
683 mouseEvent); | 691 mouseEvent); |
684 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get()) | 692 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get()) |
685 m_lastScrollbarUnderMouse = nullptr; | 693 m_lastScrollbarUnderMouse = nullptr; |
686 } | 694 } |
687 | 695 |
688 if (eventResult != WebInputEventResult::NotHandled) { | 696 if (eventResult != WebInputEventResult::NotHandled) { |
689 // scrollbars should get events anyway, even disabled controls might be scro
llable | 697 // Scrollbars should get events anyway, even disabled controls might be |
| 698 // scrollable. |
690 passMousePressEventToScrollbar(mev); | 699 passMousePressEventToScrollbar(mev); |
691 } else { | 700 } else { |
692 if (shouldRefetchEventTarget(mev)) { | 701 if (shouldRefetchEventTarget(mev)) { |
693 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); | 702 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); |
694 mev = m_frame->document()->performMouseEventHitTest( | 703 mev = m_frame->document()->performMouseEventHitTest( |
695 request, documentPoint, mouseEvent); | 704 request, documentPoint, mouseEvent); |
696 } | 705 } |
697 | 706 |
698 if (passMousePressEventToScrollbar(mev)) | 707 if (passMousePressEventToScrollbar(mev)) |
699 eventResult = WebInputEventResult::HandledSystem; | 708 eventResult = WebInputEventResult::HandledSystem; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 return WebInputEventResult::HandledSystem; | 785 return WebInputEventResult::HandledSystem; |
777 } | 786 } |
778 | 787 |
779 // Mouse events simulated from touch should not hit-test again. | 788 // Mouse events simulated from touch should not hit-test again. |
780 ASSERT(!mouseEvent.fromTouch()); | 789 ASSERT(!mouseEvent.fromTouch()); |
781 | 790 |
782 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; | 791 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; |
783 if (m_mouseEventManager->mousePressed()) { | 792 if (m_mouseEventManager->mousePressed()) { |
784 hitType |= HitTestRequest::Active; | 793 hitType |= HitTestRequest::Active; |
785 } else if (onlyUpdateScrollbars) { | 794 } else if (onlyUpdateScrollbars) { |
786 // Mouse events should be treated as "read-only" if we're updating only scro
llbars. This | 795 // Mouse events should be treated as "read-only" if we're updating only |
787 // means that :hover and :active freeze in the state they were in, rather th
an updating | 796 // scrollbars. This means that :hover and :active freeze in the state they |
788 // for nodes the mouse moves while the window is not key (which will be the
case if | 797 // were in, rather than updating for nodes the mouse moves while the window |
789 // onlyUpdateScrollbars is true). | 798 // is not key (which will be the case if onlyUpdateScrollbars is true). |
790 hitType |= HitTestRequest::ReadOnly; | 799 hitType |= HitTestRequest::ReadOnly; |
791 } | 800 } |
792 | 801 |
793 // Treat any mouse move events as readonly if the user is currently touching t
he screen. | 802 // Treat any mouse move events as readonly if the user is currently touching |
| 803 // the screen. |
794 if (m_pointerEventManager->isAnyTouchActive()) | 804 if (m_pointerEventManager->isAnyTouchActive()) |
795 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; | 805 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; |
796 HitTestRequest request(hitType); | 806 HitTestRequest request(hitType); |
797 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults( | 807 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults( |
798 mouseEvent, HitTestResult(request, LayoutPoint())); | 808 mouseEvent, HitTestResult(request, LayoutPoint())); |
799 | 809 |
800 // We don't want to do a hit-test in forceLeave scenarios because there might
actually be some other frame above this one at the specified co-ordinate. | 810 // We don't want to do a hit-test in forceLeave scenarios because there might |
801 // So we must force the hit-test to fail, while still clearing hover/active st
ate. | 811 // actually be some other frame above this one at the specified co-ordinate. |
| 812 // So we must force the hit-test to fail, while still clearing hover/active |
| 813 // state. |
802 if (forceLeave) { | 814 if (forceLeave) { |
803 m_frame->document()->updateHoverActiveState(request, 0); | 815 m_frame->document()->updateHoverActiveState(request, 0); |
804 } else { | 816 } else { |
805 mev = EventHandlingUtil::performMouseEventHitTest(m_frame, request, | 817 mev = EventHandlingUtil::performMouseEventHitTest(m_frame, request, |
806 mouseEvent); | 818 mouseEvent); |
807 } | 819 } |
808 | 820 |
809 if (hoveredNode) | 821 if (hoveredNode) |
810 *hoveredNode = mev.hitTestResult(); | 822 *hoveredNode = mev.hitTestResult(); |
811 | 823 |
(...skipping 10 matching lines...) Expand all Loading... |
822 if (onlyUpdateScrollbars) | 834 if (onlyUpdateScrollbars) |
823 return WebInputEventResult::HandledSuppressed; | 835 return WebInputEventResult::HandledSuppressed; |
824 } | 836 } |
825 | 837 |
826 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 838 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
827 LocalFrame* newSubframe = | 839 LocalFrame* newSubframe = |
828 m_capturingMouseEventsNode.get() | 840 m_capturingMouseEventsNode.get() |
829 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) | 841 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) |
830 : subframeForHitTestResult(mev); | 842 : subframeForHitTestResult(mev); |
831 | 843 |
832 // We want mouseouts to happen first, from the inside out. First send a move
event to the last subframe so that it will fire mouseouts. | 844 // We want mouseouts to happen first, from the inside out. First send a move |
| 845 // event to the last subframe so that it will fire mouseouts. |
833 if (m_lastMouseMoveEventSubframe && | 846 if (m_lastMouseMoveEventSubframe && |
834 m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && | 847 m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && |
835 m_lastMouseMoveEventSubframe != newSubframe) | 848 m_lastMouseMoveEventSubframe != newSubframe) |
836 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent( | 849 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent( |
837 mev.event()); | 850 mev.event()); |
838 | 851 |
839 if (newSubframe) { | 852 if (newSubframe) { |
840 // Update over/out state before passing the event to the subframe. | 853 // Update over/out state before passing the event to the subframe. |
841 m_pointerEventManager->sendMouseAndPointerBoundaryEvents( | 854 m_pointerEventManager->sendMouseAndPointerBoundaryEvents( |
842 updateMouseEventTargetNode(mev.innerNode()), mev.event()); | 855 updateMouseEventTargetNode(mev.innerNode()), mev.event()); |
843 | 856 |
844 // Event dispatch in sendMouseAndPointerBoundaryEvents may have caused the s
ubframe of the target | 857 // Event dispatch in sendMouseAndPointerBoundaryEvents may have caused the |
845 // node to be detached from its FrameView, in which case the event should no
t be passed. | 858 // subframe of the target node to be detached from its FrameView, in which |
| 859 // case the event should not be passed. |
846 if (newSubframe->view()) | 860 if (newSubframe->view()) |
847 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hoveredNode); | 861 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hoveredNode); |
848 } else { | 862 } else { |
849 if (scrollbar && !m_mouseEventManager->mousePressed()) | 863 if (scrollbar && !m_mouseEventManager->mousePressed()) { |
850 scrollbar->mouseMoved( | 864 // Handle hover effects on platforms that support visual feedback on |
851 mev.event()); // Handle hover effects on platforms that support visua
l feedback on scrollbar hovering. | 865 // scrollbar hovering. |
| 866 scrollbar->mouseMoved(mev.event()); |
| 867 } |
852 if (FrameView* view = m_frame->view()) { | 868 if (FrameView* view = m_frame->view()) { |
853 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); | 869 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); |
854 if (optionalCursor.isCursorChange()) { | 870 if (optionalCursor.isCursorChange()) { |
855 view->setCursor(optionalCursor.cursor()); | 871 view->setCursor(optionalCursor.cursor()); |
856 } | 872 } |
857 } | 873 } |
858 } | 874 } |
859 | 875 |
860 m_lastMouseMoveEventSubframe = newSubframe; | 876 m_lastMouseMoveEventSubframe = newSubframe; |
861 | 877 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 DataTransfer* dataTransfer) { | 1028 DataTransfer* dataTransfer) { |
1013 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 1029 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
1014 | 1030 |
1015 if (!m_frame->view()) | 1031 if (!m_frame->view()) |
1016 return eventResult; | 1032 return eventResult; |
1017 | 1033 |
1018 HitTestRequest request(HitTestRequest::ReadOnly); | 1034 HitTestRequest request(HitTestRequest::ReadOnly); |
1019 MouseEventWithHitTestResults mev = | 1035 MouseEventWithHitTestResults mev = |
1020 EventHandlingUtil::performMouseEventHitTest(m_frame, request, event); | 1036 EventHandlingUtil::performMouseEventHitTest(m_frame, request, event); |
1021 | 1037 |
1022 // Drag events should never go to text nodes (following IE, and proper mouseov
er/out dispatch) | 1038 // Drag events should never go to text nodes (following IE, and proper |
| 1039 // mouseover/out dispatch) |
1023 Node* newTarget = mev.innerNode(); | 1040 Node* newTarget = mev.innerNode(); |
1024 if (newTarget && newTarget->isTextNode()) | 1041 if (newTarget && newTarget->isTextNode()) |
1025 newTarget = FlatTreeTraversal::parent(*newTarget); | 1042 newTarget = FlatTreeTraversal::parent(*newTarget); |
1026 | 1043 |
1027 if (AutoscrollController* controller = | 1044 if (AutoscrollController* controller = |
1028 m_scrollManager->autoscrollController()) | 1045 m_scrollManager->autoscrollController()) |
1029 controller->updateDragAndDrop(newTarget, event.position(), | 1046 controller->updateDragAndDrop(newTarget, event.position(), |
1030 event.timestamp()); | 1047 event.timestamp()); |
1031 | 1048 |
1032 if (m_dragTarget != newTarget) { | 1049 if (m_dragTarget != newTarget) { |
1033 // FIXME: this ordering was explicitly chosen to match WinIE. However, | 1050 // FIXME: this ordering was explicitly chosen to match WinIE. However, |
1034 // it is sometimes incorrect when dragging within subframes, as seen with | 1051 // it is sometimes incorrect when dragging within subframes, as seen with |
1035 // LayoutTests/fast/events/drag-in-frames.html. | 1052 // LayoutTests/fast/events/drag-in-frames.html. |
1036 // | 1053 // |
1037 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <ht
tp://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. | 1054 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. |
| 1055 // <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-mode
l>. |
1038 LocalFrame* targetFrame; | 1056 LocalFrame* targetFrame; |
1039 if (targetIsFrame(newTarget, targetFrame)) { | 1057 if (targetIsFrame(newTarget, targetFrame)) { |
1040 if (targetFrame) | 1058 if (targetFrame) |
1041 eventResult = | 1059 eventResult = |
1042 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1060 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
1043 } else if (newTarget) { | 1061 } else if (newTarget) { |
1044 // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag ev
ent before firing a dragenter, dragleave, or dragover event. | 1062 // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag |
| 1063 // event before firing a dragenter, dragleave, or dragover event. |
1045 if (m_mouseEventManager->dragState().m_dragSrc) { | 1064 if (m_mouseEventManager->dragState().m_dragSrc) { |
1046 // for now we don't care if event handler cancels default behavior, sinc
e there is none | 1065 // For now we don't care if event handler cancels default behavior, |
| 1066 // since there is none. |
1047 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); | 1067 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
1048 } | 1068 } |
1049 eventResult = m_mouseEventManager->dispatchDragEvent( | 1069 eventResult = m_mouseEventManager->dispatchDragEvent( |
1050 EventTypeNames::dragenter, newTarget, event, dataTransfer); | 1070 EventTypeNames::dragenter, newTarget, event, dataTransfer); |
1051 if (eventResult == WebInputEventResult::NotHandled && | 1071 if (eventResult == WebInputEventResult::NotHandled && |
1052 findDropZone(newTarget, dataTransfer)) | 1072 findDropZone(newTarget, dataTransfer)) |
1053 eventResult = WebInputEventResult::HandledSystem; | 1073 eventResult = WebInputEventResult::HandledSystem; |
1054 } | 1074 } |
1055 | 1075 |
1056 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1076 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
1057 if (targetFrame) | 1077 if (targetFrame) |
1058 eventResult = | 1078 eventResult = |
1059 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1079 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
1060 } else if (m_dragTarget) { | 1080 } else if (m_dragTarget) { |
1061 m_mouseEventManager->dispatchDragEvent( | 1081 m_mouseEventManager->dispatchDragEvent( |
1062 EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer); | 1082 EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer); |
1063 } | 1083 } |
1064 | 1084 |
1065 if (newTarget) { | 1085 if (newTarget) { |
1066 // We do not explicitly call m_mouseEventManager->dispatchDragEvent here b
ecause it could ultimately result in the appearance that | 1086 // We do not explicitly call m_mouseEventManager->dispatchDragEvent here |
1067 // two dragover events fired. So, we mark that we should only fire a drago
ver event on the next call to this function. | 1087 // because it could ultimately result in the appearance that two dragover |
| 1088 // events fired. So, we mark that we should only fire a dragover event on |
| 1089 // the next call to this function. |
1068 m_shouldOnlyFireDragOverEvent = true; | 1090 m_shouldOnlyFireDragOverEvent = true; |
1069 } | 1091 } |
1070 } else { | 1092 } else { |
1071 LocalFrame* targetFrame; | 1093 LocalFrame* targetFrame; |
1072 if (targetIsFrame(newTarget, targetFrame)) { | 1094 if (targetIsFrame(newTarget, targetFrame)) { |
1073 if (targetFrame) | 1095 if (targetFrame) |
1074 eventResult = | 1096 eventResult = |
1075 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1097 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
1076 } else if (newTarget) { | 1098 } else if (newTarget) { |
1077 // Note, when dealing with sub-frames, we may need to fire only a dragover
event as a drag event may have been fired earlier. | 1099 // Note, when dealing with sub-frames, we may need to fire only a dragover |
| 1100 // event as a drag event may have been fired earlier. |
1078 if (!m_shouldOnlyFireDragOverEvent && | 1101 if (!m_shouldOnlyFireDragOverEvent && |
1079 m_mouseEventManager->dragState().m_dragSrc) { | 1102 m_mouseEventManager->dragState().m_dragSrc) { |
1080 // for now we don't care if event handler cancels default behavior, sinc
e there is none | 1103 // For now we don't care if event handler cancels default behavior, |
| 1104 // since there is none. |
1081 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); | 1105 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
1082 } | 1106 } |
1083 eventResult = m_mouseEventManager->dispatchDragEvent( | 1107 eventResult = m_mouseEventManager->dispatchDragEvent( |
1084 EventTypeNames::dragover, newTarget, event, dataTransfer); | 1108 EventTypeNames::dragover, newTarget, event, dataTransfer); |
1085 if (eventResult == WebInputEventResult::NotHandled && | 1109 if (eventResult == WebInputEventResult::NotHandled && |
1086 findDropZone(newTarget, dataTransfer)) | 1110 findDropZone(newTarget, dataTransfer)) |
1087 eventResult = WebInputEventResult::HandledSystem; | 1111 eventResult = WebInputEventResult::HandledSystem; |
1088 m_shouldOnlyFireDragOverEvent = false; | 1112 m_shouldOnlyFireDragOverEvent = false; |
1089 } | 1113 } |
1090 } | 1114 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 // If we're capturing, we always go right to that node. | 1167 // If we're capturing, we always go right to that node. |
1144 EventTarget* mousePointerCapturingNode = | 1168 EventTarget* mousePointerCapturingNode = |
1145 m_pointerEventManager->getMouseCapturingNode(); | 1169 m_pointerEventManager->getMouseCapturingNode(); |
1146 if (mousePointerCapturingNode && | 1170 if (mousePointerCapturingNode && |
1147 !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { | 1171 !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { |
1148 newNodeUnderMouse = mousePointerCapturingNode->toNode(); | 1172 newNodeUnderMouse = mousePointerCapturingNode->toNode(); |
1149 DCHECK(newNodeUnderMouse); | 1173 DCHECK(newNodeUnderMouse); |
1150 } else if (m_capturingMouseEventsNode) { | 1174 } else if (m_capturingMouseEventsNode) { |
1151 newNodeUnderMouse = m_capturingMouseEventsNode.get(); | 1175 newNodeUnderMouse = m_capturingMouseEventsNode.get(); |
1152 } else { | 1176 } else { |
1153 // If the target node is a text node, dispatch on the parent node - rdar://4
196646 | 1177 // If the target node is a text node, dispatch on the parent node - |
| 1178 // rdar://4196646 |
1154 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) | 1179 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) |
1155 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); | 1180 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); |
1156 } | 1181 } |
1157 return newNodeUnderMouse; | 1182 return newNodeUnderMouse; |
1158 } | 1183 } |
1159 | 1184 |
1160 bool EventHandler::isPointerEventActive(int pointerId) { | 1185 bool EventHandler::isPointerEventActive(int pointerId) { |
1161 return m_pointerEventManager->isActive(pointerId); | 1186 return m_pointerEventManager->isActive(pointerId); |
1162 } | 1187 } |
1163 | 1188 |
1164 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) { | 1189 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) { |
1165 // TODO(crbug.com/591387): This functionality should be per page not per frame
. | 1190 // TODO(crbug.com/591387): This functionality should be per page not per |
| 1191 // frame. |
1166 m_pointerEventManager->setPointerCapture(pointerId, target); | 1192 m_pointerEventManager->setPointerCapture(pointerId, target); |
1167 } | 1193 } |
1168 | 1194 |
1169 void EventHandler::releasePointerCapture(int pointerId, EventTarget* target) { | 1195 void EventHandler::releasePointerCapture(int pointerId, EventTarget* target) { |
1170 m_pointerEventManager->releasePointerCapture(pointerId, target); | 1196 m_pointerEventManager->releasePointerCapture(pointerId, target); |
1171 } | 1197 } |
1172 | 1198 |
1173 bool EventHandler::hasPointerCapture(int pointerId, | 1199 bool EventHandler::hasPointerCapture(int pointerId, |
1174 const EventTarget* target) const { | 1200 const EventTarget* target) const { |
1175 return m_pointerEventManager->hasPointerCapture(pointerId, target); | 1201 return m_pointerEventManager->hasPointerCapture(pointerId, target); |
(...skipping 19 matching lines...) Expand all Loading... |
1195 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( | 1221 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( |
1196 updateMouseEventTargetNode(targetNode), mouseEventType, mouseEvent); | 1222 updateMouseEventTargetNode(targetNode), mouseEventType, mouseEvent); |
1197 return eventResult; | 1223 return eventResult; |
1198 } | 1224 } |
1199 | 1225 |
1200 WebInputEventResult EventHandler::handleWheelEvent( | 1226 WebInputEventResult EventHandler::handleWheelEvent( |
1201 const PlatformWheelEvent& event) { | 1227 const PlatformWheelEvent& event) { |
1202 #if OS(MACOSX) | 1228 #if OS(MACOSX) |
1203 // Filter Mac OS specific phases, usually with a zero-delta. | 1229 // Filter Mac OS specific phases, usually with a zero-delta. |
1204 // https://crbug.com/553732 | 1230 // https://crbug.com/553732 |
1205 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone|,
but it shouldn't. | 1231 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone|, |
| 1232 // but it shouldn't. |
1206 const int kPlatformWheelEventPhaseNoEventMask = | 1233 const int kPlatformWheelEventPhaseNoEventMask = |
1207 PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | | 1234 PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | |
1208 PlatformWheelEventPhaseMayBegin; | 1235 PlatformWheelEventPhaseMayBegin; |
1209 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || | 1236 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || |
1210 (event.momentumPhase() & kPlatformWheelEventPhaseNoEventMask)) | 1237 (event.momentumPhase() & kPlatformWheelEventPhaseNoEventMask)) |
1211 return WebInputEventResult::NotHandled; | 1238 return WebInputEventResult::NotHandled; |
1212 #endif | 1239 #endif |
1213 Document* doc = m_frame->document(); | 1240 Document* doc = m_frame->document(); |
1214 | 1241 |
1215 if (doc->layoutViewItem().isNull()) | 1242 if (doc->layoutViewItem().isNull()) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 } | 1279 } |
1253 | 1280 |
1254 return WebInputEventResult::NotHandled; | 1281 return WebInputEventResult::NotHandled; |
1255 } | 1282 } |
1256 | 1283 |
1257 WebInputEventResult EventHandler::handleGestureEvent( | 1284 WebInputEventResult EventHandler::handleGestureEvent( |
1258 const PlatformGestureEvent& gestureEvent) { | 1285 const PlatformGestureEvent& gestureEvent) { |
1259 // Propagation to inner frames is handled below this function. | 1286 // Propagation to inner frames is handled below this function. |
1260 ASSERT(m_frame == m_frame->localFrameRoot()); | 1287 ASSERT(m_frame == m_frame->localFrameRoot()); |
1261 | 1288 |
1262 // Scrolling-related gesture events invoke EventHandler recursively for each f
rame down | 1289 // Scrolling-related gesture events invoke EventHandler recursively for each |
1263 // the chain, doing a single-frame hit-test per frame. This matches handleWhee
lEvent. | 1290 // frame down the chain, doing a single-frame hit-test per frame. This matches |
| 1291 // handleWheelEvent. |
1264 // FIXME: Add a test that traverses this path, e.g. for devtools overlay. | 1292 // FIXME: Add a test that traverses this path, e.g. for devtools overlay. |
1265 if (gestureEvent.isScrollEvent()) | 1293 if (gestureEvent.isScrollEvent()) |
1266 return handleGestureScrollEvent(gestureEvent); | 1294 return handleGestureScrollEvent(gestureEvent); |
1267 | 1295 |
1268 // Hit test across all frames and do touch adjustment as necessary for the eve
nt type. | 1296 // Hit test across all frames and do touch adjustment as necessary for the |
| 1297 // event type. |
1269 GestureEventWithHitTestResults targetedEvent = | 1298 GestureEventWithHitTestResults targetedEvent = |
1270 targetGestureEvent(gestureEvent); | 1299 targetGestureEvent(gestureEvent); |
1271 | 1300 |
1272 return handleGestureEvent(targetedEvent); | 1301 return handleGestureEvent(targetedEvent); |
1273 } | 1302 } |
1274 | 1303 |
1275 WebInputEventResult EventHandler::handleGestureEvent( | 1304 WebInputEventResult EventHandler::handleGestureEvent( |
1276 const GestureEventWithHitTestResults& targetedEvent) { | 1305 const GestureEventWithHitTestResults& targetedEvent) { |
1277 TRACE_EVENT0("input", "EventHandler::handleGestureEvent"); | 1306 TRACE_EVENT0("input", "EventHandler::handleGestureEvent"); |
1278 | 1307 |
1279 // Propagation to inner frames is handled below this function. | 1308 // Propagation to inner frames is handled below this function. |
1280 ASSERT(m_frame == m_frame->localFrameRoot()); | 1309 ASSERT(m_frame == m_frame->localFrameRoot()); |
1281 | 1310 |
1282 // Non-scrolling related gesture events do a single cross-frame hit-test and j
ump | 1311 // Non-scrolling related gesture events do a single cross-frame hit-test and |
1283 // directly to the inner most frame. This matches handleMousePressEvent etc. | 1312 // jump directly to the inner most frame. This matches handleMousePressEvent |
| 1313 // etc. |
1284 ASSERT(!targetedEvent.event().isScrollEvent()); | 1314 ASSERT(!targetedEvent.event().isScrollEvent()); |
1285 | 1315 |
1286 // update mouseout/leave/over/enter events before jumping directly to the inne
r most frame | 1316 // Update mouseout/leave/over/enter events before jumping directly to the |
| 1317 // inner most frame. |
1287 if (targetedEvent.event().type() == PlatformEvent::GestureTap) | 1318 if (targetedEvent.event().type() == PlatformEvent::GestureTap) |
1288 updateGestureTargetNodeForMouseEvent(targetedEvent); | 1319 updateGestureTargetNodeForMouseEvent(targetedEvent); |
1289 | 1320 |
1290 // Route to the correct frame. | 1321 // Route to the correct frame. |
1291 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame()) | 1322 if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame()) |
1292 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEvent); | 1323 return innerFrame->eventHandler().handleGestureEventInFrame(targetedEvent); |
1293 | 1324 |
1294 // No hit test result, handle in root instance. Perhaps we should just return
false instead? | 1325 // No hit test result, handle in root instance. Perhaps we should just return |
| 1326 // false instead? |
1295 return m_gestureManager->handleGestureEventInFrame(targetedEvent); | 1327 return m_gestureManager->handleGestureEventInFrame(targetedEvent); |
1296 } | 1328 } |
1297 | 1329 |
1298 WebInputEventResult EventHandler::handleGestureEventInFrame( | 1330 WebInputEventResult EventHandler::handleGestureEventInFrame( |
1299 const GestureEventWithHitTestResults& targetedEvent) { | 1331 const GestureEventWithHitTestResults& targetedEvent) { |
1300 return m_gestureManager->handleGestureEventInFrame(targetedEvent); | 1332 return m_gestureManager->handleGestureEventInFrame(targetedEvent); |
1301 } | 1333 } |
1302 | 1334 |
1303 WebInputEventResult EventHandler::handleGestureScrollEvent( | 1335 WebInputEventResult EventHandler::handleGestureScrollEvent( |
1304 const PlatformGestureEvent& gestureEvent) { | 1336 const PlatformGestureEvent& gestureEvent) { |
(...skipping 24 matching lines...) Expand all Loading... |
1329 | 1361 |
1330 bool EventHandler::bestClickableNodeForHitTestResult( | 1362 bool EventHandler::bestClickableNodeForHitTestResult( |
1331 const HitTestResult& result, | 1363 const HitTestResult& result, |
1332 IntPoint& targetPoint, | 1364 IntPoint& targetPoint, |
1333 Node*& targetNode) { | 1365 Node*& targetNode) { |
1334 // FIXME: Unify this with the other best* functions which are very similar. | 1366 // FIXME: Unify this with the other best* functions which are very similar. |
1335 | 1367 |
1336 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult"); | 1368 TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult"); |
1337 ASSERT(result.isRectBasedTest()); | 1369 ASSERT(result.isRectBasedTest()); |
1338 | 1370 |
1339 // If the touch is over a scrollbar, don't adjust the touch point since touch
adjustment only takes into account | 1371 // If the touch is over a scrollbar, don't adjust the touch point since touch |
1340 // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nodes
. This leads to things like textarea | 1372 // adjustment only takes into account DOM nodes so a touch over a scrollbar |
| 1373 // will be adjusted towards nearby nodes. This leads to things like textarea |
1341 // scrollbars being untouchable. | 1374 // scrollbars being untouchable. |
1342 if (result.scrollbar()) { | 1375 if (result.scrollbar()) { |
1343 targetNode = 0; | 1376 targetNode = 0; |
1344 return false; | 1377 return false; |
1345 } | 1378 } |
1346 | 1379 |
1347 IntPoint touchCenter = | 1380 IntPoint touchCenter = |
1348 m_frame->view()->contentsToRootFrame(result.roundedPointInMainFrame()); | 1381 m_frame->view()->contentsToRootFrame(result.roundedPointInMainFrame()); |
1349 IntRect touchRect = m_frame->view()->contentsToRootFrame( | 1382 IntRect touchRect = m_frame->view()->contentsToRootFrame( |
1350 result.hitTestLocation().boundingBox()); | 1383 result.hitTestLocation().boundingBox()); |
1351 | 1384 |
1352 HeapVector<Member<Node>, 11> nodes; | 1385 HeapVector<Member<Node>, 11> nodes; |
1353 copyToVector(result.listBasedTestResult(), nodes); | 1386 copyToVector(result.listBasedTestResult(), nodes); |
1354 | 1387 |
1355 // FIXME: the explicit Vector conversion copies into a temporary and is wastef
ul. | 1388 // FIXME: the explicit Vector conversion copies into a temporary and is |
| 1389 // wasteful. |
1356 return findBestClickableCandidate(targetNode, targetPoint, touchCenter, | 1390 return findBestClickableCandidate(targetNode, targetPoint, touchCenter, |
1357 touchRect, HeapVector<Member<Node>>(nodes)); | 1391 touchRect, HeapVector<Member<Node>>(nodes)); |
1358 } | 1392 } |
1359 | 1393 |
1360 bool EventHandler::bestContextMenuNodeForHitTestResult( | 1394 bool EventHandler::bestContextMenuNodeForHitTestResult( |
1361 const HitTestResult& result, | 1395 const HitTestResult& result, |
1362 IntPoint& targetPoint, | 1396 IntPoint& targetPoint, |
1363 Node*& targetNode) { | 1397 Node*& targetNode) { |
1364 ASSERT(result.isRectBasedTest()); | 1398 ASSERT(result.isRectBasedTest()); |
1365 IntPoint touchCenter = | 1399 IntPoint touchCenter = |
1366 m_frame->view()->contentsToRootFrame(result.roundedPointInMainFrame()); | 1400 m_frame->view()->contentsToRootFrame(result.roundedPointInMainFrame()); |
1367 IntRect touchRect = m_frame->view()->contentsToRootFrame( | 1401 IntRect touchRect = m_frame->view()->contentsToRootFrame( |
1368 result.hitTestLocation().boundingBox()); | 1402 result.hitTestLocation().boundingBox()); |
1369 HeapVector<Member<Node>, 11> nodes; | 1403 HeapVector<Member<Node>, 11> nodes; |
1370 copyToVector(result.listBasedTestResult(), nodes); | 1404 copyToVector(result.listBasedTestResult(), nodes); |
1371 | 1405 |
1372 // FIXME: the explicit Vector conversion copies into a temporary and is wastef
ul. | 1406 // FIXME: the explicit Vector conversion copies into a temporary and is |
| 1407 // wasteful. |
1373 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, | 1408 return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, |
1374 touchRect, | 1409 touchRect, |
1375 HeapVector<Member<Node>>(nodes)); | 1410 HeapVector<Member<Node>>(nodes)); |
1376 } | 1411 } |
1377 | 1412 |
1378 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, | 1413 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, |
1379 const IntSize& touchRadius, | 1414 const IntSize& touchRadius, |
1380 IntRect& targetArea, | 1415 IntRect& targetArea, |
1381 Node*& targetNode) { | 1416 Node*& targetNode) { |
1382 if (touchRadius.isEmpty()) | 1417 if (touchRadius.isEmpty()) |
1383 return false; | 1418 return false; |
1384 | 1419 |
1385 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(touchCenter); | 1420 IntPoint hitTestPoint = m_frame->view()->rootFrameToContents(touchCenter); |
1386 | 1421 |
1387 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | | 1422 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | |
1388 HitTestRequest::Active | | 1423 HitTestRequest::Active | |
1389 HitTestRequest::ListBased; | 1424 HitTestRequest::ListBased; |
1390 HitTestResult result = | 1425 HitTestResult result = |
1391 hitTestResultAtPoint(hitTestPoint, hitType, LayoutSize(touchRadius)); | 1426 hitTestResultAtPoint(hitTestPoint, hitType, LayoutSize(touchRadius)); |
1392 | 1427 |
1393 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); | 1428 IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius); |
1394 HeapVector<Member<Node>, 11> nodes; | 1429 HeapVector<Member<Node>, 11> nodes; |
1395 copyToVector(result.listBasedTestResult(), nodes); | 1430 copyToVector(result.listBasedTestResult(), nodes); |
1396 | 1431 |
1397 // FIXME: the explicit Vector conversion copies into a temporary and is wastef
ul. | 1432 // FIXME: the explicit Vector conversion copies into a temporary and is |
| 1433 // wasteful. |
1398 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, | 1434 return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, |
1399 HeapVector<Member<Node>>(nodes)); | 1435 HeapVector<Member<Node>>(nodes)); |
1400 } | 1436 } |
1401 | 1437 |
1402 // Update the hover and active state across all frames for this gesture. | 1438 // Update the hover and active state across all frames for this gesture. |
1403 // This logic is different than the mouse case because mice send MouseLeave even
ts to frames as they're exited. | 1439 // This logic is different than the mouse case because mice send MouseLeave |
1404 // With gestures, a single event conceptually both 'leaves' whatever frame curre
ntly had hover and enters a new frame | 1440 // events to frames as they're exited. With gestures, a single event |
| 1441 // conceptually both 'leaves' whatever frame currently had hover and enters a |
| 1442 // new frame |
1405 void EventHandler::updateGestureHoverActiveState(const HitTestRequest& request, | 1443 void EventHandler::updateGestureHoverActiveState(const HitTestRequest& request, |
1406 Element* innerElement) { | 1444 Element* innerElement) { |
1407 ASSERT(m_frame == m_frame->localFrameRoot()); | 1445 ASSERT(m_frame == m_frame->localFrameRoot()); |
1408 | 1446 |
1409 HeapVector<Member<LocalFrame>> newHoverFrameChain; | 1447 HeapVector<Member<LocalFrame>> newHoverFrameChain; |
1410 LocalFrame* newHoverFrameInDocument = | 1448 LocalFrame* newHoverFrameInDocument = |
1411 innerElement ? innerElement->document().frame() : nullptr; | 1449 innerElement ? innerElement->document().frame() : nullptr; |
1412 // Insert the ancestors of the frame having the new hovered node to the frame
chain | 1450 // Insert the ancestors of the frame having the new hovered node to the frame |
1413 // The frame chain doesn't include the main frame to avoid the redundant work
that cleans the hover state. | 1451 // chain The frame chain doesn't include the main frame to avoid the redundant |
1414 // Because the hover state for the main frame is updated by calling Document::
updateHoverActiveState | 1452 // work that cleans the hover state. Because the hover state for the main |
| 1453 // frame is updated by calling Document::updateHoverActiveState |
1415 while (newHoverFrameInDocument && newHoverFrameInDocument != m_frame) { | 1454 while (newHoverFrameInDocument && newHoverFrameInDocument != m_frame) { |
1416 newHoverFrameChain.append(newHoverFrameInDocument); | 1455 newHoverFrameChain.append(newHoverFrameInDocument); |
1417 Frame* parentFrame = newHoverFrameInDocument->tree().parent(); | 1456 Frame* parentFrame = newHoverFrameInDocument->tree().parent(); |
1418 newHoverFrameInDocument = parentFrame && parentFrame->isLocalFrame() | 1457 newHoverFrameInDocument = parentFrame && parentFrame->isLocalFrame() |
1419 ? toLocalFrame(parentFrame) | 1458 ? toLocalFrame(parentFrame) |
1420 : nullptr; | 1459 : nullptr; |
1421 } | 1460 } |
1422 | 1461 |
1423 Node* oldHoverNodeInCurDoc = m_frame->document()->hoverNode(); | 1462 Node* oldHoverNodeInCurDoc = m_frame->document()->hoverNode(); |
1424 Node* newInnermostHoverNode = innerElement; | 1463 Node* newInnermostHoverNode = innerElement; |
1425 | 1464 |
1426 if (newInnermostHoverNode != oldHoverNodeInCurDoc) { | 1465 if (newInnermostHoverNode != oldHoverNodeInCurDoc) { |
1427 size_t indexFrameChain = newHoverFrameChain.size(); | 1466 size_t indexFrameChain = newHoverFrameChain.size(); |
1428 | 1467 |
1429 // Clear the hover state on any frames which are no longer in the frame chai
n of the hovered elemen | 1468 // Clear the hover state on any frames which are no longer in the frame |
| 1469 // chain of the hovered element. |
1430 while (oldHoverNodeInCurDoc && | 1470 while (oldHoverNodeInCurDoc && |
1431 oldHoverNodeInCurDoc->isFrameOwnerElement()) { | 1471 oldHoverNodeInCurDoc->isFrameOwnerElement()) { |
1432 LocalFrame* newHoverFrame = nullptr; | 1472 LocalFrame* newHoverFrame = nullptr; |
1433 // If we can't get the frame from the new hover frame chain, | 1473 // If we can't get the frame from the new hover frame chain, |
1434 // the newHoverFrame will be null and the old hover state will be cleared. | 1474 // the newHoverFrame will be null and the old hover state will be cleared. |
1435 if (indexFrameChain > 0) | 1475 if (indexFrameChain > 0) |
1436 newHoverFrame = newHoverFrameChain[--indexFrameChain]; | 1476 newHoverFrame = newHoverFrameChain[--indexFrameChain]; |
1437 | 1477 |
1438 HTMLFrameOwnerElement* owner = | 1478 HTMLFrameOwnerElement* owner = |
1439 toHTMLFrameOwnerElement(oldHoverNodeInCurDoc); | 1479 toHTMLFrameOwnerElement(oldHoverNodeInCurDoc); |
1440 if (!owner->contentFrame() || !owner->contentFrame()->isLocalFrame()) | 1480 if (!owner->contentFrame() || !owner->contentFrame()->isLocalFrame()) |
1441 break; | 1481 break; |
1442 | 1482 |
1443 LocalFrame* oldHoverFrame = toLocalFrame(owner->contentFrame()); | 1483 LocalFrame* oldHoverFrame = toLocalFrame(owner->contentFrame()); |
1444 Document* doc = oldHoverFrame->document(); | 1484 Document* doc = oldHoverFrame->document(); |
1445 if (!doc) | 1485 if (!doc) |
1446 break; | 1486 break; |
1447 | 1487 |
1448 oldHoverNodeInCurDoc = doc->hoverNode(); | 1488 oldHoverNodeInCurDoc = doc->hoverNode(); |
1449 // If the old hovered frame is different from the new hovered frame. | 1489 // If the old hovered frame is different from the new hovered frame. |
1450 // we should clear the old hovered node from the old hovered frame. | 1490 // we should clear the old hovered node from the old hovered frame. |
1451 if (newHoverFrame != oldHoverFrame) | 1491 if (newHoverFrame != oldHoverFrame) |
1452 doc->updateHoverActiveState(request, nullptr); | 1492 doc->updateHoverActiveState(request, nullptr); |
1453 } | 1493 } |
1454 } | 1494 } |
1455 | 1495 |
1456 // Recursively set the new active/hover states on every frame in the chain of
innerElement. | 1496 // Recursively set the new active/hover states on every frame in the chain of |
| 1497 // innerElement. |
1457 m_frame->document()->updateHoverActiveState(request, innerElement); | 1498 m_frame->document()->updateHoverActiveState(request, innerElement); |
1458 } | 1499 } |
1459 | 1500 |
1460 // Update the mouseover/mouseenter/mouseout/mouseleave events across all frames
for this gesture, | 1501 // Update the mouseover/mouseenter/mouseout/mouseleave events across all frames |
1461 // before passing the targeted gesture event directly to a hit frame. | 1502 // for this gesture, before passing the targeted gesture event directly to a hit |
| 1503 // frame. |
1462 void EventHandler::updateGestureTargetNodeForMouseEvent( | 1504 void EventHandler::updateGestureTargetNodeForMouseEvent( |
1463 const GestureEventWithHitTestResults& targetedEvent) { | 1505 const GestureEventWithHitTestResults& targetedEvent) { |
1464 ASSERT(m_frame == m_frame->localFrameRoot()); | 1506 ASSERT(m_frame == m_frame->localFrameRoot()); |
1465 | 1507 |
1466 // Behaviour of this function is as follows: | 1508 // Behaviour of this function is as follows: |
1467 // - Create the chain of all entered frames. | 1509 // - Create the chain of all entered frames. |
1468 // - Compare the last frame chain under the gesture to newly entered frame cha
in from the main frame one by one. | 1510 // - Compare the last frame chain under the gesture to newly entered frame |
1469 // - If the last frame doesn't match with the entered frame, then create the c
hain of exited frames from the last frame chain. | 1511 // chain from the main frame one by one. |
1470 // - Dispatch mouseout/mouseleave events of the exited frames from the inside
out. | 1512 // - If the last frame doesn't match with the entered frame, then create the |
1471 // - Dispatch mouseover/mouseenter events of the entered frames into the insid
e. | 1513 // chain of exited frames from the last frame chain. |
| 1514 // - Dispatch mouseout/mouseleave events of the exited frames from the inside |
| 1515 // out. |
| 1516 // - Dispatch mouseover/mouseenter events of the entered frames into the |
| 1517 // inside. |
1472 | 1518 |
1473 // Insert the ancestors of the frame having the new target node to the entered
frame chain | 1519 // Insert the ancestors of the frame having the new target node to the entered |
| 1520 // frame chain. |
1474 HeapVector<Member<LocalFrame>> enteredFrameChain; | 1521 HeapVector<Member<LocalFrame>> enteredFrameChain; |
1475 LocalFrame* enteredFrameInDocument = | 1522 LocalFrame* enteredFrameInDocument = |
1476 targetedEvent.hitTestResult().innerNodeFrame(); | 1523 targetedEvent.hitTestResult().innerNodeFrame(); |
1477 while (enteredFrameInDocument) { | 1524 while (enteredFrameInDocument) { |
1478 enteredFrameChain.append(enteredFrameInDocument); | 1525 enteredFrameChain.append(enteredFrameInDocument); |
1479 Frame* parentFrame = enteredFrameInDocument->tree().parent(); | 1526 Frame* parentFrame = enteredFrameInDocument->tree().parent(); |
1480 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() | 1527 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() |
1481 ? toLocalFrame(parentFrame) | 1528 ? toLocalFrame(parentFrame) |
1482 : nullptr; | 1529 : nullptr; |
1483 } | 1530 } |
1484 | 1531 |
1485 size_t indexEnteredFrameChain = enteredFrameChain.size(); | 1532 size_t indexEnteredFrameChain = enteredFrameChain.size(); |
1486 LocalFrame* exitedFrameInDocument = m_frame; | 1533 LocalFrame* exitedFrameInDocument = m_frame; |
1487 HeapVector<Member<LocalFrame>> exitedFrameChain; | 1534 HeapVector<Member<LocalFrame>> exitedFrameChain; |
1488 // Insert the frame from the disagreement between last frames and entered fram
es | 1535 // Insert the frame from the disagreement between last frames and entered |
| 1536 // frames. |
1489 while (exitedFrameInDocument) { | 1537 while (exitedFrameInDocument) { |
1490 Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler() | 1538 Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler() |
1491 .m_mouseEventManager->getNodeUnderMouse(); | 1539 .m_mouseEventManager->getNodeUnderMouse(); |
1492 if (!lastNodeUnderTap) | 1540 if (!lastNodeUnderTap) |
1493 break; | 1541 break; |
1494 | 1542 |
1495 LocalFrame* nextExitedFrameInDocument = nullptr; | 1543 LocalFrame* nextExitedFrameInDocument = nullptr; |
1496 if (lastNodeUnderTap->isFrameOwnerElement()) { | 1544 if (lastNodeUnderTap->isFrameOwnerElement()) { |
1497 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnderTap); | 1545 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnderTap); |
1498 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) | 1546 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval, | 1634 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval, |
1587 BLINK_FROM_HERE); | 1635 BLINK_FROM_HERE); |
1588 } | 1636 } |
1589 | 1637 |
1590 return eventWithHitTestResults; | 1638 return eventWithHitTestResults; |
1591 } | 1639 } |
1592 | 1640 |
1593 GestureEventWithHitTestResults EventHandler::hitTestResultForGestureEvent( | 1641 GestureEventWithHitTestResults EventHandler::hitTestResultForGestureEvent( |
1594 const PlatformGestureEvent& gestureEvent, | 1642 const PlatformGestureEvent& gestureEvent, |
1595 HitTestRequest::HitTestRequestType hitType) { | 1643 HitTestRequest::HitTestRequestType hitType) { |
1596 // Perform the rect-based hit-test (or point-based if adjustment is disabled).
Note that | 1644 // Perform the rect-based hit-test (or point-based if adjustment is disabled). |
1597 // we don't yet apply hover/active state here because we need to resolve touch
adjustment | 1645 // Note that we don't yet apply hover/active state here because we need to |
1598 // first so that we apply hover/active it to the final adjusted node. | 1646 // resolve touch adjustment first so that we apply hover/active it to the |
| 1647 // final adjusted node. |
1599 IntPoint hitTestPoint = | 1648 IntPoint hitTestPoint = |
1600 m_frame->view()->rootFrameToContents(gestureEvent.position()); | 1649 m_frame->view()->rootFrameToContents(gestureEvent.position()); |
1601 LayoutSize padding; | 1650 LayoutSize padding; |
1602 if (shouldApplyTouchAdjustment(gestureEvent)) { | 1651 if (shouldApplyTouchAdjustment(gestureEvent)) { |
1603 padding = LayoutSize(gestureEvent.area()); | 1652 padding = LayoutSize(gestureEvent.area()); |
1604 if (!padding.isEmpty()) { | 1653 if (!padding.isEmpty()) { |
1605 padding.scale(1.f / 2); | 1654 padding.scale(1.f / 2); |
1606 hitType |= HitTestRequest::ListBased; | 1655 hitType |= HitTestRequest::ListBased; |
1607 } | 1656 } |
1608 } | 1657 } |
1609 HitTestResult hitTestResult = hitTestResultAtPoint( | 1658 HitTestResult hitTestResult = hitTestResultAtPoint( |
1610 hitTestPoint, hitType | HitTestRequest::ReadOnly, padding); | 1659 hitTestPoint, hitType | HitTestRequest::ReadOnly, padding); |
1611 | 1660 |
1612 // Adjust the location of the gesture to the most likely nearby node, as appro
priate for the | 1661 // Adjust the location of the gesture to the most likely nearby node, as |
1613 // type of event. | 1662 // appropriate for the type of event. |
1614 PlatformGestureEvent adjustedEvent = gestureEvent; | 1663 PlatformGestureEvent adjustedEvent = gestureEvent; |
1615 applyTouchAdjustment(&adjustedEvent, &hitTestResult); | 1664 applyTouchAdjustment(&adjustedEvent, &hitTestResult); |
1616 | 1665 |
1617 // Do a new hit-test at the (adjusted) gesture co-ordinates. This is necessary
because | 1666 // Do a new hit-test at the (adjusted) gesture co-ordinates. This is necessary |
1618 // rect-based hit testing and touch adjustment sometimes return a different no
de than | 1667 // because rect-based hit testing and touch adjustment sometimes return a |
1619 // what a point-based hit test would return for the same point. | 1668 // different node than what a point-based hit test would return for the same |
1620 // FIXME: Fix touch adjustment to avoid the need for a redundant hit test. htt
p://crbug.com/398914 | 1669 // point. |
| 1670 // FIXME: Fix touch adjustment to avoid the need for a redundant hit test. |
| 1671 // http://crbug.com/398914 |
1621 if (shouldApplyTouchAdjustment(gestureEvent)) { | 1672 if (shouldApplyTouchAdjustment(gestureEvent)) { |
1622 LocalFrame* hitFrame = hitTestResult.innerNodeFrame(); | 1673 LocalFrame* hitFrame = hitTestResult.innerNodeFrame(); |
1623 if (!hitFrame) | 1674 if (!hitFrame) |
1624 hitFrame = m_frame; | 1675 hitFrame = m_frame; |
1625 hitTestResult = EventHandlingUtil::hitTestResultInFrame( | 1676 hitTestResult = EventHandlingUtil::hitTestResultInFrame( |
1626 hitFrame, | 1677 hitFrame, |
1627 hitFrame->view()->rootFrameToContents(adjustedEvent.position()), | 1678 hitFrame->view()->rootFrameToContents(adjustedEvent.position()), |
1628 (hitType | HitTestRequest::ReadOnly) & ~HitTestRequest::ListBased); | 1679 (hitType | HitTestRequest::ReadOnly) & ~HitTestRequest::ListBased); |
1629 } | 1680 } |
1630 | 1681 |
1631 // If we did a rect-based hit test it must be resolved to the best single node
by now to | 1682 // If we did a rect-based hit test it must be resolved to the best single node |
1632 // ensure consumers don't accidentally use one of the other candidates. | 1683 // by now to ensure consumers don't accidentally use one of the other |
| 1684 // candidates. |
1633 ASSERT(!hitTestResult.isRectBasedTest()); | 1685 ASSERT(!hitTestResult.isRectBasedTest()); |
1634 | 1686 |
1635 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult); | 1687 return GestureEventWithHitTestResults(adjustedEvent, hitTestResult); |
1636 } | 1688 } |
1637 | 1689 |
1638 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, | 1690 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, |
1639 HitTestResult* hitTestResult) { | 1691 HitTestResult* hitTestResult) { |
1640 if (!shouldApplyTouchAdjustment(*gestureEvent)) | 1692 if (!shouldApplyTouchAdjustment(*gestureEvent)) |
1641 return; | 1693 return; |
1642 | 1694 |
(...skipping 11 matching lines...) Expand all Loading... |
1654 case PlatformEvent::GestureLongPress: | 1706 case PlatformEvent::GestureLongPress: |
1655 case PlatformEvent::GestureLongTap: | 1707 case PlatformEvent::GestureLongTap: |
1656 case PlatformEvent::GestureTwoFingerTap: | 1708 case PlatformEvent::GestureTwoFingerTap: |
1657 adjusted = bestContextMenuNodeForHitTestResult( | 1709 adjusted = bestContextMenuNodeForHitTestResult( |
1658 *hitTestResult, adjustedPoint, adjustedNode); | 1710 *hitTestResult, adjustedPoint, adjustedNode); |
1659 break; | 1711 break; |
1660 default: | 1712 default: |
1661 ASSERT_NOT_REACHED(); | 1713 ASSERT_NOT_REACHED(); |
1662 } | 1714 } |
1663 | 1715 |
1664 // Update the hit-test result to be a point-based result instead of a rect-bas
ed result. | 1716 // Update the hit-test result to be a point-based result instead of a |
1665 // FIXME: We should do this even when no candidate matches the node filter. cr
bug.com/398914 | 1717 // rect-based result. |
| 1718 // FIXME: We should do this even when no candidate matches the node filter. |
| 1719 // crbug.com/398914 |
1666 if (adjusted) { | 1720 if (adjusted) { |
1667 hitTestResult->resolveRectBasedTest( | 1721 hitTestResult->resolveRectBasedTest( |
1668 adjustedNode, m_frame->view()->rootFrameToContents(adjustedPoint)); | 1722 adjustedNode, m_frame->view()->rootFrameToContents(adjustedPoint)); |
1669 gestureEvent->applyTouchAdjustment(adjustedPoint); | 1723 gestureEvent->applyTouchAdjustment(adjustedPoint); |
1670 } | 1724 } |
1671 } | 1725 } |
1672 | 1726 |
1673 WebInputEventResult EventHandler::sendContextMenuEvent( | 1727 WebInputEventResult EventHandler::sendContextMenuEvent( |
1674 const PlatformMouseEvent& event, | 1728 const PlatformMouseEvent& event, |
1675 Node* overrideTargetNode) { | 1729 Node* overrideTargetNode) { |
1676 FrameView* v = m_frame->view(); | 1730 FrameView* v = m_frame->view(); |
1677 if (!v) | 1731 if (!v) |
1678 return WebInputEventResult::NotHandled; | 1732 return WebInputEventResult::NotHandled; |
1679 | 1733 |
1680 // Clear mouse press state to avoid initiating a drag while context menu is up
. | 1734 // Clear mouse press state to avoid initiating a drag while context menu is |
| 1735 // up. |
1681 m_mouseEventManager->setMousePressed(false); | 1736 m_mouseEventManager->setMousePressed(false); |
1682 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); | 1737 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); |
1683 HitTestRequest request(HitTestRequest::Active); | 1738 HitTestRequest request(HitTestRequest::Active); |
1684 MouseEventWithHitTestResults mev = | 1739 MouseEventWithHitTestResults mev = |
1685 m_frame->document()->performMouseEventHitTest(request, positionInContents, | 1740 m_frame->document()->performMouseEventHitTest(request, positionInContents, |
1686 event); | 1741 event); |
1687 // Since |Document::performMouseEventHitTest()| modifies layout tree for setti
ng | 1742 // Since |Document::performMouseEventHitTest()| modifies layout tree for |
1688 // hover element, we need to update layout tree for requirement of | 1743 // setting hover element, we need to update layout tree for requirement of |
1689 // |SelectionController::sendContextMenuEvent()|. | 1744 // |SelectionController::sendContextMenuEvent()|. |
1690 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1745 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
1691 | 1746 |
1692 selectionController().sendContextMenuEvent(mev, positionInContents); | 1747 selectionController().sendContextMenuEvent(mev, positionInContents); |
1693 | 1748 |
1694 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode(); | 1749 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode(); |
1695 return m_mouseEventManager->dispatchMouseEvent( | 1750 return m_mouseEventManager->dispatchMouseEvent( |
1696 updateMouseEventTargetNode(targetNode), EventTypeNames::contextmenu, | 1751 updateMouseEventTargetNode(targetNode), EventTypeNames::contextmenu, |
1697 event, 0); | 1752 event, 0); |
1698 } | 1753 } |
(...skipping 26 matching lines...) Expand all Loading... |
1725 if (!overrideTargetElement && start.anchorNode() && | 1780 if (!overrideTargetElement && start.anchorNode() && |
1726 (selection.rootEditableElement() || selection.isRange())) { | 1781 (selection.rootEditableElement() || selection.isRange())) { |
1727 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 1782 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
1728 // needs to be audited. See http://crbug.com/590369 for more details. | 1783 // needs to be audited. See http://crbug.com/590369 for more details. |
1729 doc->updateStyleAndLayoutIgnorePendingStylesheets(); | 1784 doc->updateStyleAndLayoutIgnorePendingStylesheets(); |
1730 | 1785 |
1731 IntRect firstRect = m_frame->editor().firstRectForRange( | 1786 IntRect firstRect = m_frame->editor().firstRectForRange( |
1732 selection.selection().toNormalizedEphemeralRange()); | 1787 selection.selection().toNormalizedEphemeralRange()); |
1733 | 1788 |
1734 int x = rightAligned ? firstRect.maxX() : firstRect.x(); | 1789 int x = rightAligned ? firstRect.maxX() : firstRect.x(); |
1735 // In a multiline edit, firstRect.maxY() would endup on the next line, so -1
. | 1790 // In a multiline edit, firstRect.maxY() would end up on the next line, so |
| 1791 // -1. |
1736 int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0; | 1792 int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0; |
1737 locationInRootFrame = view->contentsToRootFrame(IntPoint(x, y)); | 1793 locationInRootFrame = view->contentsToRootFrame(IntPoint(x, y)); |
1738 } else if (focusedElement) { | 1794 } else if (focusedElement) { |
1739 IntRect clippedRect = focusedElement->boundsInViewport(); | 1795 IntRect clippedRect = focusedElement->boundsInViewport(); |
1740 locationInRootFrame = | 1796 locationInRootFrame = |
1741 visualViewport.viewportToRootFrame(clippedRect.center()); | 1797 visualViewport.viewportToRootFrame(clippedRect.center()); |
1742 } else { | 1798 } else { |
1743 locationInRootFrame = IntPoint( | 1799 locationInRootFrame = IntPoint( |
1744 rightAligned ? visualViewport.visibleRect().maxX() - kContextMenuMargin | 1800 rightAligned ? visualViewport.visibleRect().maxX() - kContextMenuMargin |
1745 : visualViewport.location().x() + kContextMenuMargin, | 1801 : visualViewport.location().x() + kContextMenuMargin, |
(...skipping 13 matching lines...) Expand all Loading... |
1759 overrideTargetElement ? overrideTargetElement : doc->focusedElement(); | 1815 overrideTargetElement ? overrideTargetElement : doc->focusedElement(); |
1760 if (!targetNode) | 1816 if (!targetNode) |
1761 targetNode = doc; | 1817 targetNode = doc; |
1762 | 1818 |
1763 // Use the focused node as the target for hover and active. | 1819 // Use the focused node as the target for hover and active. |
1764 HitTestRequest request(HitTestRequest::Active); | 1820 HitTestRequest request(HitTestRequest::Active); |
1765 HitTestResult result(request, locationInRootFrame); | 1821 HitTestResult result(request, locationInRootFrame); |
1766 result.setInnerNode(targetNode); | 1822 result.setInnerNode(targetNode); |
1767 doc->updateHoverActiveState(request, result.innerElement()); | 1823 doc->updateHoverActiveState(request, result.innerElement()); |
1768 | 1824 |
1769 // The contextmenu event is a mouse event even when invoked using the keyboard
. | 1825 // The contextmenu event is a mouse event even when invoked using the |
1770 // This is required for web compatibility. | 1826 // keyboard. This is required for web compatibility. |
1771 PlatformEvent::EventType eventType = PlatformEvent::MousePressed; | 1827 PlatformEvent::EventType eventType = PlatformEvent::MousePressed; |
1772 if (m_frame->settings() && m_frame->settings()->showContextMenuOnMouseUp()) | 1828 if (m_frame->settings() && m_frame->settings()->showContextMenuOnMouseUp()) |
1773 eventType = PlatformEvent::MouseReleased; | 1829 eventType = PlatformEvent::MouseReleased; |
1774 | 1830 |
1775 PlatformMouseEvent mouseEvent( | 1831 PlatformMouseEvent mouseEvent( |
1776 locationInRootFrame, globalPosition, | 1832 locationInRootFrame, globalPosition, |
1777 WebPointerProperties::Button::NoButton, eventType, /* clickCount */ 0, | 1833 WebPointerProperties::Button::NoButton, eventType, /* clickCount */ 0, |
1778 PlatformEvent::NoModifiers, PlatformMouseEvent::RealOrIndistinguishable, | 1834 PlatformEvent::NoModifiers, PlatformMouseEvent::RealOrIndistinguishable, |
1779 WTF::monotonicallyIncreasingTime(), | 1835 WTF::monotonicallyIncreasingTime(), |
1780 WebPointerProperties::PointerType::Mouse); | 1836 WebPointerProperties::PointerType::Mouse); |
1781 | 1837 |
1782 return sendContextMenuEvent(mouseEvent, overrideTargetElement); | 1838 return sendContextMenuEvent(mouseEvent, overrideTargetElement); |
1783 } | 1839 } |
1784 | 1840 |
1785 void EventHandler::scheduleHoverStateUpdate() { | 1841 void EventHandler::scheduleHoverStateUpdate() { |
1786 if (!m_hoverTimer.isActive()) | 1842 if (!m_hoverTimer.isActive()) |
1787 m_hoverTimer.startOneShot(0, BLINK_FROM_HERE); | 1843 m_hoverTimer.startOneShot(0, BLINK_FROM_HERE); |
1788 } | 1844 } |
1789 | 1845 |
1790 void EventHandler::scheduleCursorUpdate() { | 1846 void EventHandler::scheduleCursorUpdate() { |
1791 // We only want one timer for the page, rather than each frame having it's own
timer | 1847 // We only want one timer for the page, rather than each frame having it's own |
1792 // competing which eachother (since there's only one mouse cursor). | 1848 // timer competing which eachother (since there's only one mouse cursor). |
1793 ASSERT(m_frame == m_frame->localFrameRoot()); | 1849 ASSERT(m_frame == m_frame->localFrameRoot()); |
1794 | 1850 |
1795 if (!m_cursorUpdateTimer.isActive()) | 1851 if (!m_cursorUpdateTimer.isActive()) |
1796 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); | 1852 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); |
1797 } | 1853 } |
1798 | 1854 |
1799 bool EventHandler::cursorUpdatePending() { | 1855 bool EventHandler::cursorUpdatePending() { |
1800 return m_cursorUpdateTimer.isActive(); | 1856 return m_cursorUpdateTimer.isActive(); |
1801 } | 1857 } |
1802 | 1858 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 // m_lastDeferredTapElement.get() == m_frame->document()->activeElement() | 1901 // m_lastDeferredTapElement.get() == m_frame->document()->activeElement() |
1846 HitTestRequest request(HitTestRequest::TouchEvent | | 1902 HitTestRequest request(HitTestRequest::TouchEvent | |
1847 HitTestRequest::Release); | 1903 HitTestRequest::Release); |
1848 m_frame->document()->updateHoverActiveState(request, | 1904 m_frame->document()->updateHoverActiveState(request, |
1849 m_lastDeferredTapElement.get()); | 1905 m_lastDeferredTapElement.get()); |
1850 } | 1906 } |
1851 m_lastDeferredTapElement = nullptr; | 1907 m_lastDeferredTapElement = nullptr; |
1852 } | 1908 } |
1853 | 1909 |
1854 void EventHandler::notifyElementActivated() { | 1910 void EventHandler::notifyElementActivated() { |
1855 // Since another element has been set to active, stop current timer and clear
reference. | 1911 // Since another element has been set to active, stop current timer and clear |
| 1912 // reference. |
1856 if (m_activeIntervalTimer.isActive()) | 1913 if (m_activeIntervalTimer.isActive()) |
1857 m_activeIntervalTimer.stop(); | 1914 m_activeIntervalTimer.stop(); |
1858 m_lastDeferredTapElement = nullptr; | 1915 m_lastDeferredTapElement = nullptr; |
1859 } | 1916 } |
1860 | 1917 |
1861 bool EventHandler::handleAccessKey(const WebKeyboardEvent& evt) { | 1918 bool EventHandler::handleAccessKey(const WebKeyboardEvent& evt) { |
1862 return m_keyboardEventManager->handleAccessKey(evt); | 1919 return m_keyboardEventManager->handleAccessKey(evt); |
1863 } | 1920 } |
1864 | 1921 |
1865 WebInputEventResult EventHandler::keyEvent( | 1922 WebInputEventResult EventHandler::keyEvent( |
1866 const WebKeyboardEvent& initialKeyEvent) { | 1923 const WebKeyboardEvent& initialKeyEvent) { |
1867 return m_keyboardEventManager->keyEvent(initialKeyEvent); | 1924 return m_keyboardEventManager->keyEvent(initialKeyEvent); |
1868 } | 1925 } |
1869 | 1926 |
1870 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) { | 1927 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) { |
1871 m_keyboardEventManager->defaultKeyboardEventHandler( | 1928 m_keyboardEventManager->defaultKeyboardEventHandler( |
1872 event, m_mouseEventManager->mousePressNode()); | 1929 event, m_mouseEventManager->mousePressNode()); |
1873 } | 1930 } |
1874 | 1931 |
1875 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, | 1932 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, |
1876 DragOperation operation) { | 1933 DragOperation operation) { |
1877 m_mouseEventManager->dragSourceEndedAt(event, operation); | 1934 m_mouseEventManager->dragSourceEndedAt(event, operation); |
1878 } | 1935 } |
1879 | 1936 |
1880 void EventHandler::updateDragStateAfterEditDragIfNeeded( | 1937 void EventHandler::updateDragStateAfterEditDragIfNeeded( |
1881 Element* rootEditableElement) { | 1938 Element* rootEditableElement) { |
1882 // If inserting the dragged contents removed the drag source, we still want to
fire dragend at the root editble element. | 1939 // If inserting the dragged contents removed the drag source, we still want to |
| 1940 // fire dragend at the root editble element. |
1883 if (m_mouseEventManager->dragState().m_dragSrc && | 1941 if (m_mouseEventManager->dragState().m_dragSrc && |
1884 !m_mouseEventManager->dragState().m_dragSrc->isConnected()) | 1942 !m_mouseEventManager->dragState().m_dragSrc->isConnected()) |
1885 m_mouseEventManager->dragState().m_dragSrc = rootEditableElement; | 1943 m_mouseEventManager->dragState().m_dragSrc = rootEditableElement; |
1886 } | 1944 } |
1887 | 1945 |
1888 bool EventHandler::handleTextInputEvent(const String& text, | 1946 bool EventHandler::handleTextInputEvent(const String& text, |
1889 Event* underlyingEvent, | 1947 Event* underlyingEvent, |
1890 TextEventInputType inputType) { | 1948 TextEventInputType inputType) { |
1891 // Platforms should differentiate real commands like selectAll from text input
in disguise (like insertNewline), | 1949 // Platforms should differentiate real commands like selectAll from text input |
1892 // and avoid dispatching text input events from keydown default handlers. | 1950 // in disguise (like insertNewline), and avoid dispatching text input events |
| 1951 // from keydown default handlers. |
1893 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || | 1952 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || |
1894 toKeyboardEvent(underlyingEvent)->type() == EventTypeNames::keypress); | 1953 toKeyboardEvent(underlyingEvent)->type() == EventTypeNames::keypress); |
1895 | 1954 |
1896 if (!m_frame) | 1955 if (!m_frame) |
1897 return false; | 1956 return false; |
1898 | 1957 |
1899 EventTarget* target; | 1958 EventTarget* target; |
1900 if (underlyingEvent) | 1959 if (underlyingEvent) |
1901 target = underlyingEvent->target(); | 1960 target = underlyingEvent->target(); |
1902 else | 1961 else |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe( | 2042 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe( |
1984 MouseEventWithHitTestResults& mev, | 2043 MouseEventWithHitTestResults& mev, |
1985 LocalFrame* subframe) { | 2044 LocalFrame* subframe) { |
1986 WebInputEventResult result = | 2045 WebInputEventResult result = |
1987 subframe->eventHandler().handleMouseReleaseEvent(mev.event()); | 2046 subframe->eventHandler().handleMouseReleaseEvent(mev.event()); |
1988 if (result != WebInputEventResult::NotHandled) | 2047 if (result != WebInputEventResult::NotHandled) |
1989 return result; | 2048 return result; |
1990 return WebInputEventResult::HandledSystem; | 2049 return WebInputEventResult::HandledSystem; |
1991 } | 2050 } |
1992 | 2051 |
1993 | |
1994 FrameHost* EventHandler::frameHost() const { | 2052 FrameHost* EventHandler::frameHost() const { |
1995 if (!m_frame->page()) | 2053 if (!m_frame->page()) |
1996 return nullptr; | 2054 return nullptr; |
1997 | 2055 |
1998 return &m_frame->page()->frameHost(); | 2056 return &m_frame->page()->frameHost(); |
1999 } | 2057 } |
2000 | 2058 |
2001 } // namespace blink | 2059 } // namespace blink |
OLD | NEW |