Refactor Better.js
This commit is contained in:
parent
550c917b08
commit
a2d2b42c76
1 changed files with 7 additions and 60 deletions
67
better.js
67
better.js
|
@ -1,79 +1,26 @@
|
||||||
/*
|
export default class extends HTMLElement {
|
||||||
An improved version of the default HTMLElement that provides a bunch of nice
|
|
||||||
things, most significantly:
|
|
||||||
- Automatically registering the custom element type
|
|
||||||
- Built-in event-emitting mutation observer to more easily listen to changes
|
|
||||||
- Split attribute-changed callbacks that automatically register attributes
|
|
||||||
|
|
||||||
Example:
|
|
||||||
class FooBar extends Better {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.attachShadow({mode: "open"});
|
|
||||||
this.shadowRoot.innerHTML = `<h1>Hello, <span part="name"></span>!</h1>`
|
|
||||||
this.userName = "World";
|
|
||||||
}
|
|
||||||
|
|
||||||
userNameChanged(name) { this.shadowRoot.querySelector('[part="name"]').innerHTML = this.userName; }
|
|
||||||
}
|
|
||||||
FooBar.initialise()
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class Better extends HTMLElement {
|
|
||||||
#observer
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
if (this.constructor.shadow) this.attachShadow({mode: 'open'})
|
||||||
let object = this
|
let object = this
|
||||||
this.#observer = new MutationObserver((list, observer) => {
|
|
||||||
list.forEach(m => {
|
|
||||||
m.target.dispatchEvent(new CustomEvent("mutation", {bubbles: true, detail: m, cancelable: true}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
observe(options) {
|
|
||||||
if (this.#observer) this.#observer.observe(this, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array of connected callbacks
|
get root() {
|
||||||
#connected = [];
|
return this.shadowRoot || this
|
||||||
|
|
||||||
// connectedCallback but as a promise.
|
|
||||||
// Resolves instantly when already connected and can be used more than once.
|
|
||||||
get connected() {
|
|
||||||
if (this.isConnected) return Promise.resolve(this)
|
|
||||||
else return new Promise( (yes, no) => this.#connected.push({yes, no}) )
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolves all `connected promises
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
if ("onConnect" in this) this.onConnect()
|
if ("onConnect" in this) this.onConnect()
|
||||||
this.#connected.forEach( e => e.yes(this) )
|
this.dispatchEvent(new Event("connected"))
|
||||||
this.#connected = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array of disconnected callbacks
|
|
||||||
#disconnected = [];
|
|
||||||
|
|
||||||
// disconnectedCallback but as a promise.
|
|
||||||
// Resolves instantly when already disconnected and can be used more than once.
|
|
||||||
get disconnected() {
|
|
||||||
if (this.isDisconnected) return Promise.resolve(this)
|
|
||||||
else return new Promise( (yes, no) => this.#disconnected.push({yes, no}) )
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolves all `disconnected promises
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if ("onDisconnect" in this) this.onDisonnect()
|
if ("onDisconnect" in this) this.onDisonnect()
|
||||||
this.#disconnected.forEach( e => e.yes(this) )
|
this.dispatchEvent(new Event("disconnected"))
|
||||||
this.#disconnected = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setContent(...content) {
|
|
||||||
this.innerHTML = ""
|
|
||||||
content.forEach( element => this.appendChild(element) )
|
|
||||||
}
|
|
||||||
set content(content) {
|
set content(content) {
|
||||||
this.setContent(content)
|
this.root.replaceChildren(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback(attr, old, value) {
|
attributeChangedCallback(attr, old, value) {
|
||||||
|
|
Loading…
Reference in a new issue