Changeset 195899 in webkit
- Timestamp:
- Jan 30, 2016 10:38:20 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r195897 r195899 1 2016-01-30 Ryosuke Niwa <rniwa@webkit.org> 2 3 TouchList should be retargeted 4 https://bugs.webkit.org/show_bug.cgi?id=149592 5 6 Reviewed by Antti Koivisto. 7 8 Added a regression test for retargeting touch targets on iOS. 9 10 * fast/shadow-dom/touch-event-ios-expected.txt: Added. 11 * fast/shadow-dom/touch-event-ios.html: Added. 12 * platform/mac/TestExpectations: Added the failing expectation on Mac since touch support is not enabled. 13 1 14 2016-01-30 Michael Catanzaro <mcatanzaro@igalia.com> 2 15 -
trunk/LayoutTests/platform/mac/TestExpectations
r195864 r195899 1258 1258 webkit.org/b/149441 fast/shadow-dom/css-scoping-shadow-slot-display-override.html [ ImageOnlyFailure ] 1259 1259 1260 # Touch events is not enabled on Mac 1261 webkit.org/b/149592 fast/shadow-dom/touch-event-ios.html [ Failure ] 1262 1260 1263 webkit.org/b/150225 fast/custom-elements [ Pass ] 1261 1264 -
trunk/Source/WebCore/ChangeLog
r195892 r195899 1 2016-01-30 Ryosuke Niwa <rniwa@webkit.org> 2 3 TouchList should be retargeted 4 https://bugs.webkit.org/show_bug.cgi?id=149592 5 6 Reviewed by Antti Koivisto. 7 8 Retarget touch target's using the same algorithm as the one used for related targets instead of 9 EventRelatedNodeResolver which is removed in this patch. 10 11 Also enable the retargeting on iOS. 12 13 Test: fast/shadow-dom/touch-event-ios.html 14 15 * dom/EventContext.cpp: 16 (WebCore::TouchEventContext::TouchEventContext): 17 (WebCore::TouchEventContext::handleLocalEvents): 18 (WebCore::TouchEventContext::checkReachability): 19 * dom/EventContext.h: 20 (WebCore::toTouchEventContext): 21 (WebCore::EventContext::isUnreachableNode): 22 * dom/EventDispatcher.cpp: 23 (WebCore::EventRelatedNodeResolver): Deleted. 24 (WebCore::EventPath::EventPath): 25 (WebCore::EventDispatcher::dispatchEvent): 26 (WebCore::addRelatedNodeResolversForTouchList): Deleted. 27 (WebCore::EventPath::updateTouchLists): Deleted. 28 (WebCore::EventPath::setRelatedTarget): Removed superfluous UNUSED_PARAM since the argument is always used. 29 (WebCore::EventPath::retargetTouch): Extracted from updateTouchLists/setRelatedTarget. Clones Touch object 30 with the new target for each event context just like related targets. 31 (WebCore::EventPath::retargetTouchLists): Renamed from updateTouchLists. Calls retargetTouch on each Touch 32 object in each TouchList. 33 * dom/TouchEvent.h: 34 1 35 2016-01-30 Dave Hyatt <hyatt@apple.com> 2 36 -
trunk/Source/WebCore/dom/EventContext.cpp
r191955 r195899 91 91 } 92 92 93 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)93 #if ENABLE(TOUCH_EVENTS) 94 94 TouchEventContext::TouchEventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target) 95 95 : EventContext(node, currentTarget, target) … … 106 106 void TouchEventContext::handleLocalEvents(Event& event) const 107 107 { 108 #if ndef NDEBUG108 #if !ASSERT_DISABLED 109 109 checkReachability(m_touches.get()); 110 110 checkReachability(m_targetTouches.get()); … … 113 113 ASSERT(is<TouchEvent>(event)); 114 114 TouchEvent& touchEvent = downcast<TouchEvent>(event); 115 touchEvent.setTouches(m_touches );116 touchEvent.setTargetTouches(m_targetTouches );117 touchEvent.setChangedTouches(m_changedTouches );115 touchEvent.setTouches(m_touches.get()); 116 touchEvent.setTargetTouches(m_targetTouches.get()); 117 touchEvent.setChangedTouches(m_changedTouches.get()); 118 118 EventContext::handleLocalEvents(event); 119 119 } … … 124 124 } 125 125 126 #if ndef NDEBUG126 #if !ASSERT_DISABLED 127 127 void TouchEventContext::checkReachability(TouchList* touchList) const 128 128 { -
trunk/Source/WebCore/dom/EventContext.h
r190288 r195899 36 36 37 37 class Event; 38 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)38 #if ENABLE(TOUCH_EVENTS) 39 39 class TouchList; 40 40 #endif … … 55 55 56 56 protected: 57 #if ndef NDEBUG57 #if !ASSERT_DISABLED 58 58 bool isUnreachableNode(EventTarget*); 59 59 bool isReachable(Node*) const; … … 78 78 79 79 80 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)80 #if ENABLE(TOUCH_EVENTS) 81 81 class TouchEventContext final : public EventContext { 82 82 public: … … 112 112 RefPtr<TouchList> m_targetTouches; 113 113 RefPtr<TouchList> m_changedTouches; 114 #if ndef NDEBUG114 #if !ASSERT_DISABLED 115 115 void checkReachability(TouchList*) const; 116 116 #endif … … 130 130 #endif // ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) 131 131 132 #if ndef NDEBUG132 #if !ASSERT_DISABLED 133 133 inline bool EventContext::isUnreachableNode(EventTarget* target) 134 134 { -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r194819 r195899 88 88 89 89 #if ENABLE(TOUCH_EVENTS) 90 bool updateTouchLists(const TouchEvent&);90 void retargetTouchLists(const TouchEvent&); 91 91 #endif 92 92 void setRelatedTarget(Node& origin, EventTarget&); … … 97 97 98 98 private: 99 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)100 void updateTouchListsInEventPath(const TouchList*, TouchEventContext::TouchListType);99 #if ENABLE(TOUCH_EVENTS) 100 void retargetTouch(TouchEventContext::TouchListType, const Touch&); 101 101 #endif 102 102 … … 104 104 Vector<std::unique_ptr<EventContext>, 32> m_path; 105 105 }; 106 107 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)108 // FIXME: Use RelatedNodeRetargeter instead.109 class EventRelatedNodeResolver {110 public:111 EventRelatedNodeResolver(Touch& touch, TouchEventContext::TouchListType touchListType)112 : m_relatedNode(*touch.target()->toNode())113 , m_relatedNodeTreeScope(m_relatedNode.treeScope())114 , m_relatedNodeInCurrentTreeScope(nullptr)115 , m_currentTreeScope(nullptr)116 , m_touch(&touch)117 , m_touchListType(touchListType)118 {119 ASSERT(touch.target()->toNode());120 }121 122 Touch* touch() const { return m_touch; }123 TouchEventContext::TouchListType touchListType() const { return m_touchListType; }124 125 Node* moveToParentOrShadowHost(Node& newTarget)126 {127 TreeScope& newTreeScope = newTarget.treeScope();128 if (&newTreeScope == m_currentTreeScope)129 return m_relatedNodeInCurrentTreeScope;130 131 if (m_currentTreeScope) {132 ASSERT(is<ShadowRoot>(m_currentTreeScope->rootNode()));133 ASSERT(&newTarget == downcast<ShadowRoot>(m_currentTreeScope->rootNode()).host());134 ASSERT(m_currentTreeScope->parentTreeScope() == &newTreeScope);135 }136 137 if (&newTreeScope == &m_relatedNodeTreeScope)138 m_relatedNodeInCurrentTreeScope = &m_relatedNode;139 else if (m_relatedNodeInCurrentTreeScope) {140 ASSERT(m_currentTreeScope);141 m_relatedNodeInCurrentTreeScope = &newTarget;142 } else {143 if (!m_currentTreeScope) {144 TreeScope* newTreeScopeAncestor = &newTreeScope;145 do {146 m_relatedNodeInCurrentTreeScope = findHostOfTreeScopeInTargetTreeScope(m_relatedNodeTreeScope, *newTreeScopeAncestor);147 newTreeScopeAncestor = newTreeScopeAncestor->parentTreeScope();148 if (newTreeScopeAncestor == &m_relatedNodeTreeScope) {149 m_relatedNodeInCurrentTreeScope = &m_relatedNode;150 break;151 }152 } while (newTreeScopeAncestor && !m_relatedNodeInCurrentTreeScope);153 }154 ASSERT(m_relatedNodeInCurrentTreeScope || findHostOfTreeScopeInTargetTreeScope(newTreeScope, m_relatedNodeTreeScope)155 || &newTreeScope.documentScope() != &m_relatedNodeTreeScope.documentScope());156 }157 158 m_currentTreeScope = &newTreeScope;159 160 return m_relatedNodeInCurrentTreeScope;161 }162 163 static Node* findHostOfTreeScopeInTargetTreeScope(const TreeScope& startingTreeScope, const TreeScope& targetScope)164 {165 ASSERT(&targetScope != &startingTreeScope);166 Node* previousHost = nullptr;167 for (const TreeScope* scope = &startingTreeScope; scope; scope = scope->parentTreeScope()) {168 if (scope == &targetScope) {169 ASSERT(previousHost);170 ASSERT_WITH_SECURITY_IMPLICATION(&previousHost->treeScope() == &targetScope);171 return previousHost;172 }173 if (is<ShadowRoot>(scope->rootNode()))174 previousHost = downcast<ShadowRoot>(scope->rootNode()).host();175 else176 ASSERT_WITH_SECURITY_IMPLICATION(!scope->parentTreeScope());177 }178 return nullptr;179 }180 181 private:182 Node& m_relatedNode;183 const TreeScope& m_relatedNodeTreeScope;184 Node* m_relatedNodeInCurrentTreeScope;185 TreeScope* m_currentTreeScope;186 Touch* m_touch;187 TouchEventContext::TouchListType m_touchListType;188 };189 #endif190 106 191 107 inline EventTarget* eventTargetRespectingTargetRules(Node& referenceNode) … … 312 228 if (EventTarget* relatedTarget = event.relatedTarget()) 313 229 eventPath.setRelatedTarget(*node, *relatedTarget); 314 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) 315 if (is<TouchEvent>(event)) { 316 if (!eventPath.updateTouchLists(downcast<TouchEvent>(event))) 317 return true; 318 } 230 #if ENABLE(TOUCH_EVENTS) 231 if (is<TouchEvent>(event)) 232 eventPath.retargetTouchLists(downcast<TouchEvent>(event)); 319 233 #endif 320 234 … … 404 318 405 319 bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); 406 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)320 #if ENABLE(TOUCH_EVENTS) 407 321 bool isTouchEvent = event.isTouchEvent(); 408 322 #endif … … 418 332 if (isMouseOrFocusEvent) 419 333 m_path.append(std::make_unique<MouseOrFocusEventContext>(node, currentTarget, target)); 420 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)334 #if ENABLE(TOUCH_EVENTS) 421 335 else if (isTouchEvent) 422 336 m_path.append(std::make_unique<TouchEventContext>(node, currentTarget, target)); … … 459 373 } 460 374 } 461 462 #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)463 static void addRelatedNodeResolversForTouchList(Vector<EventRelatedNodeResolver, 16>& touchTargetResolvers, TouchList* touchList, TouchEventContext::TouchListType type)464 {465 const size_t touchListSize = touchList->length();466 for (size_t i = 0; i < touchListSize; ++i)467 touchTargetResolvers.append(EventRelatedNodeResolver(*touchList->item(i), type));468 }469 470 bool EventPath::updateTouchLists(const TouchEvent& touchEvent)471 {472 if (!touchEvent.touches() || !touchEvent.targetTouches() || !touchEvent.changedTouches())473 return false;474 475 Vector<EventRelatedNodeResolver, 16> touchTargetResolvers;476 const size_t touchNodeCount = touchEvent.touches()->length() + touchEvent.targetTouches()->length() + touchEvent.changedTouches()->length();477 touchTargetResolvers.reserveInitialCapacity(touchNodeCount);478 479 addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.touches(), TouchEventContext::Touches);480 addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.targetTouches(), TouchEventContext::TargetTouches);481 addRelatedNodeResolversForTouchList(touchTargetResolvers, touchEvent.changedTouches(), TouchEventContext::ChangedTouches);482 483 ASSERT(touchTargetResolvers.size() == touchNodeCount);484 for (auto& eventPath : m_path) {485 TouchEventContext& context = toTouchEventContext(*eventPath);486 Node& nodeToMoveTo = *context.node();487 for (size_t resolverIndex = 0; resolverIndex < touchNodeCount; ++resolverIndex) {488 EventRelatedNodeResolver& currentResolver = touchTargetResolvers[resolverIndex];489 Node* nodeInCurrentTreeScope = currentResolver.moveToParentOrShadowHost(nodeToMoveTo);490 ASSERT(currentResolver.touch());491 context.touchList(currentResolver.touchListType())->append(currentResolver.touch()->cloneWithNewTarget(nodeInCurrentTreeScope));492 }493 }494 return true;495 }496 #endif497 375 498 376 class RelatedNodeRetargeter { … … 623 501 void EventPath::setRelatedTarget(Node& origin, EventTarget& relatedTarget) 624 502 { 625 UNUSED_PARAM(origin);626 503 Node* relatedNode = relatedTarget.toNode(); 627 504 if (!relatedNode || m_path.isEmpty()) … … 662 539 } 663 540 541 #if ENABLE(TOUCH_EVENTS) 542 void EventPath::retargetTouch(TouchEventContext::TouchListType touchListType, const Touch& touch) 543 { 544 EventTarget* eventTarget = touch.target(); 545 if (!eventTarget) 546 return; 547 548 Node* targetNode = eventTarget->toNode(); 549 if (!targetNode) 550 return; 551 552 RelatedNodeRetargeter retargeter(*targetNode, downcast<MouseOrFocusEventContext>(*m_path[0]).node()->treeScope()); 553 TreeScope* previousTreeScope = nullptr; 554 for (auto& context : m_path) { 555 TreeScope& currentTreeScope = context->node()->treeScope(); 556 if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) 557 retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); 558 559 Node* currentRelatedNode = retargeter.currentNode(currentTreeScope); 560 downcast<TouchEventContext>(*context).touchList(touchListType)->append(touch.cloneWithNewTarget(currentRelatedNode)); 561 562 previousTreeScope = ¤tTreeScope; 563 } 564 } 565 566 void EventPath::retargetTouchLists(const TouchEvent& touchEvent) 567 { 568 if (touchEvent.touches()) { 569 for (size_t i = 0; i < touchEvent.touches()->length(); ++i) 570 retargetTouch(TouchEventContext::Touches, *touchEvent.touches()->item(i)); 571 } 572 573 if (touchEvent.targetTouches()) { 574 for (size_t i = 0; i < touchEvent.targetTouches()->length(); ++i) 575 retargetTouch(TouchEventContext::TargetTouches, *touchEvent.targetTouches()->item(i)); 576 } 577 578 if (touchEvent.changedTouches()) { 579 for (size_t i = 0; i < touchEvent.changedTouches()->length(); ++i) 580 retargetTouch(TouchEventContext::ChangedTouches, *touchEvent.changedTouches()->item(i)); 581 } 582 } 583 #endif 584 664 585 bool EventPath::hasEventListeners(const AtomicString& eventType) const 665 586 { -
trunk/Source/WebCore/dom/TouchEvent.h
r194896 r195899 66 66 TouchList* changedTouches() const { return m_changedTouches.get(); } 67 67 68 void setTouches( PassRefPtr<TouchList>touches) { m_touches = touches; }69 void setTargetTouches( PassRefPtr<TouchList>targetTouches) { m_targetTouches = targetTouches; }70 void setChangedTouches( PassRefPtr<TouchList>changedTouches) { m_changedTouches = changedTouches; }68 void setTouches(RefPtr<TouchList>&& touches) { m_touches = touches; } 69 void setTargetTouches(RefPtr<TouchList>&& targetTouches) { m_targetTouches = targetTouches; } 70 void setChangedTouches(RefPtr<TouchList>&& changedTouches) { m_changedTouches = changedTouches; } 71 71 72 72 virtual bool isTouchEvent() const override; -
trunk/Tools/ChangeLog
r195891 r195899 1 2016-01-30 Ryosuke Niwa <rniwa@webkit.org> 2 3 TouchList should be retargeted 4 https://bugs.webkit.org/show_bug.cgi?id=149592 5 6 Reviewed by Antti Koivisto. 7 8 Added touchDownAtPoint and liftUpAtPoint to UIScriptController so that we can test touch events with 9 multiple touch targets on iOS. fast/shadow-dom/touch-event-ios.html uses this new testing feature. 10 11 * WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl: 12 * WebKitTestRunner/UIScriptContext/UIScriptController.cpp: 13 (WTR::UIScriptController::touchDownAtPoint): Added. 14 (WTR::UIScriptController::liftUpAtPoint): Added. 15 * WebKitTestRunner/UIScriptContext/UIScriptController.h: 16 * WebKitTestRunner/ios/HIDEventGenerator.h: 17 * WebKitTestRunner/ios/HIDEventGenerator.mm: 18 (-[HIDEventGenerator touchDown:touchCount:completionBlock:]): Added. Sends touch down and waits. 19 (-[HIDEventGenerator liftUp:touchCount:completionBlock:]): Ditto for lift up. 20 * WebKitTestRunner/ios/UIScriptControllerIOS.mm: 21 (WTR::UIScriptController::touchDownAtPoint): Added. 22 (WTR::UIScriptController::liftUpAtPoint): Added. 23 1 24 2016-01-30 Yusuke Suzuki <utatane.tea@gmail.com> 2 25 -
trunk/Tools/WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl
r195482 r195899 31 31 32 32 // Interaction. 33 // These functions post events asynchronously. The callback is fired when the events have been disp tached, but any33 // These functions post events asynchronously. The callback is fired when the events have been dispatched, but any 34 34 // resulting behavior may also be asynchronous. 35 void touchDownAtPoint(long x, long y, long touchCount, object callback); 36 void liftUpAtPoint(long x, long y, long touchCount, object callback); 35 37 void singleTapAtPoint(long x, long y, object callback); 36 38 void doubleTapAtPoint(long x, long y, object callback); -
trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp
r195482 r195899 119 119 } 120 120 121 void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef) 122 { 123 } 124 125 void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef) 126 { 127 } 128 121 129 void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef) 122 130 { -
trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h
r195482 r195899 48 48 void zoomToScale(double scale, JSValueRef callback); 49 49 50 void touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback); 51 void liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback); 50 52 void singleTapAtPoint(long x, long y, JSValueRef callback); 51 53 void doubleTapAtPoint(long x, long y, JSValueRef callback); -
trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.h
r195482 r195899 36 36 - (void)liftUp:(CGPoint)location; 37 37 - (void)moveToPoints:(CGPoint*)locations touchCount:(NSUInteger)count duration:(NSTimeInterval)seconds; 38 - (void)touchDown:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock; 39 - (void)liftUp:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock; 38 40 39 41 // Taps -
trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm
r195482 r195899 369 369 370 370 [self _updateTouchPoints:newLocations count:touchCount]; 371 } 372 373 - (void)touchDown:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock 374 { 375 [self touchDown:location touchCount:count]; 376 [self _sendMarkerHIDEventWithCompletionBlock:completionBlock]; 377 } 378 379 - (void)liftUp:(CGPoint)location touchCount:(NSUInteger)count completionBlock:(void (^)(void))completionBlock 380 { 381 [self liftUp:location touchCount:count]; 382 [self _sendMarkerHIDEventWithCompletionBlock:completionBlock]; 371 383 } 372 384 -
trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm
r195482 r195899 80 80 } 81 81 82 void UIScriptController::touchDownAtPoint(long x, long y, long touchCount, JSValueRef callback) 83 { 84 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 85 86 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 87 [[HIDEventGenerator sharedHIDEventGenerator] touchDown:location touchCount:touchCount completionBlock:^{ 88 if (!m_context) 89 return; 90 m_context->asyncTaskComplete(callbackID); 91 }]; 92 } 93 94 void UIScriptController::liftUpAtPoint(long x, long y, long touchCount, JSValueRef callback) 95 { 96 unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); 97 98 auto location = globalToContentCoordinates(TestController::singleton().mainWebView()->platformView(), x, y); 99 [[HIDEventGenerator sharedHIDEventGenerator] liftUp:location touchCount:touchCount completionBlock:^{ 100 if (!m_context) 101 return; 102 m_context->asyncTaskComplete(callbackID); 103 }]; 104 } 105 82 106 void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback) 83 107 {
Note: See TracChangeset
for help on using the changeset viewer.