Skip to content

Commit 3080ab2

Browse files
fix: handle escaping selectors (css-modules#10)
1 parent d6e38e6 commit 3080ab2

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

src/index.js

+29-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ function getSingleLocalNamesForComposes(root) {
5151
});
5252
}
5353

54+
const whitespace = '[\\x20\\t\\r\\n\\f]';
55+
const unescapeRegExp = new RegExp(
56+
'\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)',
57+
'ig'
58+
);
59+
60+
function unescape(str) {
61+
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
62+
const high = '0x' + escaped - 0x10000;
63+
64+
// NaN means non-codepoint
65+
// Workaround erroneous numeric interpretation of +"0x"
66+
return high !== high || escapedWhitespace
67+
? escaped
68+
: high < 0
69+
? // BMP codepoint
70+
String.fromCharCode(high + 0x10000)
71+
: // Supplemental Plane codepoint (surrogate pair)
72+
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
73+
});
74+
}
75+
5476
const processor = postcss.plugin('postcss-modules-scope', function(options) {
5577
return css => {
5678
const generateScopedName =
@@ -64,10 +86,15 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) {
6486
css.source.input.from,
6587
css.source.input.css
6688
);
89+
6790
exports[name] = exports[name] || [];
68-
if (exports[name].indexOf(scopedName) < 0) {
69-
exports[name].push(scopedName);
91+
92+
const unescapedScopedName = unescape(scopedName);
93+
94+
if (exports[name].indexOf(unescapedScopedName) < 0) {
95+
exports[name].push(unescapedScopedName);
7096
}
97+
7198
return scopedName;
7299
}
73100

test/test-cases/export-class/expected.css

+16-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010
color: rebeccapurple;
1111
}
1212

13+
._input__\31 a2b3c {
14+
color: gainsboro;
15+
}
16+
17+
._input__\32 {
18+
color: aqua;
19+
}
20+
21+
._input__𝌆 {
22+
color: fuchsia;
23+
}
24+
1325
@media (max-width: 520px) {
1426
/* selector doubled to increase specificity */
1527
._input__exportName._input__exportName {
@@ -22,7 +34,10 @@
2234
}
2335

2436
:export {
37+
2: _input__2;
2538
exportName: _input__exportName;
26-
::::: _input__\:\:\:\:;
39+
::::: _input__::::;
40+
1a2b3c: _input__1a2b3c;
41+
𝌆: _input__𝌆;
2742
newExport: _input__newExport;
2843
}

test/test-cases/export-class/source.css

+12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010
color: rebeccapurple;
1111
}
1212

13+
:local(.\31 a2b3c) {
14+
color: gainsboro;
15+
}
16+
17+
:local(.\32) {
18+
color: aqua;
19+
}
20+
21+
:local(.𝌆) {
22+
color: fuchsia;
23+
}
24+
1325
@media (max-width: 520px) {
1426
/* selector doubled to increase specificity */
1527
:local(.exportName):local(.exportName) {

0 commit comments

Comments
 (0)