Title: [246122] trunk
Revision
246122
Author
[email protected]
Date
2019-06-05 12:21:38 -0700 (Wed, 05 Jun 2019)

Log Message

[Pointer Events] Fire pointerout and pointerleave events after firing pointercancel
https://bugs.webkit.org/show_bug.cgi?id=198560

Patch by Antoine Quint <[email protected]> on 2019-06-05
Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

Mark WPT progressions. Notably, the iOS-specific tests now have 100% PASS rate.

* web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
* web-platform-tests/pointerevents/pointerevent_pointercancel_touch-expected.txt:
* web-platform-tests/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-expected.txt:
* web-platform-tests/pointerevents/pointerevent_pointerout_after_pointercancel_touch-expected.txt:

Source/WebCore:

The Pointer Events specification mandates that "pointerout" and "pointerleave" events must be dispatched
immediately after dispatching a "pointercancel" event.

Since we needed to determine the bubbling, cancelable and composed nature of those events in additional
places, we now have static methods to determine this defined in PointerEvent.h such that both PointerEvent.cpp
and PointerEventIOS.cpp may use them. This should guarantee consistency going forward.

* dom/PointerEvent.cpp:
(WebCore::PointerEvent::create):
(WebCore::PointerEvent::PointerEvent):
* dom/PointerEvent.h:
* dom/ios/PointerEventIOS.cpp:
(WebCore::pointerEventType):
(WebCore::PointerEvent::create):
(WebCore::PointerEvent::PointerEvent):
(WebCore::phaseIsCancelable): Deleted.
(WebCore::typeCanBubble): Deleted.
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::cancelPointer):

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (246121 => 246122)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2019-06-05 19:21:38 UTC (rev 246122)
@@ -1,3 +1,17 @@
+2019-06-05  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Fire pointerout and pointerleave events after firing pointercancel
+        https://bugs.webkit.org/show_bug.cgi?id=198560
+
+        Reviewed by Dean Jackson.
+
+        Mark WPT progressions. Notably, the iOS-specific tests now have 100% PASS rate.
+
+        * web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt:
+        * web-platform-tests/pointerevents/pointerevent_pointercancel_touch-expected.txt:
+        * web-platform-tests/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-expected.txt:
+        * web-platform-tests/pointerevents/pointerevent_pointerout_after_pointercancel_touch-expected.txt:
+
 2019-06-05  Javier Fernandez  <[email protected]>
 
         Update the CSS Text WPT test suite

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt (246121 => 246122)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt	2019-06-05 19:21:38 UTC (rev 246122)
@@ -1,5 +1,5 @@
 
 FAIL Mouse down and capture to green. assert_array_equals: Received events: green received pointerover,green received pointerenter,green received pointermove,green received pointerdown,green received gotpointercapture,green received pointermove,green received pointerout,green received pointerleave,green received pointerover,green received pointerenter,green received pointermove lengths differ, expected 7 got 11
-FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received pointermove,green received pointermove lengths differ, expected 11 got 6
-FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received lostpointercapture,green received pointerout,green received pointerleave,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointermove lengths differ, expected 12 got 11
+FAIL Mouse down at green and capture to blue. assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received pointermove,green received pointermove,green received pointermove lengths differ, expected 11 got 7
+FAIL Mouse down and capture to green, move to blue and release capture assert_array_equals: Received events: green received pointerout,green received pointerover,green received pointerenter,green received pointermove,green received lostpointercapture,green received pointermove,green received pointerout,green received pointerleave,blue received pointerover,blue received pointerenter,blue received pointermove,blue received pointermove property 0, expected "green received pointerover" but got "green received pointerout"
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointercancel_touch-expected.txt (246121 => 246122)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointercancel_touch-expected.txt	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointercancel_touch-expected.txt	2019-06-05 19:21:38 UTC (rev 246122)
@@ -11,7 +11,7 @@
 The following pointer types were detected: touch.
 
 
-FAIL pointercancel event received assert_true: pointerleave should be received before the test finished expected true got false
+PASS pointercancel event received 
 PASS  touch pointercancel event is a PointerEvent event 
 PASS  touch pointercancel.pointerId attribute exists 
 PASS  touch pointercancel.pointerId is readonly 
@@ -48,6 +48,6 @@
 PASS  touch pointercancel.toElement attribute exists 
 PASS  touch pointercancel.toElement is readonly 
 PASS  touch pointercancel.toElement IDL type object (JS type was object) 
-FAIL  touch pointercancel.toElement value is null. assert_equals: toElement attribute value expected null but got Element node <div id="target0" style="background: black"></div>
+PASS  touch pointercancel.toElement value is null. 
 PASS  touch pointercancel.pressure value is valid 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-expected.txt (246121 => 246122)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-expected.txt	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-expected.txt	2019-06-05 19:21:38 UTC (rev 246122)
@@ -9,5 +9,5 @@
 The following pointer types were detected: touch.
 
 
-FAIL pointerleave event received assert_true: pointerleave should be received before the test finishes expected true got false
+PASS pointerleave event received 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerout_after_pointercancel_touch-expected.txt (246121 => 246122)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerout_after_pointercancel_touch-expected.txt	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/pointerevents/pointerevent_pointerout_after_pointercancel_touch-expected.txt	2019-06-05 19:21:38 UTC (rev 246122)
@@ -9,5 +9,5 @@
 The following pointer types were detected: touch.
 
 
-FAIL pointerout event received assert_true: pointerout should be received before the test finishes expected true got false
+PASS pointerout event received 
 

Modified: trunk/Source/WebCore/ChangeLog (246121 => 246122)


--- trunk/Source/WebCore/ChangeLog	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/Source/WebCore/ChangeLog	2019-06-05 19:21:38 UTC (rev 246122)
@@ -1,3 +1,30 @@
+2019-06-05  Antoine Quint  <[email protected]>
+
+        [Pointer Events] Fire pointerout and pointerleave events after firing pointercancel
+        https://bugs.webkit.org/show_bug.cgi?id=198560
+
+        Reviewed by Dean Jackson.
+
+        The Pointer Events specification mandates that "pointerout" and "pointerleave" events must be dispatched
+        immediately after dispatching a "pointercancel" event.
+
+        Since we needed to determine the bubbling, cancelable and composed nature of those events in additional
+        places, we now have static methods to determine this defined in PointerEvent.h such that both PointerEvent.cpp
+        and PointerEventIOS.cpp may use them. This should guarantee consistency going forward.
+
+        * dom/PointerEvent.cpp:
+        (WebCore::PointerEvent::create):
+        (WebCore::PointerEvent::PointerEvent):
+        * dom/PointerEvent.h:
+        * dom/ios/PointerEventIOS.cpp:
+        (WebCore::pointerEventType):
+        (WebCore::PointerEvent::create):
+        (WebCore::PointerEvent::PointerEvent):
+        (WebCore::phaseIsCancelable): Deleted.
+        (WebCore::typeCanBubble): Deleted.
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::cancelPointer):
+
 2019-06-05  Saam Barati  <[email protected]>
 
         [WHLSL] Implement loop expressions

Modified: trunk/Source/WebCore/dom/PointerEvent.cpp (246121 => 246122)


--- trunk/Source/WebCore/dom/PointerEvent.cpp	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/Source/WebCore/dom/PointerEvent.cpp	2019-06-05 19:21:38 UTC (rev 246122)
@@ -82,16 +82,12 @@
 
 Ref<PointerEvent> PointerEvent::create(const String& type, short button, const MouseEvent& mouseEvent)
 {
-    auto isEnterOrLeave = type == eventNames().pointerenterEvent || type == eventNames().pointerleaveEvent;
-    auto canBubble = isEnterOrLeave ? CanBubble::No : CanBubble::Yes;
-    auto isCancelable = isEnterOrLeave ? IsCancelable::No : IsCancelable::Yes;
-    auto isComposed = isEnterOrLeave ? IsComposed::No : IsComposed::Yes;
-    return adoptRef(*new PointerEvent(type, canBubble, isCancelable, isComposed, button, mouseEvent));
+    return adoptRef(*new PointerEvent(type, button, mouseEvent));
 }
 
 Ref<PointerEvent> PointerEvent::create(const String& type, PointerID pointerId, const String& pointerType, IsPrimary isPrimary)
 {
-    return adoptRef(*new PointerEvent(type, CanBubble::Yes, IsCancelable::No, IsComposed::Yes, pointerId, pointerType, isPrimary));
+    return adoptRef(*new PointerEvent(type, pointerId, pointerType, isPrimary));
 }
 
 PointerEvent::PointerEvent() = default;
@@ -111,14 +107,14 @@
 {
 }
 
-PointerEvent::PointerEvent(const AtomicString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, short button, const MouseEvent& mouseEvent)
-    : MouseEvent(type, canBubble, isCancelable, isComposed, mouseEvent.view(), mouseEvent.detail(), mouseEvent.screenLocation(), { mouseEvent.clientX(), mouseEvent.clientY() }, mouseEvent.modifierKeys(), button, mouseEvent.buttons(), mouseEvent.syntheticClickType(), mouseEvent.relatedTarget())
+PointerEvent::PointerEvent(const AtomicString& type, short button, const MouseEvent& mouseEvent)
+    : MouseEvent(type, typeCanBubble(type), typeIsCancelable(type), typeIsComposed(type), mouseEvent.view(), mouseEvent.detail(), mouseEvent.screenLocation(), { mouseEvent.clientX(), mouseEvent.clientY() }, mouseEvent.modifierKeys(), button, mouseEvent.buttons(), mouseEvent.syntheticClickType(), mouseEvent.relatedTarget())
     , m_isPrimary(true)
 {
 }
 
-PointerEvent::PointerEvent(const AtomicString& type, CanBubble canBubble, IsCancelable isCancelable, IsComposed isComposed, PointerID pointerId, const String& pointerType, IsPrimary isPrimary)
-    : MouseEvent(type, canBubble, isCancelable, isComposed, nullptr, 0, { }, { }, { }, 0, 0, 0, nullptr)
+PointerEvent::PointerEvent(const AtomicString& type, PointerID pointerId, const String& pointerType, IsPrimary isPrimary)
+    : MouseEvent(type, typeCanBubble(type), typeIsCancelable(type), typeIsComposed(type), nullptr, 0, { }, { }, { }, 0, 0, 0, nullptr)
     , m_pointerId(pointerId)
     , m_pointerType(pointerType)
     , m_isPrimary(isPrimary == IsPrimary::Yes)

Modified: trunk/Source/WebCore/dom/PointerEvent.h (246121 => 246122)


--- trunk/Source/WebCore/dom/PointerEvent.h	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/Source/WebCore/dom/PointerEvent.h	2019-06-05 19:21:38 UTC (rev 246122)
@@ -27,6 +27,7 @@
 
 #if ENABLE(POINTER_EVENTS)
 
+#include "EventNames.h"
 #include "MouseEvent.h"
 #include "Node.h"
 #include "PointerID.h"
@@ -114,10 +115,15 @@
     EventInterface eventInterface() const override;
 
 private:
+    static bool typeIsEnterOrLeave(const AtomicString& type) { return type == eventNames().pointerenterEvent || type == eventNames().pointerleaveEvent; }
+    static CanBubble typeCanBubble(const AtomicString& type) { return typeIsEnterOrLeave(type) ? CanBubble::No : CanBubble::Yes; }
+    static IsCancelable typeIsCancelable(const AtomicString& type) { return typeIsEnterOrLeave(type) ? IsCancelable::No : IsCancelable::Yes; }
+    static IsComposed typeIsComposed(const AtomicString& type) { return typeIsEnterOrLeave(type) ? IsComposed::No : IsComposed::Yes; }
+
     PointerEvent();
     PointerEvent(const AtomicString&, Init&&);
-    PointerEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, short button, const MouseEvent&);
-    PointerEvent(const AtomicString& type, CanBubble, IsCancelable, IsComposed, PointerID, const String& pointerType, IsPrimary);
+    PointerEvent(const AtomicString& type, short button, const MouseEvent&);
+    PointerEvent(const AtomicString& type, PointerID, const String& pointerType, IsPrimary);
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     PointerEvent(const AtomicString& type, const PlatformTouchEvent&, IsCancelable isCancelable, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 #endif

Modified: trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp (246121 => 246122)


--- trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-06-05 19:21:38 UTC (rev 246122)
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-static AtomicString pointerEventType(PlatformTouchPoint::TouchPhaseType phase)
+static const AtomicString& pointerEventType(PlatformTouchPoint::TouchPhaseType phase)
 {
     switch (phase) {
     case PlatformTouchPoint::TouchPhaseBegan:
@@ -50,31 +50,19 @@
     return nullAtom();
 }
 
-static PointerEvent::IsCancelable phaseIsCancelable(PlatformTouchPoint::TouchPhaseType phase)
-{
-    if (phase == PlatformTouchPoint::TouchPhaseCancelled)
-        return PointerEvent::IsCancelable::No;
-    return PointerEvent::IsCancelable::Yes;
-}
-
-static Event::CanBubble typeCanBubble(const AtomicString& type)
-{
-    return (type == eventNames().pointerenterEvent || type == eventNames().pointerleaveEvent) ? Event::CanBubble::No : Event::CanBubble::Yes;
-}
-
 Ref<PointerEvent> PointerEvent::create(const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
 {
-    auto phase = event.touchPhaseAtIndex(index);
-    return adoptRef(*new PointerEvent(pointerEventType(phase), event, phaseIsCancelable(phase), index, isPrimary, WTFMove(view)));
+    const auto& type = pointerEventType(event.touchPhaseAtIndex(index));
+    return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
 }
 
 Ref<PointerEvent> PointerEvent::create(const String& type, const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
 {
-    return adoptRef(*new PointerEvent(type, event, phaseIsCancelable(event.touchPhaseAtIndex(index)), index, isPrimary, WTFMove(view)));
+    return adoptRef(*new PointerEvent(type, event, typeIsCancelable(type), index, isPrimary, WTFMove(view)));
 }
 
 PointerEvent::PointerEvent(const AtomicString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
-    : MouseEvent(type, typeCanBubble(type), isCancelable, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0, event.touchLocationAtIndex(index), event.touchLocationAtIndex(index), { }, event.modifiers(), 0, 0, nullptr, 0, 0, nullptr, IsSimulated::No, IsTrusted::Yes)
+    : MouseEvent(type, typeCanBubble(type), isCancelable, typeIsComposed(type), event.timestamp().approximateMonotonicTime(), WTFMove(view), 0, event.touchLocationAtIndex(index), event.touchLocationAtIndex(index), { }, event.modifiers(), 0, 0, nullptr, 0, 0, nullptr, IsSimulated::No, IsTrusted::Yes)
     , m_pointerId(event.touchIdentifierAtIndex(index))
     , m_width(2 * event.radiusXAtIndex(index))
     , m_height(2 * event.radiusYAtIndex(index))

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (246121 => 246122)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-05 18:36:29 UTC (rev 246121)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-05 19:21:38 UTC (rev 246122)
@@ -389,9 +389,14 @@
     if (!target)
         return;
 
-    auto event = PointerEvent::create(eventNames().pointercancelEvent, pointerId, capturingData.pointerType, capturingData.isPrimary ? PointerEvent::IsPrimary::Yes : PointerEvent::IsPrimary::No);
-    target->dispatchEvent(event);
-    processPendingPointerCapture(WTFMove(event));
+    // After firing the pointercancel event, a user agent MUST also fire a pointer event named pointerout
+    // followed by firing a pointer event named pointerleave.
+    auto isPrimary = capturingData.isPrimary ? PointerEvent::IsPrimary::Yes : PointerEvent::IsPrimary::No;
+    auto cancelEvent = PointerEvent::create(eventNames().pointercancelEvent, pointerId, capturingData.pointerType, isPrimary);
+    target->dispatchEvent(cancelEvent);
+    target->dispatchEvent(PointerEvent::create(eventNames().pointeroutEvent, pointerId, capturingData.pointerType, isPrimary));
+    target->dispatchEvent(PointerEvent::create(eventNames().pointerleaveEvent, pointerId, capturingData.pointerType, isPrimary));
+    processPendingPointerCapture(WTFMove(cancelEvent));
 }
 
 void PointerCaptureController::processPendingPointerCapture(const PointerEvent& event)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to