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.
2 lines (1 loc) • 3.35 kB
JavaScript
(function(s,t){typeof exports=="object"&&typeof module<"u"?module.exports=t():typeof define=="function"&&define.amd?define(t):(s=typeof globalThis<"u"?globalThis:s||self).Iconly=t()})(this,function(){"use strict";var g=Object.defineProperty;var h=(s,t,l)=>t in s?g(s,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):s[t]=l;var u=(s,t,l)=>h(s,typeof t!="symbol"?t+"":t,l);const t=class t{constructor(r={}){u(this,"options");u(this,"container");const e={file:"./icons.svg",version:"1.0",debug:!1,container:document.body??document.documentElement,...r};let i;if(typeof e.container=="string"){const a=document.querySelector(e.container);if(!(a&&a instanceof HTMLElement))throw new Error(`Invalid container selector: "${e.container}"`);i=a}else i=e.container;this.container=i,this.options={file:e.file,version:e.version,debug:e.debug},t.dbInstance||(t.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((i,a)=>{const n=indexedDB.open(r,e);n.onerror=()=>{const c=this.createErrorMessage(n.error,"IndexedDB error");a(new Error(c))},n.onupgradeneeded=c=>{const o=c.target.result;o.objectStoreNames.contains("icons")||o.createObjectStore("icons",{keyPath:"version"})},n.onsuccess=()=>{i(n.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 i=new DOMParser().parseFromString(r,"image/svg+xml"),a=i.querySelector("parsererror");if(a)return void this.logError("SVG parsing error:",a.textContent??"");e.innerHTML="";const n=i.documentElement;if(n){const c=document.importNode(n,!0);e.appendChild(c)}else this.logError("No valid SVG content found to insert.")}async init(){try{let r=await t.fetchData(this.options.file);const e=await t.dbInstance;if(!e)throw new Error("Failed to open IndexedDB");const i=this.getIconStore(e,"readwrite"),a=await new Promise((n,c)=>{const o=i.get(this.options.version);o.onsuccess=()=>{n(o.result)},o.onerror=()=>{const d=this.createErrorMessage(o.error,"Error getting record from store");c(new Error(d))}});a?r=a.data:await new Promise((n,c)=>{const o=i.put({version:this.options.version,data:r});o.onsuccess=()=>n(),o.onerror=()=>{const d=this.createErrorMessage(o.error,"Error putting record into store");c(new Error(d))}}),await new Promise((n,c)=>{const o=i.transaction;o.oncomplete=()=>n(),o.onerror=()=>{const d=this.createErrorMessage(o.error,"Transaction error");c(new Error(d))},o.onabort=()=>{const d=this.createErrorMessage(o.error,"Transaction aborted");c(new Error(d))}}),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){}};u(t,"dbInstance",null);let s=t;return s});