From 1f42f0e762503eb69a9f9c8761778daca5d6c46c Mon Sep 17 00:00:00 2001 From: alreadyExisted Date: Sat, 6 Apr 2019 23:09:08 +0300 Subject: [PATCH 1/5] fix: do not replace symbol @ in selectors --- src/utils.js | 3 +- .../localIdentName-option.test.js.snap | 99 +++++++++++++++++-- test/fixtures/modules/localIdentName.css | 5 + test/localIdentName-option.test.js | 24 +++++ 4 files changed, 123 insertions(+), 8 deletions(-) diff --git a/src/utils.js b/src/utils.js index c647dc82..a3ca0fec 100644 --- a/src/utils.js +++ b/src/utils.js @@ -89,7 +89,8 @@ function getLocalIdent(loaderContext, localIdentName, localName, options) { ); return hash - .replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-') + .replace(/\\@/g, '@') + .replace(new RegExp('[^a-zA-Z0-9@\\-_\u00A0-\uFFFF]', 'g'), '-') .replace(/^((-?[0-9])|--)/, '_$1'); } diff --git a/test/__snapshots__/localIdentName-option.test.js.snap b/test/__snapshots__/localIdentName-option.test.js.snap index 23e0126c..7cf64779 100644 --- a/test/__snapshots__/localIdentName-option.test.js.snap +++ b/test/__snapshots__/localIdentName-option.test.js.snap @@ -35,7 +35,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -78,7 +82,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -121,7 +129,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -164,7 +176,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -207,7 +223,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -250,7 +270,11 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] @@ -293,10 +317,71 @@ Array [ :local(.-a0-34a___f) { color: red; } -", + +:local(.m_x_\\\\@) { + margin-left: auto !important; + margin-right: auto !important; +}", "", ], ] `; exports[`localIdentName option should use hash prefix: warnings 1`] = `Array []`; + +exports[`localIdentName option should сorrectly replace symbol @ in selector: errors 1`] = `Array []`; + +exports[`localIdentName option should сorrectly replace symbol @ in selector: locals 1`] = ` +Object { + "-a0-34a___f": "-a0-34a___f--2nJ5", + "_test": "_test--23te", + "className": "className--1E8H", + "m_x_@": "m_x_@--2G3b", + "someId": "someId--3w7J", + "subClass": "subClass--3lo0", + "test": "test--NW9Y", +} +`; + +exports[`localIdentName option should сorrectly replace symbol @ in selector: module (evaluated) 1`] = ` +Array [ + Array [ + 1, + ".test--NW9Y { + background: red; +} + +._test--23te { + background: blue; +} + +.className--1E8H { + background: red; +} + +#someId--3w7J { + background: green; +} + +.className--1E8H .subClass--3lo0 { + color: green; +} + +#someId--3w7J .subClass--3lo0 { + color: blue; +} + +.-a0-34a___f--2nJ5 { + color: red; +} + +.m_x_@--2G3b { + margin-left: auto !important; + margin-right: auto !important; +}", + "", + ], +] +`; + +exports[`localIdentName option should сorrectly replace symbol @ in selector: warnings 1`] = `Array []`; diff --git a/test/fixtures/modules/localIdentName.css b/test/fixtures/modules/localIdentName.css index e670d069..154468a9 100644 --- a/test/fixtures/modules/localIdentName.css +++ b/test/fixtures/modules/localIdentName.css @@ -25,3 +25,8 @@ :local(.-a0-34a___f) { color: red; } + +:local(.m_x_\@) { + margin-left: auto !important; + margin-right: auto !important; +} \ No newline at end of file diff --git a/test/localIdentName-option.test.js b/test/localIdentName-option.test.js index 91aac177..aed12650 100644 --- a/test/localIdentName-option.test.js +++ b/test/localIdentName-option.test.js @@ -117,4 +117,28 @@ describe('localIdentName option', () => { expect(stats.compilation.warnings).toMatchSnapshot('warnings'); expect(stats.compilation.errors).toMatchSnapshot('errors'); }); + + it('should сorrectly replace symbol @ in selector', async () => { + const config = { + loader: { + options: { + importLoaders: 2, + localIdentName: '[local]--[hash:base64:4]', + modules: true, + }, + }, + }; + const testId = './modules/localIdentName.css'; + const stats = await webpack(testId, config); + const { modules } = stats.toJson(); + const module = modules.find((m) => m.id === testId); + const evaluatedModule = evaluated(module.source, modules); + + expect(evaluatedModule.locals['m_x_@']).toContain('m_x_@'); + + expect(evaluatedModule).toMatchSnapshot('module (evaluated)'); + expect(evaluatedModule.locals).toMatchSnapshot('locals'); + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); }); From a0c39ebadae3c0793672b5214b74f6329b432ea4 Mon Sep 17 00:00:00 2001 From: alreadyExisted Date: Tue, 9 Apr 2019 02:09:57 +0300 Subject: [PATCH 2/5] fix: avoid all escaped characters replaced --- src/utils.js | 51 ++++++++- .../localIdentName-option.test.js.snap | 106 +++++++++++++++++- test/fixtures/modules/localIdentName.css | 5 + test/localIdentName-option.test.js | 4 +- 4 files changed, 158 insertions(+), 8 deletions(-) diff --git a/src/utils.js b/src/utils.js index a3ca0fec..76149459 100644 --- a/src/utils.js +++ b/src/utils.js @@ -88,10 +88,7 @@ function getLocalIdent(loaderContext, localIdentName, localName, options) { options ); - return hash - .replace(/\\@/g, '@') - .replace(new RegExp('[^a-zA-Z0-9@\\-_\u00A0-\uFFFF]', 'g'), '-') - .replace(/^((-?[0-9])|--)/, '_$1'); + return normalizeIdentifier(hash); } function getFilter(filter, resourcePath, defaultFilter = null) { @@ -108,6 +105,52 @@ function getFilter(filter, resourcePath, defaultFilter = null) { }; } +function normalizeIdentifier(value) { + const escapedSymbols = [ + '~', + '!', + '@', + '#', + '$', + '%', + '&', + '^', + '*', + '(', + ')', + '{', + '}', + '[', + ']', + '`', + '/', + '=', + '?', + '+', + '\\', + '|', + '-', + '_', + ':', + ';', + "'", + '"', + ',', + '<', + '.', + '>', + ]; + + const identifiersRegExp = new RegExp( + `[^a-zA-Z0-9${escapedSymbols.join('\\')}\\-_\u00A0-\uFFFF]`, + 'g' + ); + + return value + .replace(identifiersRegExp, '-') + .replace(/^((-?[0-9])|--)/, '_$1'); +} + export { getImportPrefix, getLocalIdent, diff --git a/test/__snapshots__/localIdentName-option.test.js.snap b/test/__snapshots__/localIdentName-option.test.js.snap index 7cf64779..088594af 100644 --- a/test/__snapshots__/localIdentName-option.test.js.snap +++ b/test/__snapshots__/localIdentName-option.test.js.snap @@ -39,6 +39,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -86,6 +91,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -133,6 +143,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -180,6 +195,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -227,6 +247,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -274,6 +299,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -321,6 +351,11 @@ Array [ :local(.m_x_\\\\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\\\\&W\\\\?) { + margin-left: auto !important; + margin-right: auto !important; }", "", ], @@ -329,11 +364,75 @@ Array [ exports[`localIdentName option should use hash prefix: warnings 1`] = `Array []`; +exports[`localIdentName option should сorrectly replace escaped symbols in selector: errors 1`] = `Array []`; + +exports[`localIdentName option should сorrectly replace escaped symbols in selector: locals 1`] = ` +Object { + "-a0-34a___f": "-a0-34a___f--2nJ5", + "B&W?": "B&W?--1s8i", + "_test": "_test--23te", + "className": "className--1E8H", + "m_x_@": "m_x_@--2G3b", + "someId": "someId--3w7J", + "subClass": "subClass--3lo0", + "test": "test--NW9Y", +} +`; + +exports[`localIdentName option should сorrectly replace escaped symbols in selector: module (evaluated) 1`] = ` +Array [ + Array [ + 1, + ".test--NW9Y { + background: red; +} + +._test--23te { + background: blue; +} + +.className--1E8H { + background: red; +} + +#someId--3w7J { + background: green; +} + +.className--1E8H .subClass--3lo0 { + color: green; +} + +#someId--3w7J .subClass--3lo0 { + color: blue; +} + +.-a0-34a___f--2nJ5 { + color: red; +} + +.m_x_\\\\@--2G3b { + margin-left: auto !important; + margin-right: auto !important; +} + +.B\\\\&W\\\\?--1s8i { + margin-left: auto !important; + margin-right: auto !important; +}", + "", + ], +] +`; + +exports[`localIdentName option should сorrectly replace escaped symbols in selector: warnings 1`] = `Array []`; + exports[`localIdentName option should сorrectly replace symbol @ in selector: errors 1`] = `Array []`; exports[`localIdentName option should сorrectly replace symbol @ in selector: locals 1`] = ` Object { "-a0-34a___f": "-a0-34a___f--2nJ5", + "B&W?": "B&W?--1s8i", "_test": "_test--23te", "className": "className--1E8H", "m_x_@": "m_x_@--2G3b", @@ -375,7 +474,12 @@ Array [ color: red; } -.m_x_@--2G3b { +.m_x_\\\\@--2G3b { + margin-left: auto !important; + margin-right: auto !important; +} + +.B\\\\&W\\\\?--1s8i { margin-left: auto !important; margin-right: auto !important; }", diff --git a/test/fixtures/modules/localIdentName.css b/test/fixtures/modules/localIdentName.css index 154468a9..6d8e221e 100644 --- a/test/fixtures/modules/localIdentName.css +++ b/test/fixtures/modules/localIdentName.css @@ -29,4 +29,9 @@ :local(.m_x_\@) { margin-left: auto !important; margin-right: auto !important; +} + +:local(.B\&W\?) { + margin-left: auto !important; + margin-right: auto !important; } \ No newline at end of file diff --git a/test/localIdentName-option.test.js b/test/localIdentName-option.test.js index aed12650..7ead50ae 100644 --- a/test/localIdentName-option.test.js +++ b/test/localIdentName-option.test.js @@ -118,7 +118,7 @@ describe('localIdentName option', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it('should сorrectly replace symbol @ in selector', async () => { + it('should сorrectly replace escaped symbols in selector', async () => { const config = { loader: { options: { @@ -134,8 +134,6 @@ describe('localIdentName option', () => { const module = modules.find((m) => m.id === testId); const evaluatedModule = evaluated(module.source, modules); - expect(evaluatedModule.locals['m_x_@']).toContain('m_x_@'); - expect(evaluatedModule).toMatchSnapshot('module (evaluated)'); expect(evaluatedModule.locals).toMatchSnapshot('locals'); expect(stats.compilation.warnings).toMatchSnapshot('warnings'); From 81d9f903ef17c551dfbe677e20c249009a08bd41 Mon Sep 17 00:00:00 2001 From: alreadyExisted Date: Tue, 9 Apr 2019 02:36:32 +0300 Subject: [PATCH 3/5] test: update snap --- .../localIdentName-option.test.js.snap | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/test/__snapshots__/localIdentName-option.test.js.snap b/test/__snapshots__/localIdentName-option.test.js.snap index 088594af..70637578 100644 --- a/test/__snapshots__/localIdentName-option.test.js.snap +++ b/test/__snapshots__/localIdentName-option.test.js.snap @@ -426,66 +426,3 @@ Array [ `; exports[`localIdentName option should сorrectly replace escaped symbols in selector: warnings 1`] = `Array []`; - -exports[`localIdentName option should сorrectly replace symbol @ in selector: errors 1`] = `Array []`; - -exports[`localIdentName option should сorrectly replace symbol @ in selector: locals 1`] = ` -Object { - "-a0-34a___f": "-a0-34a___f--2nJ5", - "B&W?": "B&W?--1s8i", - "_test": "_test--23te", - "className": "className--1E8H", - "m_x_@": "m_x_@--2G3b", - "someId": "someId--3w7J", - "subClass": "subClass--3lo0", - "test": "test--NW9Y", -} -`; - -exports[`localIdentName option should сorrectly replace symbol @ in selector: module (evaluated) 1`] = ` -Array [ - Array [ - 1, - ".test--NW9Y { - background: red; -} - -._test--23te { - background: blue; -} - -.className--1E8H { - background: red; -} - -#someId--3w7J { - background: green; -} - -.className--1E8H .subClass--3lo0 { - color: green; -} - -#someId--3w7J .subClass--3lo0 { - color: blue; -} - -.-a0-34a___f--2nJ5 { - color: red; -} - -.m_x_\\\\@--2G3b { - margin-left: auto !important; - margin-right: auto !important; -} - -.B\\\\&W\\\\?--1s8i { - margin-left: auto !important; - margin-right: auto !important; -}", - "", - ], -] -`; - -exports[`localIdentName option should сorrectly replace symbol @ in selector: warnings 1`] = `Array []`; From 7ff45c2498041cf54197c90768c42a3650b9a956 Mon Sep 17 00:00:00 2001 From: "v.polyanskiy" Date: Tue, 9 Apr 2019 13:42:51 +0300 Subject: [PATCH 4/5] style: fix eol-last in css --- test/fixtures/modules/localIdentName.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/modules/localIdentName.css b/test/fixtures/modules/localIdentName.css index 6d8e221e..282de45d 100644 --- a/test/fixtures/modules/localIdentName.css +++ b/test/fixtures/modules/localIdentName.css @@ -34,4 +34,4 @@ :local(.B\&W\?) { margin-left: auto !important; margin-right: auto !important; -} \ No newline at end of file +} From 925af44085c51fa3d437bee118ce08e234fd0634 Mon Sep 17 00:00:00 2001 From: "v.polyanskiy" Date: Tue, 9 Apr 2019 15:09:51 +0300 Subject: [PATCH 5/5] test: update snap --- .../localIdentName-option.test.js.snap | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/test/__snapshots__/localIdentName-option.test.js.snap b/test/__snapshots__/localIdentName-option.test.js.snap index 70637578..12b98210 100644 --- a/test/__snapshots__/localIdentName-option.test.js.snap +++ b/test/__snapshots__/localIdentName-option.test.js.snap @@ -44,7 +44,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -96,7 +97,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -148,7 +150,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -200,7 +203,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -252,7 +256,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -304,7 +309,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -356,7 +362,8 @@ Array [ :local(.B\\\\&W\\\\?) { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ] @@ -419,7 +426,8 @@ Array [ .B\\\\&W\\\\?--1s8i { margin-left: auto !important; margin-right: auto !important; -}", +} +", "", ], ]