Use web components for SVG icons
This commit is contained in:
@ -13,8 +13,9 @@ import ServiceWorkerManager from "./ServiceWorkerManager"
|
||||
import ServerEvents from "./ServerEvents"
|
||||
import { displayAiringDate, displayDate, displayTime } from "./DateView"
|
||||
import { findAll, supportsWebP, requestIdleCallback, swapElements, delay, findAllInside } from "./Utils"
|
||||
import * as actions from "./Actions"
|
||||
import ToolTip from "./Elements/tool-tip/tool-tip"
|
||||
import * as actions from "./Actions"
|
||||
import * as WebComponents from "./WebComponents"
|
||||
|
||||
export default class AnimeNotifier {
|
||||
app: Application
|
||||
@ -102,7 +103,7 @@ export default class AnimeNotifier {
|
||||
}
|
||||
|
||||
// Web components
|
||||
this.registerWebComponents()
|
||||
WebComponents.register()
|
||||
|
||||
// Tooltip
|
||||
this.tip = new ToolTip()
|
||||
@ -210,23 +211,6 @@ export default class AnimeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
registerWebComponents() {
|
||||
if(!("customElements" in window)) {
|
||||
console.warn("Web components not supported in your current browser")
|
||||
return
|
||||
}
|
||||
|
||||
// Custom element names must have a dash in their name
|
||||
const elements = new Map<string, Function>([
|
||||
["tool-tip", ToolTip]
|
||||
])
|
||||
|
||||
// Register all custom elements
|
||||
for(const [tag, definition] of elements.entries()) {
|
||||
window.customElements.define(tag, definition)
|
||||
}
|
||||
}
|
||||
|
||||
applyPageTitle() {
|
||||
let headers = document.getElementsByTagName("h1")
|
||||
|
||||
|
@ -147,6 +147,12 @@ export default class Diff {
|
||||
}
|
||||
}
|
||||
|
||||
// Never diff the contents of web components
|
||||
if(a.nodeName.includes("-")) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Child nodes
|
||||
Diff.childNodes(a, b)
|
||||
}
|
||||
}
|
||||
|
10
scripts/Elements/svg-icon/svg-icon.scarlet
Normal file
10
scripts/Elements/svg-icon/svg-icon.scarlet
Normal file
@ -0,0 +1,10 @@
|
||||
svg-icon
|
||||
display inline-block
|
||||
width 1em
|
||||
height 1em
|
||||
|
||||
svg
|
||||
display inherit
|
||||
width 1em
|
||||
height 1em
|
||||
fill currentColor
|
48
scripts/Elements/svg-icon/svg-icon.ts
Normal file
48
scripts/Elements/svg-icon/svg-icon.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import Diff from "scripts/Diff"
|
||||
|
||||
export default class SVGIcon extends HTMLElement {
|
||||
static cache = new Map<string, Promise<string>>()
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["name"]
|
||||
}
|
||||
|
||||
attributeChangedCallback(attrName) {
|
||||
if(attrName === "name") {
|
||||
this.render()
|
||||
}
|
||||
}
|
||||
|
||||
async render() {
|
||||
let cache = SVGIcon.cache[this.name]
|
||||
|
||||
if(cache) {
|
||||
let text = await cache
|
||||
Diff.mutations.queue(() => this.innerHTML = text)
|
||||
return
|
||||
}
|
||||
|
||||
SVGIcon.cache[this.name] = new Promise(async (resolve, reject) => {
|
||||
let url = `//media.notify.moe/images/icons/${this.name}.svg`
|
||||
let response = await fetch(url)
|
||||
|
||||
if(!response.ok) {
|
||||
console.warn(`Failed loading SVG icon: ${url}`)
|
||||
reject(response.statusText)
|
||||
return
|
||||
}
|
||||
|
||||
let text = await response.text()
|
||||
Diff.mutations.queue(() => this.innerHTML = text)
|
||||
resolve(text)
|
||||
})
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute("name") || ""
|
||||
}
|
||||
|
||||
set name(value: string) {
|
||||
this.setAttribute("name", value)
|
||||
}
|
||||
}
|
20
scripts/WebComponents.ts
Normal file
20
scripts/WebComponents.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import ToolTip from "./Elements/tool-tip/tool-tip"
|
||||
import SVGIcon from "./Elements/svg-icon/svg-icon"
|
||||
|
||||
export function register() {
|
||||
if(!("customElements" in window)) {
|
||||
console.warn("Web components not supported in your current browser")
|
||||
return
|
||||
}
|
||||
|
||||
// Custom element names must have a dash in their name
|
||||
const elements = new Map<string, Function>([
|
||||
["tool-tip", ToolTip],
|
||||
["svg-icon", SVGIcon]
|
||||
])
|
||||
|
||||
// Register all custom elements
|
||||
for(const [tag, definition] of elements.entries()) {
|
||||
window.customElements.define(tag, definition)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user