1
0
Эх сурвалжийг харах

cache the results of font tests

Gildas 5 жил өмнө
parent
commit
27c6a565ba

+ 37 - 32
lib/single-file/modules/css-fonts-alt-minifier.js

@@ -58,7 +58,7 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 	const FONT_MAX_LOAD_DELAY = 5000;
 
 	return {
-		process: async (doc, stylesheets, fontURLs) => {
+		process: async (doc, stylesheets, fontURLs, fontTests) => {
 			const fontsDetails = {
 				fonts: new Map(),
 				medias: new Map(),
@@ -87,9 +87,9 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 				const media = stylesheetInfo.mediaText;
 				if (cssRules) {
 					if (media && media != MEDIA_ALL) {
-						await processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fontURLs, stats);
+						await processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fontURLs, fontTests, stats);
 					} else {
-						await processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontURLs, stats);
+						await processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontURLs, fontTests, stats);
 					}
 					stats.rules.discarded -= cssRules.getSize();
 				}
@@ -168,7 +168,7 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 		fontsDetails.supports.forEach(supportsFontsDetails => processFontDetails(supportsFontsDetails));
 	}
 
-	async function processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontURLs, stats) {
+	async function processFontFaceRules(cssRules, sheetIndex, fontsDetails, fontURLs, fontTests, stats) {
 		const cssTree = singlefile.lib.vendor.cssTree;
 		const removedRules = [];
 		let mediaIndex = 0, supportsIndex = 0;
@@ -176,17 +176,17 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 			const ruleData = cssRule.data;
 			if (ruleData.type == "Atrule" && ruleData.name == "media" && ruleData.block && ruleData.block.children && ruleData.prelude) {
 				const mediaText = cssTree.generate(ruleData.prelude);
-				await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText), fontURLs, stats);
+				await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + mediaIndex + "-" + mediaText), fontURLs, fontTests, stats);
 				mediaIndex++;
 			} else if (ruleData.type == "Atrule" && ruleData.name == "supports" && ruleData.block && ruleData.block.children && ruleData.prelude) {
 				const supportsText = cssTree.generate(ruleData.prelude);
-				await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.supports.get("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText), fontURLs, stats);
+				await processFontFaceRules(ruleData.block.children, sheetIndex, fontsDetails.supports.get("supports-" + sheetIndex + "-" + supportsIndex + "-" + supportsText), fontURLs, fontTests, stats);
 				supportsIndex++;
 			} else if (ruleData.type == "Atrule" && ruleData.name == "font-face") {
 				const key = getFontKey(ruleData);
 				const fontInfo = fontsDetails.fonts.get(key);
 				if (fontInfo) {
-					const processed = await processFontFaceRule(ruleData, fontInfo, fontURLs, stats);
+					const processed = await processFontFaceRule(ruleData, fontInfo, fontURLs, fontTests, stats);
 					if (processed) {
 						fontsDetails.fonts.delete(key);
 					}
@@ -198,7 +198,7 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 		removedRules.forEach(cssRule => cssRules.remove(cssRule));
 	}
 
-	async function processFontFaceRule(ruleData, fontInfo, fontURLs, stats) {
+	async function processFontFaceRule(ruleData, fontInfo, fontURLs, fontTests, stats) {
 		const cssTree = singlefile.lib.vendor.cssTree;
 
 		const removedNodes = [];
@@ -212,34 +212,39 @@ this.singlefile.lib.modules.fontsAltMinifier = this.singlefile.lib.modules.fonts
 		const srcDeclaration = ruleData.block.children.filter(node => node.property == "src").tail;
 		if (srcDeclaration) {
 			await Promise.all(fontInfo.map(async (source, sourceIndex) => {
-				if (FontFace) {
-					const fontFace = new FontFace("test-font", source.src);
-					try {
-						await fontFace.load();
-						await fontFace.loaded;
-						source.valid = true;
-					} catch (error) {
-						const declarationFontURLs = fontURLs.get(srcDeclaration.data);
-						if (declarationFontURLs) {
-							const fontURL = declarationFontURLs[declarationFontURLs.length - sourceIndex - 1];
-							if (fontURL) {
-								const fontFace = new FontFace("test-font", "url(" + fontURL + ")");
-								try {
-									await Promise.race(
-										[
-											fontFace.load().then(() => fontFace.loaded).then(() => source.valid = true),
-											new Promise(resolve => setTimeout.call(window, () => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY))
-										]);
-								} catch (error) {
-									// ignored
+				if (fontTests.has(source.src)) {
+					source.valid = fontTests.get(source.src);
+				} else {
+					if (FontFace) {
+						const fontFace = new FontFace("test-font", source.src);
+						try {
+							await fontFace.load();
+							await fontFace.loaded;
+							source.valid = true;
+						} catch (error) {
+							const declarationFontURLs = fontURLs.get(srcDeclaration.data);
+							if (declarationFontURLs) {
+								const fontURL = declarationFontURLs[declarationFontURLs.length - sourceIndex - 1];
+								if (fontURL) {
+									const fontFace = new FontFace("test-font", "url(" + fontURL + ")");
+									try {
+										await Promise.race(
+											[
+												fontFace.load().then(() => fontFace.loaded).then(() => source.valid = true),
+												new Promise(resolve => setTimeout.call(window, () => { source.valid = true; resolve(); }, FONT_MAX_LOAD_DELAY))
+											]);
+									} catch (error) {
+										// ignored
+									}
 								}
+							} else {
+								source.valid = true;
 							}
-						} else {
-							source.valid = true;
 						}
+					} else {
+						source.valid = true;
 					}
-				} else {
-					source.valid = true;
+					fontTests.set(source.src, source.valid);
 				}
 			}));
 			const findSource = (fontFormat, testValidity) => fontInfo.find(source => !source.src.match(EMPTY_URL_SOURCE) && source.format == fontFormat && (!testValidity || source.valid));

+ 3 - 1
lib/single-file/single-file-core.js

@@ -161,6 +161,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 			this.options.baseURI = rootDocDefined && this.options.doc.baseURI;
 			this.options.rootDocument = root;
 			this.options.updatedResources = this.options.updatedResources || {};
+			this.options.fontTests = new Map();
 			this.batchRequest = new BatchRequest();
 			this.processor = new Processor(options, this.batchRequest);
 			if (rootDocDefined) {
@@ -404,6 +405,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 			this.stylesheets = new Map();
 			this.styles = new Map();
 			this.cssVariables = new Map();
+			this.fontTests = options.fontTests;
 		}
 
 		initialize() {
@@ -1224,7 +1226,7 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 		}
 
 		async removeAlternativeFonts() {
-			await util.removeAlternativeFonts(this.doc, this.stylesheets, this.options.fontURLs);
+			await util.removeAlternativeFonts(this.doc, this.stylesheets, this.options.fontURLs, this.options.fontTests);
 		}
 
 		async processFrames() {

+ 2 - 2
lib/single-file/single-file-util.js

@@ -153,8 +153,8 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
 				removeUnusedFonts(doc, stylesheets, styles, options) {
 					return modules.fontsMinifier.process(doc, stylesheets, styles, options);
 				},
-				removeAlternativeFonts(doc, stylesheets, fontURLs) {
-					return modules.fontsAltMinifier.process(doc, stylesheets, fontURLs);
+				removeAlternativeFonts(doc, stylesheets, fontURLs, fontTests) {
+					return modules.fontsAltMinifier.process(doc, stylesheets, fontURLs, fontTests);
 				},
 				getMediaAllInfo(doc, stylesheets, styles) {
 					return modules.matchedRules.getMediaAllInfo(doc, stylesheets, styles);