summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js')
-rw-r--r--node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js85
1 files changed, 85 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js b/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js
new file mode 100644
index 00000000..74b40a1e
--- /dev/null
+++ b/node_modules/webpack/lib/runtime/AutoPublicPathRuntimeModule.js
@@ -0,0 +1,85 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
+const { getUndoPath } = require("../util/identifier");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+
+class AutoPublicPathRuntimeModule extends RuntimeModule {
+ constructor() {
+ super("publicPath", RuntimeModule.STAGE_BASIC);
+ }
+
+ /**
+ * @returns {string | null} runtime code
+ */
+ generate() {
+ const compilation = /** @type {Compilation} */ (this.compilation);
+ const { scriptType, importMetaName, path } = compilation.outputOptions;
+ const chunkName = compilation.getPath(
+ JavascriptModulesPlugin.getChunkFilenameTemplate(
+ /** @type {Chunk} */
+ (this.chunk),
+ compilation.outputOptions
+ ),
+ {
+ chunk: this.chunk,
+ contentHashType: "javascript"
+ }
+ );
+ const undoPath = getUndoPath(
+ chunkName,
+ /** @type {string} */ (path),
+ false
+ );
+
+ return Template.asString([
+ "var scriptUrl;",
+ scriptType === "module"
+ ? `if (typeof ${importMetaName}.url === "string") scriptUrl = ${importMetaName}.url`
+ : Template.asString([
+ `if (${RuntimeGlobals.global}.importScripts) scriptUrl = ${RuntimeGlobals.global}.location + "";`,
+ `var document = ${RuntimeGlobals.global}.document;`,
+ "if (!scriptUrl && document) {",
+ Template.indent([
+ // Technically we could use `document.currentScript instanceof window.HTMLScriptElement`,
+ // but an attacker could try to inject `<script>HTMLScriptElement = HTMLImageElement</script>`
+ // and use `<img name="currentScript" src="https://attacker.controlled.server/"></img>`
+ "if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')",
+ Template.indent("scriptUrl = document.currentScript.src;"),
+ "if (!scriptUrl) {",
+ Template.indent([
+ 'var scripts = document.getElementsByTagName("script");',
+ "if(scripts.length) {",
+ Template.indent([
+ "var i = scripts.length - 1;",
+ "while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;"
+ ]),
+ "}"
+ ]),
+ "}"
+ ]),
+ "}"
+ ]),
+ "// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration",
+ '// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.',
+ 'if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");',
+ 'scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");',
+ !undoPath
+ ? `${RuntimeGlobals.publicPath} = scriptUrl;`
+ : `${RuntimeGlobals.publicPath} = scriptUrl + ${JSON.stringify(
+ undoPath
+ )};`
+ ]);
+ }
+}
+
+module.exports = AutoPublicPathRuntimeModule;