request.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { isEncodedDataUrl, isSvgDataUrl, validateContent } from "./validate";
  2. export const ioniconContent = new Map();
  3. const requests = new Map();
  4. let parser;
  5. export const getSvgContent = (url, sanitize) => {
  6. // see if we already have a request for this url
  7. let req = requests.get(url);
  8. if (!req) {
  9. if (typeof fetch !== 'undefined' && typeof document !== 'undefined') {
  10. /**
  11. * If the url is a data url of an svg, then try to parse it
  12. * with the DOMParser. This works with content security policies enabled.
  13. */
  14. if (isSvgDataUrl(url) && isEncodedDataUrl(url)) {
  15. if (!parser) {
  16. /**
  17. * Create an instance of the DOM parser. This creates a single
  18. * parser instance for the entire app, which is more efficient.
  19. */
  20. parser = new DOMParser();
  21. }
  22. const doc = parser.parseFromString(url, 'text/html');
  23. const svg = doc.querySelector('svg');
  24. if (svg) {
  25. ioniconContent.set(url, svg.outerHTML);
  26. }
  27. return Promise.resolve();
  28. }
  29. else {
  30. // we don't already have a request
  31. req = fetch(url).then((rsp) => {
  32. if (rsp.ok) {
  33. return rsp.text().then((svgContent) => {
  34. if (svgContent && sanitize !== false) {
  35. svgContent = validateContent(svgContent);
  36. }
  37. ioniconContent.set(url, svgContent || '');
  38. });
  39. }
  40. ioniconContent.set(url, '');
  41. });
  42. // cache for the same requests
  43. requests.set(url, req);
  44. }
  45. }
  46. else {
  47. // set to empty for ssr scenarios and resolve promise
  48. ioniconContent.set(url, '');
  49. return Promise.resolve();
  50. }
  51. }
  52. return req;
  53. };