haikuwebkit/LayoutTests/fast/shadow-dom/mouseenter-mouseleave-on-sl...

52 lines
1.6 KiB
HTML
Raw Permalink Normal View History

mouseenter and mouseleave events don't get dispatched even when there is a capturing event listener for a slot ancestor https://bugs.webkit.org/show_bug.cgi?id=188561 Reviewed by Darin Adler. Source/WebCore: This patch makes mouseenter and mouseleave events to work with shadow trees and slots therein, and makes them uncomposed as discussed in https://github.com/w3c/uievents/issues/208. This patch also makes these events dispatched on DOM tree ancestors of the currently hovered element instead of render tree's hover ancestors to be consistent with the check in hierarchyHasCapturingEventListeners and other browsers. In particular, using hover ancestors is problematic when there is an element with display: contents such as slot elements, which do not have a render object. Tests: fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary.html fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree.html fast/shadow-dom/mouseenter-mouseleave-on-slot-parent.html * dom/MouseEvent.cpp: (WebCore::MouseEvent::create): * page/EventHandler.cpp: (WebCore::nearestCommonHoverAncestor): Deleted. (WebCore::hierarchyHasCapturingEventListeners): Use parentInComposedTree. Else we would miss capturing event listeners on inclusive ancestors of slots. (WebCore::EventHandler::updateMouseEventTargetNode): Use the composed tree's ancestor chain to fire mouseenter and mouseleave events. This is needed to dispatch mouseenter / mouseleave events on slot elements. Also removed comments which just state what is self-evident from the code beneath them. LayoutTests: Added tests for listening to mouseenter and mouseleave events using capturing and bubbling event listeners across shadow boundaries. * fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary-expected.txt: Added. * fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary.html: Added. * fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree-expected.txt: Added. * fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree.html: Added. * fast/shadow-dom/mouseenter-mouseleave-on-slot-parent-expected.txt: Added. * fast/shadow-dom/mouseenter-mouseleave-on-slot-parent.html: Added. * platform/ios/TestExpectations: Skip the new tests since mouse events aren't supported on iOS. Canonical link: https://commits.webkit.org/204451@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235865 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-10 21:54:14 +00:00
<!DOCTYPE html>
<html>
<body>
<p>This tests mouseenter and mouseleave event fires when capturing event listeners are only present on the slot element's parent.<br>
To manually test, move the mouse cursor into the box below and move it out.<br>
You should see mouseenter events on slotContainer, slot, and target in that order and mouseleave events in the reverse order.</p>
<div id="hostParent"><div id="host"><span id="target" style="border: solid 1px black; padding: 0.5rem;">content</span></div></div><pre id="log"></pre>
<script>
const host = document.getElementById('host');
const shadowRoot = host.attachShadow({mode: 'closed'});
shadowRoot.innerHTML = `
<div id="slotContainer">
<slot id="slot"></slot>
</div>`;
const slot = shadowRoot.querySelector('slot');
const target = document.getElementById('target');
slot.parentNode.addEventListener('mouseenter', logEvent, true);
slot.parentNode.addEventListener('mouseleave', logEvent, true);
function log(text) {
document.getElementById('log').textContent += text + '\n';
}
function logEvent(event) {
log(`${event.type} on ${event.target.id}`);
}
function logPhase(phase) {
log(`\n==${phase}==`);
}
if (!window.eventSender)
document.write('This test requires eventSender');
else {
testRunner.dumpAsText();
const targetRect = target.getBoundingClientRect();
const x = targetRect.x + 40;
logPhase('Entering target');
eventSender.mouseMoveTo(x, targetRect.top + 5);
logPhase('Leaving target');
eventSender.mouseMoveTo(x, targetRect.bottom + 5);
host.parentNode.style.display = 'none';
}
</script>
</body>
</html>