|
|
@@ -18,11 +18,10 @@
|
|
|
* along with SingleFile. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
-/* global CSSRule, cssWhat, parseCss, RulesMatcher */
|
|
|
+/* global CSSRule, parseCss, RulesMatcher */
|
|
|
|
|
|
this.cssMinifier = this.cssMinifier || (() => {
|
|
|
|
|
|
- const SEPARATOR_TYPES = ["descendant", "child", "sibling", "adjacent"];
|
|
|
const REMOVED_PSEUDO_CLASSES = ["focus", "focus-within", "hover", "link", "visited", "active"];
|
|
|
const REMOVED_PSEUDO_ELEMENTS = ["after", "before", "first-line", "first-letter", "placeholder", "-webkit-input-placeholder", "selection", "marker", "cue", "-webkit-progress-bar", "-webkit-progress-value", "-webkit-inner-spin-button", "-webkit-outer-spin-button", "-webkit-search-cancel-button", "-webkit-search-cancel-button"];
|
|
|
const IGNORED_SELECTORS = ["::-webkit-scrollbar", "::-webkit-scrollbar-button", "::-webkit-scrollbar-thumb", "::-webkit-scrollbar-track", "::-webkit-scrollbar-track-piece", "::-webkit-scrollbar-corner", "::-webkit-resizer"];
|
|
|
@@ -66,10 +65,10 @@ this.cssMinifier = this.cssMinifier || (() => {
|
|
|
unusedStyles.forEach(style => cssRule.style.removeProperty(style.name));
|
|
|
}
|
|
|
if (ruleInfo.matchedSelectors.size < ruleInfo.selectorsText.length) {
|
|
|
- cssRule.selectorText = ruleInfo.selectorsText.filter(selector => ruleInfo.matchedSelectors.has(selector) || (testFilterSelector(selector) && doc.querySelector(getFilteredSelector(selector)))).join(",");
|
|
|
+ cssRule.selectorText = ruleInfo.selectorsText.filter(selectorText => ruleInfo.matchedSelectors.has(selectorText) || testIgnoredSelector(selectorText)).join(",");
|
|
|
}
|
|
|
} else {
|
|
|
- if (!IGNORED_SELECTORS.find(selector => cssRule.selectorText.toLowerCase().includes(selector)) && !testFilterSelector(cssRule.selectorText)) {
|
|
|
+ if (!testIgnoredSelector(cssRule.selectorText)) {
|
|
|
const parent = cssRule.parentRule || cssRule.parentStyleSheet;
|
|
|
let indexRule = 0;
|
|
|
while (cssRule != parent.cssRules[indexRule] && indexRule < parent.cssRules.length) {
|
|
|
@@ -85,6 +84,10 @@ this.cssMinifier = this.cssMinifier || (() => {
|
|
|
stats.discarded -= cssRules.length;
|
|
|
}
|
|
|
|
|
|
+ function testIgnoredSelector(selectorText) {
|
|
|
+ return IGNORED_SELECTORS.find(selector => selectorText.toLowerCase().includes(selector)) || testFilterSelector(selectorText);
|
|
|
+ }
|
|
|
+
|
|
|
function processStyle(doc, cssStyle, mediaInfo) {
|
|
|
const styleInfo = mediaInfo.styles.get(cssStyle);
|
|
|
if (styleInfo) {
|
|
|
@@ -114,35 +117,4 @@ this.cssMinifier = this.cssMinifier || (() => {
|
|
|
return REMOVED_PSEUDO_CLASSES.find(pseudoClass => selector.includes(":" + pseudoClass)) || REMOVED_PSEUDO_ELEMENTS.find(pseudoElement => selector.includes("::" + pseudoElement));
|
|
|
}
|
|
|
|
|
|
- function getFilteredSelector(selector) {
|
|
|
- const selectors = cssWhat.parse(selector);
|
|
|
- return cssWhat.stringify(selectors.map(selector => filterPseudoClasses(selector)));
|
|
|
-
|
|
|
- function filterPseudoClasses(selector) {
|
|
|
- const tokens = selector.filter(token => {
|
|
|
- if (token.data) {
|
|
|
- if (Array.isArray(token.data)) {
|
|
|
- token.data = token.data.map(selector => filterPseudoClasses(selector));
|
|
|
- }
|
|
|
- }
|
|
|
- const test = ((token.type != "pseudo" || !REMOVED_PSEUDO_CLASSES.includes(token.name))
|
|
|
- && (token.type != "pseudo-element" || !REMOVED_PSEUDO_ELEMENTS.includes(token.name)));
|
|
|
- return test;
|
|
|
- });
|
|
|
- let insertedTokens = 0;
|
|
|
- tokens.forEach((token, index) => {
|
|
|
- if (SEPARATOR_TYPES.includes(token.type)) {
|
|
|
- if (!tokens[index - 1] || SEPARATOR_TYPES.includes(tokens[index - 1].type)) {
|
|
|
- tokens.splice(index + insertedTokens, 0, { type: "universal" });
|
|
|
- insertedTokens++;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- if (!tokens.length || SEPARATOR_TYPES.includes(tokens[tokens.length - 1].type)) {
|
|
|
- tokens.push({ type: "universal" });
|
|
|
- }
|
|
|
- return tokens;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
})();
|