Add Hot Module Replacement for SVG icons using the custom component
This commit is contained in:
parent
f15f3a4456
commit
fde3881653
2 changed files with 29 additions and 9 deletions
|
|
@ -13,7 +13,9 @@ export class DotDungeonIcon extends HTMLElement {
|
||||||
static _cache = new Map();
|
static _cache = new Map();
|
||||||
#style;
|
#style;
|
||||||
#container;
|
#container;
|
||||||
|
/** @type {null | string} */
|
||||||
_name;
|
_name;
|
||||||
|
/** @type {null | string} */
|
||||||
_path;
|
_path;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
@ -25,7 +27,9 @@ export class DotDungeonIcon extends HTMLElement {
|
||||||
this.#shadow.appendChild(this.#container);
|
this.#shadow.appendChild(this.#container);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_mounted = false;
|
||||||
async connectedCallback() {
|
async connectedCallback() {
|
||||||
|
if (this._mounted) return;
|
||||||
|
|
||||||
this._name = this.getAttribute(`name`);
|
this._name = this.getAttribute(`name`);
|
||||||
this._path = this.getAttribute(`path`);
|
this._path = this.getAttribute(`path`);
|
||||||
|
|
@ -58,20 +62,31 @@ export class DotDungeonIcon extends HTMLElement {
|
||||||
the slot content, as then we can have a default per-icon usage
|
the slot content, as then we can have a default per-icon usage
|
||||||
*/
|
*/
|
||||||
let content;
|
let content;
|
||||||
// TODO: Make name request
|
|
||||||
if (this._name) {
|
if (this._name) {
|
||||||
content = await this.#getIcon(`./systems/dotdungeon/assets/${this._name}.svg`);
|
content = await this.#getIcon(`./systems/dotdungeon/assets/${this._name}.svg`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: make path request
|
|
||||||
if (this._path && !content) {
|
if (this._path && !content) {
|
||||||
content = await this.#getIcon(this._path);
|
content = await this.#getIcon(this._path);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: insert content into DOM
|
|
||||||
if (content) {
|
if (content) {
|
||||||
this.#container.appendChild(content);
|
this.#container.appendChild(content.cloneNode(true));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is so that when we get an HMR event from Foundry we can appropriately
|
||||||
|
handle it using our logic to update the component and the icon cache.
|
||||||
|
*/
|
||||||
|
Hooks.on(`dd-hmr:svg`, (iconName, data) => {
|
||||||
|
if (this._name === iconName || this._path?.endsWith(data.path)) {
|
||||||
|
const svg = this.#parseSVG(data.content);
|
||||||
|
DotDungeonIcon._cache.set(iconName, svg);
|
||||||
|
this.#container.replaceChildren(svg.cloneNode(true));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this._mounted = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
#embedStyles() {
|
#embedStyles() {
|
||||||
|
|
@ -98,10 +113,15 @@ export class DotDungeonIcon extends HTMLElement {
|
||||||
};
|
};
|
||||||
|
|
||||||
console.debug(`.dungeon | Adding icon ${path} to the cache`);
|
console.debug(`.dungeon | Adding icon ${path} to the cache`);
|
||||||
const temp = document.createElement(`div`);
|
const svg = this.#parseSVG(await r.text());
|
||||||
temp.innerHTML = await r.text();
|
|
||||||
const svg = temp.querySelector(`svg`);
|
|
||||||
DotDungeonIcon._cache.set(path, svg);
|
DotDungeonIcon._cache.set(path, svg);
|
||||||
return svg;
|
return svg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Takes an SVG string and returns it as a DOM node */
|
||||||
|
#parseSVG(content) {
|
||||||
|
const temp = document.createElement(`div`);
|
||||||
|
temp.innerHTML = content;
|
||||||
|
return temp.querySelector(`svg`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import * as hbs from "../handlebars.mjs";
|
||||||
const loaders = {
|
const loaders = {
|
||||||
svg(data) {
|
svg(data) {
|
||||||
const iconName = data.path.split(`/`).slice(-1)[0].slice(0, -4);
|
const iconName = data.path.split(`/`).slice(-1)[0].slice(0, -4);
|
||||||
console.log(`.dungeon | hot-reloading icon: ${iconName}`);
|
console.debug(`.dungeon | hot-reloading icon: ${iconName}`);
|
||||||
CONFIG.CACHE.icons[iconName] = data.content;
|
Hooks.call(`dd-hmr:svg`, iconName, data);
|
||||||
},
|
},
|
||||||
hbs(data) {
|
hbs(data) {
|
||||||
if (!hbs.partials.some(p => data.path.endsWith(p))) {
|
if (!hbs.partials.some(p => data.path.endsWith(p))) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue