Chromium Code Reviews| 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 |