source: frontend/node_modules/webpack/lib/dependencies/CssUrlDependency.js

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

Fix frontend appearance

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Ivan Kopeykin @vankop
4*/
5
6"use strict";
7
8const { ASSET_URL_TYPE } = require("../ModuleSourceTypeConstants");
9const RawDataUrlModule = require("../asset/RawDataUrlModule");
10const makeSerializable = require("../util/makeSerializable");
11const memoize = require("../util/memoize");
12const ModuleDependency = require("./ModuleDependency");
13
14/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
15/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
16/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
17/** @typedef {import("../Dependency")} Dependency */
18/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
19/** @typedef {import("../Module")} Module */
20/** @typedef {import("../Module").BuildInfo} BuildInfo */
21/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
22/** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
23/** @typedef {import("../javascript/JavascriptParser").Range} Range */
24/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
25/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
26/** @typedef {import("../util/Hash")} Hash */
27/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
28
29const getIgnoredRawDataUrlModule = memoize(
30 () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)")
31);
32
33class CssUrlDependency extends ModuleDependency {
34 /**
35 * Creates an instance of CssUrlDependency.
36 * @param {string} request request
37 * @param {Range} range range of the argument
38 * @param {"string" | "url" | "src"} urlType dependency type e.g. url() or string
39 */
40 constructor(request, range, urlType) {
41 super(request);
42 this.range = range;
43 this.urlType = urlType;
44 }
45
46 get type() {
47 return "css url()";
48 }
49
50 get category() {
51 return "url";
52 }
53
54 /**
55 * Creates an ignored module.
56 * @param {string} context context directory
57 * @returns {Module} ignored module
58 */
59 createIgnoredModule(context) {
60 return getIgnoredRawDataUrlModule();
61 }
62
63 /**
64 * Updates the hash with the data contributed by this instance.
65 * @param {Hash} hash hash to be updated
66 * @param {UpdateHashContext} context context
67 * @returns {void}
68 */
69 updateHash(hash, context) {
70 // The dependency template substitutes the referenced asset's hashed
71 // filename into the rendered CSS at code-generation time. Folding the
72 // asset module's content hash into the dependency hash ensures the
73 // CSS module's hash invalidates — and the CSS chunk's contenthash
74 // updates — whenever the referenced asset's content changes.
75 const { chunkGraph } = context;
76 const module = chunkGraph.moduleGraph.getModule(this);
77 if (!module) return;
78 const buildInfo = /** @type {BuildInfo | undefined} */ (module.buildInfo);
79 if (buildInfo && buildInfo.hash) {
80 hash.update(/** @type {string} */ (buildInfo.hash));
81 }
82 }
83
84 /**
85 * Serializes this instance into the provided serializer context.
86 * @param {ObjectSerializerContext} context context
87 */
88 serialize(context) {
89 const { write } = context;
90 write(this.urlType);
91 super.serialize(context);
92 }
93
94 /**
95 * Restores this instance from the provided deserializer context.
96 * @param {ObjectDeserializerContext} context context
97 */
98 deserialize(context) {
99 const { read } = context;
100 this.urlType = read();
101 super.deserialize(context);
102 }
103}
104
105/**
106 * Returns string in quotes if needed.
107 * @param {string} str string
108 * @returns {string} string in quotes if needed
109 */
110const cssEscapeString = (str) => {
111 let countWhiteOrBracket = 0;
112 let countQuotation = 0;
113 let countApostrophe = 0;
114 for (let i = 0; i < str.length; i++) {
115 const cc = str.charCodeAt(i);
116 switch (cc) {
117 case 9: // tab
118 case 10: // nl
119 case 32: // space
120 case 40: // (
121 case 41: // )
122 countWhiteOrBracket++;
123 break;
124 case 34:
125 countQuotation++;
126 break;
127 case 39:
128 countApostrophe++;
129 break;
130 }
131 }
132 if (countWhiteOrBracket < 2) {
133 return str.replace(/[\n\t ()'"\\]/g, (m) => `\\${m}`);
134 } else if (countQuotation <= countApostrophe) {
135 return `"${str.replace(/[\n"\\]/g, (m) => `\\${m}`)}"`;
136 }
137 return `'${str.replace(/[\n'\\]/g, (m) => `\\${m}`)}'`;
138};
139
140CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
141 ModuleDependency.Template
142) {
143 /**
144 * Applies the plugin by registering its hooks on the compiler.
145 * @param {Dependency} dependency the dependency for which the template should be applied
146 * @param {ReplaceSource} source the current replace source which can be modified
147 * @param {DependencyTemplateContext} templateContext the context object
148 * @returns {void}
149 */
150 apply(
151 dependency,
152 source,
153 { type, moduleGraph, runtimeTemplate, codeGenerationResults }
154 ) {
155 if (type === "javascript") return;
156 const dep = /** @type {CssUrlDependency} */ (dependency);
157 const module = /** @type {Module} */ (moduleGraph.getModule(dep));
158
159 /** @type {string | undefined} */
160 let newValue;
161
162 switch (dep.urlType) {
163 case "string":
164 newValue = cssEscapeString(
165 this.assetUrl({
166 module,
167 codeGenerationResults
168 })
169 );
170 break;
171 case "url":
172 newValue = `url(${cssEscapeString(
173 this.assetUrl({
174 module,
175 codeGenerationResults
176 })
177 )})`;
178 break;
179 case "src":
180 newValue = `src(${cssEscapeString(
181 this.assetUrl({
182 module,
183 codeGenerationResults
184 })
185 )})`;
186 break;
187 }
188
189 source.replace(
190 dep.range[0],
191 dep.range[1] - 1,
192 /** @type {string} */ (newValue)
193 );
194 }
195
196 /**
197 * Returns the url of the asset.
198 * @param {object} options options object
199 * @param {Module} options.module the module
200 * @param {RuntimeSpec=} options.runtime runtime
201 * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
202 * @returns {string} the url of the asset
203 */
204 assetUrl({ runtime, module, codeGenerationResults }) {
205 if (!module) {
206 return "data:,";
207 }
208 const codeGen = codeGenerationResults.get(module, runtime);
209 const data = codeGen.data;
210 if (!data) return "data:,";
211 const url = data.get("url");
212 if (!url || !url[ASSET_URL_TYPE]) return "data:,";
213 return url[ASSET_URL_TYPE];
214 }
215};
216
217makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency");
218
219CssUrlDependency.PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__";
220CssUrlDependency.PUBLIC_PATH_FULL_HASH = "__WEBPACK_CSS_PUBLIC_PATH_FULL_HASH_";
221
222module.exports = CssUrlDependency;
Note: See TracBrowser for help on using the repository browser.