2022-02-08 18:00:18 +00:00
|
|
|
export default class extends HTMLElement {
|
2021-05-22 12:58:07 +00:00
|
|
|
constructor() {
|
|
|
|
super()
|
2022-02-08 18:00:18 +00:00
|
|
|
if (this.constructor.shadow) this.attachShadow({mode: 'open'})
|
2021-05-22 12:58:07 +00:00
|
|
|
let object = this
|
|
|
|
}
|
|
|
|
|
2022-02-08 18:00:18 +00:00
|
|
|
get root() {
|
|
|
|
return this.shadowRoot || this
|
2020-10-27 15:40:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
connectedCallback() {
|
2021-08-02 21:00:33 +00:00
|
|
|
if ("onConnect" in this) this.onConnect()
|
2022-02-08 18:00:18 +00:00
|
|
|
this.dispatchEvent(new Event("connected"))
|
2020-10-27 15:40:38 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 12:42:40 +00:00
|
|
|
disconnectedCallback() {
|
|
|
|
if ("onDisconnect" in this) this.onDisonnect()
|
2022-02-08 18:00:18 +00:00
|
|
|
this.dispatchEvent(new Event("disconnected"))
|
2021-08-03 12:42:40 +00:00
|
|
|
}
|
|
|
|
|
2021-02-22 21:35:05 +00:00
|
|
|
set content(content) {
|
2022-02-08 18:00:18 +00:00
|
|
|
this.root.replaceChildren(content)
|
2021-02-22 21:35:05 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 14:32:19 +00:00
|
|
|
attributeChangedCallback(attr, old, value) {
|
|
|
|
let name = attr.replace(/-([a-z])/, (_, l) => l.toUpperCase())
|
|
|
|
let attribute = this.constructor.attributes[name]
|
|
|
|
if (name+"Changed" in this)
|
|
|
|
if (typeof(attribute.get) == "function")
|
|
|
|
this[name+"Changed"](attribute.get.call(this, value), attribute.get.call(this, old))
|
|
|
|
else
|
|
|
|
this[name+"Changed"](value, old)
|
|
|
|
}
|
2020-10-27 15:40:38 +00:00
|
|
|
// Adds property/attribute mappings to the object.
|
2021-06-30 11:54:37 +00:00
|
|
|
static initialise(name = this.name) {
|
2021-08-03 14:32:19 +00:00
|
|
|
let attributes = this.attributes
|
|
|
|
? [...Object.keys(this.attributes)]
|
|
|
|
: []
|
|
|
|
/* See HTMLElement API */
|
2021-02-22 21:35:05 +00:00
|
|
|
Object.defineProperty(this, "observedAttributes", {
|
2021-08-03 14:32:19 +00:00
|
|
|
get() { return attributes.map(attr => attr.replace(/[A-Z]/, u => "-"+u.toLowerCase())) }
|
2021-05-02 07:47:10 +00:00
|
|
|
})
|
2021-08-03 14:32:19 +00:00
|
|
|
attributes.forEach(name => {
|
|
|
|
let attribute = this.attributes[name]
|
|
|
|
let htmlName = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
|
|
|
|
let prop = {}
|
|
|
|
/* Is there a get filter? */
|
|
|
|
if (typeof attribute.get == "function")
|
|
|
|
prop.get = function() { return attribute.get.call(this, this.getAttribute(htmlName)) }
|
|
|
|
else
|
|
|
|
prop.get = function() { return this.getAttribute(htmlName) }
|
|
|
|
/* Is there a set filter? */
|
|
|
|
if (typeof attribute.set == "function")
|
|
|
|
prop.set = function(val) { return this.setAttribute(htmlName, attribute.set.call(this, val)) }
|
|
|
|
else if (attribute.set === false)
|
|
|
|
prop.set = function(val) { throw(`Attribute ${name} cannot be set`) }
|
|
|
|
else
|
|
|
|
prop.set = function(val) { this.setAttribute(htmlName, val) }
|
|
|
|
|
|
|
|
Object.defineProperty(this.prototype, name, prop)
|
2021-02-22 21:35:05 +00:00
|
|
|
})
|
|
|
|
name = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase()
|
2021-05-17 15:18:58 +00:00
|
|
|
if (this.extends)
|
|
|
|
customElements.define(name, this, { extends: this.extends })
|
|
|
|
else
|
|
|
|
customElements.define(name, this)
|
2021-02-22 21:35:05 +00:00
|
|
|
return name
|
2020-10-27 15:40:38 +00:00
|
|
|
}
|
2021-06-30 11:54:37 +00:00
|
|
|
static initialize(name) { this.initialise(name) }
|
2020-10-27 15:40:38 +00:00
|
|
|
}
|