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...) 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" |
75 #include "core/page/FocusController.h" | 76 #include "core/page/FocusController.h" |
76 #include "core/page/FrameTree.h" | 77 #include "core/page/FrameTree.h" |
77 #include "core/page/InjectedStyleSheets.h" | 78 #include "core/page/InjectedStyleSheets.h" |
78 #include "core/page/Page.h" | 79 #include "core/page/Page.h" |
79 #include "core/page/PagePopupClient.h" | 80 #include "core/page/PagePopupClient.h" |
80 #include "core/page/PointerLockController.h" | 81 #include "core/page/PointerLockController.h" |
81 #include "core/page/ScopedPageLoadDeferrer.h" | 82 #include "core/page/ScopedPageLoadDeferrer.h" |
82 #include "core/page/TouchDisambiguation.h" | 83 #include "core/page/TouchDisambiguation.h" |
83 #include "core/rendering/RenderView.h" | 84 #include "core/rendering/RenderView.h" |
84 #include "core/rendering/RenderWidget.h" | 85 #include "core/rendering/RenderWidget.h" |
(...skipping 579 matching lines...) Loading... |
664 eventSwallowed = true; | 665 eventSwallowed = true; |
665 | 666 |
666 m_client->didHandleGestureEvent(event, eventCancelled); | 667 m_client->didHandleGestureEvent(event, eventCancelled); |
667 return eventSwallowed; | 668 return eventSwallowed; |
668 default: | 669 default: |
669 break; | 670 break; |
670 } | 671 } |
671 | 672 |
672 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); | 673 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); |
673 | 674 |
674 // Special handling for double tap and scroll events as we don't want to | 675 // FIXME: Remove redundant hit tests by pushing the call to EventHandler::ta
rgetGestureEvent |
675 // hit test for them. | 676 // up to this point and pass GestureEventWithHitTestResults around. |
676 switch (event.type) { | |
677 case WebInputEvent::GestureDoubleTap: | |
678 if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor()
!= maximumPageScaleFactor()) { | |
679 m_client->cancelScheduledContentIntents(); | |
680 animateDoubleTapZoom(platformEvent.position()); | |
681 } | |
682 // GestureDoubleTap is currently only used by Android for zooming. For W
ebCore, | |
683 // GestureTap with tap count = 2 is used instead. So we drop GestureDoub
leTap here. | |
684 eventSwallowed = true; | |
685 m_client->didHandleGestureEvent(event, eventCancelled); | |
686 return eventSwallowed; | |
687 case WebInputEvent::GestureScrollBegin: | |
688 case WebInputEvent::GesturePinchBegin: | |
689 m_client->cancelScheduledContentIntents(); | |
690 case WebInputEvent::GestureScrollEnd: | |
691 case WebInputEvent::GestureScrollUpdate: | |
692 case WebInputEvent::GestureScrollUpdateWithoutPropagation: | |
693 case WebInputEvent::GesturePinchEnd: | |
694 case WebInputEvent::GesturePinchUpdate: | |
695 case WebInputEvent::GestureFlingStart: | |
696 // Scrolling-related gesture events invoke EventHandler recursively for
each frame down | |
697 // the chain, doing a single-frame hit-test per frame. This matches hand
leWheelEvent. | |
698 // Perhaps we could simplify things by rewriting scroll handling to work
inner frame | |
699 // out, and then unify with other gesture events. | |
700 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureS
crollEvent(platformEvent); | |
701 m_client->didHandleGestureEvent(event, eventCancelled); | |
702 return eventSwallowed; | |
703 default: | |
704 break; | |
705 } | |
706 | |
707 // Hit test across all frames and do touch adjustment as necessary for the e
vent type. | |
708 GestureEventWithHitTestResults targetedEvent = | |
709 m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(pl
atformEvent); | |
710 | 677 |
711 // Handle link highlighting outside the main switch to avoid getting lost in
the | 678 // Handle link highlighting outside the main switch to avoid getting lost in
the |
712 // complicated set of cases handled below. | 679 // complicated set of cases handled below. |
713 switch (event.type) { | 680 switch (event.type) { |
714 case WebInputEvent::GestureShowPress: | 681 case WebInputEvent::GestureShowPress: |
715 // Queue a highlight animation, then hand off to regular handler. | 682 // Queue a highlight animation, then hand off to regular handler. |
716 enableTapHighlightAtPoint(targetedEvent); | 683 enableTapHighlightAtPoint(platformEvent); |
717 break; | 684 break; |
718 case WebInputEvent::GestureTapCancel: | 685 case WebInputEvent::GestureTapCancel: |
719 case WebInputEvent::GestureTap: | 686 case WebInputEvent::GestureTap: |
720 case WebInputEvent::GestureLongPress: | 687 case WebInputEvent::GestureLongPress: |
721 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | 688 for (size_t i = 0; i < m_linkHighlights.size(); ++i) |
722 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | 689 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); |
723 break; | 690 break; |
724 default: | 691 default: |
725 break; | 692 break; |
726 } | 693 } |
727 | 694 |
728 switch (event.type) { | 695 switch (event.type) { |
729 case WebInputEvent::GestureTap: { | 696 case WebInputEvent::GestureTap: { |
730 m_client->cancelScheduledContentIntents(); | 697 m_client->cancelScheduledContentIntents(); |
731 // FIXME: Use targeted event here and save another hit test. | 698 if (detectContentOnTouch(platformEvent.position())) { |
732 if (detectContentOnTouch(targetedEvent.event().position())) { | |
733 eventSwallowed = true; | 699 eventSwallowed = true; |
734 break; | 700 break; |
735 } | 701 } |
736 | 702 |
737 RefPtr<PopupContainer> selectPopup; | 703 RefPtr<PopupContainer> selectPopup; |
738 selectPopup = m_selectPopup; | 704 selectPopup = m_selectPopup; |
739 hideSelectPopup(); | 705 hideSelectPopup(); |
740 ASSERT(!m_selectPopup); | 706 ASSERT(!m_selectPopup); |
741 | 707 |
742 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. | 708 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. |
(...skipping 15 matching lines...) Loading... |
758 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { | 724 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { |
759 enableTapHighlights(highlightNodes); | 725 enableTapHighlights(highlightNodes); |
760 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | 726 for (size_t i = 0; i < m_linkHighlights.size(); ++i) |
761 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | 727 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); |
762 eventSwallowed = true; | 728 eventSwallowed = true; |
763 eventCancelled = true; | 729 eventCancelled = true; |
764 break; | 730 break; |
765 } | 731 } |
766 } | 732 } |
767 | 733 |
768 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); | 734 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); |
769 | 735 |
770 if (m_selectPopup && m_selectPopup == selectPopup) { | 736 if (m_selectPopup && m_selectPopup == selectPopup) { |
771 // That tap triggered a select popup which is the same as the one th
at | 737 // That tap triggered a select popup which is the same as the one th
at |
772 // was showing before the tap. It means the user tapped the select | 738 // was showing before the tap. It means the user tapped the select |
773 // while the popup was showing, and as a result we first closed then | 739 // while the popup was showing, and as a result we first closed then |
774 // immediately reopened the select popup. It needs to be closed. | 740 // immediately reopened the select popup. It needs to be closed. |
775 hideSelectPopup(); | 741 hideSelectPopup(); |
776 } | 742 } |
777 | 743 |
778 break; | 744 break; |
779 } | 745 } |
780 case WebInputEvent::GestureTwoFingerTap: | 746 case WebInputEvent::GestureTwoFingerTap: |
781 case WebInputEvent::GestureLongPress: | 747 case WebInputEvent::GestureLongPress: |
782 case WebInputEvent::GestureLongTap: { | 748 case WebInputEvent::GestureLongTap: { |
783 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 749 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
784 break; | 750 break; |
785 | 751 |
786 m_client->cancelScheduledContentIntents(); | 752 m_client->cancelScheduledContentIntents(); |
787 m_page->contextMenuController().clearContextMenu(); | 753 m_page->contextMenuController().clearContextMenu(); |
788 m_contextMenuAllowed = true; | 754 m_contextMenuAllowed = true; |
789 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); | 755 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); |
790 m_contextMenuAllowed = false; | 756 m_contextMenuAllowed = false; |
791 | 757 |
792 break; | 758 break; |
793 } | 759 } |
794 case WebInputEvent::GestureShowPress: | 760 case WebInputEvent::GestureShowPress: { |
| 761 m_client->cancelScheduledContentIntents(); |
| 762 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); |
| 763 break; |
| 764 } |
| 765 case WebInputEvent::GestureDoubleTap: |
| 766 if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor()
!= maximumPageScaleFactor()) { |
| 767 m_client->cancelScheduledContentIntents(); |
| 768 animateDoubleTapZoom(platformEvent.position()); |
| 769 } |
| 770 // GestureDoubleTap is currently only used by Android for zooming. For W
ebCore, |
| 771 // GestureTap with tap count = 2 is used instead. So we drop GestureDoub
leTap here. |
| 772 eventSwallowed = true; |
| 773 break; |
| 774 case WebInputEvent::GestureScrollBegin: |
| 775 case WebInputEvent::GesturePinchBegin: |
795 m_client->cancelScheduledContentIntents(); | 776 m_client->cancelScheduledContentIntents(); |
796 case WebInputEvent::GestureTapDown: | 777 case WebInputEvent::GestureTapDown: |
| 778 case WebInputEvent::GestureScrollEnd: |
| 779 case WebInputEvent::GestureScrollUpdate: |
| 780 case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
797 case WebInputEvent::GestureTapCancel: | 781 case WebInputEvent::GestureTapCancel: |
798 case WebInputEvent::GestureTapUnconfirmed: { | 782 case WebInputEvent::GestureTapUnconfirmed: |
799 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(targetedEvent); | 783 case WebInputEvent::GesturePinchEnd: |
| 784 case WebInputEvent::GesturePinchUpdate: |
| 785 case WebInputEvent::GestureFlingStart: { |
| 786 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); |
800 break; | 787 break; |
801 } | 788 } |
802 default: | 789 default: |
803 ASSERT_NOT_REACHED(); | 790 ASSERT_NOT_REACHED(); |
804 } | 791 } |
805 m_client->didHandleGestureEvent(event, eventCancelled); | 792 m_client->didHandleGestureEvent(event, eventCancelled); |
806 return eventSwallowed; | 793 return eventSwallowed; |
807 } | 794 } |
808 | 795 |
809 void WebViewImpl::transferActiveWheelFlingAnimation(const WebActiveWheelFlingPar
ameters& parameters) | 796 void WebViewImpl::transferActiveWheelFlingAnimation(const WebActiveWheelFlingPar
ameters& parameters) |
(...skipping 402 matching lines...) Loading... |
1212 static bool showsHandCursor(Node* node, LocalFrame* frame) | 1199 static bool showsHandCursor(Node* node, LocalFrame* frame) |
1213 { | 1200 { |
1214 if (!node || !node->renderer()) | 1201 if (!node || !node->renderer()) |
1215 return false; | 1202 return false; |
1216 | 1203 |
1217 ECursor cursor = node->renderer()->style()->cursor(); | 1204 ECursor cursor = node->renderer()->style()->cursor(); |
1218 return cursor == CURSOR_POINTER | 1205 return cursor == CURSOR_POINTER |
1219 || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, n
ode->isLink())); | 1206 || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, n
ode->isLink())); |
1220 } | 1207 } |
1221 | 1208 |
1222 Node* WebViewImpl::bestTapNode(const GestureEventWithHitTestResults& targetedTap
Event) | 1209 Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) |
1223 { | 1210 { |
1224 TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); | 1211 TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); |
1225 | 1212 |
1226 if (!m_page || !m_page->mainFrame()) | 1213 if (!m_page || !m_page->mainFrame()) |
1227 return 0; | 1214 return 0; |
1228 | 1215 |
1229 Node* bestTouchNode = targetedTapEvent.hitTestResult().innerNode(); | 1216 // FIXME: Rely on earlier hit test instead of hit testing again. |
| 1217 GestureEventWithHitTestResults targetedEvent = |
| 1218 m_page->deprecatedLocalMainFrame()->eventHandler().targetGestureEvent(ta
pEvent, true); |
| 1219 Node* bestTouchNode = targetedEvent.hitTestResult().innerNode(); |
1230 | 1220 |
1231 // We might hit something like an image map that has no renderer on it | 1221 // We might hit something like an image map that has no renderer on it |
1232 // Walk up the tree until we have a node with an attached renderer | 1222 // Walk up the tree until we have a node with an attached renderer |
1233 // FIXME: This wants to walk composed tree with NodeRenderingTraversal::pare
nt(). | 1223 // FIXME: This wants to walk composed tree with NodeRenderingTraversal::pare
nt(). |
1234 while (bestTouchNode && !bestTouchNode->renderer()) | 1224 while (bestTouchNode && !bestTouchNode->renderer()) |
1235 bestTouchNode = NodeRenderingTraversal::parent(bestTouchNode); | 1225 bestTouchNode = NodeRenderingTraversal::parent(bestTouchNode); |
1236 | 1226 |
1237 Node* cursorDefiningAncestor = | 1227 Node* cursorDefiningAncestor = |
1238 findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFra
me()); | 1228 findCursorDefiningAncestor(bestTouchNode, m_page->deprecatedLocalMainFra
me()); |
1239 // We show a highlight on tap only when the current node shows a hand cursor | 1229 // We show a highlight on tap only when the current node shows a hand cursor |
1240 if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_pa
ge->deprecatedLocalMainFrame())) { | 1230 if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_pa
ge->deprecatedLocalMainFrame())) { |
1241 return 0; | 1231 return 0; |
1242 } | 1232 } |
1243 | 1233 |
1244 // We should pick the largest enclosing node with hand cursor set. We do thi
s by first jumping | 1234 // We should pick the largest enclosing node with hand cursor set. We do thi
s by first jumping |
1245 // up to cursorDefiningAncestor (which is already known to have hand cursor
set). Then we locate | 1235 // up to cursorDefiningAncestor (which is already known to have hand cursor
set). Then we locate |
1246 // the next cursor-defining ancestor up in the the tree and repeat the jumps
as long as the node | 1236 // the next cursor-defining ancestor up in the the tree and repeat the jumps
as long as the node |
1247 // has hand cursor set. | 1237 // has hand cursor set. |
1248 do { | 1238 do { |
1249 bestTouchNode = cursorDefiningAncestor; | 1239 bestTouchNode = cursorDefiningAncestor; |
1250 cursorDefiningAncestor = findCursorDefiningAncestor(NodeRenderingTravers
al::parent(bestTouchNode), | 1240 cursorDefiningAncestor = findCursorDefiningAncestor(NodeRenderingTravers
al::parent(bestTouchNode), |
1251 m_page->deprecatedLocalMainFrame()); | 1241 m_page->deprecatedLocalMainFrame()); |
1252 } while (cursorDefiningAncestor && showsHandCursor(cursorDefiningAncestor, m
_page->deprecatedLocalMainFrame())); | 1242 } while (cursorDefiningAncestor && showsHandCursor(cursorDefiningAncestor, m
_page->deprecatedLocalMainFrame())); |
1253 | 1243 |
1254 return bestTouchNode; | 1244 return bestTouchNode; |
1255 } | 1245 } |
1256 | 1246 |
1257 void WebViewImpl::enableTapHighlightAtPoint(const GestureEventWithHitTestResults
& targetedTapEvent) | 1247 void WebViewImpl::enableTapHighlightAtPoint(const PlatformGestureEvent& tapEvent
) |
1258 { | 1248 { |
1259 Node* touchNode = bestTapNode(targetedTapEvent); | 1249 Node* touchNode = bestTapNode(tapEvent); |
1260 | 1250 |
1261 WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes; | 1251 WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes; |
1262 highlightNodes.append(touchNode); | 1252 highlightNodes.append(touchNode); |
1263 | 1253 |
1264 enableTapHighlights(highlightNodes); | 1254 enableTapHighlights(highlightNodes); |
1265 } | 1255 } |
1266 | 1256 |
1267 void WebViewImpl::enableTapHighlights(WillBeHeapVector<RawPtrWillBeMember<Node>
>& highlightNodes) | 1257 void WebViewImpl::enableTapHighlights(WillBeHeapVector<RawPtrWillBeMember<Node>
>& highlightNodes) |
1268 { | 1258 { |
1269 if (highlightNodes.isEmpty()) | 1259 if (highlightNodes.isEmpty()) |
(...skipping 3057 matching lines...) Loading... |
4327 const PageScaleConstraints& constraints = m_pageScaleConstraintsSet.pageDefi
nedConstraints(); | 4317 const PageScaleConstraints& constraints = m_pageScaleConstraintsSet.pageDefi
nedConstraints(); |
4328 | 4318 |
4329 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 4319 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
4330 return false; | 4320 return false; |
4331 | 4321 |
4332 return mainFrameImpl()->frameView()->layoutSize().width() == m_size.width | 4322 return mainFrameImpl()->frameView()->layoutSize().width() == m_size.width |
4333 || (constraints.minimumScale == constraints.maximumScale && constraints.
minimumScale != -1); | 4323 || (constraints.minimumScale == constraints.maximumScale && constraints.
minimumScale != -1); |
4334 } | 4324 } |
4335 | 4325 |
4336 } // namespace blink | 4326 } // namespace blink |
OLD | NEW |