OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 #include "core/loader/DocumentLoader.h" | 65 #include "core/loader/DocumentLoader.h" |
66 #include "core/loader/FrameLoader.h" | 66 #include "core/loader/FrameLoader.h" |
67 #include "core/loader/UniqueIdentifier.h" | 67 #include "core/loader/UniqueIdentifier.h" |
68 #include "core/page/Chrome.h" | 68 #include "core/page/Chrome.h" |
69 #include "core/page/ContextMenuController.h" | 69 #include "core/page/ContextMenuController.h" |
70 #include "core/page/ContextMenuProvider.h" | 70 #include "core/page/ContextMenuProvider.h" |
71 #include "core/page/DragController.h" | 71 #include "core/page/DragController.h" |
72 #include "core/page/DragData.h" | 72 #include "core/page/DragData.h" |
73 #include "core/page/DragSession.h" | 73 #include "core/page/DragSession.h" |
74 #include "core/page/EventHandler.h" | 74 #include "core/page/EventHandler.h" |
75 #include "core/page/EventWithHitTestResults.h" | |
76 #include "core/page/FocusController.h" | 75 #include "core/page/FocusController.h" |
77 #include "core/page/FrameTree.h" | 76 #include "core/page/FrameTree.h" |
78 #include "core/page/InjectedStyleSheets.h" | 77 #include "core/page/InjectedStyleSheets.h" |
79 #include "core/page/Page.h" | 78 #include "core/page/Page.h" |
80 #include "core/page/PagePopupClient.h" | 79 #include "core/page/PagePopupClient.h" |
81 #include "core/page/PointerLockController.h" | 80 #include "core/page/PointerLockController.h" |
82 #include "core/page/ScopedPageLoadDeferrer.h" | 81 #include "core/page/ScopedPageLoadDeferrer.h" |
83 #include "core/page/TouchDisambiguation.h" | 82 #include "core/page/TouchDisambiguation.h" |
84 #include "core/rendering/RenderView.h" | 83 #include "core/rendering/RenderView.h" |
85 #include "core/rendering/RenderWidget.h" | 84 #include "core/rendering/RenderWidget.h" |
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 eventSwallowed = true; | 669 eventSwallowed = true; |
671 | 670 |
672 m_client->didHandleGestureEvent(event, eventCancelled); | 671 m_client->didHandleGestureEvent(event, eventCancelled); |
673 return eventSwallowed; | 672 return eventSwallowed; |
674 default: | 673 default: |
675 break; | 674 break; |
676 } | 675 } |
677 | 676 |
678 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); | 677 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); |
679 | 678 |
680 // FIXME: Remove redundant hit tests by pushing the call to EventHandler::ta
rgetGestureEvent | 679 // Special handling for double tap and scroll events as we don't want to |
681 // up to this point and pass GestureEventWithHitTestResults around. | 680 // hit test for them. |
| 681 switch (event.type) { |
| 682 case WebInputEvent::GestureDoubleTap: |
| 683 if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor()
!= maximumPageScaleFactor()) { |
| 684 m_client->cancelScheduledContentIntents(); |
| 685 animateDoubleTapZoom(platformEvent.position()); |
| 686 } |
| 687 // GestureDoubleTap is currently only used by Android for zooming. For W
ebCore, |
| 688 // GestureTap with tap count = 2 is used instead. So we drop GestureDoub
leTap here. |
| 689 eventSwallowed = true; |
| 690 m_client->didHandleGestureEvent(event, eventCancelled); |
| 691 return eventSwallowed; |
| 692 case WebInputEvent::GestureScrollBegin: |
| 693 case WebInputEvent::GesturePinchBegin: |
| 694 m_client->cancelScheduledContentIntents(); |
| 695 case WebInputEvent::GestureScrollEnd: |
| 696 case WebInputEvent::GestureScrollUpdate: |
| 697 case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
| 698 case WebInputEvent::GesturePinchEnd: |
| 699 case WebInputEvent::GesturePinchUpdate: |
| 700 case WebInputEvent::GestureFlingStart: |
| 701 // Scrolling-related gesture events invoke EventHandler recursively for
each frame down |
| 702 // the chain, doing a single-frame hit-test per frame. This matches hand
leWheelEvent. |
| 703 // Perhaps we could simplify things by rewriting scroll handling to work
inner frame |
| 704 // out, and then unify with other gesture events. |
| 705 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureS
crollEvent(platformEvent); |
| 706 m_client->didHandleGestureEvent(event, eventCancelled); |
| 707 return eventSwallowed; |
| 708 default: |
| 709 break; |
| 710 } |
| 711 |
| 712 // Hit test across all frames and do touch adjustment as necessary for the e
vent type. |
| 713 GestureEventWithHitTestResults targetedEvent = |
| 714 m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(pl
atformEvent); |
682 | 715 |
683 // Handle link highlighting outside the main switch to avoid getting lost in
the | 716 // Handle link highlighting outside the main switch to avoid getting lost in
the |
684 // complicated set of cases handled below. | 717 // complicated set of cases handled below. |
685 switch (event.type) { | 718 switch (event.type) { |
686 case WebInputEvent::GestureShowPress: | 719 case WebInputEvent::GestureShowPress: |
687 // Queue a highlight animation, then hand off to regular handler. | 720 // Queue a highlight animation, then hand off to regular handler. |
688 enableTapHighlightAtPoint(platformEvent); | 721 enableTapHighlightAtPoint(targetedEvent); |
689 break; | 722 break; |
690 case WebInputEvent::GestureTapCancel: | 723 case WebInputEvent::GestureTapCancel: |
691 case WebInputEvent::GestureTap: | 724 case WebInputEvent::GestureTap: |
692 case WebInputEvent::GestureLongPress: | 725 case WebInputEvent::GestureLongPress: |
693 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | 726 for (size_t i = 0; i < m_linkHighlights.size(); ++i) |
694 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | 727 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); |
695 break; | 728 break; |
696 default: | 729 default: |
697 break; | 730 break; |
698 } | 731 } |
699 | 732 |
700 switch (event.type) { | 733 switch (event.type) { |
701 case WebInputEvent::GestureTap: { | 734 case WebInputEvent::GestureTap: { |
702 m_client->cancelScheduledContentIntents(); | 735 m_client->cancelScheduledContentIntents(); |
| 736 // FIXME: Use targeted event here and save another hit test. |
| 737 // FIXME: Content intent should be generated using same node that was hi
ghlighted. crbug.com/416746 |
703 if (detectContentOnTouch(platformEvent.position())) { | 738 if (detectContentOnTouch(platformEvent.position())) { |
704 eventSwallowed = true; | 739 eventSwallowed = true; |
705 break; | 740 break; |
706 } | 741 } |
707 | 742 |
708 RefPtr<PopupContainer> selectPopup; | 743 RefPtr<PopupContainer> selectPopup; |
709 selectPopup = m_selectPopup; | 744 selectPopup = m_selectPopup; |
710 hideSelectPopup(); | 745 hideSelectPopup(); |
711 ASSERT(!m_selectPopup); | 746 ASSERT(!m_selectPopup); |
712 | 747 |
(...skipping 16 matching lines...) Expand all Loading... |
729 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { | 764 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { |
730 enableTapHighlights(highlightNodes); | 765 enableTapHighlights(highlightNodes); |
731 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | 766 for (size_t i = 0; i < m_linkHighlights.size(); ++i) |
732 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | 767 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); |
733 eventSwallowed = true; | 768 eventSwallowed = true; |
734 eventCancelled = true; | 769 eventCancelled = true; |
735 break; | 770 break; |
736 } | 771 } |
737 } | 772 } |
738 | 773 |
739 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); | 774 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); |
740 | 775 |
741 if (m_selectPopup && m_selectPopup == selectPopup) { | 776 if (m_selectPopup && m_selectPopup == selectPopup) { |
742 // That tap triggered a select popup which is the same as the one th
at | 777 // That tap triggered a select popup which is the same as the one th
at |
743 // was showing before the tap. It means the user tapped the select | 778 // was showing before the tap. It means the user tapped the select |
744 // while the popup was showing, and as a result we first closed then | 779 // while the popup was showing, and as a result we first closed then |
745 // immediately reopened the select popup. It needs to be closed. | 780 // immediately reopened the select popup. It needs to be closed. |
746 hideSelectPopup(); | 781 hideSelectPopup(); |
747 } | 782 } |
748 | 783 |
749 break; | 784 break; |
750 } | 785 } |
751 case WebInputEvent::GestureTwoFingerTap: | 786 case WebInputEvent::GestureTwoFingerTap: |
752 case WebInputEvent::GestureLongPress: | 787 case WebInputEvent::GestureLongPress: |
753 case WebInputEvent::GestureLongTap: { | 788 case WebInputEvent::GestureLongTap: { |
754 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 789 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
755 break; | 790 break; |
756 | 791 |
757 m_client->cancelScheduledContentIntents(); | 792 m_client->cancelScheduledContentIntents(); |
758 m_page->contextMenuController().clearContextMenu(); | 793 m_page->contextMenuController().clearContextMenu(); |
759 m_contextMenuAllowed = true; | 794 m_contextMenuAllowed = true; |
760 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); | 795 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); |
761 m_contextMenuAllowed = false; | 796 m_contextMenuAllowed = false; |
762 | 797 |
763 break; | 798 break; |
764 } | 799 } |
765 case WebInputEvent::GestureShowPress: { | 800 case WebInputEvent::GestureShowPress: |
766 m_client->cancelScheduledContentIntents(); | |
767 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); | |
768 break; | |
769 } | |
770 case WebInputEvent::GestureDoubleTap: | |
771 if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor()
!= maximumPageScaleFactor()) { | |
772 m_client->cancelScheduledContentIntents(); | |
773 animateDoubleTapZoom(platformEvent.position()); | |
774 } | |
775 // GestureDoubleTap is currently only used by Android for zooming. For W
ebCore, | |
776 // GestureTap with tap count = 2 is used instead. So we drop GestureDoub
leTap here. | |
777 eventSwallowed = true; | |
778 break; | |
779 case WebInputEvent::GestureScrollBegin: | |
780 case WebInputEvent::GesturePinchBegin: | |
781 m_client->cancelScheduledContentIntents(); | 801 m_client->cancelScheduledContentIntents(); |
782 case WebInputEvent::GestureTapDown: | 802 case WebInputEvent::GestureTapDown: |
783 case WebInputEvent::GestureScrollEnd: | |
784 case WebInputEvent::GestureScrollUpdate: | |
785 case WebInputEvent::GestureScrollUpdateWithoutPropagation: | |
786 case WebInputEvent::GestureTapCancel: | 803 case WebInputEvent::GestureTapCancel: |
787 case WebInputEvent::GestureTapUnconfirmed: | 804 case WebInputEvent::GestureTapUnconfirmed: { |
788 case WebInputEvent::GesturePinchEnd: | 805 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); |
789 case WebInputEvent::GesturePinchUpdate: | |
790 case WebInputEvent::GestureFlingStart: { | |
791 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); | |
792 break; | 806 break; |
793 } | 807 } |
794 default: | 808 default: |
795 ASSERT_NOT_REACHED(); | 809 ASSERT_NOT_REACHED(); |
796 } | 810 } |
797 m_client->didHandleGestureEvent(event, eventCancelled); | 811 m_client->didHandleGestureEvent(event, eventCancelled); |
798 return eventSwallowed; | 812 return eventSwallowed; |
799 } | 813 } |
800 | 814 |
801 void WebViewImpl::transferActiveWheelFlingAnimation(const WebActiveWheelFlingPar
ameters& parameters) | 815 void WebViewImpl::transferActiveWheelFlingAnimation(const WebActiveWheelFlingPar
ameters& parameters) |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 static bool showsHandCursor(Node* node, LocalFrame* frame) | 1218 static bool showsHandCursor(Node* node, LocalFrame* frame) |
1205 { | 1219 { |
1206 if (!node || !node->renderer()) | 1220 if (!node || !node->renderer()) |
1207 return false; | 1221 return false; |
1208 | 1222 |
1209 ECursor cursor = node->renderer()->style()->cursor(); | 1223 ECursor cursor = node->renderer()->style()->cursor(); |
1210 return cursor == CURSOR_POINTER | 1224 return cursor == CURSOR_POINTER |
1211 || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, n
ode->isLink())); | 1225 || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, n
ode->isLink())); |
1212 } | 1226 } |
1213 | 1227 |
1214 Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) | 1228 Node* WebViewImpl::bestTapNode(const GestureEventWithHitTestResults& targetedTap
Event) |
1215 { | 1229 { |
1216 TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); | 1230 TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); |
1217 | 1231 |
1218 if (!m_page || !m_page->mainFrame()) | 1232 if (!m_page || !m_page->mainFrame()) |
1219 return 0; | 1233 return 0; |
1220 | 1234 |
1221 // FIXME: Rely on earlier hit test instead of hit testing again. | 1235 Node* bestTouchNode = targetedTapEvent.hitTestResult().innerNode(); |
1222 GestureEventWithHitTestResults targetedEvent = | |
1223 m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(ta
pEvent, true); | |
1224 Node* bestTouchNode = targetedEvent.hitTestResult().innerNode(); | |
1225 | 1236 |
1226 // We might hit something like an image map that has no renderer on it | 1237 // We might hit something like an image map that has no renderer on it |
1227 // Walk up the tree until we have a node with an attached renderer | 1238 // Walk up the tree until we have a node with an attached renderer |
1228 // FIXME: This wants to walk composed tree with NodeRenderingTraversal::pare
nt(). | 1239 // FIXME: This wants to walk composed tree with NodeRenderingTraversal::pare
nt(). |
1229 while (bestTouchNode && !bestTouchNode->renderer()) | 1240 while (bestTouchNode && !bestTouchNode->renderer()) |
1230 bestTouchNode = NodeRenderingTraversal::parent(bestTouchNode); | 1241 bestTouchNode = NodeRenderingTraversal::parent(bestTouchNode); |
1231 | 1242 |
1232 Node* cursorDefiningAncestor = | 1243 Node* cursorDefiningAncestor = |
1233 findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFra
me()); | 1244 findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFra
me()); |
1234 // We show a highlight on tap only when the current node shows a hand cursor | 1245 // We show a highlight on tap only when the current node shows a hand cursor |
1235 if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_pa
ge->deprecatedLocalMainFrame())) { | 1246 if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_pa
ge->deprecatedLocalMainFrame())) { |
1236 return 0; | 1247 return 0; |
1237 } | 1248 } |
1238 | 1249 |
1239 // We should pick the largest enclosing node with hand cursor set. We do thi
s by first jumping | 1250 // We should pick the largest enclosing node with hand cursor set. We do thi
s by first jumping |
1240 // up to cursorDefiningAncestor (which is already known to have hand cursor
set). Then we locate | 1251 // up to cursorDefiningAncestor (which is already known to have hand cursor
set). Then we locate |
1241 // the next cursor-defining ancestor up in the the tree and repeat the jumps
as long as the node | 1252 // the next cursor-defining ancestor up in the the tree and repeat the jumps
as long as the node |
1242 // has hand cursor set. | 1253 // has hand cursor set. |
1243 do { | 1254 do { |
1244 bestTouchNode = cursorDefiningAncestor; | 1255 bestTouchNode = cursorDefiningAncestor; |
1245 cursorDefiningAncestor = findCursorDefiningAncestor(NodeRenderingTravers
al::parent(bestTouchNode), | 1256 cursorDefiningAncestor = findCursorDefiningAncestor(NodeRenderingTravers
al::parent(bestTouchNode), |
1246 m_page->deprecatedLocalMainFrame()); | 1257 m_page->deprecatedLocalMainFrame()); |
1247 } while (cursorDefiningAncestor && showsHandCursor(cursorDefiningAncestor, m
_page->deprecatedLocalMainFrame())); | 1258 } while (cursorDefiningAncestor && showsHandCursor(cursorDefiningAncestor, m
_page->deprecatedLocalMainFrame())); |
1248 | 1259 |
1249 return bestTouchNode; | 1260 return bestTouchNode; |
1250 } | 1261 } |
1251 | 1262 |
1252 void WebViewImpl::enableTapHighlightAtPoint(const PlatformGestureEvent& tapEvent
) | 1263 void WebViewImpl::enableTapHighlightAtPoint(const GestureEventWithHitTestResults
& targetedTapEvent) |
1253 { | 1264 { |
1254 Node* touchNode = bestTapNode(tapEvent); | 1265 Node* touchNode = bestTapNode(targetedTapEvent); |
1255 | 1266 |
1256 WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes; | 1267 WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes; |
1257 highlightNodes.append(touchNode); | 1268 highlightNodes.append(touchNode); |
1258 | 1269 |
1259 enableTapHighlights(highlightNodes); | 1270 enableTapHighlights(highlightNodes); |
1260 } | 1271 } |
1261 | 1272 |
1262 void WebViewImpl::enableTapHighlights(WillBeHeapVector<RawPtrWillBeMember<Node>
>& highlightNodes) | 1273 void WebViewImpl::enableTapHighlights(WillBeHeapVector<RawPtrWillBeMember<Node>
>& highlightNodes) |
1263 { | 1274 { |
1264 if (highlightNodes.isEmpty()) | 1275 if (highlightNodes.isEmpty()) |
(...skipping 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4373 const PageScaleConstraints& constraints = m_pageScaleConstraintsSet.pageDefi
nedConstraints(); | 4384 const PageScaleConstraints& constraints = m_pageScaleConstraintsSet.pageDefi
nedConstraints(); |
4374 | 4385 |
4375 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 4386 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
4376 return false; | 4387 return false; |
4377 | 4388 |
4378 return mainFrameImpl()->frameView()->layoutSize().width() == m_size.width | 4389 return mainFrameImpl()->frameView()->layoutSize().width() == m_size.width |
4379 || (constraints.minimumScale == constraints.maximumScale && constraints.
minimumScale != -1); | 4390 || (constraints.minimumScale == constraints.maximumScale && constraints.
minimumScale != -1); |
4380 } | 4391 } |
4381 | 4392 |
4382 } // namespace blink | 4393 } // namespace blink |
OLD | NEW |