Skip to content

Commit 157f3c7

Browse files
Fix pointerevent_after_target_removed_from_slot.html asserts
This CL updates the test its and expectations to match the event hittest behavior in practice after either the slot or the element placed in the slot is removed. To avoid boundary event complications caused by layout changes, all relevant elements are made same sized. The expectations are written based on the following observations: each test starts with `host` containing the shadow-root containing `parent` containing `slot` in which `child` is placed; `child` remains hidden as a a sibling of the shadow-root until placed in `slot`. - Removing `slot` returns `child` back to the hidden position. - Removing `child` exposes the subtree of `slot`. Manual testing: https://codepen.io/mustaqahmed/full/LEGgpMQ Bug: 404479707 Change-Id: I2ce50112f7f1bdb2a4cb6417e7477f59be5e1b89 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7107458 Reviewed-by: Robert Flack <[email protected]> Commit-Queue: Mustaq Ahmed <[email protected]> Cr-Commit-Position: refs/heads/main@{#1541198}
1 parent 3bc11de commit 157f3c7

File tree

1 file changed

+103
-81
lines changed

1 file changed

+103
-81
lines changed

pointerevents/pointerevent_after_target_removed_from_slot.html

Lines changed: 103 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<!DOCTYPE HTML>
2-
<link rel="help" href="https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface">
3-
<title>Enter/leave events fired to parent after child is removed from slot</title>
2+
<link rel="help"
3+
href="https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface">
4+
<title>Pointerevents fired after a slotted element is removed</title>
45
<meta name="variant" content="?mouse">
56
<script src="/resources/testharness.js"></script>
67
<script src="/resources/testharnessreport.js"></script>
@@ -9,116 +10,106 @@
910
<script src="/resources/testdriver-vendor.js"></script>
1011
<script src="pointerevent_support.js"></script>
1112

12-
<template id="template">
13-
<style>
14-
div {
15-
width: 100px;
16-
height: 100px;
17-
}
18-
</style>
19-
<div id="parent">
20-
<slot id="slot">slot</slot>
21-
</div>
22-
</template>
23-
2413
<style>
25-
div, my-elem {
14+
div {
2615
width: 100px;
2716
height: 100px;
2817
display: block;
2918
}
3019
</style>
3120

32-
<my-elem id="host">
33-
<div id="child">child</div>
34-
</my-elem>
35-
<div id="done">done</div>
21+
<div id="host">
22+
<template id="template" shadowrootmode="open">
23+
<style>
24+
div {
25+
width: 100px;
26+
height: 100px;
27+
}
28+
</style>
29+
<div id="parent">
30+
<slot id="slot">
31+
<div></div>
32+
</slot>
33+
</div>
34+
</template>
35+
36+
<div id="filler"></div>
37+
</div>
38+
<div id="done"></div>
3639

3740
<script>
3841
"use strict";
3942

40-
customElements.define(
41-
"my-elem",
42-
class extends HTMLElement {
43-
constructor() {
44-
super();
45-
let content = document.getElementById("template").content;
46-
const shadowRoot = this.attachShadow({ mode: "open" });
47-
shadowRoot.appendChild(content.cloneNode(true));
48-
}
49-
},
50-
);
51-
5243
const pointer_type = location.search.substring(1);
5344

54-
const shadow_host = document.getElementById("host");
55-
const parent = shadow_host.shadowRoot.getElementById("parent");
45+
const host = document.getElementById("host");
46+
const parent = host.shadowRoot.getElementById("parent");
5647
const slot = parent.firstElementChild;
57-
const slotted_child = document.getElementById("child");
48+
const filler = document.getElementById("filler");
5849
const done = document.getElementById("done");
5950

6051
let event_log = [];
61-
let elem_to_remove;
6252

6353
function logEvent(e) {
6454
if (e.eventPhase == e.AT_TARGET) {
6555
event_log.push(e.type + "@" + e.target.id);
6656
}
6757
}
6858

69-
function removeChildFromSlot() {
70-
elem_to_remove.remove();
71-
event_log.push("(child-removed)");
72-
}
73-
74-
function restoreChildInSlot() {
75-
if (!slotted_child.parentElement) {
76-
shadow_host.appendChild(slotted_child);
77-
}
78-
if (!slot.parentElement) {
79-
parent.appendChild(slot);
59+
const modifier_methods = {
60+
"remove-slot": {
61+
"remover": () => { slot.remove(); event_log.push("(removed)"); },
62+
"restorer": () => { parent.appendChild(slot); }
63+
},
64+
"remove-filler": {
65+
"remover": () => { filler.remove(); event_log.push("(removed)"); },
66+
"restorer": () => { host.appendChild(filler); }
67+
},
68+
"change-slotname": {
69+
"remover": () => { filler.slot = "xyz"; event_log.push("(removed)"); },
70+
"restorer": () => { filler.slot = ""; }
8071
}
8172
}
8273

8374
function setup() {
8475
const events = ["pointerover", "pointerout",
8576
"pointerenter", "pointerleave", "pointerdown", "pointerup"];
86-
let targets = [shadow_host, parent, slot, slotted_child];
77+
let targets = [host, parent, slot, filler];
8778
for (let i = 0; i < targets.length; i++) {
8879
events.forEach(event => targets[i].addEventListener(event, logEvent));
8980
}
9081
}
9182

92-
function addPromiseTest(remover_event, tested_elem_to_remove,
83+
function addPromiseTest(remover_event, removal_type,
9384
expected_events) {
94-
assert_true(["slot", "slotted-child"].includes(tested_elem_to_remove),
95-
"Unexpcted tested_elem_to_remove param");
85+
assert_true(Object.keys(modifier_methods).includes(removal_type),
86+
"[sanity check] Unknown removal_type param");
9687

97-
const test_name = `Pointer events from ${pointer_type} `+
98-
`received before/after ${tested_elem_to_remove} removal `+
88+
const test_name = `${pointer_type} events with ${removal_type} ` +
9989
`at ${remover_event}`;
10090

10191
promise_test(async test => {
10292
event_log = [];
103-
elem_to_remove = (tested_elem_to_remove == "slot" ? slot : slotted_child);
10493

105-
restoreChildInSlot();
106-
child.addEventListener(remover_event, removeChildFromSlot,
107-
{ once: true });
94+
filler.addEventListener(remover_event,
95+
modifier_methods[removal_type].remover,
96+
{ once: true });
97+
test.add_cleanup(modifier_methods[removal_type].restorer);
98+
10899
// TODO([email protected]): It would be more robust if we could remove
109100
// the event listener above through `test.add_cleanup()` but strangely the
110-
// cleanup call fails after the test that removes the slotted-child! This
101+
// cleanup call fails after the test that removes the filler! This
111102
// happens even if we make the shadow DOM construction dynamic inside this
112103
// `promise_test`!!!
113104

114105
let done_click_promise = getEvent("click", done);
115106

116107
let actions = new test_driver.Actions()
117108
.addPointer("TestPointer", pointer_type)
118-
.pointerMove(-30, -30, {origin: shadow_host})
109+
.pointerMove(-30, -30, {origin: host})
119110
.pointerDown()
120111
.pointerUp()
121-
.pointerMove(30, 30, {origin: shadow_host})
112+
.pointerMove(30, 30, {origin: host})
122113
.pointerDown()
123114
.pointerUp()
124115
.pointerMove(0, 0, {origin: done})
@@ -128,10 +119,13 @@
128119
await actions.send();
129120
await done_click_promise;
130121

131-
let removal_in_event_log = event_log.indexOf("(child-removed)");
132-
let removal_in_expected_list = expected_events.indexOf("(child-removed)");
133-
assert_true(removal_in_event_log != -1 && removal_in_expected_list != -1,
134-
"(child-removed) expected in both lists");
122+
let removal_in_event_log = event_log.indexOf("(removed)");
123+
assert_true(removal_in_event_log != -1,
124+
"(removed) in event log");
125+
126+
let removal_in_expected_list = expected_events.indexOf("(removed)");
127+
assert_true(removal_in_expected_list != -1,
128+
"[sanity check] (removed) in expected events");
135129

136130
assert_equals(event_log.slice(0, removal_in_event_log).toString(),
137131
expected_events.slice(0, removal_in_expected_list).toString(),
@@ -146,11 +140,12 @@
146140

147141
addPromiseTest(
148142
"pointerdown",
149-
"slot",
143+
"remove-slot",
150144
[
151-
"pointerover@child",
152-
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
153-
"pointerdown@child", "(child-removed)",
145+
"pointerover@filler",
146+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
147+
"pointerdown@filler", "(removed)",
148+
"pointerout@filler", "pointerleave@filler",
154149
"pointerover@parent", "pointerover@host", "pointerup@parent", "pointerup@host",
155150
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
156151
"pointerout@parent", "pointerout@host",
@@ -159,12 +154,25 @@
159154
);
160155
addPromiseTest(
161156
"pointerdown",
162-
"slotted-child",
157+
"remove-filler",
158+
[
159+
"pointerover@filler",
160+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
161+
"pointerdown@filler", "(removed)",
162+
"pointerover@slot", "pointerup@slot",
163+
"pointerdown@slot", "pointerup@slot",
164+
"pointerout@slot",
165+
"pointerleave@slot", "pointerleave@parent", "pointerleave@host"
166+
]
167+
);
168+
addPromiseTest(
169+
"pointerdown",
170+
"change-slotname",
163171
[
164-
"pointerover@child",
165-
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
166-
"pointerdown@child", "(child-removed)",
167-
"pointerleave@slot",
172+
"pointerover@filler",
173+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
174+
"pointerdown@filler", "(removed)",
175+
"pointerout@filler", "pointerleave@filler",
168176
"pointerover@parent", "pointerover@host", "pointerup@parent", "pointerup@host",
169177
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
170178
"pointerout@parent", "pointerout@host",
@@ -173,11 +181,12 @@
173181
);
174182
addPromiseTest(
175183
"pointerup",
176-
"slot",
184+
"remove-slot",
177185
[
178-
"pointerover@child",
179-
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
180-
"pointerdown@child", "pointerup@child", "(child-removed)",
186+
"pointerover@filler",
187+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
188+
"pointerdown@filler", "pointerup@filler", "(removed)",
189+
"pointerout@filler", "pointerleave@filler",
181190
"pointerover@parent", "pointerover@host",
182191
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
183192
"pointerout@parent", "pointerout@host",
@@ -186,12 +195,25 @@
186195
);
187196
addPromiseTest(
188197
"pointerup",
189-
"slotted-child",
198+
"remove-filler",
199+
[
200+
"pointerover@filler",
201+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
202+
"pointerdown@filler", "pointerup@filler", "(removed)",
203+
"pointerover@slot",
204+
"pointerdown@slot", "pointerup@slot",
205+
"pointerout@slot",
206+
"pointerleave@slot", "pointerleave@parent", "pointerleave@host"
207+
]
208+
);
209+
addPromiseTest(
210+
"pointerup",
211+
"change-slotname",
190212
[
191-
"pointerover@child",
192-
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
193-
"pointerdown@child", "pointerup@child", "(child-removed)",
194-
"pointerleave@slot",
213+
"pointerover@filler",
214+
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
215+
"pointerdown@filler", "pointerup@filler", "(removed)",
216+
"pointerout@filler", "pointerleave@filler",
195217
"pointerover@parent", "pointerover@host",
196218
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
197219
"pointerout@parent", "pointerout@host",

0 commit comments

Comments
 (0)