OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/events/PointerEventManager.h" | 5 #include "core/events/PointerEventManager.h" |
6 #include "core/dom/shadow/ComposedTreeTraversal.h" | |
6 | 7 |
7 namespace blink { | 8 namespace blink { |
8 | 9 |
9 namespace { | 10 namespace { |
10 | 11 |
11 inline int toInt(WebPointerProperties::PointerType t) { return static_cast<int>( t); } | 12 inline int toInt(WebPointerProperties::PointerType t) { return static_cast<int>( t); } |
12 | 13 |
13 const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT ype type) | 14 const char* pointerTypeNameForWebPointPointerType(WebPointerProperties::PointerT ype type) |
14 { | 15 { |
15 switch (type) { | 16 switch (type) { |
16 case WebPointerProperties::PointerType::Unknown: | 17 case WebPointerProperties::PointerType::Unknown: |
17 return ""; | 18 return ""; |
18 case WebPointerProperties::PointerType::Touch: | 19 case WebPointerProperties::PointerType::Touch: |
19 return "touch"; | 20 return "touch"; |
20 case WebPointerProperties::PointerType::Pen: | 21 case WebPointerProperties::PointerType::Pen: |
21 return "pen"; | 22 return "pen"; |
22 case WebPointerProperties::PointerType::Mouse: | 23 case WebPointerProperties::PointerType::Mouse: |
23 return "mouse"; | 24 return "mouse"; |
24 } | 25 } |
25 ASSERT_NOT_REACHED(); | 26 ASSERT_NOT_REACHED(); |
26 return ""; | 27 return ""; |
27 } | 28 } |
28 | 29 |
30 const AtomicString& pointerEventNameForTouchPointState(PlatformTouchPoint::State state) | |
31 { | |
32 switch (state) { | |
33 case PlatformTouchPoint::TouchReleased: | |
34 return EventTypeNames::pointerup; | |
35 case PlatformTouchPoint::TouchCancelled: | |
36 return EventTypeNames::pointercancel; | |
37 case PlatformTouchPoint::TouchPressed: | |
38 return EventTypeNames::pointerdown; | |
39 case PlatformTouchPoint::TouchMoved: | |
40 return EventTypeNames::pointermove; | |
41 case PlatformTouchPoint::TouchStationary: | |
42 // Fall through to default | |
43 default: | |
44 ASSERT_NOT_REACHED(); | |
45 return emptyAtom; | |
46 } | |
47 } | |
48 | |
49 bool isInDocument(EventTarget *n) | |
50 { | |
51 return n && n->toNode() && n->toNode()->inDocument(); | |
52 } | |
53 | |
54 void sendPointerEventToTarget(EventTarget *target, | |
55 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent) | |
56 { | |
57 if (isInDocument(target)) | |
58 target->dispatchEvent(pointerevent); | |
59 } | |
60 | |
29 } // namespace | 61 } // namespace |
30 | 62 |
31 const PointerEventManager::MappedId PointerEventManager::s_invalidId = 0; | 63 const PointerEventManager::MappedId PointerEventManager::s_invalidId = 0; |
32 | 64 |
33 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons. | 65 // Mouse id is 1 to behave the same as MS Edge for compatibility reasons. |
34 const PointerEventManager::MappedId PointerEventManager::s_mouseId = 1; | 66 const PointerEventManager::MappedId PointerEventManager::s_mouseId = 1; |
35 | 67 |
36 EventTarget* PointerEventManager::getCapturingNode(PassRefPtrWillBeRawPtr<Pointe rEvent> pointerEvent) | 68 EventTarget* PointerEventManager::getCapturingNode(PassRefPtrWillBeRawPtr<Pointe rEvent> pointerEvent) |
37 { | 69 { |
38 // TODO(nzolghadr): Add APIs to set the capturing nodes and return the corre ct node here | 70 // TODO(nzolghadr): Add APIs to set the capturing nodes and return the corre ct node here |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter | 114 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter |
83 && type != EventTypeNames::pointerleave && type != EventTypeNames::point ercancel); | 115 && type != EventTypeNames::pointerleave && type != EventTypeNames::point ercancel); |
84 | 116 |
85 pointerEventInit.setView(view); | 117 pointerEventInit.setView(view); |
86 if (relatedTarget) | 118 if (relatedTarget) |
87 pointerEventInit.setRelatedTarget(relatedTarget); | 119 pointerEventInit.setRelatedTarget(relatedTarget); |
88 | 120 |
89 return PointerEvent::create(type, pointerEventInit); | 121 return PointerEvent::create(type, pointerEventInit); |
90 } | 122 } |
91 | 123 |
92 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create(const AtomicStr ing& type, | 124 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create( |
125 const AtomicString& type, | |
93 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, | 126 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, |
94 const double width, const double height, | 127 const double width, const double height, |
95 const double clientX, const double clientY) | 128 const double clientX, const double clientY) |
96 { | 129 { |
97 const PlatformTouchPoint::State pointState = touchPoint.state(); | 130 const PlatformTouchPoint::State pointState = touchPoint.state(); |
98 | 131 |
99 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::TouchRel eased | 132 bool pointerReleasedOrCancelled = pointState == PlatformTouchPoint::TouchRel eased |
100 || pointState == PlatformTouchPoint::TouchCancelled; | 133 || pointState == PlatformTouchPoint::TouchCancelled; |
101 | 134 |
102 bool isEnterOrLeave = false; | 135 bool isEnterOrLeave = false; |
(...skipping 16 matching lines...) Expand all Loading... | |
119 touchPoint.force(), pointerEventInit.buttons())); | 152 touchPoint.force(), pointerEventInit.buttons())); |
120 | 153 |
121 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers); | 154 UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit, modifiers); |
122 | 155 |
123 pointerEventInit.setBubbles(!isEnterOrLeave); | 156 pointerEventInit.setBubbles(!isEnterOrLeave); |
124 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != PlatformTouc hPoint::TouchCancelled); | 157 pointerEventInit.setCancelable(!isEnterOrLeave && pointState != PlatformTouc hPoint::TouchCancelled); |
125 | 158 |
126 return PointerEvent::create(type, pointerEventInit); | 159 return PointerEvent::create(type, pointerEventInit); |
127 } | 160 } |
128 | 161 |
129 | 162 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::create( |
130 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel(co nst PlatformTouchPoint& touchPoint) | 163 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent, |
164 const AtomicString& type, | |
165 PassRefPtrWillBeRawPtr<EventTarget> relatedTarget) | |
131 { | 166 { |
132 PointerEventInit pointerEventInit; | 167 PointerEventInit pointerEventInit; |
133 | 168 |
169 pointerEventInit.setPointerId(pointerevent->pointerId()); | |
170 pointerEventInit.setPointerType(pointerevent->pointerType()); | |
171 pointerEventInit.setIsPrimary(pointerevent->isPrimary()); | |
172 pointerEventInit.setWidth(pointerevent->width()); | |
173 pointerEventInit.setHeight(pointerevent->height()); | |
174 pointerEventInit.setTiltX(pointerevent->tiltX()); | |
175 pointerEventInit.setTiltY(pointerevent->tiltY()); | |
176 pointerEventInit.setScreenX(pointerevent->screenX()); | |
177 pointerEventInit.setScreenY(pointerevent->screenY()); | |
178 pointerEventInit.setClientX(pointerevent->clientX()); | |
179 pointerEventInit.setClientY(pointerevent->clientY()); | |
180 pointerEventInit.setButton(pointerevent->button()); | |
181 pointerEventInit.setButtons(pointerevent->buttons()); | |
182 pointerEventInit.setPressure(pointerevent->pressure()); | |
183 | |
184 pointerEventInit.setBubbles(type != EventTypeNames::pointerenter | |
185 && type != EventTypeNames::pointerleave); | |
186 pointerEventInit.setCancelable(type != EventTypeNames::pointerenter | |
187 && type != EventTypeNames::pointerleave | |
188 && type != EventTypeNames::pointercancel); | |
189 | |
190 return PointerEvent::create(type, pointerEventInit); | |
191 } | |
192 | |
193 void PointerEventManager::sendNodeTransitionEvents( | |
mustaq
2016/02/08 17:01:34
This duplication looks bad. All you need here is a
Navid Zolghadr
2016/02/10 16:25:29
Done.
| |
194 EventTarget* exitedTarget, EventTarget* enteredTarget, | |
195 PassRefPtrWillBeRawPtr<PointerEvent> pointerEvent) | |
196 { | |
197 if (exitedTarget == enteredTarget) | |
198 return; | |
199 | |
200 if (!RuntimeEnabledFeatures::pointerEventEnabled()) | |
201 return; | |
202 | |
203 // Create lists of all exited/entered ancestors, locate the common ancestor | |
204 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> exitedAncestors; | |
205 WillBeHeapVector<RefPtrWillBeMember<Node>, 32> enteredAncestors; | |
206 if (isInDocument(exitedTarget)) { | |
207 Node* exitedNode = exitedTarget->toNode(); | |
208 exitedNode->updateDistribution(); | |
209 for (Node* node = exitedNode; node; node = ComposedTreeTraversal::parent (*node)) | |
210 exitedAncestors.append(node); | |
211 } | |
212 if (isInDocument(enteredTarget)) { | |
213 Node* enteredNode = enteredTarget->toNode(); | |
214 enteredNode->updateDistribution(); | |
215 for (Node* node = enteredNode; node; node = ComposedTreeTraversal::paren t(*node)) | |
216 enteredAncestors.append(node); | |
217 } | |
218 | |
219 size_t exitedAncestorIndex = exitedAncestors.size(); | |
220 size_t enteredAncestorIndex = enteredAncestors.size(); | |
221 if (!exitedAncestors.isEmpty() && !enteredAncestors.isEmpty()) { | |
222 for (size_t i = exitedAncestors.size(), j = enteredAncestors.size(); i>0 && j>0; j--, i--) { | |
223 if (exitedAncestors[i-1] == enteredAncestors[j-1]) { | |
224 exitedAncestorIndex = i-1; | |
225 enteredAncestorIndex = j-1; | |
226 } else { | |
227 break; | |
228 } | |
229 } | |
230 } | |
231 | |
232 // Dispatch pointerout | |
233 sendPointerEventToTarget(exitedTarget, | |
234 create(pointerEvent, EventTypeNames::pointerout, enteredTarget)); | |
235 | |
236 // Dispatch pointerleave events, in child-to-parent order | |
237 for (size_t i = 0; i < exitedAncestorIndex; i++) { | |
238 sendPointerEventToTarget(exitedAncestors[i].get(), | |
239 create(pointerEvent, EventTypeNames::pointerleave, enteredTarget)); | |
240 } | |
241 | |
242 // Dispatch pointerover | |
243 sendPointerEventToTarget(enteredTarget, | |
244 create(pointerEvent, EventTypeNames::pointerover, exitedTarget)); | |
245 | |
246 // Dispatch pointerenter events, in parent-to-child order. | |
247 for (size_t j = enteredAncestorIndex; j > 0; j--) { | |
248 sendPointerEventToTarget(enteredAncestors[j-1].get(), | |
249 create(pointerEvent, EventTypeNames::pointerenter, exitedTarget)); | |
250 } | |
251 } | |
252 | |
253 void PointerEventManager::setNodeUnderPointer( | |
254 PassRefPtrWillBeRawPtr<PointerEvent> pointerevent, EventTarget* target) | |
255 { | |
256 if (m_nodeUnderPointer.contains(pointerevent->pointerId())) { | |
257 sendNodeTransitionEvents(m_nodeUnderPointer.get( | |
258 pointerevent->pointerId()), target, pointerevent); | |
259 if (!target) | |
260 m_nodeUnderPointer.remove(pointerevent->pointerId()); | |
261 else | |
262 m_nodeUnderPointer.set(pointerevent->pointerId(), target); | |
263 } else if (target) { | |
264 sendNodeTransitionEvents(nullptr, target, pointerevent); | |
265 m_nodeUnderPointer.add(pointerevent->pointerId(), target); | |
266 } | |
267 } | |
268 | |
269 void PointerEventManager::sendTouchCancelPointerEvent(PassRefPtrWillBeRawPtr<Eve ntTarget> target, | |
270 const PlatformTouchPoint& point) | |
271 { | |
272 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = | |
273 createPointerCancel(point); | |
274 | |
275 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing | |
276 target->dispatchEvent(pointerEvent.get()); | |
277 | |
278 remove(pointerEvent); | |
279 setNodeUnderPointer(pointerEvent, nullptr); | |
280 } | |
281 | |
282 bool PointerEventManager::sendTouchPointerEvent( | |
283 PassRefPtrWillBeRawPtr<EventTarget> target, | |
284 const PlatformTouchPoint& touchPoint, PlatformEvent::Modifiers modifiers, | |
285 const double width, const double height, | |
286 const double clientX, const double clientY) | |
287 { | |
288 RefPtrWillBeRawPtr<PointerEvent> pointerEvent = create( | |
289 pointerEventNameForTouchPointState(touchPoint.state()), | |
290 touchPoint, modifiers, width, height, clientX, clientY); | |
291 | |
292 setNodeUnderPointer(pointerEvent, target); | |
293 | |
294 // TODO(nzolghadr): crbug.com/579553 dealing with implicit touch capturing v s pointer event capturing | |
295 target->dispatchEvent(pointerEvent.get()); | |
296 | |
297 if (touchPoint.state() == PlatformTouchPoint::TouchReleased | |
298 || touchPoint.state() == PlatformTouchPoint::TouchCancelled) { | |
299 remove(pointerEvent); | |
300 setNodeUnderPointer(pointerEvent, nullptr); | |
301 } | |
302 | |
303 return pointerEvent->defaultPrevented() || pointerEvent->defaultHandled(); | |
304 } | |
305 | |
306 PassRefPtrWillBeRawPtr<PointerEvent> PointerEventManager::createPointerCancel( | |
307 const PlatformTouchPoint& touchPoint) | |
308 { | |
309 PointerEventInit pointerEventInit; | |
310 | |
134 setIdAndType(pointerEventInit, touchPoint.pointerProperties()); | 311 setIdAndType(pointerEventInit, touchPoint.pointerProperties()); |
135 | 312 |
136 pointerEventInit.setBubbles(true); | 313 pointerEventInit.setBubbles(true); |
137 pointerEventInit.setCancelable(false); | 314 pointerEventInit.setCancelable(false); |
138 | 315 |
139 return PointerEvent::create(EventTypeNames::pointercancel, pointerEventInit) ; | 316 return PointerEvent::create(EventTypeNames::pointercancel, pointerEventInit) ; |
140 } | 317 } |
141 | 318 |
142 PointerEventManager::PointerEventManager() | 319 PointerEventManager::PointerEventManager() |
143 { | 320 { |
144 clear(); | 321 clear(); |
145 } | 322 } |
146 | 323 |
147 PointerEventManager::~PointerEventManager() | 324 PointerEventManager::~PointerEventManager() |
148 { | 325 { |
149 clear(); | 326 clear(); |
150 } | 327 } |
151 | 328 |
329 DEFINE_TRACE(PointerEventManager) | |
330 { | |
331 visitor->trace(m_nodeUnderPointer); | |
332 } | |
333 | |
152 void PointerEventManager::clear() | 334 void PointerEventManager::clear() |
153 { | 335 { |
154 for (int type = 0; type <= toInt(WebPointerProperties::PointerType::LastEntr y); type++) { | 336 for (int type = 0; type <= toInt(WebPointerProperties::PointerType::LastEntr y); type++) { |
155 m_primaryId[type] = PointerEventManager::s_invalidId; | 337 m_primaryId[type] = PointerEventManager::s_invalidId; |
156 m_idCount[type] = 0; | 338 m_idCount[type] = 0; |
157 } | 339 } |
158 m_idMapping.clear(); | 340 m_idMapping.clear(); |
159 m_idReverseMapping.clear(); | 341 m_idReverseMapping.clear(); |
342 m_nodeUnderPointer.clear(); | |
160 | 343 |
161 // Always add mouse pointer in initialization and never remove it. | 344 // Always add mouse pointer in initialization and never remove it. |
162 // No need to add it to m_idMapping as it is not going to be used with the e xisting APIs | 345 // No need to add it to m_idMapping as it is not going to be used with the e xisting APIs |
163 m_primaryId[toInt(WebPointerProperties::PointerType::Mouse)] = s_mouseId; | 346 m_primaryId[toInt(WebPointerProperties::PointerType::Mouse)] = s_mouseId; |
164 m_idReverseMapping.add(s_mouseId, IncomingId(toInt(WebPointerProperties::Poi nterType::Mouse), 0)); | 347 m_idReverseMapping.add(s_mouseId, IncomingId(toInt(WebPointerProperties::Poi nterType::Mouse), 0)); |
165 | 348 |
166 m_currentId = PointerEventManager::s_mouseId+1; | 349 m_currentId = PointerEventManager::s_mouseId+1; |
167 } | 350 } |
168 | 351 |
169 PointerEventManager::MappedId PointerEventManager::add(const IncomingId p) | 352 PointerEventManager::MappedId PointerEventManager::add(const IncomingId p) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 if (!m_idReverseMapping.contains(mappedId)) | 389 if (!m_idReverseMapping.contains(mappedId)) |
207 return false; | 390 return false; |
208 | 391 |
209 IncomingId p = m_idReverseMapping.get(mappedId); | 392 IncomingId p = m_idReverseMapping.get(mappedId); |
210 int type = p.first; | 393 int type = p.first; |
211 return m_primaryId[type] == mappedId; | 394 return m_primaryId[type] == mappedId; |
212 } | 395 } |
213 | 396 |
214 | 397 |
215 } // namespace blink | 398 } // namespace blink |
OLD | NEW |