From a768b60cb9f16e7a4f30bb62f42305da89275c64 Mon Sep 17 00:00:00 2001 From: Kasperi Keski-Loppi Date: Mon, 30 Aug 2021 23:34:59 +0300 Subject: [PATCH] Fixes issue where minimalcss would fail if CSS selectors had escaped colons --- src/utils.js | 12 +++++++++++- tests/utils.test.js | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index dd0eaa8f..2eeed977 100644 --- a/src/utils.js +++ b/src/utils.js @@ -18,17 +18,27 @@ function memoize(fn) { * Reduce a CSS selector to be without any pseudo class parts. * For example, from `a:hover` return `a`. And from `input::-moz-focus-inner` * to `input`. + * * Also, more advanced ones like `a[href^="javascript:"]:after` to * `a[href^="javascript:"]`. + * * The last example works too if the input was `a[href^='javascript:']:after` * instead (using ' instead of "). * + * As per CSS spec [1], special characters can be escaped by using a backslash. + * For a

Title

element, the corresponding CSS selector + * would be .md\:title { font-size: 32px; }. If the negative lookbehind founds the + * escape char, this function returns the selector as is. Special thanks to valtzu + * for helping to solve the issue. + * + * [1]: https://www.w3.org/TR/CSS2/syndata.html + * * @param {string} selector * @return {string} */ const reduceCSSSelector = memoize((selector) => { return selector.split( - /:(?=([^"'\\]*(\\.|["']([^"'\\]*\\.)*[^"'\\]*['"]))*[^"']*$)/g + /(? { expect(f('a[href^="javascript:"]:after')).toEqual('a[href^="javascript:"]'); // Should work with ' instead of " too. expect(f("a[href^='javascript:']:after")).toEqual("a[href^='javascript:']"); + // Should leave the selector as is if escape char is found + expect(f(`.md\\:title`)).toEqual(".md\\:title"); }); test('Test parentSelectors', async () => {