|
|
@@ -358,16 +358,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
removeUnusedCSSRules() {
|
|
|
- const doc = this.doc;
|
|
|
- const rulesCache = {};
|
|
|
- doc.querySelectorAll("style").forEach(style => {
|
|
|
- const cssRules = [];
|
|
|
- if (style.sheet) {
|
|
|
- DomProcessorHelper.processRules(this.doc, style.sheet.cssRules, cssRules, rulesCache);
|
|
|
- const stylesheetContent = cssRules.join("");
|
|
|
- style.textContent = this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
- }
|
|
|
- });
|
|
|
+ this.dom.rulesMinifier(this.doc);
|
|
|
}
|
|
|
|
|
|
removeHiddenElements() {
|
|
|
@@ -438,7 +429,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
async inlineStylesheets(initialization) {
|
|
|
await Promise.all(Array.from(this.doc.querySelectorAll("style")).map(async styleElement => {
|
|
|
const stylesheetContent = initialization ? await DomProcessorHelper.resolveImportURLs(styleElement.textContent, this.baseURI, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled }) : await DomProcessorHelper.processStylesheet(styleElement.textContent, this.baseURI);
|
|
|
- styleElement.textContent = this.options.compressCSS && !this.options.removeUnusedCSSRules ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
+ styleElement.textContent = !initialization && this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
@@ -529,7 +520,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
await Promise.all(Array.from(this.doc.querySelectorAll("link[rel*=stylesheet]")).map(async linkElement => {
|
|
|
const stylesheetContent = await DomProcessorHelper.resolveLinkStylesheetURLs(linkElement.href, this.baseURI, linkElement.media, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
|
|
|
const styleElement = this.doc.createElement("style");
|
|
|
- styleElement.textContent = this.options.compressCSS && !this.options.removeUnusedCSSRules ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
+ styleElement.textContent = stylesheetContent;
|
|
|
linkElement.parentElement.replaceChild(styleElement, linkElement);
|
|
|
}));
|
|
|
}
|
|
|
@@ -679,31 +670,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- static processRules(doc, rules, cssRules, cache) {
|
|
|
- if (rules) {
|
|
|
- Array.from(rules).forEach(rule => {
|
|
|
- if (rule.media) {
|
|
|
- cssRules.push("@media " + Array.prototype.join.call(rule.media, ",") + " {");
|
|
|
- DomProcessorHelper.processRules(doc, rule.cssRules, cssRules, cache);
|
|
|
- cssRules.push("}");
|
|
|
- } else if (rule.selectorText) {
|
|
|
- const selector = DomUtil.getFilteredSelector(rule.selectorText);
|
|
|
- if (selector) {
|
|
|
- try {
|
|
|
- if (cache[selector] || doc.querySelector(selector)) {
|
|
|
- cssRules.push(rule.cssText);
|
|
|
- cache[selector] = true;
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- cssRules.push(rule.cssText);
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- cssRules.push(rule.cssText);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
// -------
|
|
|
@@ -723,7 +689,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const REGEXP_IMPORT_SIMPLE_QUOTES_FN = /@import\s*'([^']*)'\s*([^;]*)/i;
|
|
|
const REGEXP_IMPORT_DOUBLE_QUOTES_FN = /@import\s*"([^"]*)"\s*([^;]*)/i;
|
|
|
const REGEXP_IMPORT_NO_QUOTES_FN = /@import\s*([^;]*)\s*([^;]*)/i;
|
|
|
- const REGEXP_PSEUDO_CLASSES = /::after|::before|::first-line|::first-letter|:focus|:focus-within|:hover|:link|:visited|:active/gi;
|
|
|
|
|
|
class DomUtil {
|
|
|
static normalizeURL(url) {
|
|
|
@@ -792,26 +757,6 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- static getFilteredSelector(selector) {
|
|
|
- if (selector.match(REGEXP_PSEUDO_CLASSES)) {
|
|
|
- let selectors = selector.split(/\s*,\s*/g);
|
|
|
- selector = selectors.map(selector => {
|
|
|
- const simpleSelectors = selector.split(/\s*[ >~+]\s*/g);
|
|
|
- const separators = selector.match(/\s*[ >~+]\s*/g);
|
|
|
- return simpleSelectors.map((selector, selectorIndex) => {
|
|
|
- while (selector.match(REGEXP_PSEUDO_CLASSES)) {
|
|
|
- selector = selector.replace(REGEXP_PSEUDO_CLASSES, "").trim();
|
|
|
- }
|
|
|
- selector = selector.replace(/:?:[^(]+\(\)/g, "");
|
|
|
- if (selector == "") {
|
|
|
- selector = "*";
|
|
|
- }
|
|
|
- return selector + (separators && separators[selectorIndex] ? separators[selectorIndex] : "");
|
|
|
- }).join("");
|
|
|
- }).join(",");
|
|
|
- }
|
|
|
- return selector;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
return { getClass };
|