Skip to content

Commit

Permalink
DOM: Test 'slotchange' event firing during move
Browse files Browse the repository at this point in the history
See whatwg/dom#1307 (comment).

[email protected]

Bug: 40150299
Change-Id: I9529941e05591620da5b3c11635693a15f0ce866
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6111212
Reviewed-by: Noam Rosenthal <[email protected]>
Commit-Queue: Dominic Farolino <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1399350}
  • Loading branch information
domfarolino authored and chromium-wpt-export-bot committed Dec 20, 2024
1 parent 2331838 commit 45901e8
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions dom/nodes/moveBefore/tentative/slotchange-events.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<title>slotchanged event</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>

<script>
customElements.define(
"custom-element",
class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: "open"});
const slot = document.createElement('slot');
slot.name = 'content';
shadowRoot.append(slot);
}
},
);

promise_test(async t => {
const customElement = document.body.appendChild(document.createElement('custom-element'));
t.add_cleanup(() => customElement.remove());

const slot = customElement.shadowRoot.children[0];
const slotChangePromise = new Promise((resolve, reject) => {
slot.addEventListener('slotchange', e => resolve(), {once: true});
t.step_timeout(() => reject('Timeout; slotchange was not fired'), 1500);
});

const defaultContentP = customElement.shadowRoot.appendChild(document.createElement('p'));
slot.moveBefore(defaultContentP, null);
await slotChangePromise;
}, "Moving default content into a slot fires 'slotchange' event");

promise_test(async t => {
const customElement = document.body.appendChild(document.createElement('custom-element'));
t.add_cleanup(() => customElement.remove());

const slot = customElement.shadowRoot.children[0];
const defaultContentP = slot.appendChild(document.createElement('p'));

// Wait for "signal a slot change" to asynchronously settle. This should fire
// the 'slotchange' event for the insertion above, but we will not assert that,
// since this test is only testing that 'slotchange' is fired on removal. We
// separate this out in case an implementation fires one but not the other
// (i.e., Chromium, at the time of writing this).
await new Promise(resolve => t.step_timeout(() => resolve()));

const slotChangePromise = new Promise((resolve, reject) => {
slot.addEventListener('slotchange', e => resolve(), {once: true});
t.step_timeout(() => reject('Timeout; slotchange was not fired'), 1500);
});

// Move `defaultContentP` OUT of the slot, and into the ShadowRoot. This
// triggers "signal a slot change" on `defaultContentP`'s old parent, which is
// the slot.
customElement.shadowRoot.moveBefore(defaultContentP, null);
await slotChangePromise;
}, "Moving default content out of a slot fires 'slotchange' event");

promise_test(async t => {
const customElement = document.body.appendChild(document.createElement('custom-element'));
t.add_cleanup(() => customElement.remove());

const slot = customElement.shadowRoot.children[0];
const slottable = document.body.appendChild(document.createElement('p'));
slottable.slot = 'content';

{
const slotChangePromise = new Promise((resolve, reject) => {
slot.addEventListener('slotchange', e => {
if (slot.assignedNodes().includes(slottable)) {
resolve();
} else {
reject('slot.assignedNodes() did not include the slottable after move');
}
}, {once: true});

t.step_timeout(() => reject('Timeout; slotchange (whiling moving an element in) was not fired'), 1500);
});

// Move the slottable INTO the custom element, thus slotting it.
customElement.moveBefore(slottable, null);
await slotChangePromise;
}

{
const slotChangePromise = new Promise((resolve, reject) => {
slot.addEventListener('slotchange', e => {
if (slot.assignedNodes().length === 0) {
resolve();
} else {
reject('slot.assignedNodes() not empty after the slottable moved out');
}
}, {once: true});

t.step_timeout(() => reject('Timeout; slotchange (whiling moving an element out) was not fired'), 1500);
});

// Move the slottable OUT of the custom element, thus unslotting it.
document.body.moveBefore(slottable, null);
await slotChangePromise;
}
}, "Moving a slottable into and out out of a custom element fires 'slotchange' event");
</script>

0 comments on commit 45901e8

Please sign in to comment.