soo.js
Version:
custom-elements with renderer
68 lines (55 loc) • 1.55 kB
JavaScript
function cssToDom(css) {
const node = document.createElement("style")
node.textContent = css
return node
}
export default class Element extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: "open" })
}
//Element is connected
async connectedCallback() {
this.install.apply(this)
this.beforeRender()
const element = await this.render()
if (this.css) this.shadowRoot.appendChild(cssToDom(this.css()))
this.shadowRoot.appendChild(element)
this.installed()
}
//Element is removed
disconnectedCallback() {
this.uninstall()
}
//Fire container event
fire(name, data) {
this.dispatchEvent(new CustomEvent(name, { detail: data }))
}
//Fire event on document
fireGlobal(name, data) {
document.dispatchEvent(new CustomEvent(name, { detail: data }))
}
//Update element
async update() {
this.beforeUpdate()
const element = await this.render()
//Check if element is Fragment node, if so just remove children one by one.
if (element.nodeType === 11) {
this.shadowRoot.childNodes.forEach(item => {
//Skip style element and text crap, remove other nodes
if (item.tagName !== "STYLE" && item.nodeType !== 3) item.remove()
})
this.shadowRoot.appendChild(element)
} else {
//Refresh rendered element with new one
this.shadowRoot.lastChild.replaceWith(element)
}
this.updated()
}
install() {}
installed() {}
uninstall() {}
beforeUpdate() {}
updated() {}
beforeRender() {}
}