[Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointereven...
authorgraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Apr 2019 13:31:17 +0000 (13:31 +0000)
committergraouts@webkit.org <graouts@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 18 Apr 2019 13:31:17 +0000 (13:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197004

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

* web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt: Added.

Source/WebCore:

We need to release pointer capture when an element that has pointer capture is disconnected from the DOM.

* dom/Element.cpp:
(WebCore::Element::removedFromAncestor): Notify the PointerCaptureController that an element was disconnected.
* dom/PointerEvent.cpp:
(WebCore::PointerEvent::create): Broaden createPointerCancelEvent() to take in an event type so that we may use it to create a
lostpointercapture event as well.
(WebCore::PointerEvent::createPointerCancelEvent): Deleted.
* dom/PointerEvent.h:
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::elementWasRemoved): Check whether the provided element matches one of the target overrides recorded
in the map of captured pointer IDs.
(WebCore::PointerCaptureController::pointerEventWasDispatched): This block of code was actually useless in this location, the new code
added in elementWasRemoved() performs the actions that the spec text mandates.
(WebCore::PointerCaptureController::cancelPointer): Replace the call to createPointerCancelEvent() with one to create().
* page/PointerCaptureController.h:

LayoutTests:

* platform/mac/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244423 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/PointerEvent.cpp
Source/WebCore/dom/PointerEvent.h
Source/WebCore/page/PointerCaptureController.cpp
Source/WebCore/page/PointerCaptureController.h

index 3d6eada..0cd5996 100644 (file)
@@ -1,3 +1,12 @@
+2019-04-18  Antoine Quint  <graouts@apple.com>
+
+        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html
+        https://bugs.webkit.org/show_bug.cgi?id=197004
+
+        Reviewed by Antti Koivisto.
+
+        * platform/mac/TestExpectations:
+
 2019-04-17  Antoine Quint  <graouts@apple.com>
 
         [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_on_event_handlers.html
index 1a1aca8..d14a8fb 100644 (file)
@@ -1,3 +1,12 @@
+2019-04-18  Antoine Quint  <graouts@apple.com>
+
+        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html
+        https://bugs.webkit.org/show_bug.cgi?id=197004
+
+        Reviewed by Antti Koivisto.
+
+        * web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt: Added.
+
 2019-04-17  Antoine Quint  <graouts@apple.com>
 
         [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_on_event_handlers.html
diff --git a/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-expected.txt
new file mode 100644 (file)
index 0000000..b7fc959
--- /dev/null
@@ -0,0 +1,18 @@
+Pointer Events - lostpointercapture when capturing element is removed
+
+Test Description: This test checks if lostpointercapture is fired at the document when the capturing node is removed from the document. Complete the following actions:
+Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged inside of the black rectangle.
+"lostpointercapture" should be logged inside of the black rectangle after a short delay.
+
+
+
+Pointer Events Capture Test
+
+The following pointer types were detected: mouse.
+
+The following events were logged: gotpointercapture@target1, lostpointercapture@document.
+
+
+PASS lostpointercapture event received 
+PASS lostpointercapture is dispatched on the document 
+
index 4816dc5..736dac8 100644 (file)
@@ -1879,7 +1879,6 @@ imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_pointerlo
 imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_pointermove_in_pointerlock-manual.html [ Skip ]
 imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_pointermove_on_chorded_mouse_button_when_locked-manual.html [ Skip ]
 
-webkit.org/b/197004 imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html [ Skip ]
 webkit.org/b/197005 imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html [ Skip ]
 webkit.org/b/197008 imported/w3c/web-platform-tests/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html [ Pass Failure ]
 webkit.org/b/197007 imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_coordinates_when_locked.html [ Skip ]
index 37261b3..4850a82 100644 (file)
@@ -1,3 +1,27 @@
+2019-04-18  Antoine Quint  <graouts@apple.com>
+
+        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_for_disconnected_node.html
+        https://bugs.webkit.org/show_bug.cgi?id=197004
+
+        Reviewed by Antti Koivisto.
+
+        We need to release pointer capture when an element that has pointer capture is disconnected from the DOM.
+
+        * dom/Element.cpp:
+        (WebCore::Element::removedFromAncestor): Notify the PointerCaptureController that an element was disconnected.
+        * dom/PointerEvent.cpp:
+        (WebCore::PointerEvent::create): Broaden createPointerCancelEvent() to take in an event type so that we may use it to create a
+        lostpointercapture event as well.
+        (WebCore::PointerEvent::createPointerCancelEvent): Deleted.
+        * dom/PointerEvent.h:
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::elementWasRemoved): Check whether the provided element matches one of the target overrides recorded
+        in the map of captured pointer IDs.
+        (WebCore::PointerCaptureController::pointerEventWasDispatched): This block of code was actually useless in this location, the new code
+        added in elementWasRemoved() performs the actions that the spec text mandates.
+        (WebCore::PointerCaptureController::cancelPointer): Replace the call to createPointerCancelEvent() with one to create().
+        * page/PointerCaptureController.h:
+
 2019-04-17  Antoine Quint  <graouts@apple.com>
 
         [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_on_event_handlers.html
index 108e824..4d4b9df 100644 (file)
@@ -1990,6 +1990,10 @@ void Element::removedFromAncestor(RemovalType removalType, ContainerNode& oldPar
     if (document().page())
         document().page()->pointerLockController().elementRemoved(*this);
 #endif
+#if ENABLE(POINTER_EVENTS)
+    if (document().page() && RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled())
+        document().page()->pointerCaptureController().elementWasRemoved(*this);
+#endif
 
     setSavedLayerScrollPosition(ScrollPosition());
 
index a5b7d1c..b679a13 100644 (file)
@@ -84,9 +84,9 @@ RefPtr<PointerEvent> PointerEvent::create(const MouseEvent& mouseEvent)
     return adoptRef(*new PointerEvent(type, canBubble, isCancelable, isComposed, mouseEvent));
 }
 
-Ref<PointerEvent> PointerEvent::createPointerCancelEvent(PointerID pointerId, const String& pointerType)
+Ref<PointerEvent> PointerEvent::create(const String& type, PointerID pointerId, const String& pointerType)
 {
-    return adoptRef(*new PointerEvent(eventNames().pointercancelEvent, CanBubble::Yes, IsCancelable::No, IsComposed::Yes, pointerId, pointerType));
+    return adoptRef(*new PointerEvent(type, CanBubble::Yes, IsCancelable::No, IsComposed::Yes, pointerId, pointerType));
 }
 
 PointerEvent::PointerEvent() = default;
index 578976d..b12ab2d 100644 (file)
@@ -73,7 +73,7 @@ public:
     }
 
     static RefPtr<PointerEvent> create(const MouseEvent&);
-    static Ref<PointerEvent> createPointerCancelEvent(PointerID, const String& pointerType);
+    static Ref<PointerEvent> create(const String& type, PointerID, const String& pointerType);
 
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
index 7594175..08517c6 100644 (file)
@@ -128,6 +128,24 @@ void PointerCaptureController::pointerLockWasApplied()
     }
 }
 
+void PointerCaptureController::elementWasRemoved(Element& element)
+{
+    for (auto& keyAndValue : m_activePointerIdsToCapturingData) {
+        auto& capturingData = keyAndValue.value;
+        if (capturingData.pendingTargetOverride == &element || capturingData.targetOverride == &element) {
+            // https://w3c.github.io/pointerevents/#implicit-release-of-pointer-capture
+            // When the pointer capture target override is no longer connected, the pending pointer capture target override and pointer capture target
+            // override nodes SHOULD be cleared and also a PointerEvent named lostpointercapture corresponding to the captured pointer SHOULD be fired
+            // at the document.
+            auto pointerId = keyAndValue.key;
+            auto pointerType = capturingData.pointerType;
+            releasePointerCapture(&element, pointerId);
+            element.document().enqueueDocumentEvent(PointerEvent::create(eventNames().lostpointercaptureEvent, pointerId, pointerType));
+            return;
+        }
+    }
+}
+
 void PointerCaptureController::touchEndedOrWasCancelledForIdentifier(PointerID pointerId)
 {
     m_activePointerIdsToCapturingData.remove(pointerId);
@@ -231,14 +249,6 @@ void PointerCaptureController::pointerEventWasDispatched(const PointerEvent& eve
         // Pointer Capture steps to fire lostpointercapture if necessary.
         if (event.type() == eventNames().pointerupEvent)
             capturingData.pendingTargetOverride = nullptr;
-
-        // When the pointer capture target override is no longer connected, the pending pointer capture target override and pointer
-        // capture target override nodes SHOULD be cleared and also a PointerEvent named lostpointercapture corresponding to the captured
-        // pointer SHOULD be fired at the document.
-        if (capturingData.targetOverride && !capturingData.targetOverride->isConnected()) {
-            capturingData.pendingTargetOverride = nullptr;
-            capturingData.targetOverride = nullptr;
-        }
     }
 
     processPendingPointerCapture(event);
@@ -281,7 +291,7 @@ void PointerCaptureController::cancelPointer(PointerID pointerId, const IntPoint
     if (!target)
         return;
 
-    auto event = PointerEvent::createPointerCancelEvent(pointerId, capturingData.pointerType);
+    auto event = PointerEvent::create(eventNames().pointercancelEvent, pointerId, capturingData.pointerType);
     target->dispatchEvent(event);
     processPendingPointerCapture(WTFMove(event));
 }
index 173341d..4708f04 100644 (file)
@@ -46,6 +46,7 @@ public:
     bool hasPointerCapture(Element*, PointerID);
 
     void pointerLockWasApplied();
+    void elementWasRemoved(Element&);
 
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     std::pair<bool, bool> dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);