From f461320ec05a534021afbe20de0fe097d1016871 Mon Sep 17 00:00:00 2001 From: Christian Kaisermann Date: Tue, 30 Jun 2020 10:10:57 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20prevent=20globalify=20to?= =?UTF-8?q?=20wrongly=20split=20escaped=20selectors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: 🧨 Uses Lookbehind assertions, so Node 9.11.2+ is needed ✅ Closes: Closes #191 --- src/modules/globalifySelector.ts | 15 +++++++++++---- test/modules.test.ts | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/modules/globalifySelector.ts b/src/modules/globalifySelector.ts index cdd54188..ef54ed95 100644 --- a/src/modules/globalifySelector.ts +++ b/src/modules/globalifySelector.ts @@ -1,9 +1,14 @@ -const combinatorPattern = /(\s*[ >+~,]\s*)(?![^[]+\])/g; +/* + * Split a selector string (ex: div > foo ~ .potato) by + * separators: space, >, +, ~ and comma (maybe not needed) + * We use a negative lookbehind assertion to prevent matching + * escaped combinators like `\~`. + */ +const combinatorPattern = /(?+~,]\s*)(?![^[]+\])/g; export function globalifySelector(selector: string) { - return selector - .trim() - .split(combinatorPattern) + const parts = selector.trim().split(combinatorPattern); + const modifiedSelector = parts .map((selectorPart: string, index: number) => { // if this is the separator if (index % 2 !== 0) { @@ -25,4 +30,6 @@ export function globalifySelector(selector: string) { return `:global(${selectorPart})`; }) .join(''); + + return modifiedSelector; } diff --git a/test/modules.test.ts b/test/modules.test.ts index c7bdbf13..a15b0ef5 100644 --- a/test/modules.test.ts +++ b/test/modules.test.ts @@ -71,6 +71,14 @@ describe('globalifySelector', () => { ); expect(globalifySelector(selector2)).toEqual(':global(div), :global(span)'); }); + + it('correctly treats selectors with escaped combinator characters', async () => { + const selector1 = '.\\~positive.\\!normal ~ .\\+foo'; + + expect(globalifySelector(selector1)).toEqual( + ':global(.\\~positive.\\!normal) ~ :global(.\\+foo)', + ); + }); }); describe(`parse svelte file`, () => {