Refactor BetterHTMLElement with more meta-magic

This commit is contained in:
Talia 2021-02-22 22:35:05 +01:00
parent f97ae06d3e
commit d703ae148d
No known key found for this signature in database
GPG Key ID: AD727AD22802D0D6
1 changed files with 23 additions and 7 deletions

View File

@ -1,5 +1,5 @@
export class BetterHTMLElement extends HTMLElement { export class BetterHTMLElement extends HTMLElement {
attributeChangedCallback(name, old, value) { this[name+"Changed"](value, old) } attributeChangedCallback(name, old, value) { if (name+"Changed" in this) this[name+"Changed"](value, old) }
// Array of connected callbacks // Array of connected callbacks
#connected = []; #connected = [];
@ -17,31 +17,47 @@ export class BetterHTMLElement extends HTMLElement {
this.#connected = []; this.#connected = [];
} }
setContent(...content) {
this.innerHTML = ""
content.forEach( element => this.appendChild(element) )
}
set content(content) {
this.setContent(content)
}
// Fancier way to register an element // Fancier way to register an element
// TODO: Unregister old names first // TODO: Unregister old names first
// TODO: Register name internally // TODO: Register name internally
static set tagName(name) { customElements.define(name, this) } static set tagName(name) { customElements.define(name, this) }
// Adds property/attribute mappings to the object. // Adds property/attribute mappings to the object.
static addProps(fields = this.observedAttributes) { static initialize(name = this.name) {
fields.forEach( attr => Object.defineProperty(this.prototype, attr, { const names = Object
.getOwnPropertyNames(this.prototype)
.filter(name => name.search(/Changed$/)+1)
.map(name => name.replace(/Changed$/, ''))
Object.defineProperty(this, "observedAttributes", {
get() { return names }
})
names.forEach( attr => Object.defineProperty(this.prototype, attr, {
get() { return this.getAttribute(attr) }, get() { return this.getAttribute(attr) },
set(val) { this.setAttribute(attr, val) } set(val) { this.setAttribute(attr, val) }
})) }))
name = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
customElements.define(name, this)
return name
} }
} }
/* Example: /* Example:
class FooBar extends BetterHTMLElement { class FooBar extends BetterHTMLElement {
static get observedAttributes() { return [ "name" ] }
constructor() { constructor() {
super(); super();
this.attachShadow({mode: "open"}); this.attachShadow({mode: "open"});
this.shadowRoot.innerHTML = `<h1>Hello, <span id="name"></span></h1>` this.shadowRoot.innerHTML = `<h1>Hello, <span id="name"></span></h1>`
} }
nameChanged(name) { this.shadowRoot.querySelector("#name").innerHTML=name; } nameChanged(name) { this.shadowRoot.querySelector("#name").innerHTML=name; }
} }
FooBar.addProps() FooBar.initialize()
FooBar.tagName = "foo-bar"
*/ */