- 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