Title: [246061] trunk
Revision
246061
Author
[email protected]
Date
2019-06-04 07:34:11 -0700 (Tue, 04 Jun 2019)

Log Message

The "mouseenter" and "pointerenter" events are fired from the bottom up
https://bugs.webkit.org/show_bug.cgi?id=198036
<rdar://problem/50940350>

Patch by Antoine Quint <[email protected]> on 2019-06-04
Reviewed by Darin Adler.

Source/WebCore:

Ensure "mouseenter" and "pointerenter" events are dispatched from the bottom up to match the UI Events spec
at https://w3c.github.io/uievents/#events-mouseevent-event-order. We also fix the issue where "pointerevent"
and "pointerleave" events were dispatched as bubbling events on iOS which is not correct and was caught by the
new iOS test.

Tests: pointerevents/ios/enter-leave-order.html
       pointerevents/mouse/enter-leave-order.html

* dom/ios/PointerEventIOS.cpp:
(WebCore::typeCanBubble):
(WebCore::PointerEvent::PointerEvent):
* page/EventHandler.cpp:
(WebCore::EventHandler::updateMouseEventTargetNode):
* page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):

LayoutTests:

* fast/events/mouseenter-mouseleave-capture-expected.txt:
* fast/events/mouseenter-mouseleave-expected.txt:
* fast/events/mouseenterleave-on-subframe-expected.txt:
* fast/events/shadow-event-path-expected.txt:
* fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt:
* fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt:
* fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt:
* platform/mac-wk1/TestExpectations:
* platform/mac-wk2/fast/events/shadow-event-path-expected.txt:
* platform/mac/fast/events/shadow-event-path-2-expected.txt:
* pointerevents/ios/enter-leave-order-expected.txt: Added.
* pointerevents/ios/enter-leave-order.html: Added.
* pointerevents/mouse/enter-leave-order-expected.txt: Added.
* pointerevents/mouse/enter-leave-order.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246060 => 246061)


--- trunk/LayoutTests/ChangeLog	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/ChangeLog	2019-06-04 14:34:11 UTC (rev 246061)
@@ -1,3 +1,26 @@
+2019-06-04  Antoine Quint  <[email protected]>
+
+        The "mouseenter" and "pointerenter" events are fired from the bottom up
+        https://bugs.webkit.org/show_bug.cgi?id=198036
+        <rdar://problem/50940350>
+
+        Reviewed by Darin Adler.
+
+        * fast/events/mouseenter-mouseleave-capture-expected.txt:
+        * fast/events/mouseenter-mouseleave-expected.txt:
+        * fast/events/mouseenterleave-on-subframe-expected.txt:
+        * fast/events/shadow-event-path-expected.txt:
+        * fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt:
+        * fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt:
+        * fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt:
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac-wk2/fast/events/shadow-event-path-expected.txt:
+        * platform/mac/fast/events/shadow-event-path-2-expected.txt:
+        * pointerevents/ios/enter-leave-order-expected.txt: Added.
+        * pointerevents/ios/enter-leave-order.html: Added.
+        * pointerevents/mouse/enter-leave-order-expected.txt: Added.
+        * pointerevents/mouse/enter-leave-order.html: Added.
+
 2019-06-04  Cathie Chen  <[email protected]>
 
         JS wrapper of target in ResizeObserverEntry/ResizeObserver shouldn't get collected ahead

Modified: trunk/LayoutTests/fast/events/mouseenter-mouseleave-capture-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/events/mouseenter-mouseleave-capture-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/events/mouseenter-mouseleave-capture-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -8,8 +8,8 @@
 mouseMoveTo(110,140)
 mouseout on html
 mouseover on outer1
+mouseenter on body
 mouseenter on outer1
-mouseenter on body
 mousemove on outer1
 
 mouseMoveTo(130,140)
@@ -22,8 +22,8 @@
 mouseout on inner1
 mouseleave on inner1
 mouseover on inner3
+mouseenter on inner2
 mouseenter on inner3
-mouseenter on inner2
 mousemove on inner3
 
 mouseMoveTo(180,140)

Modified: trunk/LayoutTests/fast/events/mouseenter-mouseleave-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/events/mouseenter-mouseleave-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/events/mouseenter-mouseleave-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -9,8 +9,8 @@
 mouseMoveTo(110,140)
 mouseout on html
 mouseover on outer1
+mouseenter on body
 mouseenter on outer1
-mouseenter on body
 mousemove on outer1
 
 mouseMoveTo(130,140)
@@ -23,8 +23,8 @@
 mouseout on inner1
 mouseleave on inner1
 mouseover on inner3
+mouseenter on inner2
 mouseenter on inner3
-mouseenter on inner2
 mousemove on inner3
 
 mouseMoveTo(180,140)

Modified: trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -1,9 +1,9 @@
 
 This is a test of a mouseleave events in an inner-document. The test is success if we get matching mouseleave events for every mouseenter event, and if the logged nodeNames of event targets does not include '#document'.
 
+mouseenter on HTML
+mouseenter on BODY
 mouseenter on DIV
-mouseenter on BODY
-mouseenter on HTML
 mouseleave on DIV
 mouseleave on BODY
 mouseleave on HTML

Modified: trunk/LayoutTests/fast/events/shadow-event-path-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/events/shadow-event-path-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/events/shadow-event-path-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -39,16 +39,16 @@
     target:input#target
     relatedTarget:null
 
-mouseenter@input#target
-    target:input#target
+mouseenter@html
+    target:html
     relatedTarget:null
 
-mouseenter@div#divInsideSummary
-    target:div#divInsideSummary
+mouseenter@body
+    target:body
     relatedTarget:null
 
-mouseenter@summary
-    target:summary
+mouseenter@div#detailsContainer
+    target:div#detailsContainer
     relatedTarget:null
 
 mouseenter@details
@@ -55,16 +55,16 @@
     target:details
     relatedTarget:null
 
-mouseenter@div#detailsContainer
-    target:div#detailsContainer
+mouseenter@summary
+    target:summary
     relatedTarget:null
 
-mouseenter@body
-    target:body
+mouseenter@div#divInsideSummary
+    target:div#divInsideSummary
     relatedTarget:null
 
-mouseenter@html
-    target:html
+mouseenter@input#target
+    target:input#target
     relatedTarget:null
 
 mousemove@input#target

Modified: trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -14,8 +14,8 @@
 mouseenter on slot
 
 ==Entering slotted element==
+mouseenter on targetParent
 mouseenter on target
-mouseenter on targetParent
 
 ==Leaving slotted element==
 mouseleave on target

Modified: trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -4,10 +4,10 @@
 
 
 ==Entering target==
+mouseenter on hostParent
+mouseenter on host
+mouseenter on container
 mouseenter on target
-mouseenter on container
-mouseenter on host
-mouseenter on hostParent
 
 ==Leaving target==
 mouseleave on target

Modified: trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt (246060 => 246061)


--- trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -4,9 +4,9 @@
 
 
 ==Entering target==
+mouseenter on slotContainer
+mouseenter on slot
 mouseenter on target
-mouseenter on slot
-mouseenter on slotContainer
 
 ==Leaving target==
 mouseleave on target

Modified: trunk/LayoutTests/platform/mac/fast/events/shadow-event-path-2-expected.txt (246060 => 246061)


--- trunk/LayoutTests/platform/mac/fast/events/shadow-event-path-2-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/platform/mac/fast/events/shadow-event-path-2-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -67,8 +67,8 @@
     target:input#target
     relatedTarget:html
 
-mouseenter@input#target
-    target:input#target
+mouseenter@body
+    target:body
     relatedTarget:html
 
 mouseenter@div#detailsContainer
@@ -75,8 +75,8 @@
     target:div#detailsContainer
     relatedTarget:html
 
-mouseenter@body
-    target:body
+mouseenter@input#target
+    target:input#target
     relatedTarget:html
 
 mousemove@input#target

Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (246060 => 246061)


--- trunk/LayoutTests/platform/mac-wk1/TestExpectations	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations	2019-06-04 14:34:11 UTC (rev 246061)
@@ -689,6 +689,7 @@
 
 webkit.org/b/194309 media/modern-media-controls/compact-media-controls/compact-media-controls-layout.html [ Pass Failure ]
 
+webkit.org/b/195098 pointerevents/mouse/enter-leave-order.html [ Failure ]
 webkit.org/b/195098 pointerevents/mouse/over-enter-out-leave.html [ Failure ]
 webkit.org/b/195098 pointerevents/mouse/pointer-capture.html [ Failure ]
 webkit.org/b/195098 pointerevents/mouse/pointer-events-before-mouse-events.html [ Failure ]

Modified: trunk/LayoutTests/platform/mac-wk2/fast/events/shadow-event-path-expected.txt (246060 => 246061)


--- trunk/LayoutTests/platform/mac-wk2/fast/events/shadow-event-path-expected.txt	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/LayoutTests/platform/mac-wk2/fast/events/shadow-event-path-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -39,16 +39,16 @@
     target:input#target
     relatedTarget:null
 
-mouseenter@input#target
-    target:input#target
+mouseenter@html
+    target:html
     relatedTarget:null
 
-mouseenter@div#divInsideSummary
-    target:div#divInsideSummary
+mouseenter@body
+    target:body
     relatedTarget:null
 
-mouseenter@summary
-    target:summary
+mouseenter@div#detailsContainer
+    target:div#detailsContainer
     relatedTarget:null
 
 mouseenter@details
@@ -55,16 +55,16 @@
     target:details
     relatedTarget:null
 
-mouseenter@div#detailsContainer
-    target:div#detailsContainer
+mouseenter@summary
+    target:summary
     relatedTarget:null
 
-mouseenter@body
-    target:body
+mouseenter@div#divInsideSummary
+    target:div#divInsideSummary
     relatedTarget:null
 
-mouseenter@html
-    target:html
+mouseenter@input#target
+    target:input#target
     relatedTarget:null
 
 mousemove@input#target

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


--- trunk/LayoutTests/pointerevents/ios/enter-leave-order-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/enter-leave-order-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -0,0 +1,3 @@
+
+PASS Testing that "pointerenter" events are dispatched from top to bottom and "pointerleave" events are dispatched bottom to top. 
+

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


--- trunk/LayoutTests/pointerevents/ios/enter-leave-order.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/enter-leave-order.html	2019-06-04 14:34:11 UTC (rev 246061)
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+
+div.test-container {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    width: 100px;
+    height: 100px;
+}
+
+#top {
+    left: 50px;
+    top: 50px;
+}
+
+</style>
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script>
+
+'use strict';
+
+const events = [];
+
+function logEvent(event)
+{
+    events.push(`${event.type}@${event.target.id}`);
+}
+
+function makeDiv(id)
+{
+    const div = document.createElement("div");
+    div.addEventListener("pointerenter", logEvent);
+    div.addEventListener("pointerleave", logEvent);
+    div.className = "test-container";
+    div.id = id;
+    return div;
+}
+
+document.body.appendChild(makeDiv("top")).appendChild(makeDiv("middle")).appendChild(makeDiv("bottom"));
+
+async_test(test => {
+    const tapped = ui.tap({ x: 100, y: 100 }).then(() => {
+        assert_array_equals(events, [
+            "pointerenter@top",
+            "pointerenter@middle",
+            "pointerenter@bottom",
+            "pointerleave@bottom",
+            "pointerleave@middle",
+            "pointerleave@top"
+        ]);
+        test.done();
+    });
+}, `Testing that "pointerenter" events are dispatched from top to bottom and "pointerleave" events are dispatched bottom to top.`);
+
+</script>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/pointerevents/mouse/enter-leave-order-expected.txt (0 => 246061)


--- trunk/LayoutTests/pointerevents/mouse/enter-leave-order-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/mouse/enter-leave-order-expected.txt	2019-06-04 14:34:11 UTC (rev 246061)
@@ -0,0 +1,3 @@
+
+PASS Testing that "pointerenter" events are dispatched from top to bottom and "pointerleave" events are dispatched bottom to top. 
+

Added: trunk/LayoutTests/pointerevents/mouse/enter-leave-order.html (0 => 246061)


--- trunk/LayoutTests/pointerevents/mouse/enter-leave-order.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/mouse/enter-leave-order.html	2019-06-04 14:34:11 UTC (rev 246061)
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+
+div.test-container {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    width: 100px;
+    height: 100px;
+}
+
+#top {
+    left: 50px;
+    top: 50px;
+}
+
+</style>
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script>
+
+'use strict';
+
+const events = [];
+
+function logEvent(event)
+{
+    events.push(`${event.type}@${event.target.id}`);
+}
+
+function makeDiv(id)
+{
+    const div = document.createElement("div");
+    div.addEventListener("pointerenter", logEvent);
+    div.addEventListener("pointerleave", logEvent);
+    div.className = "test-container";
+    div.id = id;
+    return div;
+}
+
+// Add three nested and fully overlapping elements.
+document.body.appendChild(makeDiv("top")).appendChild(makeDiv("middle")).appendChild(makeDiv("bottom"));
+
+// mouse over and out of the elements.
+eventSender.mouseMoveTo(75, 75);
+eventSender.mouseMoveTo(25, 25);
+
+test(() => {
+    assert_array_equals(events, [
+        "pointerenter@top",
+        "pointerenter@middle",
+        "pointerenter@bottom",
+        "pointerleave@bottom",
+        "pointerleave@middle",
+        "pointerleave@top"
+    ]);
+}, `Testing that "pointerenter" events are dispatched from top to bottom and "pointerleave" events are dispatched bottom to top.`);
+
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (246060 => 246061)


--- trunk/Source/WebCore/ChangeLog	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/Source/WebCore/ChangeLog	2019-06-04 14:34:11 UTC (rev 246061)
@@ -1,3 +1,27 @@
+2019-06-04  Antoine Quint  <[email protected]>
+
+        The "mouseenter" and "pointerenter" events are fired from the bottom up
+        https://bugs.webkit.org/show_bug.cgi?id=198036
+        <rdar://problem/50940350>
+
+        Reviewed by Darin Adler.
+
+        Ensure "mouseenter" and "pointerenter" events are dispatched from the bottom up to match the UI Events spec
+        at https://w3c.github.io/uievents/#events-mouseevent-event-order. We also fix the issue where "pointerevent"
+        and "pointerleave" events were dispatched as bubbling events on iOS which is not correct and was caught by the
+        new iOS test.
+ 
+        Tests: pointerevents/ios/enter-leave-order.html
+               pointerevents/mouse/enter-leave-order.html
+
+        * dom/ios/PointerEventIOS.cpp:
+        (WebCore::typeCanBubble):
+        (WebCore::PointerEvent::PointerEvent):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::updateMouseEventTargetNode):
+        * page/PointerCaptureController.cpp:
+        (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
+
 2019-06-04  Cathie Chen  <[email protected]>
 
         JS wrapper of target in ResizeObserverEntry/ResizeObserver shouldn't get collected ahead

Modified: trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp (246060 => 246061)


--- trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp	2019-06-04 14:34:11 UTC (rev 246061)
@@ -57,6 +57,11 @@
     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);
@@ -69,7 +74,7 @@
 }
 
 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)
+    : 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)
     , m_pointerId(event.touchIdentifierAtIndex(index))
     , m_width(2 * event.radiusXAtIndex(index))
     , m_height(2 * event.radiusYAtIndex(index))

Modified: trunk/Source/WebCore/page/EventHandler.cpp (246060 => 246061)


--- trunk/Source/WebCore/page/EventHandler.cpp	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/Source/WebCore/page/EventHandler.cpp	2019-06-04 14:34:11 UTC (rev 246061)
@@ -2594,7 +2594,7 @@
             if (m_elementUnderMouse)
                 m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
 
-            for (auto& chain : enteredElementsChain) {
+            for (auto& chain : WTF::makeReversedRange(enteredElementsChain)) {
                 if (hasCapturingMouseEnterListener || chain->hasEventListeners(eventNames().pointerenterEvent) || chain->hasEventListeners(eventNames().mouseenterEvent))
                     chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseenterEvent, 0, m_lastElementUnderMouse.get());
             }

Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (246060 => 246061)


--- trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-04 11:14:10 UTC (rev 246060)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp	2019-06-04 14:34:11 UTC (rev 246061)
@@ -190,9 +190,18 @@
             }
         }
 
-        for (Element* element = &downcast<Element>(target); element; element = element->parentElementInComposedTree()) {
+        Vector<Ref<Element>, 32> targetChain;
+        for (Element* element = targetElement; element; element = element->parentElementInComposedTree()) {
             if (hasCapturingListenerInHierarchy || element->hasEventListeners(type))
+                targetChain.append(*element);
+        }
+
+        if (type == eventNames().pointerenterEvent) {
+            for (auto& element : WTF::makeReversedRange(targetChain))
                 element->dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
+        } else {
+            for (auto& element : targetChain)
+                element->dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
         }
     };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to