source: frontend/node_modules/webpack/lib/css/CssInjectStyleRuntimeModule.js@ cdcff72

Last change on this file since cdcff72 was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Natsu @xiaoxiaojx
4*/
5
6"use strict";
7
8const { SyncWaterfallHook } = require("tapable");
9const Compilation = require("../Compilation");
10const RuntimeGlobals = require("../RuntimeGlobals");
11const RuntimeModule = require("../RuntimeModule");
12const Template = require("../Template");
13
14/** @typedef {import("../Chunk")} Chunk */
15/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
16
17/**
18 * @typedef {object} CssInjectCompilationHooks
19 * @property {SyncWaterfallHook<[string, Chunk]>} createStyle
20 */
21
22/** @type {WeakMap<Compilation, CssInjectCompilationHooks>} */
23const compilationHooksMap = new WeakMap();
24
25class CssInjectStyleRuntimeModule extends RuntimeModule {
26 /**
27 * @param {Compilation} compilation the compilation
28 * @returns {CssInjectCompilationHooks} hooks
29 */
30 static getCompilationHooks(compilation) {
31 if (!(compilation instanceof Compilation)) {
32 throw new TypeError(
33 "The 'compilation' argument must be an instance of Compilation"
34 );
35 }
36 let hooks = compilationHooksMap.get(compilation);
37 if (hooks === undefined) {
38 hooks = {
39 createStyle: new SyncWaterfallHook(["source", "chunk"])
40 };
41 compilationHooksMap.set(compilation, hooks);
42 }
43 return hooks;
44 }
45
46 /**
47 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
48 */
49 constructor(runtimeRequirements) {
50 super("css inject style", RuntimeModule.STAGE_ATTACH);
51 /** @type {ReadOnlyRuntimeRequirements} */
52 this._runtimeRequirements = runtimeRequirements;
53 }
54
55 /**
56 * Generates runtime code for this runtime module.
57 * @returns {string | null} runtime code
58 */
59 generate() {
60 const compilation = /** @type {Compilation} */ (this.compilation);
61 const { runtimeTemplate, outputOptions } = compilation;
62 const { uniqueName } = outputOptions;
63 const { _runtimeRequirements } = this;
64
65 /** @type {boolean} */
66 const withHmr =
67 _runtimeRequirements &&
68 _runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers);
69
70 const { createStyle } =
71 CssInjectStyleRuntimeModule.getCompilationHooks(compilation);
72
73 // Only emit the nonce check when scriptNonce is part of the runtime
74 // requirements. Otherwise referencing `__webpack_require__.nc` would
75 // keep the require runtime alive for nothing.
76 const withScriptNonce =
77 _runtimeRequirements &&
78 _runtimeRequirements.has(RuntimeGlobals.scriptNonce);
79
80 const createStyleElementCode = Template.asString([
81 "var style = document.createElement('style');",
82 "",
83 ...(withScriptNonce
84 ? [
85 `if (${RuntimeGlobals.scriptNonce}) {`,
86 Template.indent(
87 `style.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
88 ),
89 "}"
90 ]
91 : []),
92 'style.setAttribute("data-webpack", getDataWebpackId(key));'
93 ]);
94
95 return Template.asString([
96 `var dataWebpackPrefix = ${uniqueName ? JSON.stringify(`${uniqueName}:`) : '"webpack:"'};`,
97 "",
98 "function getDataWebpackId(identifier) {",
99 Template.indent("return dataWebpackPrefix + identifier;"),
100 "}",
101 "",
102 "function findStyleElement(identifier) {",
103 Template.indent([
104 "var elements = document.getElementsByTagName('style');",
105 "for (var i = 0; i < elements.length; i++) {",
106 Template.indent([
107 "var el = elements[i];",
108 "if (el.getAttribute('data-webpack') === getDataWebpackId(identifier)) {",
109 Template.indent("return el;"),
110 "}"
111 ]),
112 "}",
113 "return null;"
114 ]),
115 "}",
116 "",
117 "function insertStyleElement(key) {",
118 Template.indent([
119 createStyle.call(
120 createStyleElementCode,
121 /** @type {Chunk} */ (this.chunk)
122 ),
123 "",
124 "document.head.appendChild(style);",
125 "",
126 "return style;"
127 ]),
128 "}",
129 "",
130 `${RuntimeGlobals.cssInjectStyle} = ${runtimeTemplate.basicFunction(
131 "identifier, css",
132 [
133 "var element = findStyleElement(identifier) || insertStyleElement(identifier);",
134 "element.textContent = css;"
135 ]
136 )};`,
137 "",
138 withHmr
139 ? Template.asString([
140 "",
141 "function removeStyleElement(styleElement) {",
142 Template.indent([
143 "if (styleElement.parentNode) {",
144 Template.indent(
145 "styleElement.parentNode.removeChild(styleElement);"
146 ),
147 "}"
148 ]),
149 "}",
150 `${RuntimeGlobals.cssInjectStyle}.removeModules = ${runtimeTemplate.basicFunction(
151 "removedModules",
152 [
153 "if (!removedModules) return;",
154 "var identifiers = Array.isArray(removedModules) ? removedModules : [removedModules];",
155 "for (var i = 0; i < identifiers.length; i++) {",
156 Template.indent([
157 "var identifier = identifiers[i];",
158 "var element = findStyleElement(identifier);",
159 "if (element) {",
160 Template.indent("removeStyleElement(element);"),
161 "}"
162 ]),
163 "}"
164 ]
165 )};`,
166 `${RuntimeGlobals.hmrDownloadUpdateHandlers}.cssInjectStyle = ${runtimeTemplate.basicFunction(
167 "chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList, css",
168 [
169 "if (removedModules) {",
170 Template.indent(
171 `${RuntimeGlobals.cssInjectStyle}.removeModules(removedModules);`
172 ),
173 "}"
174 ]
175 )};`
176 ])
177 : "// no css inject style HMR download handler"
178 ]);
179 }
180}
181
182module.exports = CssInjectStyleRuntimeModule;
Note: See TracBrowser for help on using the repository browser.