Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: sky/engine/core/page/EventHandler.cpp

Issue 868133003: Remove touch events from Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/page/EventHandler.h ('k') | sky/engine/core/rendering/HitTestRequest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 27
28 #include "sky/engine/config.h" 28 #include "sky/engine/config.h"
29 #include "sky/engine/core/page/EventHandler.h" 29 #include "sky/engine/core/page/EventHandler.h"
30 30
31 #include "gen/sky/core/HTMLNames.h" 31 #include "gen/sky/core/HTMLNames.h"
32 #include "gen/sky/platform/RuntimeEnabledFeatures.h" 32 #include "gen/sky/platform/RuntimeEnabledFeatures.h"
33 #include "sky/engine/bindings/core/v8/ExceptionStatePlaceholder.h" 33 #include "sky/engine/bindings/core/v8/ExceptionStatePlaceholder.h"
34 #include "sky/engine/core/dom/Document.h" 34 #include "sky/engine/core/dom/Document.h"
35 #include "sky/engine/core/dom/DocumentMarkerController.h" 35 #include "sky/engine/core/dom/DocumentMarkerController.h"
36 #include "sky/engine/core/dom/NodeRenderingTraversal.h" 36 #include "sky/engine/core/dom/NodeRenderingTraversal.h"
37 #include "sky/engine/core/dom/TouchList.h"
38 #include "sky/engine/core/dom/shadow/ShadowRoot.h" 37 #include "sky/engine/core/dom/shadow/ShadowRoot.h"
39 #include "sky/engine/core/editing/Editor.h" 38 #include "sky/engine/core/editing/Editor.h"
40 #include "sky/engine/core/editing/FrameSelection.h" 39 #include "sky/engine/core/editing/FrameSelection.h"
41 #include "sky/engine/core/editing/TextIterator.h" 40 #include "sky/engine/core/editing/TextIterator.h"
42 #include "sky/engine/core/editing/htmlediting.h" 41 #include "sky/engine/core/editing/htmlediting.h"
43 #include "sky/engine/core/events/DOMWindowEventQueue.h" 42 #include "sky/engine/core/events/DOMWindowEventQueue.h"
44 #include "sky/engine/core/events/EventPath.h" 43 #include "sky/engine/core/events/EventPath.h"
45 #include "sky/engine/core/events/KeyboardEvent.h" 44 #include "sky/engine/core/events/KeyboardEvent.h"
46 #include "sky/engine/core/events/TextEvent.h" 45 #include "sky/engine/core/events/TextEvent.h"
47 #include "sky/engine/core/events/TouchEvent.h"
48 #include "sky/engine/core/fetch/ImageResource.h" 46 #include "sky/engine/core/fetch/ImageResource.h"
49 #include "sky/engine/core/frame/FrameView.h" 47 #include "sky/engine/core/frame/FrameView.h"
50 #include "sky/engine/core/frame/LocalFrame.h" 48 #include "sky/engine/core/frame/LocalFrame.h"
51 #include "sky/engine/core/frame/Settings.h" 49 #include "sky/engine/core/frame/Settings.h"
52 #include "sky/engine/core/loader/FrameLoaderClient.h" 50 #include "sky/engine/core/loader/FrameLoaderClient.h"
53 #include "sky/engine/core/page/AutoscrollController.h" 51 #include "sky/engine/core/page/AutoscrollController.h"
54 #include "sky/engine/core/page/Chrome.h" 52 #include "sky/engine/core/page/Chrome.h"
55 #include "sky/engine/core/page/ChromeClient.h" 53 #include "sky/engine/core/page/ChromeClient.h"
56 #include "sky/engine/core/page/EditorClient.h" 54 #include "sky/engine/core/page/EditorClient.h"
57 #include "sky/engine/core/page/EventWithHitTestResults.h" 55 #include "sky/engine/core/page/EventWithHitTestResults.h"
58 #include "sky/engine/core/page/FocusController.h" 56 #include "sky/engine/core/page/FocusController.h"
59 #include "sky/engine/core/page/Page.h" 57 #include "sky/engine/core/page/Page.h"
60 #include "sky/engine/core/rendering/HitTestRequest.h" 58 #include "sky/engine/core/rendering/HitTestRequest.h"
61 #include "sky/engine/core/rendering/HitTestResult.h" 59 #include "sky/engine/core/rendering/HitTestResult.h"
62 #include "sky/engine/core/rendering/RenderLayer.h" 60 #include "sky/engine/core/rendering/RenderLayer.h"
63 #include "sky/engine/core/rendering/RenderView.h" 61 #include "sky/engine/core/rendering/RenderView.h"
64 #include "sky/engine/core/rendering/style/RenderStyle.h" 62 #include "sky/engine/core/rendering/style/RenderStyle.h"
65 #include "sky/engine/platform/PlatformGestureEvent.h" 63 #include "sky/engine/platform/PlatformGestureEvent.h"
66 #include "sky/engine/platform/PlatformKeyboardEvent.h" 64 #include "sky/engine/platform/PlatformKeyboardEvent.h"
67 #include "sky/engine/platform/PlatformTouchEvent.h"
68 #include "sky/engine/platform/TraceEvent.h" 65 #include "sky/engine/platform/TraceEvent.h"
69 #include "sky/engine/platform/WindowsKeyboardCodes.h" 66 #include "sky/engine/platform/WindowsKeyboardCodes.h"
70 #include "sky/engine/platform/geometry/FloatPoint.h" 67 #include "sky/engine/platform/geometry/FloatPoint.h"
71 #include "sky/engine/platform/graphics/Image.h" 68 #include "sky/engine/platform/graphics/Image.h"
72 #include "sky/engine/platform/heap/Handle.h" 69 #include "sky/engine/platform/heap/Handle.h"
73 #include "sky/engine/platform/scroll/ScrollAnimator.h" 70 #include "sky/engine/platform/scroll/ScrollAnimator.h"
74 #include "sky/engine/platform/scroll/Scrollbar.h" 71 #include "sky/engine/platform/scroll/Scrollbar.h"
75 #include "sky/engine/wtf/Assertions.h" 72 #include "sky/engine/wtf/Assertions.h"
76 #include "sky/engine/wtf/CurrentTime.h" 73 #include "sky/engine/wtf/CurrentTime.h"
77 #include "sky/engine/wtf/StdLibExtras.h" 74 #include "sky/engine/wtf/StdLibExtras.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 , m_capturesDragging(false) 130 , m_capturesDragging(false)
134 , m_mouseDownMayStartSelect(false) 131 , m_mouseDownMayStartSelect(false)
135 , m_mouseDownMayStartDrag(false) 132 , m_mouseDownMayStartDrag(false)
136 , m_selectionInitiationState(HaveNotStartedSelection) 133 , m_selectionInitiationState(HaveNotStartedSelection)
137 , m_hoverTimer(this, &EventHandler::hoverTimerFired) 134 , m_hoverTimer(this, &EventHandler::hoverTimerFired)
138 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) 135 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
139 , m_mouseDownMayStartAutoscroll(false) 136 , m_mouseDownMayStartAutoscroll(false)
140 , m_clickCount(0) 137 , m_clickCount(0)
141 , m_shouldOnlyFireDragOverEvent(false) 138 , m_shouldOnlyFireDragOverEvent(false)
142 , m_mousePositionIsUnknown(true) 139 , m_mousePositionIsUnknown(true)
143 , m_touchPressed(false)
144 , m_scrollGestureHandlingNode(nullptr) 140 , m_scrollGestureHandlingNode(nullptr)
145 , m_lastGestureScrollOverWidget(false) 141 , m_lastGestureScrollOverWidget(false)
146 , m_maxMouseMovedDuration(0) 142 , m_maxMouseMovedDuration(0)
147 , m_didStartDrag(false) 143 , m_didStartDrag(false)
148 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) 144 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
149 , m_lastShowPressTimestamp(0) 145 , m_lastShowPressTimestamp(0)
150 { 146 {
151 } 147 }
152 148
153 EventHandler::~EventHandler() 149 EventHandler::~EventHandler()
(...skipping 12 matching lines...) Expand all
166 m_clickNode = nullptr; 162 m_clickNode = nullptr;
167 m_dragTarget = nullptr; 163 m_dragTarget = nullptr;
168 m_shouldOnlyFireDragOverEvent = false; 164 m_shouldOnlyFireDragOverEvent = false;
169 m_mousePositionIsUnknown = true; 165 m_mousePositionIsUnknown = true;
170 m_lastKnownMousePosition = IntPoint(); 166 m_lastKnownMousePosition = IntPoint();
171 m_lastKnownMouseGlobalPosition = IntPoint(); 167 m_lastKnownMouseGlobalPosition = IntPoint();
172 m_mousePressNode = nullptr; 168 m_mousePressNode = nullptr;
173 m_mousePressed = false; 169 m_mousePressed = false;
174 m_capturesDragging = false; 170 m_capturesDragging = false;
175 m_previousWheelScrolledNode = nullptr; 171 m_previousWheelScrolledNode = nullptr;
176 m_targetForTouchID.clear();
177 m_touchSequenceDocument.clear();
178 m_scrollGestureHandlingNode = nullptr; 172 m_scrollGestureHandlingNode = nullptr;
179 m_lastGestureScrollOverWidget = false; 173 m_lastGestureScrollOverWidget = false;
180 m_previousGestureScrolledNode = nullptr; 174 m_previousGestureScrolledNode = nullptr;
181 m_scrollbarHandlingScrollGesture = nullptr; 175 m_scrollbarHandlingScrollGesture = nullptr;
182 m_maxMouseMovedDuration = 0; 176 m_maxMouseMovedDuration = 0;
183 m_didStartDrag = false; 177 m_didStartDrag = false;
184 m_touchPressed = false;
185 m_mouseDownMayStartSelect = false; 178 m_mouseDownMayStartSelect = false;
186 m_mouseDownMayStartDrag = false; 179 m_mouseDownMayStartDrag = false;
187 m_lastShowPressTimestamp = 0; 180 m_lastShowPressTimestamp = 0;
188 m_lastDeferredTapElement = nullptr; 181 m_lastDeferredTapElement = nullptr;
189 } 182 }
190 183
191 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) 184 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
192 { 185 {
193 if (!nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get())) 186 if (!nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get()))
194 return; 187 return;
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } 820 }
828 821
829 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent) 822 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
830 { 823 {
831 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); 824 const PlatformGestureEvent& gestureEvent = targetedEvent.event();
832 825
833 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the 826 // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the
834 // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code 827 // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
835 // and LongPress is such a special scenario that it's unlikely to matter muc h in practice. 828 // and LongPress is such a special scenario that it's unlikely to matter muc h in practice.
836 829
837 #if OS(ANDROID) 830 IntPoint hitTestPoint = gestureEvent.position();
838 bool shouldLongPressSelectWord = true; 831 HitTestResult result = hitTestResultAtPoint(hitTestPoint);
839 #else 832 Node* innerNode = result.targetNode();
840 bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()- >touchEditingEnabled(); 833 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
841 #endif 834 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitespace) ;
842 if (shouldLongPressSelectWord) { 835 if (m_frame->selection().isRange()) {
843 IntPoint hitTestPoint = gestureEvent.position(); 836 focusDocumentView();
844 HitTestResult result = hitTestResultAtPoint(hitTestPoint); 837 return true;
845 Node* innerNode = result.targetNode();
846 if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
847 selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitesp ace);
848 if (m_frame->selection().isRange()) {
849 focusDocumentView();
850 return true;
851 }
852 } 838 }
853 } 839 }
840
854 return true; 841 return true;
855 } 842 }
856 843
857 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent) 844 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& ta rgetedEvent)
858 { 845 {
859 return false; 846 return false;
860 } 847 }
861 848
862 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer) 849 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& ge stureEvent, RenderObject* renderer)
863 { 850 {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 if (shouldKeepActiveForMinInterval) { 987 if (shouldKeepActiveForMinInterval) {
1001 m_lastDeferredTapElement = hitTestResult.innerElement(); 988 m_lastDeferredTapElement = hitTestResult.innerElement();
1002 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE); 989 m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterva l, FROM_HERE);
1003 } 990 }
1004 991
1005 return GestureEventWithHitTestResults(gestureEvent, hitTestResult); 992 return GestureEventWithHitTestResults(gestureEvent, hitTestResult);
1006 } 993 }
1007 994
1008 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(Platfo rmEvent::Type type) 995 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(Platfo rmEvent::Type type)
1009 { 996 {
1010 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent; 997 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly;
1011 switch (type) { 998 switch (type) {
1012 case PlatformEvent::GestureShowPress: 999 case PlatformEvent::GestureShowPress:
1013 case PlatformEvent::GestureTapUnconfirmed: 1000 case PlatformEvent::GestureTapUnconfirmed:
1014 return hitType | HitTestRequest::Active; 1001 return hitType | HitTestRequest::Active;
1015 case PlatformEvent::GestureTapDownCancel: 1002 case PlatformEvent::GestureTapDownCancel:
1016 // A TapDownCancel received when no element is active shouldn't really b e changing hover state. 1003 // A TapDownCancel received when no element is active shouldn't really b e changing hover state.
1017 if (!m_frame->document()->activeHoverElement()) 1004 if (!m_frame->document()->activeHoverElement())
1018 hitType |= HitTestRequest::ReadOnly; 1005 hitType |= HitTestRequest::ReadOnly;
1019 return hitType | HitTestRequest::Release; 1006 return hitType | HitTestRequest::Release;
1020 case PlatformEvent::GestureTap: 1007 case PlatformEvent::GestureTap:
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 m_lastScrollbarUnderMouse->mouseExited(); 1207 m_lastScrollbarUnderMouse->mouseExited();
1221 1208
1222 // Send mouse entered if we're setting a new scrollbar. 1209 // Send mouse entered if we're setting a new scrollbar.
1223 if (scrollbar && setLast) 1210 if (scrollbar && setLast)
1224 scrollbar->mouseEntered(); 1211 scrollbar->mouseEntered();
1225 1212
1226 m_lastScrollbarUnderMouse = setLast ? scrollbar : 0; 1213 m_lastScrollbarUnderMouse = setLast ? scrollbar : 0;
1227 } 1214 }
1228 } 1215 }
1229 1216
1230 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state)
1231 {
1232 switch (state) {
1233 case PlatformTouchPoint::TouchReleased:
1234 return EventTypeNames::touchend;
1235 case PlatformTouchPoint::TouchCancelled:
1236 return EventTypeNames::touchcancel;
1237 case PlatformTouchPoint::TouchPressed:
1238 return EventTypeNames::touchstart;
1239 case PlatformTouchPoint::TouchMoved:
1240 return EventTypeNames::touchmove;
1241 case PlatformTouchPoint::TouchStationary:
1242 // TouchStationary state is not converted to touch events, so fall throu gh to assert.
1243 default:
1244 ASSERT_NOT_REACHED();
1245 return emptyAtom;
1246 }
1247 }
1248
1249 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout Point& point, HitTestRequest::HitTestRequestType hitType) 1217 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const Layout Point& point, HitTestRequest::HitTestRequestType hitType)
1250 { 1218 {
1251 HitTestResult result(point); 1219 HitTestResult result(point);
1252 1220
1253 if (!frame || !frame->contentRenderer()) 1221 if (!frame || !frame->contentRenderer())
1254 return result; 1222 return result;
1255 if (frame->view()) { 1223 if (frame->view()) {
1256 IntRect rect = frame->view()->visibleContentRect(); 1224 IntRect rect = frame->view()->visibleContentRect();
1257 if (!rect.contains(roundedIntPoint(point))) 1225 if (!rect.contains(roundedIntPoint(point)))
1258 return result; 1226 return result;
1259 } 1227 }
1260 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result); 1228 frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
1261 return result; 1229 return result;
1262 } 1230 }
1263 1231
1264 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
1265 {
1266 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
1267
1268 const Vector<PlatformTouchPoint>& points = event.touchPoints();
1269
1270 unsigned i;
1271 bool freshTouchEvents = true;
1272 bool allTouchReleased = true;
1273 for (i = 0; i < points.size(); ++i) {
1274 const PlatformTouchPoint& point = points[i];
1275 if (point.state() != PlatformTouchPoint::TouchPressed)
1276 freshTouchEvents = false;
1277 if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
1278 allTouchReleased = false;
1279 }
1280 if (freshTouchEvents) {
1281 // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
1282 // have cleared the active document when we saw the last release. But we
1283 // have some tests that violate this, ClusterFuzz could trigger it, and
1284 // there may be cases where the browser doesn't reliably release all
1285 // touches. http://crbug.com/345372 tracks this.
1286 m_touchSequenceDocument.clear();
1287 }
1288
1289 ASSERT(m_frame->view());
1290 if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touc hSequenceDocument->frame()->view())) {
1291 // If the active touch document has no frame or view, it's probably bein g destroyed
1292 // so we can't dispatch events.
1293 return false;
1294 }
1295
1296 // First do hit tests for any new touch points.
1297 for (i = 0; i < points.size(); ++i) {
1298 const PlatformTouchPoint& point = points[i];
1299
1300 // Touch events implicitly capture to the touched node, and don't change
1301 // active/hover states themselves (Gesture events do). So we only need
1302 // to hit-test on touchstart, and it can be read-only.
1303 if (point.state() == PlatformTouchPoint::TouchPressed) {
1304 HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEv ent | HitTestRequest::ReadOnly | HitTestRequest::Active;
1305 LayoutPoint pagePoint = roundedLayoutPoint(point.pos());
1306 HitTestResult result;
1307 if (!m_touchSequenceDocument) {
1308 result = hitTestResultAtPoint(pagePoint, hitType);
1309 } else if (m_touchSequenceDocument->frame()) {
1310 LayoutPoint framePoint = roundedLayoutPoint(point.pos());
1311 result = hitTestResultInFrame(m_touchSequenceDocument->frame(), framePoint, hitType);
1312 } else
1313 continue;
1314
1315 Node* node = result.innerNode();
1316 if (!node)
1317 continue;
1318
1319 // Touch events should not go to text nodes
1320 if (node->isTextNode())
1321 node = NodeRenderingTraversal::parent(node);
1322
1323 if (!m_touchSequenceDocument) {
1324 // Keep track of which document should receive all touch events
1325 // in the active sequence. This must be a single document to
1326 // ensure we don't leak Nodes between documents.
1327 m_touchSequenceDocument = &(result.innerNode()->document());
1328 ASSERT(m_touchSequenceDocument->frame()->view());
1329 }
1330
1331 // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
1332 // since we shouldn't get a touchstart for a touch that's already
1333 // down. However EventSender allows this to be violated and there's
1334 // some tests that take advantage of it. There may also be edge
1335 // cases in the browser where this happens.
1336 // See http://crbug.com/345372.
1337 m_targetForTouchID.set(point.id(), node);
1338
1339 TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node );
1340 if (effectiveTouchAction != TouchActionAuto)
1341 m_frame->page()->chrome().client().setTouchAction(effectiveTouch Action);
1342 }
1343 }
1344
1345 m_touchPressed = !allTouchReleased;
1346
1347 // If there's no document receiving touch events, then we can skip all the
1348 // rest of this work.
1349 if (!m_touchSequenceDocument || !m_touchSequenceDocument->frame()) {
1350 if (allTouchReleased)
1351 m_touchSequenceDocument.clear();
1352 return false;
1353 }
1354
1355 // Build up the lists to use for the 'touches', 'targetTouches' and
1356 // 'changedTouches' attributes in the JS event. See
1357 // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
1358 // lists fit together.
1359
1360 // Holds the complete set of touches on the screen.
1361 RefPtr<TouchList> touches = TouchList::create();
1362
1363 // A different view on the 'touches' list above, filtered and grouped by
1364 // event target. Used for the 'targetTouches' list in the JS event.
1365 typedef HashMap<EventTarget*, RefPtr<TouchList> > TargetTouchesHeapMap;
1366 TargetTouchesHeapMap touchesByTarget;
1367
1368 // Array of touches per state, used to assemble the 'changedTouches' list.
1369 typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
1370 struct {
1371 // The touches corresponding to the particular change state this struct
1372 // instance represents.
1373 RefPtr<TouchList> m_touches;
1374 // Set of targets involved in m_touches.
1375 EventTargetSet m_targets;
1376 } changedTouches[PlatformTouchPoint::TouchStateEnd];
1377
1378 for (i = 0; i < points.size(); ++i) {
1379 const PlatformTouchPoint& point = points[i];
1380 PlatformTouchPoint::State pointState = point.state();
1381 RefPtr<EventTarget> touchTarget = nullptr;
1382
1383 if (pointState == PlatformTouchPoint::TouchReleased || pointState == Pla tformTouchPoint::TouchCancelled) {
1384 // The target should be the original target for this touch, so get
1385 // it from the hashmap. As it's a release or cancel we also remove
1386 // it from the map.
1387 touchTarget = m_targetForTouchID.take(point.id());
1388 } else {
1389 // No hittest is performed on move or stationary, since the target
1390 // is not allowed to change anyway.
1391 touchTarget = m_targetForTouchID.get(point.id());
1392 }
1393
1394 LocalFrame* targetFrame = 0;
1395 bool knownTarget = false;
1396 if (touchTarget) {
1397 Document& doc = touchTarget->toNode()->document();
1398 // If the target node has moved to a new document while it was being touched,
1399 // we can't send events to the new document because that could leak nodes
1400 // from one document to another. See http://crbug.com/394339.
1401 if (&doc == m_touchSequenceDocument.get()) {
1402 targetFrame = doc.frame();
1403 knownTarget = true;
1404 }
1405 }
1406 if (!knownTarget) {
1407 // If we don't have a target registered for the point it means we've
1408 // missed our opportunity to do a hit test for it (due to some
1409 // optimization that prevented blink from ever seeing the
1410 // touchstart), or that the touch started outside the active touch
1411 // sequence document. We should still include the touch in the
1412 // Touches list reported to the application (eg. so it can
1413 // differentiate between a one and two finger gesture), but we won't
1414 // actually dispatch any events for it. Set the target to the
1415 // Document so that there's some valid node here. Perhaps this
1416 // should really be LocalDOMWindow, but in all other cases the targe t of
1417 // a Touch is a Node so using the window could be a breaking change.
1418 // Since we know there was no handler invoked, the specific target
1419 // should be completely irrelevant to the application.
1420 touchTarget = m_touchSequenceDocument;
1421 targetFrame = m_touchSequenceDocument->frame();
1422 }
1423 ASSERT(targetFrame);
1424
1425 RefPtr<Touch> touch = Touch::create(
1426 targetFrame, touchTarget.get(), point.id(), point.screenPos(), point .pos(), point.radius(), point.rotationAngle(), point.force());
1427
1428 // Ensure this target's touch list exists, even if it ends up empty, so
1429 // it can always be passed to TouchEvent::Create below.
1430 TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.f ind(touchTarget.get());
1431 if (targetTouchesIterator == touchesByTarget.end()) {
1432 touchesByTarget.set(touchTarget.get(), TouchList::create());
1433 targetTouchesIterator = touchesByTarget.find(touchTarget.get());
1434 }
1435
1436 // touches and targetTouches should only contain information about
1437 // touches still on the screen, so if this point is released or
1438 // cancelled it will only appear in the changedTouches list.
1439 if (pointState != PlatformTouchPoint::TouchReleased && pointState != Pla tformTouchPoint::TouchCancelled) {
1440 touches->append(touch);
1441 targetTouchesIterator->value->append(touch);
1442 }
1443
1444 // Now build up the correct list for changedTouches.
1445 // Note that any touches that are in the TouchStationary state (e.g. if
1446 // the user had several points touched but did not move them all) should
1447 // never be in the changedTouches list so we do not handle them
1448 // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
1449 // for further discussion about the TouchStationary state.
1450 if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) {
1451 ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
1452 if (!changedTouches[pointState].m_touches)
1453 changedTouches[pointState].m_touches = TouchList::create();
1454 changedTouches[pointState].m_touches->append(touch);
1455 changedTouches[pointState].m_targets.add(touchTarget);
1456 }
1457 }
1458 if (allTouchReleased)
1459 m_touchSequenceDocument.clear();
1460
1461 // Now iterate the changedTouches list and m_targets within it, sending
1462 // events to the targets as required.
1463 bool swallowedEvent = false;
1464 for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state ) {
1465 if (!changedTouches[state].m_touches)
1466 continue;
1467
1468 const AtomicString& stateName(eventNameForTouchPointState(static_cast<Pl atformTouchPoint::State>(state)));
1469 const EventTargetSet& targetsForState = changedTouches[state].m_targets;
1470 for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
1471 EventTarget* touchEventTarget = it->get();
1472 RefPtr<TouchEvent> touchEvent = TouchEvent::create(
1473 touches.get(), touchesByTarget.get(touchEventTarget), changedTou ches[state].m_touches.get(),
1474 stateName, touchEventTarget->toNode()->document().domWindow(),
1475 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey (), event.cancelable());
1476 touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
1477 swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
1478 }
1479 }
1480
1481 return swallowedEvent;
1482 }
1483
1484 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2) 1232 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
1485 { 1233 {
1486 if (action1 == TouchActionNone || action2 == TouchActionNone) 1234 if (action1 == TouchActionNone || action2 == TouchActionNone)
1487 return TouchActionNone; 1235 return TouchActionNone;
1488 if (action1 == TouchActionAuto) 1236 if (action1 == TouchActionAuto)
1489 return action2; 1237 return action2;
1490 if (action2 == TouchActionAuto) 1238 if (action2 == TouchActionAuto)
1491 return action1; 1239 return action1;
1492 if (!(action1 & action2)) 1240 if (!(action1 & action2))
1493 return TouchActionNone; 1241 return TouchActionNone;
(...skipping 25 matching lines...) Expand all
1519 1267
1520 void EventHandler::focusDocumentView() 1268 void EventHandler::focusDocumentView()
1521 { 1269 {
1522 Page* page = m_frame->page(); 1270 Page* page = m_frame->page();
1523 if (!page) 1271 if (!page)
1524 return; 1272 return;
1525 page->focusController().focusDocumentView(m_frame); 1273 page->focusController().focusDocumentView(m_frame);
1526 } 1274 }
1527 1275
1528 } // namespace blink 1276 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/page/EventHandler.h ('k') | sky/engine/core/rendering/HitTestRequest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698