Use css parser to add hover class name to selectors.
Previously we use a regexp to match all the CSS selectors and add our hover class name to it, which has been proved not solid and may be very slow in some situation. Using a production ready css parser can handle this better and also provide ability's to do more accurate things to the recorded stylesheets.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { parse } from './css';
|
||||
import {
|
||||
serializedNodeWithId,
|
||||
NodeType,
|
||||
@@ -55,20 +56,23 @@ function getTagName(n: elementNode): string {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
const CSS_SELECTOR = /([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g;
|
||||
const HOVER_SELECTOR = /([^\\]):hover/g;
|
||||
export function addHoverClass(cssText: string): string {
|
||||
return cssText.replace(CSS_SELECTOR, (match, p1: string, p2: string) => {
|
||||
if (HOVER_SELECTOR.test(p1)) {
|
||||
const newSelector = p1.replace(HOVER_SELECTOR, '$1.\\:hover');
|
||||
return `${p1.replace(/\s*$/, '')}, ${newSelector.replace(
|
||||
/^\s*/,
|
||||
'',
|
||||
)}${p2}`;
|
||||
} else {
|
||||
return match;
|
||||
const ast = parse(cssText);
|
||||
if (!ast.stylesheet) {
|
||||
return cssText;
|
||||
}
|
||||
ast.stylesheet.rules.forEach(rule => {
|
||||
if ('selectors' in rule) {
|
||||
(rule.selectors || []).forEach((selector: string) => {
|
||||
if (HOVER_SELECTOR.test(selector)) {
|
||||
const newSelector = selector.replace(HOVER_SELECTOR, '$1.\\:hover');
|
||||
cssText = cssText.replace(selector, `${selector}, ${newSelector}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return cssText;
|
||||
}
|
||||
|
||||
function buildNode(n: serializedNodeWithId, doc: Document): Node | null {
|
||||
|
||||
Reference in New Issue
Block a user