Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Support Pointer Events on macOS
https://bugs.webkit.org/show_bug.cgi?id=195008 <rdar://problem/47454419> Patch by Antoine Quint <graouts@apple.com> on 2019-02-27 Reviewed by Dean Jackson. Source/JavaScriptCore: * Configurations/FeatureDefines.xcconfig: Source/WebCore: We now dispatch relevant pointer events as we prepare to dispatch mouse events. In most cases, this means we dispatch a pointer event of the same type, with "mouse" being substituted by "pointer", and with the same properties with the exception that if preventDefault() is called for a "pointerdown" event, the matching "mousedown" will not be dispatched, and the same behavior also extends to "pointerup". Tests: pointerevents/mouse/over-enter-out-leave.html pointerevents/mouse/pointer-capture.html pointerevents/mouse/pointer-event-basic-properties.html pointerevents/mouse/pointer-events-before-mouse-events.html pointerevents/mouse/pointerdown-prevent-default.html * Configurations/FeatureDefines.xcconfig: * dom/Document.cpp: All of the touch-action related members and functions should be iOS-specific since the touch-action property does not have any effect on macOS. (WebCore::Document::invalidateRenderingDependentRegions): (WebCore::Document::nodeWillBeRemoved): (WebCore::Document::updateTouchActionElements): * dom/Document.h: * dom/Element.cpp: (WebCore::Element::dispatchMouseEvent): Dispatch a pointer event matching the mouse event that is about to be dispatched. If preventDefault() is called in the event handler for either "pointerdown" or "pointerup", do not proceed with dispatching the mouse event. * dom/PointerEvent.cpp: (WebCore::pointerEventType): (WebCore::PointerEvent::create): * dom/PointerEvent.h: * page/EventHandler.cpp: Check both the pointer and mouse events to see if we need to dispatch "enter" and "leave" events. (WebCore::hierarchyHasCapturingEventListeners): (WebCore::EventHandler::updateMouseEventTargetNode): * page/PointerCaptureController.cpp: Fix a build error which only happened on macOS. (WebCore::PointerCaptureController::PointerCaptureController): Create the CapturingData for the unique mouse pointer. (WebCore::PointerCaptureController::hasPointerCapture): The code did not match the spec cited in the comment, only the pending target override needs to be considered to determine whether a given element has pointer capture enabled. (WebCore::PointerCaptureController::dispatchEvent): Dispatch the provided pointer event, accounting for pointer capture if it is set. * page/PointerLockController.cpp: Fix a build error which only happened on macOS. * style/StyleTreeResolver.cpp: (WebCore::Style::TreeResolver::resolveElement): Code related to touch-action is only relevant to iOS. Source/WebCore/PAL: * Configurations/FeatureDefines.xcconfig: Source/WebKit: * Configurations/FeatureDefines.xcconfig: Source/WebKitLegacy/mac: Add a WebKitLegacy API to enable and disable the Pointer Events runtime feature. * Configurations/FeatureDefines.xcconfig: * WebView/WebPreferenceKeysPrivate.h: * WebView/WebPreferences.mm: (+[WebPreferences initialize]): (-[WebPreferences pointerEventsEnabled]): (-[WebPreferences setPointerEventsEnabled:]): * WebView/WebPreferencesPrivate.h: * WebView/WebView.mm: (-[WebView _preferencesChanged:]): Tools: * DumpRenderTree/mac/DumpRenderTree.mm: (enableExperimentalFeatures): Enable the PointerEvents runtime feature in DumpRenderTree such that tests targeting WK1 may test the Pointer Events feature. * TestWebKitAPI/Configurations/FeatureDefines.xcconfig: LayoutTests: * platform/mac-wk1/TestExpectations: Mark select tests as failures due to webkit.org/b/195008. * platform/mac/TestExpectations: Enable the new mouse-based tests. * pointerevents/mouse/over-enter-out-leave-expected.txt: Added. * pointerevents/mouse/over-enter-out-leave.html: Added. * pointerevents/mouse/pointer-capture-expected.txt: Added. * pointerevents/mouse/pointer-capture.html: Added. * pointerevents/mouse/pointer-event-basic-properties-expected.txt: Added. * pointerevents/mouse/pointer-event-basic-properties.html: Added. * pointerevents/mouse/pointer-events-before-mouse-events-expected.txt: Added. * pointerevents/mouse/pointer-events-before-mouse-events.html: Added. * pointerevents/mouse/pointerdown-prevent-default-expected.txt: Added. * pointerevents/mouse/pointerdown-prevent-default.html: Added. * pointerevents/utils.js: (prototype.clear): Canonical link: https://commits.webkit.org/209453@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242137 268f45cc-cd09-0410-ab3c-d52691b4dbfc
- Loading branch information
1 parent
560d978
commit 8d0069b644e77635e68d0354377bb27a7a7fba04
Showing
40 changed files
with
535 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,3 @@ | ||
|
||
PASS Testing that "pointerover" and "pointerenter" are dispatched when entering an element's bounds and that "pointerout" and "pointerleave" are dispatched when leaving an element's bounds. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset=utf-8> | ||
</head> | ||
<body> | ||
<script src="../../resources/testharness.js"></script> | ||
<script src="../../resources/testharnessreport.js"></script> | ||
<script src="../utils.js"></script> | ||
<script> | ||
|
||
'use strict'; | ||
|
||
target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => { | ||
const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointerout", "pointerleave"]); | ||
|
||
eventSender.mouseMoveTo(50, 50); | ||
eventSender.mouseMoveTo(150, 150); | ||
eventSender.mouseMoveTo(250, 250); | ||
|
||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointerover", x: 150, y: 150, isPrimary: true }, | ||
{ type: "pointerenter", x: 150, y: 150, isPrimary: true }, | ||
{ type: "pointerout", x: 250, y: 250, isPrimary: true }, | ||
{ type: "pointerleave", x: 250, y: 250, isPrimary: true }, | ||
]); | ||
test.done(); | ||
}, `Testing that "pointerover" and "pointerenter" are dispatched when entering an element's bounds and that "pointerout" and "pointerleave" are dispatched when leaving an element's bounds.`); | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,3 @@ | ||
|
||
PASS Testing that setting pointer capture on an element dispatches pointermove events to that element even when the pointer is outside of its bounds. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,73 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset=utf-8> | ||
</head> | ||
<body> | ||
<script src="../../resources/testharness.js"></script> | ||
<script src="../../resources/testharnessreport.js"></script> | ||
<script src="../utils.js"></script> | ||
<script> | ||
|
||
'use strict'; | ||
|
||
target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => { | ||
const eventTracker = new EventTracker(target, ["pointermove", "gotpointercapture", "lostpointercapture"]); | ||
|
||
// Start with the mouse outside of the target. | ||
eventSender.mouseMoveTo(50, 50); | ||
|
||
// Move it over the target, this yields a "pointermove" event. | ||
eventSender.mouseMoveTo(150, 150); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointermove", x: 150, y: 150 } | ||
]); | ||
eventTracker.clear(); | ||
|
||
// Press the mouse and move it outside the target and release it, this does not yield a "pointermove" event since there is no capture. | ||
eventSender.mouseDown(); | ||
eventSender.mouseMoveTo(250, 250); | ||
eventSender.mouseUp(); | ||
|
||
// Now, move the mouse over the target again. | ||
eventSender.mouseMoveTo(150, 150); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointermove", x: 150, y: 150 } | ||
]); | ||
eventTracker.clear(); | ||
|
||
// And press the mouse button again, but set the capture while handling the "pointerdown" event. | ||
let pointerId; | ||
target.addEventListener("pointerdown", event => { | ||
pointerId = event.pointerId; | ||
assert_false(target.hasPointerCapture(pointerId), "The target does not have pointer capture by default."); | ||
target.setPointerCapture(pointerId); | ||
assert_true(target.hasPointerCapture(pointerId), "The target has pointer capture after calling setPointerCapture()."); | ||
}); | ||
eventSender.mouseDown(); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "gotpointercapture" } | ||
]); | ||
eventTracker.clear(); | ||
|
||
// Move the mouse oustide the target again, this time this yields a "pointermove" event since the target has pointer capture. | ||
eventSender.mouseMoveTo(250, 250); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointermove", x: 250, y: 250 } | ||
]); | ||
eventTracker.clear(); | ||
|
||
// Finally, release capture and mouse the mouse again, this should not yield a "pointermove" event. | ||
target.releasePointerCapture(pointerId); | ||
assert_false(target.hasPointerCapture(pointerId), "The target no longer has pointer capture after calling releasePointerCapture()."); | ||
eventSender.mouseMoveTo(240, 240); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "lostpointercapture" } | ||
]); | ||
|
||
test.done(); | ||
}, `Testing that setting pointer capture on an element dispatches pointermove events to that element even when the pointer is outside of its bounds.`); | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,3 @@ | ||
|
||
PASS Testing the basic properties of a pointer event triggered by a mouse. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,29 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset=utf-8> | ||
</head> | ||
<body> | ||
<script src="../../resources/testharness.js"></script> | ||
<script src="../../resources/testharnessreport.js"></script> | ||
<script src="../utils.js"></script> | ||
<script> | ||
|
||
'use strict'; | ||
|
||
target_test((target, test) => { | ||
eventSender.mouseMoveTo(50, 50); | ||
eventSender.mouseDown(); | ||
|
||
target.addEventListener("pointerdown", event => { | ||
assert_equals(event.pointerId, 1, "The pointer's identifier is 1."); | ||
assert_equals(event.pointerType, "mouse", "The pointer type is 'mouse'."); | ||
assert_true(event.isPrimary, "The pointer is the primary pointer."); | ||
}); | ||
|
||
test.done(); | ||
}, `Testing the basic properties of a pointer event triggered by a mouse.`); | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,3 @@ | ||
|
||
PASS Testing that pointer events are dispatched prior to compatibility mouse events. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,59 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset=utf-8> | ||
</head> | ||
<body> | ||
<script src="../../resources/testharness.js"></script> | ||
<script src="../../resources/testharnessreport.js"></script> | ||
<script src="../utils.js"></script> | ||
<script> | ||
|
||
'use strict'; | ||
|
||
target_test({ x: "100px", y: "100px", width: "100px", height: "100px" }, (target, test) => { | ||
const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointermove", "pointerdown", "pointerup", "pointerout", "pointerleave", | ||
"mouseover", "mouseenter", "mousemove", "mousedown", "mouseup", "mouseout", "mouseleave", "click"]); | ||
// Start outside of the target. | ||
eventSender.mouseMoveTo(50, 50); | ||
|
||
// Move the cursor over the target. | ||
eventSender.mouseMoveTo(150, 150); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointerover", x: 150, y: 150 }, | ||
{ type: "mouseover", x: 150, y: 150 }, | ||
{ type: "pointerenter", x: 150, y: 150 }, | ||
{ type: "mouseenter", x: 150, y: 150 }, | ||
{ type: "pointermove", x: 150, y: 150 }, | ||
{ type: "mousemove", x: 150, y: 150 }, | ||
]); | ||
eventTracker.clear(); | ||
|
||
// Click. | ||
eventSender.mouseDown(); | ||
eventSender.mouseUp(); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointerdown", x: 150, y: 150 }, | ||
{ type: "mousedown", x: 150, y: 150 }, | ||
{ type: "pointerup", x: 150, y: 150 }, | ||
{ type: "mouseup", x: 150, y: 150 }, | ||
{ type: "click", x: 150, y: 150 }, | ||
]); | ||
eventTracker.clear(); | ||
|
||
// Move the cursor outside the target. | ||
eventSender.mouseMoveTo(250, 250); | ||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointerout", x: 250, y: 250 }, | ||
{ type: "mouseout", x: 250, y: 250 }, | ||
{ type: "pointerleave", x: 250, y: 250 }, | ||
{ type: "mouseleave", x: 250, y: 250 }, | ||
]); | ||
eventTracker.clear(); | ||
|
||
test.done(); | ||
}, `Testing that pointer events are dispatched prior to compatibility mouse events.`); | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,3 @@ | ||
|
||
PASS Testing that calling preventDefault() when handling a "pointerdown" event does not dispatch a "mousedown" event. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -0,0 +1,38 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset=utf-8> | ||
</head> | ||
<body> | ||
<script src="../../resources/testharness.js"></script> | ||
<script src="../../resources/testharnessreport.js"></script> | ||
<script src="../utils.js"></script> | ||
<script> | ||
|
||
'use strict'; | ||
|
||
target_test((target, test) => { | ||
const eventTracker = new EventTracker(target, ["pointerdown", "mousedown"]); | ||
|
||
// Press the mouse once without calling preventDefault(). | ||
eventSender.mouseMoveTo(50, 50); | ||
eventSender.mouseDown(); | ||
eventSender.mouseUp(); | ||
|
||
// Press it again and call preventDefault(). | ||
target.addEventListener("pointerdown", event => event.preventDefault()); | ||
eventSender.mouseMoveTo(50, 50); | ||
eventSender.mouseDown(); | ||
eventSender.mouseUp(); | ||
|
||
eventTracker.assertMatchesEvents([ | ||
{ type: "pointerdown", x: 50, y: 50 }, | ||
{ type: "mousedown", x: 50, y: 50 }, | ||
{ type: "pointerdown", x: 50, y: 50 }, | ||
]); | ||
test.done(); | ||
}, `Testing that calling preventDefault() when handling a "pointerdown" event does not dispatch a "mousedown" event.`); | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -44,6 +44,11 @@ class EventTracker | ||
target.addEventListener(eventName, this); | ||
} | ||
|
||
clear() | ||
{ | ||
this.events = []; | ||
} | ||
|
||
handleEvent(event) | ||
{ | ||
if (event instanceof PointerEvent) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.