diff --git a/src/utils.js b/src/utils.js index dd0eaa8..2eeed97 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 () => {