xyc
2024-05-17 6b24f642b01cf3cd1be0d5833273fa2867d389e1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// MIT License
// From: https://github.com/uupaa/dynamic-import-polyfill/blob/master/importModule.js
 
/**
 * @module importModule
 */
 
function toAbsoluteURL (url) {
  const a = document.createElement('a');
  a.setAttribute('href', url); // <a href="hoge.html">
  return a.cloneNode(false).href; // -> "http://example.com/hoge.html"
}
 
function addScriptAtts (script, atts) {
  ['id', 'class', 'type'].forEach((prop) => {
    if (prop in atts) {
      script[prop] = atts[prop];
    }
  });
}
 
// Additions by Brett
/**
* @typedef {PlainObject} module:importModule.ImportConfig
* @property {string} global The variable name to set on `window` (when not using the modular version)
* @property {boolean} [returnDefault=false]
*/
/**
* @function module:importModule.importSetGlobalDefault
* @param {string} url
* @param {module:importModule.ImportConfig} config
* @returns {*} The return depends on the export of the targeted module.
*/
export async function importSetGlobalDefault (url, config) {
  return importSetGlobal(url, {...config, returnDefault: true});
}
/**
* @function module:importModule.importSetGlobal
* @param {string} url
* @param {module:importModule.ImportConfig} config
* @returns {ArbitraryModule|*} The return depends on the export of the targeted module.
*/
export async function importSetGlobal (url, {global, returnDefault}) {
  // Todo: Replace calls to this function with `import()` when supported
  const modularVersion = !('svgEditor' in window) ||
    !window.svgEditor ||
    window.svgEditor.modules !== false;
  if (modularVersion) {
    return importModule(url, undefined, {returnDefault});
  }
  await importScript(url);
  return window[global];
}
// Addition by Brett
export function importScript (url, atts = {}) {
  if (Array.isArray(url)) {
    return Promise.all(url.map((u) => {
      return importScript(u, atts);
    }));
  }
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    const destructor = () => {
      script.onerror = null;
      script.onload = null;
      script.remove();
      script.src = '';
    };
    script.defer = 'defer';
    addScriptAtts(script, atts);
    script.onerror = () => {
      reject(new Error(`Failed to import: ${url}`));
      destructor();
    };
    script.onload = () => {
      resolve();
      destructor();
    };
    script.src = url;
 
    document.head.append(script);
  });
}
 
export function importModule (url, atts = {}, {returnDefault = false} = {}) {
  if (Array.isArray(url)) {
    return Promise.all(url.map((u) => {
      return importModule(u, atts);
    }));
  }
  return new Promise((resolve, reject) => {
    const vector = '$importModule$' + Math.random().toString(32).slice(2);
    const script = document.createElement('script');
    const destructor = () => {
      delete window[vector];
      script.onerror = null;
      script.onload = null;
      script.remove();
      URL.revokeObjectURL(script.src);
      script.src = '';
    };
    addScriptAtts(script, atts);
    script.defer = 'defer';
    script.type = 'module';
    script.onerror = () => {
      reject(new Error(`Failed to import: ${url}`));
      destructor();
    };
    script.onload = () => {
      resolve(window[vector]);
      destructor();
    };
    const absURL = toAbsoluteURL(url);
    const loader = `import * as m from '${absURL.replace(/'/g, "\\'")}'; window.${vector} = ${returnDefault ? 'm.default || ' : ''}m;`; // export Module
    const blob = new Blob([loader], {type: 'text/javascript'});
    script.src = URL.createObjectURL(blob);
 
    document.head.append(script);
  });
}
 
export default importModule;