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.16 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;module.exports=u;