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`, () => {