fix(wasm): align custom element runtime source
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-03 23:18:01 +00:00
parent bf5ec80c8b
commit 94833edf43
2 changed files with 13 additions and 9 deletions

View file

@ -8,7 +8,8 @@ import (
var canonicalSlotOrder = []string{"H", "L", "C", "R", "F"}
// isValidCustomElementTag reports whether tag is a safe custom element name.
// cmd/wasm/components.go: isValidCustomElementTag reports whether tag is a safe
// custom element name.
// It mirrors the codegen package validation without importing the heavier
// template and logging dependencies into the WASM-linked path.
func isValidCustomElementTag(tag string) bool {
@ -33,8 +34,9 @@ func isValidCustomElementTag(tag string) bool {
return true
}
// tagToClassName converts a kebab-case tag into a PascalCase class name.
// Example: nav-bar -> NavBar.
// cmd/wasm/components.go: tagToClassName converts a kebab-case tag into a
// PascalCase class name.
// Example: tagToClassName("nav-bar") returns NavBar.
func tagToClassName(tag string) string {
var b strings.Builder
for part := range strings.SplitSeq(tag, "-") {
@ -47,20 +49,21 @@ func tagToClassName(tag string) string {
return b.String()
}
// jsStringLiteral returns a quoted JavaScript string literal.
// cmd/wasm/components.go: jsStringLiteral returns a quoted JavaScript string literal.
func jsStringLiteral(s string) string {
return strconv.Quote(s)
}
// customElementClassSource returns a JavaScript class expression that mirrors
// the codegen bundle's closed-shadow custom element behaviour.
// cmd/wasm/components.go: customElementClassSource returns a JavaScript class
// expression that mirrors the codegen bundle's closed-shadow custom element
// behaviour.
func customElementClassSource(tag, slot string) string {
className := tagToClassName(tag)
return "class " + className + " extends HTMLElement {" +
"constructor(){super();this._shadow=this.attachShadow({mode:\"closed\"});}" +
"connectedCallback(){this._shadow.textContent=\"\";const slot=this.getAttribute(\"data-slot\")||" + jsStringLiteral(slot) + ";" +
"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}}));}" +
"render(html){const tpl=document.createElement(\"template\");tpl.insertAdjacentHTML(\"afterbegin\",html);" +
"this._shadow.textContent=\"\";this._shadow.appendChild(tpl.content.cloneNode(true));}" +
"this.#shadow.textContent=\"\";this.#shadow.appendChild(tpl.content.cloneNode(true));}" +
"}"
}

View file

@ -64,6 +64,7 @@ func TestCustomElementClassSource(t *testing.T) {
assert.Contains(t, src, `class NavBar extends HTMLElement`)
assert.Contains(t, src, `mode:"closed"`)
assert.Contains(t, src, `#shadow`)
assert.Contains(t, src, `data-slot`)
assert.Contains(t, src, `wc-ready`)
assert.Contains(t, src, `nav-bar`)