|
@@ -30,16 +30,14 @@ 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 = {};
|
|
|
|
|
- const unmatchedSelectorsCache = [];
|
|
|
|
|
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, matchedElementsCache, unmatchedSelectorsCache);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, styleElement.sheet.cssRules, mediaInfo, styleIndex);
|
|
|
} else {
|
|
} else {
|
|
|
- getMatchedElementsRules(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex, matchedElementsCache, unmatchedSelectorsCache);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, styleElement.sheet.cssRules, this.mediaAllInfo, styleIndex);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -62,12 +60,12 @@ this.RulesMatcher = this.RulesMatcher || (() => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex, matchedElementsCache, unmatchedSelectorsCache) {
|
|
|
|
|
|
|
+ function getMatchedElementsRules(doc, cssRules, mediaInfo, sheetIndex) {
|
|
|
Array.from(cssRules).forEach((cssRule, ruleIndex) => {
|
|
Array.from(cssRules).forEach((cssRule, ruleIndex) => {
|
|
|
if (cssRule.type == CSSRule.MEDIA_RULE) {
|
|
if (cssRule.type == CSSRule.MEDIA_RULE) {
|
|
|
const ruleMediaInfo = createMediaInfo(cssRule.media);
|
|
const ruleMediaInfo = createMediaInfo(cssRule.media);
|
|
|
mediaInfo.medias.set(cssRule.media, ruleMediaInfo);
|
|
mediaInfo.medias.set(cssRule.media, ruleMediaInfo);
|
|
|
- getMatchedElementsRules(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex, matchedElementsCache, unmatchedSelectorsCache);
|
|
|
|
|
|
|
+ getMatchedElementsRules(doc, cssRule.cssRules, ruleMediaInfo, sheetIndex);
|
|
|
} else if (cssRule.type == CSSRule.STYLE_RULE) {
|
|
} else if (cssRule.type == CSSRule.STYLE_RULE) {
|
|
|
if (cssRule.selectorText) {
|
|
if (cssRule.selectorText) {
|
|
|
let selectors;
|
|
let selectors;
|
|
@@ -78,30 +76,15 @@ 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, matchedElementsCache, unmatchedSelectorsCache));
|
|
|
|
|
|
|
+ selectors.forEach((selector, selectorIndex) => getMatchedElementsSelector(doc, cssRule, selector, selectorsText[selectorIndex], selectorsText, mediaInfo, ruleIndex, sheetIndex));
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function getMatchedElementsSelector(doc, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex, matchedElementsCache, unmatchedSelectorsCache) {
|
|
|
|
|
- let matchedElements = matchedElementsCache[selectorText];
|
|
|
|
|
- if (!matchedElements) {
|
|
|
|
|
- let selectorIndex = 0, selectorsLength = unmatchedSelectorsCache.length, unmatchedSelector;
|
|
|
|
|
- while (selectorIndex < selectorsLength && !(unmatchedSelector = selectorText.startsWith(unmatchedSelectorsCache[selectorIndex]))) {
|
|
|
|
|
- selectorIndex++;
|
|
|
|
|
- }
|
|
|
|
|
- if (selectorIndex < selectorsLength && unmatchedSelector) {
|
|
|
|
|
- matchedElements = [];
|
|
|
|
|
- } else {
|
|
|
|
|
- matchedElements = doc.querySelectorAll(selectorText);
|
|
|
|
|
- if (!matchedElements.length) {
|
|
|
|
|
- unmatchedSelectorsCache.push(selectorText + " ");
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- matchedElementsCache[selectorText] = matchedElements;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ function getMatchedElementsSelector(doc, cssRule, selector, selectorText, selectorsText, mediaInfo, ruleIndex, sheetIndex) {
|
|
|
|
|
+ const matchedElements = doc.querySelectorAll(selectorText);
|
|
|
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));
|
|
|
}
|
|
}
|