iconly
Version:
Iconly is designed to load and cache SVG icons in the browser, using IndexedDB to store the data. It retrieves the icons from a given SVG file, stores them in IndexedDB, and inserts them into the DOM for easy access and use.
101 lines (100 loc) • 4.05 kB
JavaScript
var g = Object.defineProperty;
var h = (d, r, e) => r in d ? g(d, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : d[r] = e;
var l = (d, r, e) => h(d, typeof r != "symbol" ? r + "" : r, e);
const a = class a {
constructor(r = {}) {
l(this, "options");
l(this, "container");
const e = { file: "./icons.svg", version: "1.0", debug: !1, container: document.body ?? document.documentElement, ...r };
let n;
if (typeof e.container == "string") {
const i = document.querySelector(e.container);
if (!(i && i instanceof HTMLElement)) throw new Error(`Invalid container selector: "${e.container}"`);
n = i;
} else n = e.container;
this.container = n, this.options = { file: e.file, version: e.version, debug: e.debug }, a.dbInstance || (a.dbInstance = this.openDB("iconlyDB", 1));
}
async openDB(r, e) {
if (!("indexedDB" in window)) throw this.logError("This browser does not support IndexedDB"), new Error("IndexedDB not supported");
return await new Promise((n, i) => {
const o = indexedDB.open(r, e);
o.onerror = () => {
const s = this.createErrorMessage(o.error, "IndexedDB error");
i(new Error(s));
}, o.onupgradeneeded = (s) => {
const t = s.target.result;
t.objectStoreNames.contains("icons") || t.createObjectStore("icons", { keyPath: "version" });
}, o.onsuccess = () => {
n(o.result);
};
});
}
getIconStore(r, e) {
return r.transaction("icons", e).objectStore("icons");
}
static async fetchData(r) {
const e = await fetch(r);
if (!e.ok) throw new Error(`Failed to fetch icons from "${r}"`);
return e.text();
}
insert(r) {
let e = document.getElementById("iconset");
e || (e = document.createElement("div"), e.id = "iconset", e.setAttribute("aria-hidden", "true"), e.style.cssText = "width: 0; height: 0; position: absolute; left: -9999px;", this.container.appendChild(e));
const n = new DOMParser().parseFromString(r, "image/svg+xml"), i = n.querySelector("parsererror");
if (i) return void this.logError("SVG parsing error:", i.textContent ?? "");
e.innerHTML = "";
const o = n.documentElement;
if (o) {
const s = document.importNode(o, !0);
e.appendChild(s);
} else this.logError("No valid SVG content found to insert.");
}
async init() {
try {
let r = await a.fetchData(this.options.file);
const e = await a.dbInstance;
if (!e) throw new Error("Failed to open IndexedDB");
const n = this.getIconStore(e, "readwrite"), i = await new Promise((o, s) => {
const t = n.get(this.options.version);
t.onsuccess = () => {
o(t.result);
}, t.onerror = () => {
const c = this.createErrorMessage(t.error, "Error getting record from store");
s(new Error(c));
};
});
i ? r = i.data : await new Promise((o, s) => {
const t = n.put({ version: this.options.version, data: r });
t.onsuccess = () => o(), t.onerror = () => {
const c = this.createErrorMessage(t.error, "Error putting record into store");
s(new Error(c));
};
}), await new Promise((o, s) => {
const t = n.transaction;
t.oncomplete = () => o(), t.onerror = () => {
const c = this.createErrorMessage(t.error, "Transaction error");
s(new Error(c));
}, t.onabort = () => {
const c = this.createErrorMessage(t.error, "Transaction aborted");
s(new Error(c));
};
}), this.insert(r), this.logDebug("Iconly has successfully initialized.");
} catch (r) {
const e = r instanceof Error ? r : new Error(String(r));
this.logError("Error initializing Iconly:", e.message);
}
}
createErrorMessage(r, e) {
return r && (r instanceof DOMException || r instanceof Error) && r.message || e;
}
logDebug(...r) {
this.options.debug;
}
logError(...r) {
}
};
l(a, "dbInstance", null);
let u = a;
export {
u as default
};