Title: [245286] trunk
Revision
245286
Author
[email protected]
Date
2019-05-14 09:50:37 -0700 (Tue, 14 May 2019)

Log Message

[Pointer Events] The pointerenter and pointerleave events target the wrong element on iOS
https://bugs.webkit.org/show_bug.cgi?id=197881
<rdar://problem/50187657>

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

Source/WebCore:

Test: pointerevents/ios/enter-leave-target.html

The "pointerenter" and "pointerleave" should target the element on which the event listener was added and not
the element that would otherwise hit test. This matches the behavior of "mouseenter" and "mouseleave" on macOS.

* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):

LayoutTests:

Add a test where we tap an element that is the child of another element where the parent is the element with the "pointerenter"
and "pointerleave" events registered. The test shows that we correctly set the target to the parent element and not the child.

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

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245285 => 245286)


--- trunk/LayoutTests/ChangeLog	2019-05-14 16:43:51 UTC (rev 245285)
+++ trunk/LayoutTests/ChangeLog	2019-05-14 16:50:37 UTC (rev 245286)
@@ -1,3 +1,17 @@
+2019-05-14  Antoine Quint  <[email protected]>
+
+        [Pointer Events] The pointerenter and pointerleave events target the wrong element on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=197881
+        <rdar://problem/50187657>
+
+        Reviewed by Dean Jackson.
+
+        Add a test where we tap an element that is the child of another element where the parent is the element with the "pointerenter"
+        and "pointerleave" events registered. The test shows that we correctly set the target to the parent element and not the child.
+
+        * pointerevents/ios/enter-leave-target-expected.txt: Added.
+        * pointerevents/ios/enter-leave-target.html: Added.
+
 2019-05-14  Daniel Bates  <[email protected]>
 
         [iOS] Cannot scroll to beginning of document after scrolling to end of document and vice versa via key commands

Added: trunk/LayoutTests/pointerevents/ios/enter-leave-target-expected.txt (0 => 245286)


--- trunk/LayoutTests/pointerevents/ios/enter-leave-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/enter-leave-target-expected.txt	2019-05-14 16:50:37 UTC (rev 245286)
@@ -0,0 +1,3 @@
+
+PASS Testing that "pointerenter" and "pointerleave" have the element on which the event listener was added as their target. 
+

Added: trunk/LayoutTests/pointerevents/ios/enter-leave-target.html (0 => 245286)


--- trunk/LayoutTests/pointerevents/ios/enter-leave-target.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/enter-leave-target.html	2019-05-14 16:50:37 UTC (rev 245286)
@@ -0,0 +1,44 @@
+<!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) => {
+    // Add a child element covering the same bounds as the target so that it hit tests when tapping.
+    target.appendChild(document.createElement("div")).setAttribute("style", "position: absolute; width: 100%; height: 100%;");
+
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=197882
+    // [Pointer Events] Listening to a "pointerover", "pointerenter", "pointerout" or "pointerleave" event alone does not fire the event on iOS
+    target.addEventListener("pointerdown", event => { });
+
+    const entered = new Promise(resolve => {
+        target.addEventListener("pointerenter", event => {
+            assert_equals(event.target, target, `The ${event.type} event target matches the element on which the event listener was added.`);
+            resolve();
+        });
+    });
+
+    const left = new Promise(resolve => {
+        target.addEventListener("pointerleave", event => {
+            assert_equals(event.target, target, `The ${event.type} event target matches the element on which the event listener was added.`);
+            resolve();
+        });
+    });
+
+    const tapped = ui.tap({ x: 100, y: 100 });
+
+    Promise.all([entered, left, tapped]).then(() => test.done());
+}, `Testing that "pointerenter" and "pointerleave" have the element on which the event listener was added as their target.`);
+
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (245285 => 245286)


--- trunk/Source/WebCore/ChangeLog	2019-05-14 16:43:51 UTC (rev 245285)
+++ trunk/Source/WebCore/ChangeLog	2019-05-14 16:50:37 UTC (rev 245286)
@@ -1,3 +1,19 @@
+2019-05-14  Antoine Quint  <[email protected]>
+
+        [Pointer Events] The pointerenter and pointerleave events target the wrong element on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=197881
+        <rdar://problem/50187657>
+
+        Reviewed by Dean Jackson.
+
+        Test: pointerevents/ios/enter-leave-target.html
+
+        The "pointerenter" and "pointerleave" should target the element on which the event listener was added and not
+        the element that would otherwise hit test. This matches the behavior of "mouseenter" and "mouseleave" on macOS.
+
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
+
 2019-05-14  Said Abou-Hallawa  <[email protected]>
 
         [CG] Adding support for HEIF-sequence ('public.heics') images

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (245285 => 245286)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-05-14 16:43:51 UTC (rev 245285)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-05-14 16:50:37 UTC (rev 245286)
@@ -164,6 +164,26 @@
         target.dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
     };
 
+    auto dispatchEnterOrLeaveEvent = [&](const String& type) {
+        if (!is<Element>(&target))
+            return;
+
+        auto* targetElement = &downcast<Element>(target);
+
+        bool hasCapturingListenerInHierarchy = false;
+        for (ContainerNode* curr = targetElement; curr; curr = curr->parentInComposedTree()) {
+            if (curr->hasCapturingEventListeners(type)) {
+                hasCapturingListenerInHierarchy = true;
+                break;
+            }
+        }
+
+        for (Element* element = &downcast<Element>(target); element; element = element->parentElementInComposedTree()) {
+            if (hasCapturingListenerInHierarchy || element->hasEventListeners(type))
+                element->dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
+        }
+    };
+
     auto pointerEvent = PointerEvent::create(platformTouchEvent, index, isPrimary, view);
 
     if (pointerEvent->type() == eventNames().pointerdownEvent) {
@@ -171,7 +191,7 @@
         // 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);
+        dispatchEnterOrLeaveEvent(eventNames().pointerenterEvent);
     }
 
     pointerEventWillBeDispatched(pointerEvent, &target);
@@ -183,7 +203,7 @@
         // 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);
+        dispatchEnterOrLeaveEvent(eventNames().pointerleaveEvent);
     }
 }
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to