diff --git a/core/static/bundled/utils/web-components.ts b/core/static/bundled/utils/web-components.ts index fc4315cc..690defc0 100644 --- a/core/static/bundled/utils/web-components.ts +++ b/core/static/bundled/utils/web-components.ts @@ -18,6 +18,42 @@ export function registerComponent(name: string, options?: ElementDefinitionOptio }; } +/** + * Abstract class used to create HTML tags inheriting from HTMLElements + * You should not use this class outside of typing ! + * + * Please, see the `inheritHtmlElement` factory if you want to use this class. + **/ +export abstract class InheritedHtmlElement< + K extends keyof HTMLElementTagNameMap, +> extends HTMLElement { + abstract readonly inheritedTagName: K; + protected node: HTMLElementTagNameMap[K]; + + connectedCallback(autoAddNode?: boolean) { + this.node = document.createElement(this.inheritedTagName); + const attributes: Attr[] = []; // We need to make a copy to delete while iterating + for (const attr of this.attributes) { + if (attr.name in this.node) { + attributes.push(attr); + } + } + + for (const attr of attributes) { + this.removeAttributeNode(attr); + this.node.setAttributeNode(attr); + } + + this.node.innerHTML = this.innerHTML; + this.innerHTML = ""; + + // Automatically add node to DOM if autoAddNode is true or unspecified + if (autoAddNode === undefined || autoAddNode) { + this.appendChild(this.node); + } + } +} + /** * Safari doesn't support inheriting from HTML tags on web components * The technique is to: @@ -35,31 +71,7 @@ export function registerComponent(name: string, options?: ElementDefinitionOptio * ``` **/ export function inheritHtmlElement(tagName: K) { - return class Inherited extends HTMLElement { + return class InheritedHtmlElementImpl extends InheritedHtmlElement { readonly inheritedTagName = tagName; - protected node: HTMLElementTagNameMap[K]; - - connectedCallback(autoAddNode?: boolean) { - this.node = document.createElement(tagName); - const attributes: Attr[] = []; // We need to make a copy to delete while iterating - for (const attr of this.attributes) { - if (attr.name in this.node) { - attributes.push(attr); - } - } - - for (const attr of attributes) { - this.removeAttributeNode(attr); - this.node.setAttributeNode(attr); - } - - this.node.innerHTML = this.innerHTML; - this.innerHTML = ""; - - // Automatically add node to DOM if autoAddNode is true or unspecified - if (autoAddNode === undefined || autoAddNode) { - this.appendChild(this.node); - } - } }; }