|
@@ -39,14 +39,15 @@ this.RulesMatcher = this.RulesMatcher || (() => {
|
|
|
constructor(doc) {
|
|
constructor(doc) {
|
|
|
this.doc = doc;
|
|
this.doc = doc;
|
|
|
this.mediaAllInfo = createMediaInfo(MEDIA_ALL);
|
|
this.mediaAllInfo = createMediaInfo(MEDIA_ALL);
|
|
|
|
|
+ const matchedElementsCache = new Map();
|
|
|
doc.querySelectorAll("style").forEach((styleElement, styleIndex) => {
|
|
doc.querySelectorAll("style").forEach((styleElement, styleIndex) => {
|
|
|
if (styleElement.sheet) {
|
|
if (styleElement.sheet) {
|
|
|
if (styleElement.media && styleElement.media != MEDIA_ALL) {
|
|
if (styleElement.media && styleElement.media != MEDIA_ALL) {
|
|
|
const mediaInfo = createMediaInfo(styleElement.media);
|
|
const mediaInfo = createMediaInfo(styleElement.media);
|
|
|
this.mediaAllInfo.medias.set(styleIndex + "-" + styleElement.media, mediaInfo);
|
|
this.mediaAllInfo.medias.set(styleIndex + "-" + styleElement.media, mediaInfo);
|
|
|
- getMatchedElementsRules(doc, styleElement.sheet.cssRules, mediaInfo, styleIndex);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, styleElement.sheet.cssRules, mediaInfo, styleIndex, matchedElementsCache);
|
|
|
} else {
|
|
} else {
|
|
|
- getMatchedElementsRules(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex, matchedElementsCache);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -69,14 +70,14 @@ this.RulesMatcher = this.RulesMatcher || (() => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex) {
|
|
|
|
|
|
|
+ function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, matchedElementsCache) {
|
|
|
Array.from(cssRules).forEach((cssRule, ruleIndex) => {
|
|
Array.from(cssRules).forEach((cssRule, ruleIndex) => {
|
|
|
const cssRuleType = cssRule.type;
|
|
const cssRuleType = cssRule.type;
|
|
|
if (cssRuleType == CSSRule.MEDIA_RULE) {
|
|
if (cssRuleType == CSSRule.MEDIA_RULE) {
|
|
|
const cssRuleMedia = cssRule.media;
|
|
const cssRuleMedia = cssRule.media;
|
|
|
const ruleMediaInfo = createMediaInfo(cssRuleMedia);
|
|
const ruleMediaInfo = createMediaInfo(cssRuleMedia);
|
|
|
mediaInfo.medias.set(cssRuleMedia, ruleMediaInfo);
|
|
mediaInfo.medias.set(cssRuleMedia, ruleMediaInfo);
|
|
|
- getMatchedElementsRules(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex, matchedElementsCache);
|
|
|
} else if (cssRuleType == CSSRule.STYLE_RULE) {
|
|
} else if (cssRuleType == CSSRule.STYLE_RULE) {
|
|
|
const selectorText = cssRule.selectorText;
|
|
const selectorText = cssRule.selectorText;
|
|
|
if (selectorText) {
|
|
if (selectorText) {
|
|
@@ -88,15 +89,19 @@ this.RulesMatcher = this.RulesMatcher || (() => {
|
|
|
}
|
|
}
|
|
|
if (selectors) {
|
|
if (selectors) {
|
|
|
const selectorsText = selectors.map(selector => cssWhat.stringify([selector]));
|
|
const selectorsText = selectors.map(selector => cssWhat.stringify([selector]));
|
|
|
- selectors.forEach((selector, selectorIndex) => getMatchedElementsSelector(doc, cssRule, selector, selectorsText[selectorIndex], selectorsText, mediaInfo, ruleIndex, sheetIndex));
|
|
|
|
|
|
|
+ selectors.forEach((selector, selectorIndex) => getMatchedElementsSelector(doc, cssRule, selector, selectorsText[selectorIndex], selectorsText, mediaInfo, ruleIndex, sheetIndex, matchedElementsCache));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function getMatchedElementsSelector(doc, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex) {
|
|
|
|
|
- const matchedElements = doc.querySelectorAll(selectorText);
|
|
|
|
|
|
|
+ function getMatchedElementsSelector(doc, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex, matchedElementsCache) {
|
|
|
|
|
+ const cachedMatchedElements = matchedElementsCache.get(selectorText);
|
|
|
|
|
+ const matchedElements = cachedMatchedElements || doc.querySelectorAll(selectorText);
|
|
|
|
|
+ if (!cachedMatchedElements) {
|
|
|
|
|
+ matchedElementsCache.set(selectorText, matchedElements);
|
|
|
|
|
+ }
|
|
|
if (matchedElements.length) {
|
|
if (matchedElements.length) {
|
|
|
matchedElements.forEach(element => addRule(element, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex));
|
|
matchedElements.forEach(element => addRule(element, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex));
|
|
|
}
|
|
}
|