source: imaps-frontend/node_modules/webpack/lib/runtime/LoadScriptRuntimeModule.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3*/
4
5"use strict";
6
7const { SyncWaterfallHook } = require("tapable");
8const Compilation = require("../Compilation");
9const RuntimeGlobals = require("../RuntimeGlobals");
10const Template = require("../Template");
11const HelperRuntimeModule = require("./HelperRuntimeModule");
12
13/** @typedef {import("../Chunk")} Chunk */
14/** @typedef {import("../Compiler")} Compiler */
15
16/**
17 * @typedef {object} LoadScriptCompilationHooks
18 * @property {SyncWaterfallHook<[string, Chunk]>} createScript
19 */
20
21/** @type {WeakMap<Compilation, LoadScriptCompilationHooks>} */
22const compilationHooksMap = new WeakMap();
23
24class LoadScriptRuntimeModule extends HelperRuntimeModule {
25 /**
26 * @param {Compilation} compilation the compilation
27 * @returns {LoadScriptCompilationHooks} hooks
28 */
29 static getCompilationHooks(compilation) {
30 if (!(compilation instanceof Compilation)) {
31 throw new TypeError(
32 "The 'compilation' argument must be an instance of Compilation"
33 );
34 }
35 let hooks = compilationHooksMap.get(compilation);
36 if (hooks === undefined) {
37 hooks = {
38 createScript: new SyncWaterfallHook(["source", "chunk"])
39 };
40 compilationHooksMap.set(compilation, hooks);
41 }
42 return hooks;
43 }
44
45 /**
46 * @param {boolean=} withCreateScriptUrl use create script url for trusted types
47 * @param {boolean=} withFetchPriority use `fetchPriority` attribute
48 */
49 constructor(withCreateScriptUrl, withFetchPriority) {
50 super("load script");
51 this._withCreateScriptUrl = withCreateScriptUrl;
52 this._withFetchPriority = withFetchPriority;
53 }
54
55 /**
56 * @returns {string | null} runtime code
57 */
58 generate() {
59 const compilation = /** @type {Compilation} */ (this.compilation);
60 const { runtimeTemplate, outputOptions } = compilation;
61 const {
62 scriptType,
63 chunkLoadTimeout: loadTimeout,
64 crossOriginLoading,
65 uniqueName,
66 charset
67 } = outputOptions;
68 const fn = RuntimeGlobals.loadScript;
69
70 const { createScript } =
71 LoadScriptRuntimeModule.getCompilationHooks(compilation);
72
73 const code = Template.asString([
74 "script = document.createElement('script');",
75 scriptType ? `script.type = ${JSON.stringify(scriptType)};` : "",
76 charset ? "script.charset = 'utf-8';" : "",
77 `script.timeout = ${/** @type {number} */ (loadTimeout) / 1000};`,
78 `if (${RuntimeGlobals.scriptNonce}) {`,
79 Template.indent(
80 `script.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
81 ),
82 "}",
83 uniqueName
84 ? 'script.setAttribute("data-webpack", dataWebpackPrefix + key);'
85 : "",
86 this._withFetchPriority
87 ? Template.asString([
88 "if(fetchPriority) {",
89 Template.indent(
90 'script.setAttribute("fetchpriority", fetchPriority);'
91 ),
92 "}"
93 ])
94 : "",
95 `script.src = ${
96 this._withCreateScriptUrl
97 ? `${RuntimeGlobals.createScriptUrl}(url)`
98 : "url"
99 };`,
100 crossOriginLoading
101 ? crossOriginLoading === "use-credentials"
102 ? 'script.crossOrigin = "use-credentials";'
103 : Template.asString([
104 "if (script.src.indexOf(window.location.origin + '/') !== 0) {",
105 Template.indent(
106 `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
107 ),
108 "}"
109 ])
110 : ""
111 ]);
112
113 return Template.asString([
114 "var inProgress = {};",
115 uniqueName
116 ? `var dataWebpackPrefix = ${JSON.stringify(`${uniqueName}:`)};`
117 : "// data-webpack is not used as build has no uniqueName",
118 "// loadScript function to load a script via script tag",
119 `${fn} = ${runtimeTemplate.basicFunction(
120 `url, done, key, chunkId${
121 this._withFetchPriority ? ", fetchPriority" : ""
122 }`,
123 [
124 "if(inProgress[url]) { inProgress[url].push(done); return; }",
125 "var script, needAttach;",
126 "if(key !== undefined) {",
127 Template.indent([
128 'var scripts = document.getElementsByTagName("script");',
129 "for(var i = 0; i < scripts.length; i++) {",
130 Template.indent([
131 "var s = scripts[i];",
132 `if(s.getAttribute("src") == url${
133 uniqueName
134 ? ' || s.getAttribute("data-webpack") == dataWebpackPrefix + key'
135 : ""
136 }) { script = s; break; }`
137 ]),
138 "}"
139 ]),
140 "}",
141 "if(!script) {",
142 Template.indent([
143 "needAttach = true;",
144 createScript.call(code, /** @type {Chunk} */ (this.chunk))
145 ]),
146 "}",
147 "inProgress[url] = [done];",
148 `var onScriptComplete = ${runtimeTemplate.basicFunction(
149 "prev, event",
150 Template.asString([
151 "// avoid mem leaks in IE.",
152 "script.onerror = script.onload = null;",
153 "clearTimeout(timeout);",
154 "var doneFns = inProgress[url];",
155 "delete inProgress[url];",
156 "script.parentNode && script.parentNode.removeChild(script);",
157 `doneFns && doneFns.forEach(${runtimeTemplate.returningFunction(
158 "fn(event)",
159 "fn"
160 )});`,
161 "if(prev) return prev(event);"
162 ])
163 )}`,
164 `var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), ${loadTimeout});`,
165 "script.onerror = onScriptComplete.bind(null, script.onerror);",
166 "script.onload = onScriptComplete.bind(null, script.onload);",
167 "needAttach && document.head.appendChild(script);"
168 ]
169 )};`
170 ]);
171 }
172}
173
174module.exports = LoadScriptRuntimeModule;
Note: See TracBrowser for help on using the repository browser.