children-changed-callback
Version:
Mixin to provide subclasses of HTMLElement with .childrenChangedCallback(newList, oldList) and .visibleChildren().
159 lines (137 loc) • 4.96 kB
HTML
<html lang="en">
<body>
<script>
function printInfoAboutExampleComponents(time) {
console.log(" ");
console.log("*** " + time + " ***");
let exes = document.querySelectorAll("example-component");
console.log("Found #" + (exes ? exes.length : 0) + " example-components.");
for (let i = 0; i < exes.length; i++) {
let ex = exes[i];
console.log("example-component: " + ex.id + " .children.length:" + ex.children.length);
console.log("example-component.exampleComponentLog: " + ex.exampleComponentLog);
}
}
function testDocumentState(expect) {
let res = Array.from(document.querySelectorAll("example-component") || []).map(ex => ({
id: ex.id,
childCount: ex.children.length,
method: ex.exampleComponentLog ? ex.exampleComponentLog.name : "undefined"
}));
if (res.length !== expect.length)
return res.length + " !== " + expect.length;
for (let i = 0; i < res.length; i++) {
let a = res[i];
let b = expect[i];
if (a.id !== b.id || a.childCount !== b.childCount || a.method !== b.method)
return JSON.stringify(res[i]) + " !== " + JSON.stringify(expect[i]);
}
return true;
}
function createDiv(msg, success) {
const div = document.createElement("div");
div.style.background = success === true ? "green" : "red";
div.textContent = msg + ": " + success;
document.querySelector("body").appendChild(div);
}
window.printInfoAboutExampleComponents = printInfoAboutExampleComponents;
createDiv("start", testDocumentState([]));
</script>
<example-component id="ex1">
<span>a</span>
<span>b</span>
<span>c</span>
</example-component>
<script>
createDiv("after ex1", testDocumentState([
{id: "ex1", childCount: 3, method: "undefined"}
]));
</script>
<example-component id="ex2">
<span>d</span>
<script>
createDiv("during ex2", testDocumentState([
{id: "ex1", childCount: 3, method: "undefined"},
{id: "ex2", childCount: 2, method: "undefined"},
]));
</script>
<span>e</span>
<span>f</span>
</example-component>
<script type="module">
let expecteds = [
"ex1 constructor true",
"ex1 connectedCallback",
"ex2 constructor true",
"ex2 connectedCallback",
"ex3 constructor true",
"ex3 connectedCallback",
"ex4 constructor true",
"ex4 connectedCallback",
"ex1 childrenChangedCallback",
"ex2 childrenChangedCallback",
"ex3 childrenChangedCallback",
"ex4 childrenChangedCallback"
];
import {ChildrenChangedMixin} from "../src/ChildrenChangedMixin.js";
class ExampleComponent extends ChildrenChangedMixin(HTMLElement) {
constructor() {
super();
let testValue = expecteds.shift();
createDiv(testValue, (this.id+" constructor "+this.isConnected) === testValue)
}
connectedCallback() {
let testValue = expecteds.shift();
createDiv(testValue, (this.id+" connectedCallback") === testValue)
}
childrenChangedCallback(oldList, newList) {
let testValue = expecteds.shift();
createDiv(testValue, (this.id+" childrenChangedCallback") === testValue)
}
exampleComponentLog(msg) {
//nothing here
}
}
createDiv("Before customElements.define", testDocumentState([
{id: "ex1", childCount: 3, method: "undefined"},
{id: "ex2", childCount: 4, method: "undefined"},
{id: "ex3", childCount: 3, method: "undefined"},
{id: "ex4", childCount: 4, method: "undefined"},
]));
customElements.define("example-component", ExampleComponent);
createDiv("After customElements.define", testDocumentState([
{id: "ex1", childCount: 3, method: "exampleComponentLog"},
{id: "ex2", childCount: 4, method: "exampleComponentLog"},
{id: "ex3", childCount: 3, method: "exampleComponentLog"},
{id: "ex4", childCount: 4, method: "exampleComponentLog"},
]));
</script>
<example-component id="ex3">
<span>z</span>
<span>x</span>
<span>y</span>
</example-component>
<script type="module">
createDiv("after ex3, should be complete since script type='module' runs after full parse", testDocumentState([
{id: "ex1", childCount: 3, method: "exampleComponentLog"},
{id: "ex2", childCount: 4, method: "exampleComponentLog"},
{id: "ex3", childCount: 3, method: "exampleComponentLog"},
{id: "ex4", childCount: 4, method: "exampleComponentLog"}
]));
</script>
<example-component id="ex4">
<span>1</span>
<script type="module">
createDiv("during ex4, should be complete since script type='module' runs after full parse", testDocumentState([
{id: "ex1", childCount: 3, method: "exampleComponentLog"},
{id: "ex2", childCount: 4, method: "exampleComponentLog"},
{id: "ex3", childCount: 3, method: "exampleComponentLog"},
{id: "ex4", childCount: 4, method: "exampleComponentLog"}
]));
</script>
<span>2</span>
<span>3</span>
</example-component>
</body>
</html>