From 8365f777cab6bd4835429e03d34011f233d95a9f Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Wed, 27 Nov 2019 22:41:51 +0300 Subject: [PATCH] fix: add additional space after the escape sequence (#17) --- package.json | 1 + src/index.js | 11 +++ test/test-cases/escape-sequence/expected.css | 80 ++++++++++++++++++++ test/test-cases/escape-sequence/options.js | 21 +++++ test/test-cases/escape-sequence/source.css | 75 ++++++++++++++++++ 5 files changed, 188 insertions(+) create mode 100644 test/test-cases/escape-sequence/expected.css create mode 100644 test/test-cases/escape-sequence/options.js create mode 100644 test/test-cases/escape-sequence/source.css diff --git a/package.json b/package.json index 82dcc84..e521388 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "postcss-selector-parser": "^6.0.0" }, "devDependencies": { + "cssesc": "^3.0.0", "chokidar-cli": "^1.0.1", "codecov.io": "^0.1.2", "coveralls": "^3.0.2", diff --git a/src/index.js b/src/index.js index 0f3bdcf..e593bff 100644 --- a/src/index.js +++ b/src/index.js @@ -152,6 +152,17 @@ const processor = postcss.plugin('postcss-modules-scope', function(options) { // non-container node selector.first.spaces = node.spaces; + const nextNode = node.next(); + + if ( + nextNode && + nextNode.type === 'combinator' && + nextNode.value === ' ' && + /\\[A-F0-9]{1,6}$/.test(selector.last.value) + ) { + selector.last.spaces.after = ' '; + } + node.replaceWith(selector); return; diff --git a/test/test-cases/escape-sequence/expected.css b/test/test-cases/escape-sequence/expected.css new file mode 100644 index 0000000..a4c52d0 --- /dev/null +++ b/test/test-cases/escape-sequence/expected.css @@ -0,0 +1,80 @@ +.\1F600 { + color: red; +} + +.\1F600 .\1F600 { + color: red; +} + +.\1F600 .\1F600 .\1F600 { + color: red; +} + +.\1F600 A { + color: red; +} + +.\1F600 .\1F600 { + color: red; +} + +.\1F600 .\1F600 { + color: red; +} + +.\1F600 .\1F600 .\1F600 { + color: red; +} + +.\1F600 .\1F600 A .\1F600 { + color: red; +} + +#\1F600 #\1F600 #\1F600 { + color: red; +} + +#\1F600 #\1F600 A #\1F600 { + color: red; +} + +.a .\1F600 b { + color: red; +} + +.\1F600 > .\1F600 > .\1F600 { + color: red; +} + +.\1F600 .\1F600 { + color: red; +} + +.\1F600.\1F600 { + color: red; +} + +.\1F600 .\1F600 { + color: red; +} + +.\1F600 .a { + color: red; +} + +.\1F600.a { + color: red; +} + +.a .\1F600 { + color: red; +} + +.a.\1F600 { + color: red; +} + +:export { + smile: 😀; + smile_with_A: 😀A; +} diff --git a/test/test-cases/escape-sequence/options.js b/test/test-cases/escape-sequence/options.js new file mode 100644 index 0000000..7e95fd4 --- /dev/null +++ b/test/test-cases/escape-sequence/options.js @@ -0,0 +1,21 @@ +const cssesc = require('cssesc'); + +const filenameReservedRegex = /[<>:"/\\|?*\x00-\x1F]/g; +const reControlChars = /[\u0000-\u001f\u0080-\u009f]/g; +const reRelativePath = /^\.+/; + +module.exports = { + generateScopedName: function(name) { + return cssesc( + name + .replace(/smile/, '😀') + .replace(/_with_A/g, 'A') + .replace(/^((-?[0-9])|--)/, '_$1') + .replace(filenameReservedRegex, '-') + .replace(reControlChars, '-') + .replace(reRelativePath, '-') + .replace(/\./g, '-'), + { isIdentifier: true } + ); + }, +}; diff --git a/test/test-cases/escape-sequence/source.css b/test/test-cases/escape-sequence/source.css new file mode 100644 index 0000000..5f3cecf --- /dev/null +++ b/test/test-cases/escape-sequence/source.css @@ -0,0 +1,75 @@ +:local(.smile) { + color: red; +} + +:local(.smile) :local(.smile) { + color: red; +} + +:local(.smile) :local(.smile) :local(.smile) { + color: red; +} + +:local(.smile_with_A) { + color: red; +} + +.\1F600 :local(.smile) { + color: red; +} + +:local(.smile) .\1F600 { + color: red; +} + +.\1F600 :local(.smile) .\1F600 { + color: red; +} + +.\1F600 :local(.smile_with_A) .\1F600 { + color: red; +} + +#\1F600 :local(#smile) #\1F600 { + color: red; +} + +#\1F600 :local(#smile_with_A) #\1F600 { + color: red; +} + +.a :local(.smile) b { + color: red; +} + +:local(.smile) > :local(.smile) > :local(.smile) { + color: red; +} + +.\1F600 :local(.smile) { + color: red; +} + +.\1F600:local(.smile) { + color: red; +} + +.\1F600 :local(.smile) { + color: red; +} + +:local(.smile) .a { + color: red; +} + +:local(.smile).a { + color: red; +} + +.a :local(.smile) { + color: red; +} + +.a:local(.smile) { + color: red; +}