Skip to content

Commit 7ddc48b

Browse files
author
evilebottnawi
committed
fix: utf-8 characters support, emoji also 😸.
1 parent b90d8dd commit 7ddc48b

File tree

4 files changed

+63
-52
lines changed

4 files changed

+63
-52
lines changed

‎lib/processCss.js

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
/*
2-
MIT License http://www.opensource.org/licenses/mit-license.php
3-
Author Tobias Koppers @sokra
4-
*/
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
55
var formatCodeFrame = require("babel-code-frame");
6-
var Tokenizer = require("css-selector-tokenizer");
76
var postcss = require("postcss");
87
var loaderUtils = require("loader-utils");
98
var assign = require("object-assign");
@@ -42,15 +41,19 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
4241

4342
if(options.import) {
4443
css.walkAtRules(/import/i, function(rule) {
45-
var values = Tokenizer.parseValues(rule.params);
46-
var url = values.nodes[0].nodes[0];
47-
if(url.type === "url") {
48-
url = url.url;
49-
} else if(url.type === "string") {
50-
url = url.value;
44+
var tokens = valueParser(rule.params);
45+
var importNode = tokens.nodes[0];
46+
var url = null;
47+
if (importNode.type === "function" && importNode.value === 'url') {
48+
url = importNode.nodes[0].value;
49+
} else if(importNode.type === "string") {
50+
url = importNode.value;
5151
} else throw rule.error("Unexpected format" + rule.params);
52-
values.nodes[0].nodes.shift();
53-
var mediaQuery = Tokenizer.stringifyValues(values);
52+
if (!url) {
53+
return;
54+
}
55+
tokens.nodes.shift();
56+
var mediaQuery = tokens.toString().trim();
5457
if(loaderUtils.isUrlRequest(url, options.root) && options.mode === "global") {
5558
url = loaderUtils.urlToRequest(url, options.root);
5659
}
@@ -86,45 +89,45 @@ var parserPlugin = postcss.plugin("css-loader-parser", function(options) {
8689
exports[exportName] = replaceImportsInString(exports[exportName]);
8790
});
8891

89-
function processNode(item) {
90-
switch (item.type) {
91-
case "value":
92-
item.nodes.forEach(processNode);
93-
break;
94-
case "nested-item":
95-
item.nodes.forEach(processNode);
96-
break;
97-
case "item":
98-
var importIndex = imports["$" + item.name];
92+
css.walkDecls(function(decl) {
93+
var tokens = valueParser(decl.value);
94+
tokens.walk(function (node) {
95+
if (node.type === 'word') {
96+
var importIndex = imports["$" + node.value];
9997
if (typeof importIndex === "number") {
100-
item.name = "___CSS_LOADER_IMPORT___" + importIndex + "___";
98+
node.value = "___CSS_LOADER_IMPORT___" + importIndex + "___";
10199
}
102-
break;
103-
case "url":
104-
if (options.url && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url, options.root)) {
105-
// Don't remove quotes around url when contain space
106-
if (item.url.indexOf(" ") === -1) {
107-
item.stringType = "";
108-
}
109-
delete item.innerSpacingBefore;
110-
delete item.innerSpacingAfter;
111-
var url = item.url;
112-
item.url = "___CSS_LOADER_URL___" + urlItems.length + "___";
113-
urlItems.push({
114-
url: url
115-
});
100+
}
101+
102+
if (options.url && node.type === 'function' && node.value === 'url') {
103+
delete node.before;
104+
delete node.after;
105+
if (!node.nodes) {
106+
return;
116107
}
117-
break;
118-
}
119-
}
120108

121-
css.walkDecls(function(decl) {
122-
var values = Tokenizer.parseValues(decl.value);
123-
values.nodes.forEach(function(value) {
124-
value.nodes.forEach(processNode);
109+
node.nodes.forEach(function (nestedNode) {
110+
if (nestedNode.type !== 'word' && nestedNode.type !== 'string') {
111+
return;
112+
}
113+
var value = nestedNode.value;
114+
if (!/^#/.test(value) && loaderUtils.isUrlRequest(value, options.root)) {
115+
// Don't remove quotes around url when contain space
116+
if (value.indexOf(" ") === -1) {
117+
nestedNode.quote = "";
118+
}
119+
var url = value;
120+
nestedNode.value = "___CSS_LOADER_URL___" + urlItems.length + "___";
121+
urlItems.push({
122+
url: url
123+
});
124+
}
125+
})
126+
}
125127
});
126-
decl.value = Tokenizer.stringifyValues(values);
128+
decl.value = tokens.toString();
127129
});
130+
128131
css.walkAtRules(function(atrule) {
129132
if(typeof atrule.params === "string") {
130133
atrule.params = replaceImportsInString(atrule.params);

‎package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
],
1414
"dependencies": {
1515
"babel-code-frame": "^6.11.0",
16-
"css-selector-tokenizer": "^0.7.0",
1716
"cssnano": ">=2.6.1 <4",
1817
"loader-utils": "^1.0.2",
1918
"lodash.camelcase": "^4.3.0",

‎test/importTest.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,29 @@ describe("import", function() {
99
], "", {
1010
"./test.css": [[2, ".test{a: b}", ""]]
1111
});
12-
test("import camelcase", "@IMPORT url(test.css);\n.class { a: b c d; }", [
12+
test("import 2", "@import url('test.css');\n.class { a: b c d; }", [
13+
[2, ".test{a: b}", "screen"],
14+
[1, ".class { a: b c d; }", ""]
15+
], "", {
16+
"./test.css": [[2, ".test{a: b}", "screen"]]
17+
});
18+
test("import non ascii characters (emoji)", "@import url(😸.css);\n.class { a: b c d; }", [
1319
[2, ".test{a: b}", ""],
1420
[1, ".class { a: b c d; }", ""]
1521
], "", {
16-
"./test.css": [[2, ".test{a: b}", ""]]
22+
"./😸.css": [[2, ".test{a: b}", ""]]
1723
});
18-
test("import with string", "@import \"test.css\";\n.class { a: b c d; }", [
24+
test("import camelcase", "@IMPORT url(test.css);\n.class { a: b c d; }", [
1925
[2, ".test{a: b}", ""],
2026
[1, ".class { a: b c d; }", ""]
2127
], "", {
2228
"./test.css": [[2, ".test{a: b}", ""]]
2329
});
24-
test("import 2", "@import url('test.css');\n.class { a: b c d; }", [
25-
[2, ".test{a: b}", "screen"],
30+
test("import with string", "@import \"test.css\";\n.class { a: b c d; }", [
31+
[2, ".test{a: b}", ""],
2632
[1, ".class { a: b c d; }", ""]
2733
], "", {
28-
"./test.css": [[2, ".test{a: b}", "screen"]]
34+
"./test.css": [[2, ".test{a: b}", ""]]
2935
});
3036
test("import with media", "@import url('~test/css') screen and print;\n.class { a: b c d; }", [
3137
[3, ".test{a: b}", "((min-width: 100px)) and (screen and print)"],

‎test/simpleTest.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ describe("simple", function() {
2929
/*test("escape characters (two)", ".class { content: \"\\F10C \\F10D\" }", [
3030
[1, ".class { content: \"\\F10C \\F10D\" }", ""]
3131
]);*/
32+
/*test("non-ascii characters", "body { font-family: '😸'; }", [
33+
[1, "body { font-family: '😸'; }", ""]
34+
]);*/
3235
testMinimize("minimized simple", ".class { a: b c d; }", [
3336
[1, ".class{a:b c d}", ""]
3437
]);

0 commit comments

Comments
 (0)