fix(wasm): bubble wc-ready lifecycle event
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-04 01:16:08 +00:00
parent 87ebb7958d
commit 030a41f732
5 changed files with 8 additions and 4 deletions

View file

@ -63,7 +63,7 @@ func customElementClassSource(tag, slot string) string {
"#shadow;" +
"constructor(){super();this.#shadow=this.attachShadow({mode:\"closed\"});}" +
"connectedCallback(){this.#shadow.textContent=\"\";const slot=this.getAttribute(\"data-slot\")||" + jsStringLiteral(slot) + ";" +
"this.dispatchEvent(new CustomEvent(\"wc-ready\",{detail:{tag:" + jsStringLiteral(tag) + ",slot}}));}" +
"this.dispatchEvent(new CustomEvent(\"wc-ready\",{detail:{tag:" + jsStringLiteral(tag) + ",slot},bubbles:true,composed:true}));}" +
"render(html){const tpl=document.createElement(\"template\");tpl.insertAdjacentHTML(\"afterbegin\",html);" +
"this.#shadow.textContent=\"\";this.#shadow.appendChild(tpl.content.cloneNode(true));}" +
"}"

View file

@ -68,6 +68,8 @@ func TestCustomElementClassSource(t *testing.T) {
assert.Contains(t, src, `#shadow`)
assert.Contains(t, src, `data-slot`)
assert.Contains(t, src, `wc-ready`)
assert.Contains(t, src, `bubbles:true`)
assert.Contains(t, src, `composed:true`)
assert.Contains(t, src, `nav-bar`)
assert.Contains(t, src, `H`)
}

View file

@ -45,7 +45,7 @@ var wcTemplate = template.Must(template.New("wc").Parse(`class {{.ClassName}} ex
connectedCallback() {
this.#shadow.textContent = "";
const slot = this.getAttribute("data-slot") || "{{.Slot}}";
this.dispatchEvent(new CustomEvent("wc-ready", { detail: { tag: "{{.Tag}}", slot } }));
this.dispatchEvent(new CustomEvent("wc-ready", { detail: { tag: "{{.Tag}}", slot }, bubbles: true, composed: true }));
}
render(html) {
const tpl = document.createElement("template");

View file

@ -14,6 +14,8 @@ func TestGenerateClass_Good(t *testing.T) {
assert.Contains(t, js, "class PhotoGrid extends HTMLElement")
assert.Contains(t, js, "attachShadow")
assert.Contains(t, js, `mode: "closed"`)
assert.Contains(t, js, `bubbles: true`)
assert.Contains(t, js, `composed: true`)
assert.Contains(t, js, "photo-grid")
}

View file

@ -271,7 +271,7 @@ gohtml.registerComponents(slots)
Slot content is injected via `Raw()`. The caller is responsible for sanitisation -- the WASM module is a rendering engine for trusted content produced server-side or by the application's own templates.
`registerComponents(slots)` accepts the same slot-map shape used by the codegen CLI and registers closed-shadow custom elements in the browser at runtime. It skips invalid or duplicate tags and mirrors the generated component lifecycle by dispatching a `wc-ready` event when each element connects.
`registerComponents(slots)` accepts the same slot-map shape used by the codegen CLI and registers closed-shadow custom elements in the browser at runtime. It skips invalid or duplicate tags and mirrors the generated component lifecycle by dispatching a bubbling, composed `wc-ready` event when each element connects.
### Size Budget
@ -307,7 +307,7 @@ The `codegen` package (`codegen/codegen.go`) generates ES2022 class definitions
1. A class extending `HTMLElement` with a private `#shadow` field.
2. `constructor()` attaching a closed shadow root (`mode: "closed"`).
3. `connectedCallback()` dispatching a `wc-ready` custom event with the tag name and slot.
3. `connectedCallback()` dispatching a bubbling, composed `wc-ready` custom event with the tag name and slot.
4. `render(html)` method that sets shadow content from a `<template>` clone.
5. A `customElements.define()` registration call.