Przeglądaj źródła

remove unused fonts

Gildas 7 lat temu
rodzic
commit
a008aecbec
1 zmienionych plików z 45 dodań i 3 usunięć
  1. 45 3
      lib/single-file/rules-minifier.js

+ 45 - 3
lib/single-file/rules-minifier.js

@@ -18,13 +18,21 @@
  *   along with SingleFile.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/* global CSSRule */
+
 this.rulesMinifier = this.rulesMinifier || (() => {
 
 	const REGEXP_PSEUDO_CLASSES = /::after|::before|::first-line|::first-letter|:focus|:focus-within|:hover|:link|:visited|:active/gi;
 
 	return {
 		process: doc => {
-			const rulesCache = {};
+			const rulesCache = {
+				selectors: {},
+				fonts: {
+					declared: {},
+					used: {}
+				}
+			};
 			const stats = {
 				processed: 0,
 				discarded: 0
@@ -37,6 +45,14 @@ this.rulesMinifier = this.rulesMinifier || (() => {
 					stats.discarded += processed - style.sheet.cssRules.length;
 				}
 			});
+			const unusedFonts = Object.keys(rulesCache.fonts.declared).filter(fontFamily => !Object.keys(rulesCache.fonts.used).includes(fontFamily));
+			doc.querySelectorAll("style").forEach(style => {
+				if (style.sheet) {
+					const processed = style.sheet.cssRules.length;
+					style.textContent = deleteUnusedFonts(doc, style.sheet.cssRules, unusedFonts);
+					stats.discarded += processed - style.sheet.cssRules.length;
+				}
+			});
 			return stats;
 		}
 	};
@@ -53,14 +69,40 @@ this.rulesMinifier = this.rulesMinifier || (() => {
 					const selector = getFilteredSelector(rule.selectorText);
 					if (selector) {
 						try {
-							if (cache[selector] || doc.querySelector(selector)) {
+							if (cache.selectors[selector] || doc.querySelector(selector)) {
 								stylesheetContent += rule.cssText;
-								cache[selector] = true;
+								cache.selectors[selector] = true;
+								if (rule.style.fontFamily) {
+									rule.style.fontFamily.split(",").forEach(fontFamily => cache.fonts.used[fontFamily.trim()] = true);
+								}
 							}
 						} catch (error) {
 							stylesheetContent += rule.cssText;
 						}
 					}
+				} else {
+					if (rule.type == CSSRule.FONT_FACE_RULE) {
+						cache.fonts.declared[rule.style.fontFamily.trim()] = true;
+					}
+					stylesheetContent += rule.cssText;
+				}
+			});
+		}
+		return stylesheetContent;
+	}
+
+	function deleteUnusedFonts(doc, rules, unusedFonts) {
+		let stylesheetContent = "";
+		if (rules) {
+			Array.from(rules).forEach(rule => {
+				if (rule.media) {
+					stylesheetContent += "@media " + Array.prototype.join.call(rule.media, ",") + " {";
+					stylesheetContent += deleteUnusedFonts(doc, rule.cssRules, unusedFonts);
+					stylesheetContent += "}";
+				} else if (rule.selectorText) {
+					stylesheetContent += rule.cssText;
+				} else if (rule.type == CSSRule.FONT_FACE_RULE && !unusedFonts.includes(rule.style.fontFamily.trim())) {
+					stylesheetContent += rule.cssText;
 				} else {
 					stylesheetContent += rule.cssText;
 				}