|
3 | 3 | Author Tobias Koppers @sokra
|
4 | 4 | */
|
5 | 5 | var formatCodeFrame = require("babel-code-frame");
|
6 |
| -var Tokenizer = require("css-selector-tokenizer"); |
7 | 6 | var postcss = require("postcss");
|
8 |
| -var loaderUtils = require("loader-utils"); |
9 |
| - |
10 |
| -var icssUtils = require('icss-utils'); |
11 |
| -var valueParser = require('postcss-value-parser'); |
12 |
| - |
13 |
| -var parserPlugin = postcss.plugin("css-loader-parser", function(options) { |
14 |
| - return function(css) { |
15 |
| - var imports = {}; |
16 |
| - var exports = {}; |
17 |
| - var importItems = []; |
18 |
| - var urlItems = []; |
19 |
| - |
20 |
| - function replaceImportsInString(str) { |
21 |
| - if(options.import) { |
22 |
| - var tokens = valueParser(str); |
23 |
| - tokens.walk(function (node) { |
24 |
| - if (node.type !== 'word') { |
25 |
| - return; |
26 |
| - } |
27 |
| - var token = node.value; |
28 |
| - var importIndex = imports["$" + token]; |
29 |
| - if(typeof importIndex === "number") { |
30 |
| - node.value = "___CSS_LOADER_IMPORT___" + importIndex + "___"; |
31 |
| - } |
32 |
| - }) |
33 |
| - return tokens.toString(); |
34 |
| - } |
35 |
| - return str; |
36 |
| - } |
37 |
| - |
38 |
| - if(options.import) { |
39 |
| - css.walkAtRules(/^import$/i, function(rule) { |
40 |
| - var values = Tokenizer.parseValues(rule.params); |
41 |
| - var url = values.nodes[0].nodes[0]; |
42 |
| - if(url && url.type === "url") { |
43 |
| - url = url.url; |
44 |
| - } else if(url && url.type === "string") { |
45 |
| - url = url.value; |
46 |
| - } else throw rule.error("Unexpected format " + rule.params); |
47 |
| - if (!url.replace(/\s/g, '').length) { |
48 |
| - return; |
49 |
| - } |
50 |
| - values.nodes[0].nodes.shift(); |
51 |
| - var mediaQuery = Tokenizer.stringifyValues(values); |
52 |
| - |
53 |
| - if(loaderUtils.isUrlRequest(url)) { |
54 |
| - url = loaderUtils.urlToRequest(url); |
55 |
| - } |
56 |
| - |
57 |
| - importItems.push({ |
58 |
| - url: url, |
59 |
| - mediaQuery: mediaQuery |
60 |
| - }); |
61 |
| - rule.remove(); |
62 |
| - }); |
63 |
| - } |
64 |
| - |
65 |
| - var icss = icssUtils.extractICSS(css); |
66 |
| - exports = icss.icssExports; |
67 |
| - Object.keys(icss.icssImports).forEach(function(key) { |
68 |
| - var url = loaderUtils.parseString(key); |
69 |
| - Object.keys(icss.icssImports[key]).forEach(function(prop) { |
70 |
| - imports["$" + prop] = importItems.length; |
71 |
| - importItems.push({ |
72 |
| - url: url, |
73 |
| - export: icss.icssImports[key][prop] |
74 |
| - }); |
75 |
| - }) |
76 |
| - }); |
77 |
| - |
78 |
| - Object.keys(exports).forEach(function(exportName) { |
79 |
| - exports[exportName] = replaceImportsInString(exports[exportName]); |
80 |
| - }); |
81 |
| - |
82 |
| - function processNode(item) { |
83 |
| - switch (item.type) { |
84 |
| - case "value": |
85 |
| - item.nodes.forEach(processNode); |
86 |
| - break; |
87 |
| - case "nested-item": |
88 |
| - item.nodes.forEach(processNode); |
89 |
| - break; |
90 |
| - case "item": |
91 |
| - var importIndex = imports["$" + item.name]; |
92 |
| - if (typeof importIndex === "number") { |
93 |
| - item.name = "___CSS_LOADER_IMPORT___" + importIndex + "___"; |
94 |
| - } |
95 |
| - break; |
96 |
| - case "url": |
97 |
| - if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url)) { |
98 |
| - // Strip quotes, they will be re-added if the module needs them |
99 |
| - item.stringType = ""; |
100 |
| - delete item.innerSpacingBefore; |
101 |
| - delete item.innerSpacingAfter; |
102 |
| - // For backward-compat after dropping css modules |
103 |
| - var url = loaderUtils.urlToRequest(item.url.trim()); |
104 |
| - item.url = "___CSS_LOADER_URL___" + urlItems.length + "___"; |
105 |
| - urlItems.push({ |
106 |
| - url: url |
107 |
| - }); |
108 |
| - } |
109 |
| - break; |
110 |
| - } |
111 |
| - } |
112 |
| - |
113 |
| - css.walkDecls(function(decl) { |
114 |
| - var values = Tokenizer.parseValues(decl.value); |
115 |
| - values.nodes.forEach(function(value) { |
116 |
| - value.nodes.forEach(processNode); |
117 |
| - }); |
118 |
| - decl.value = Tokenizer.stringifyValues(values); |
119 |
| - }); |
120 |
| - css.walkAtRules(function(atrule) { |
121 |
| - if(typeof atrule.params === "string") { |
122 |
| - atrule.params = replaceImportsInString(atrule.params); |
123 |
| - } |
124 |
| - }); |
125 |
| - |
126 |
| - options.importItems = importItems; |
127 |
| - options.urlItems = urlItems; |
128 |
| - options.exports = exports; |
129 |
| - }; |
130 |
| -}); |
| 7 | +var plugin = require("./plugin"); |
131 | 8 |
|
132 | 9 | module.exports = function processCss(inputSource, inputMap, options, callback) {
|
133 |
| - var query = options.query; |
134 |
| - |
135 |
| - var parserOptions = { |
136 |
| - url: query.url !== false, |
137 |
| - import: query.import !== false, |
138 |
| - resolve: options.resolve |
139 |
| - }; |
140 |
| - |
141 |
| - var pipeline = postcss([ |
142 |
| - parserPlugin(parserOptions) |
143 |
| - ]); |
144 |
| - |
145 |
| - pipeline.process(inputSource, { |
146 |
| - // we need a prefix to avoid path rewriting of PostCSS |
147 |
| - from: "/css-loader!" + options.from, |
148 |
| - to: options.to, |
149 |
| - map: options.sourceMap ? { |
150 |
| - prev: inputMap, |
151 |
| - sourcesContent: true, |
152 |
| - inline: false, |
153 |
| - annotation: false |
154 |
| - } : null |
155 |
| - }).then(function(result) { |
156 |
| - callback(null, { |
157 |
| - source: result.css, |
158 |
| - map: result.map && result.map.toJSON(), |
159 |
| - exports: parserOptions.exports, |
160 |
| - importItems: parserOptions.importItems, |
161 |
| - importItemRegExpG: /___CSS_LOADER_IMPORT___([0-9]+)___/g, |
162 |
| - importItemRegExp: /___CSS_LOADER_IMPORT___([0-9]+)___/, |
163 |
| - urlItems: parserOptions.urlItems, |
164 |
| - urlItemRegExpG: /___CSS_LOADER_URL___([0-9]+)___/g, |
165 |
| - urlItemRegExp: /___CSS_LOADER_URL___([0-9]+)___/ |
166 |
| - }); |
167 |
| - }).catch(function(err) { |
168 |
| - if (err.name === 'CssSyntaxError') { |
169 |
| - var wrappedError = new CSSLoaderError( |
170 |
| - 'Syntax Error', |
171 |
| - err.reason, |
172 |
| - err.line != null && err.column != null |
173 |
| - ? {line: err.line, column: err.column} |
174 |
| - : null, |
175 |
| - err.input.source |
176 |
| - ); |
177 |
| - callback(wrappedError); |
178 |
| - } else { |
179 |
| - callback(err); |
180 |
| - } |
181 |
| - }); |
| 10 | + var query = options.query; |
| 11 | + var parserOptions = { |
| 12 | + url: query.url !== false, |
| 13 | + import: query.import !== false, |
| 14 | + resolve: options.resolve |
| 15 | + }; |
| 16 | + |
| 17 | + postcss([plugin(parserOptions)]) |
| 18 | + .process(inputSource, { |
| 19 | + // we need a prefix to avoid path rewriting of PostCSS |
| 20 | + from: "/css-loader!" + options.from, |
| 21 | + to: options.to, |
| 22 | + map: options.sourceMap |
| 23 | + ? { |
| 24 | + prev: inputMap, |
| 25 | + sourcesContent: true, |
| 26 | + inline: false, |
| 27 | + annotation: false |
| 28 | + } |
| 29 | + : null |
| 30 | + }) |
| 31 | + .then(function(result) { |
| 32 | + callback(null, { |
| 33 | + source: result.css, |
| 34 | + map: result.map && result.map.toJSON(), |
| 35 | + exports: parserOptions.exports, |
| 36 | + importItems: parserOptions.importItems, |
| 37 | + importItemRegExpG: /___CSS_LOADER_IMPORT___([0-9]+)___/g, |
| 38 | + importItemRegExp: /___CSS_LOADER_IMPORT___([0-9]+)___/, |
| 39 | + urlItems: parserOptions.urlItems, |
| 40 | + urlItemRegExpG: /___CSS_LOADER_URL___([0-9]+)___/g, |
| 41 | + urlItemRegExp: /___CSS_LOADER_URL___([0-9]+)___/ |
| 42 | + }); |
| 43 | + }) |
| 44 | + .catch(function(err) { |
| 45 | + if (err.name === "CssSyntaxError") { |
| 46 | + var wrappedError = new CSSLoaderError( |
| 47 | + "Syntax Error", |
| 48 | + err.reason, |
| 49 | + err.line != null && err.column != null |
| 50 | + ? { line: err.line, column: err.column } |
| 51 | + : null, |
| 52 | + err.input.source |
| 53 | + ); |
| 54 | + callback(wrappedError); |
| 55 | + } else { |
| 56 | + callback(err); |
| 57 | + } |
| 58 | + }); |
182 | 59 | };
|
183 | 60 |
|
184 | 61 | function formatMessage(message, loc, source) {
|
185 |
| - var formatted = message; |
186 |
| - if (loc) { |
187 |
| - formatted = formatted |
188 |
| - + ' (' + loc.line + ':' + loc.column + ')'; |
189 |
| - } |
190 |
| - if (loc && source) { |
191 |
| - formatted = formatted |
192 |
| - + '\n\n' + formatCodeFrame(source, loc.line, loc.column) + '\n'; |
193 |
| - } |
194 |
| - return formatted; |
| 62 | + var formatted = message; |
| 63 | + if (loc) { |
| 64 | + formatted = formatted + " (" + loc.line + ":" + loc.column + ")"; |
| 65 | + } |
| 66 | + if (loc && source) { |
| 67 | + formatted = |
| 68 | + formatted + "\n\n" + formatCodeFrame(source, loc.line, loc.column) + "\n"; |
| 69 | + } |
| 70 | + return formatted; |
195 | 71 | }
|
196 | 72 |
|
197 | 73 | function CSSLoaderError(name, message, loc, source, error) {
|
198 |
| - Error.call(this); |
199 |
| - Error.captureStackTrace(this, CSSLoaderError); |
200 |
| - this.name = name; |
201 |
| - this.error = error; |
202 |
| - this.message = formatMessage(message, loc, source); |
203 |
| - this.hideStack = true; |
| 74 | + Error.call(this); |
| 75 | + Error.captureStackTrace(this, CSSLoaderError); |
| 76 | + this.name = name; |
| 77 | + this.error = error; |
| 78 | + this.message = formatMessage(message, loc, source); |
| 79 | + this.hideStack = true; |
204 | 80 | }
|
205 | 81 |
|
206 | 82 | CSSLoaderError.prototype = Object.create(Error.prototype);
|
|
0 commit comments