68 lines
1.3 KiB
TypeScript
Raw Normal View History

2019-08-30 07:04:28 +00:00
import Diff from "scripts/Diff"
export default class SVGIcon extends HTMLElement {
2019-08-31 11:29:03 +00:00
static cache = new Map<string, Promise<Node>>()
2019-08-30 07:04:28 +00:00
static get observedAttributes() {
return ["name"]
}
attributeChangedCallback(attrName) {
if(attrName === "name") {
this.render()
}
}
async render() {
2019-11-17 09:25:14 +00:00
const cache = SVGIcon.cache.get(this.name)
2019-08-30 07:04:28 +00:00
if(cache) {
2019-11-17 09:25:14 +00:00
const svg = await cache
2019-08-31 11:29:03 +00:00
Diff.mutations.queue(() => {
// Remove all existing child nodes
while(this.firstChild) {
this.removeChild(this.firstChild)
}
// Append a clone of the cached SVG node
this.appendChild(svg.cloneNode(true))
})
2019-08-30 07:04:28 +00:00
return
}
2019-08-31 04:45:42 +00:00
SVGIcon.cache.set(this.name, new Promise(async (resolve, reject) => {
2019-11-17 09:25:14 +00:00
const url = `//media.notify.moe/images/icons/${this.name}.svg`
const response = await fetch(url)
2019-08-30 07:04:28 +00:00
if(!response.ok) {
console.warn(`Failed loading SVG icon: ${url}`)
reject(response.statusText)
return
}
2019-11-17 09:25:14 +00:00
const text = await response.text()
2019-08-31 11:29:03 +00:00
Diff.mutations.queue(() => {
this.innerHTML = text
2019-11-17 09:25:14 +00:00
const svg = this.firstChild
2019-08-31 11:29:03 +00:00
if(!svg) {
console.warn("Invalid SVG icon:", svg)
return
}
resolve(svg)
})
2019-08-31 04:45:42 +00:00
}))
2019-08-30 07:04:28 +00:00
}
get name() {
return this.getAttribute("name") || ""
}
set name(value: string) {
this.setAttribute("name", value)
}
}