UNPKG

ionicons

Version:

Premium icons for Ionic.

79 lines (78 loc) 2.34 kB
import { isEncodedDataUrl, isSvgDataUrl, validateContent } from "./validate"; export const ioniconContent = new Map(); const requests = new Map(); let parser; /** * Safely fallback to an empty svg */ function safeFallback(url) { const svg = ''; ioniconContent.set(url, svg); return svg; } export const getSvgContent = (url, sanitize) => { /** * See if we already have a request for this url */ const req = requests.get(url); if (req) { return req; } if (typeof fetch !== 'undefined' && typeof document !== 'undefined') { /** * If the url is a data url of an svg, then try to parse it * with the DOMParser. This works with content security policies enabled. */ if (isSvgDataUrl(url) && isEncodedDataUrl(url)) { return Promise.resolve(getSvgByUrl(url)); } return fetchSvg(url, sanitize); } return Promise.resolve(safeFallback(url)); }; function getSvgByUrl(url) { if (!parser) { /** * Create an instance of the DOM parser. This creates a single * parser instance for the entire app, which is more efficient. */ parser = new DOMParser(); } const doc = parser.parseFromString(url, 'text/html'); const svg = doc.querySelector('svg'); if (svg) { ioniconContent.set(url, svg.outerHTML); return svg.outerHTML; } throw new Error(`Could not parse svg from ${url}`); } function fetchSvg(url, sanitize) { /** * We don't already have a request */ const req = fetch(url) .then((rsp) => { /** * When fetching from a file:// URL, some browsers return * a 0 status code even when the request succeeds so don't * rely on rsp.ok as the only signal of success. */ return rsp .text() .then((svgContent) => { if (svgContent && sanitize !== false) { svgContent = validateContent(svgContent); } const svg = svgContent || ''; ioniconContent.set(url, svg); return svg; }) .catch(() => safeFallback(url)); }) .catch(() => safeFallback(url)); /** * Cache for the same requests */ requests.set(url, req); return req; }