Title: [241723] trunk
Revision
241723
Author
grao...@webkit.org
Date
2019-02-18 09:52:34 -0800 (Mon, 18 Feb 2019)

Log Message

[iOS] Dispatch additional events along with pointerdown and pointerup
https://bugs.webkit.org/show_bug.cgi?id=194776
<rdar://problem/48164284>

Reviewed by Brent Fulgham.

Source/WebCore:

The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout"
and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace
it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also
allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private.

Test: pointerevents/ios/over-enter-out-leave.html

* dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types.
* dom/PointerEvent.h:
* dom/ios/PointerEventIOS.cpp:
(WebCore::PointerEvent::create):
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted.
* page/EventHandler.h:
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex()
and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events
had defaultPrevented() or defaultHanded() return true and return those values as a pair.
(WebCore::PointerCaptureController::pointerEventWasDispatched):
* page/PointerCaptureController.h:

LayoutTests:

Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".

* pointerevents/ios/over-enter-out-leave-expected.txt: Added.
* pointerevents/ios/over-enter-out-leave.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (241722 => 241723)


--- trunk/LayoutTests/ChangeLog	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/LayoutTests/ChangeLog	2019-02-18 17:52:34 UTC (rev 241723)
@@ -1,3 +1,16 @@
+2019-02-18  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Dispatch additional events along with pointerdown and pointerup
+        https://bugs.webkit.org/show_bug.cgi?id=194776
+        <rdar://problem/48164284>
+
+        Reviewed by Brent Fulgham.
+
+        Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".
+
+        * pointerevents/ios/over-enter-out-leave-expected.txt: Added.
+        * pointerevents/ios/over-enter-out-leave.html: Added.
+
 2019-02-18  Sihui Liu  <sihui_...@apple.com>
 
         IndexedDB: leak IDBDatabase and IDBTransacstion in layout tests

Added: trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt (0 => 241723)


--- trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt	2019-02-18 17:52:34 UTC (rev 241723)
@@ -0,0 +1,3 @@
+
+PASS Testing that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup". 
+

Added: trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html (0 => 241723)


--- trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html	2019-02-18 17:52:34 UTC (rev 241723)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script>
+
+'use strict';
+
+target_test({ width: "200px", height: "200px" }, (target, test) => {
+    document.body.style.width = "2000px";
+    document.body.style.height = "2000px";
+
+    const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointerdown", "pointerup", "pointerout", "pointerleave"]);
+
+    const touch = ui.finger();
+    ui.sequence([
+        touch.begin({ x: 100, y: 100 }),
+        touch.end()
+    ]).then(() => {
+        eventTracker.assertMatchesEvents([
+            { type: "pointerover", x: 100, y: 100, isPrimary: true },
+            { type: "pointerenter", x: 100, y: 100, isPrimary: true },
+            { type: "pointerdown", x: 100, y: 100, isPrimary: true },
+            { type: "pointerup", x: 100, y: 100, isPrimary: false },
+            { type: "pointerout", x: 100, y: 100, isPrimary: false },
+            { type: "pointerleave", x: 100, y: 100, isPrimary: false },
+        ]);
+        test.done();
+    });
+}, `Testing that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".`);
+
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (241722 => 241723)


--- trunk/Source/WebCore/ChangeLog	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/ChangeLog	2019-02-18 17:52:34 UTC (rev 241723)
@@ -1,3 +1,32 @@
+2019-02-18  Antoine Quint  <grao...@apple.com>
+
+        [iOS] Dispatch additional events along with pointerdown and pointerup
+        https://bugs.webkit.org/show_bug.cgi?id=194776
+        <rdar://problem/48164284>
+
+        Reviewed by Brent Fulgham.
+
+        The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout"
+        and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace
+        it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also
+        allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private.
+
+        Test: pointerevents/ios/over-enter-out-leave.html
+
+        * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types.
+        * dom/PointerEvent.h:
+        * dom/ios/PointerEventIOS.cpp:
+        (WebCore::PointerEvent::create):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted.
+        * page/EventHandler.h:
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex()
+        and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events
+        had defaultPrevented() or defaultHanded() return true and return those values as a pair.
+        (WebCore::PointerCaptureController::pointerEventWasDispatched):
+        * page/PointerCaptureController.h:
+
 2019-02-18  Sihui Liu  <sihui_...@apple.com>
 
         IndexedDB: leak IDBDatabase and IDBTransacstion in layout tests

Modified: trunk/Source/WebCore/dom/EventNames.h (241722 => 241723)


--- trunk/Source/WebCore/dom/EventNames.h	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/EventNames.h	2019-02-18 17:52:34 UTC (rev 241723)
@@ -206,7 +206,11 @@
     macro(pointerlockerror) \
     macro(pointercancel) \
     macro(pointerdown) \
+    macro(pointerenter) \
+    macro(pointerleave) \
     macro(pointermove) \
+    macro(pointerout) \
+    macro(pointerover) \
     macro(pointerup) \
     macro(popstate) \
     macro(previoustrack) \

Modified: trunk/Source/WebCore/dom/PointerEvent.h (241722 => 241723)


--- trunk/Source/WebCore/dom/PointerEvent.h	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/PointerEvent.h	2019-02-18 17:52:34 UTC (rev 241723)
@@ -83,6 +83,7 @@
 
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
     static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
+    static Ref<PointerEvent> create(const String& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
 #endif
 
     static const String& mousePointerType();

Modified: trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp (241722 => 241723)


--- trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-02-18 17:52:34 UTC (rev 241723)
@@ -63,6 +63,11 @@
     return adoptRef(*new PointerEvent(pointerEventType(phase), event, phaseIsCancelable(phase), 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)));
+}
+
 PointerEvent::PointerEvent(const AtomicString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
     : MouseEvent(type, CanBubble::Yes, 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)
     , m_pointerId(event.touchIdentifierAtIndex(index))

Modified: trunk/Source/WebCore/page/EventHandler.cpp (241722 => 241723)


--- trunk/Source/WebCore/page/EventHandler.cpp	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2019-02-18 17:52:34 UTC (rev 241723)
@@ -114,11 +114,6 @@
 #include "TouchList.h"
 #endif
 
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-#include "PointerCaptureController.h"
-#include "PointerEvent.h"
-#endif
-
 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
 #include "PlatformTouchEvent.h"
 #endif
@@ -4271,18 +4266,6 @@
 }
 #endif // ENABLE(TOUCH_EVENTS)
 
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-Ref<PointerEvent> EventHandler::dispatchPointerEventForTouchAtIndex(EventTarget& target, const PlatformTouchEvent& platformTouchEvent, unsigned index, bool isPrimary)
-{
-    auto& pointerCaptureController = m_frame.page()->pointerCaptureController();
-    auto pointerEvent = PointerEvent::create(platformTouchEvent, index, isPrimary, m_frame.windowProxy());
-    pointerCaptureController.pointerEventWillBeDispatched(pointerEvent, &target);
-    target.dispatchEvent(pointerEvent);
-    pointerCaptureController.pointerEventWasDispatched(pointerEvent);
-    return pointerEvent;
-}
-#endif // ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-
 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
 {
     m_mousePositionIsUnknown = false;

Modified: trunk/Source/WebCore/page/EventHandler.h (241722 => 241723)


--- trunk/Source/WebCore/page/EventHandler.h	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/EventHandler.h	2019-02-18 17:52:34 UTC (rev 241723)
@@ -81,7 +81,6 @@
 class PlatformKeyboardEvent;
 class PlatformTouchEvent;
 class PlatformWheelEvent;
-class PointerEvent;
 class RenderBox;
 class RenderElement;
 class RenderLayer;
@@ -320,10 +319,6 @@
     WEBCORE_EXPORT bool handleTouchEvent(const PlatformTouchEvent&);
 #endif
 
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-    Ref<PointerEvent> dispatchPointerEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary);
-#endif
-
     bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
     void updateCursor();
 

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (241722 => 241723)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-02-18 17:52:34 UTC (rev 241723)
@@ -134,6 +134,47 @@
     return iterator != m_activePointerIdsToCapturingData.end() && iterator->value.cancelled;
 }
 
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+std::pair<bool, bool> PointerCaptureController::dispatchEventForTouchAtIndex(EventTarget& target, const PlatformTouchEvent& platformTouchEvent, unsigned index, bool isPrimary, WindowProxy& view)
+{
+    bool defaultPrevented = false;
+    bool defaultHandled = false;
+
+    auto dispatchEvent = [&](const String& type) {
+        auto event = PointerEvent::create(type, platformTouchEvent, index, isPrimary, view);
+        target.dispatchEvent(event);
+        defaultPrevented |= event->defaultPrevented();
+        defaultHandled |= event->defaultHandled();
+    };
+
+    auto pointerEvent = PointerEvent::create(platformTouchEvent, index, isPrimary, view);
+
+    if (pointerEvent->type() == eventNames().pointerdownEvent) {
+        // https://w3c.github.io/pointerevents/#the-pointerdown-event
+        // For input devices that do not support hover, a user agent MUST also fire a pointer event named pointerover followed by a pointer event named
+        // pointerenter prior to dispatching the pointerdown event.
+        dispatchEvent(eventNames().pointeroverEvent);
+        dispatchEvent(eventNames().pointerenterEvent);
+    }
+
+    pointerEventWillBeDispatched(pointerEvent, &target);
+    target.dispatchEvent(pointerEvent);
+    defaultPrevented |= pointerEvent->defaultPrevented();
+    defaultHandled |= pointerEvent->defaultHandled();
+    pointerEventWasDispatched(pointerEvent);
+
+    if (pointerEvent->type() == eventNames().pointerupEvent) {
+        // https://w3c.github.io/pointerevents/#the-pointerup-event
+        // For input devices that do not support hover, a user agent MUST also fire a pointer event named pointerout followed by a
+        // pointer event named pointerleave after dispatching the pointerup event.
+        dispatchEvent(eventNames().pointeroutEvent);
+        dispatchEvent(eventNames().pointerleaveEvent);
+    }
+
+    return { defaultPrevented, defaultHandled };
+}
+#endif
+
 void PointerCaptureController::pointerEventWillBeDispatched(const PointerEvent& event, EventTarget* target)
 {
     // https://w3c.github.io/pointerevents/#implicit-pointer-capture
@@ -170,7 +211,7 @@
         // 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.

Modified: trunk/Source/WebCore/page/PointerCaptureController.h (241722 => 241723)


--- trunk/Source/WebCore/page/PointerCaptureController.h	2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/PointerCaptureController.h	2019-02-18 17:52:34 UTC (rev 241723)
@@ -47,10 +47,13 @@
 
     void pointerLockWasApplied();
 
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+    std::pair<bool, bool> dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
+#endif
+
     void touchEndedOrWasCancelledForIdentifier(PointerID);
     bool hasCancelledPointerEventForIdentifier(PointerID);
-    void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);
-    void pointerEventWasDispatched(const PointerEvent&);
+    void dispatchEvent(PointerEvent&, EventTarget*);
     WEBCORE_EXPORT void cancelPointer(PointerID, const IntPoint&);
 
 private:
@@ -61,6 +64,8 @@
         bool cancelled { false };
     };
 
+    void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);
+    void pointerEventWasDispatched(const PointerEvent&);
     void processPendingPointerCapture(const PointerEvent&);
 
     Page& m_page;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to