Quellcode durchsuchen

handle FontFace used in a inline script

Former-commit-id: b2fcd4ca57e6d33aa96b217d569e43b93924cf81
Gildas vor 6 Jahren
Ursprung
Commit
6b021bf679
1 geänderte Dateien mit 54 neuen und 0 gelöschten Zeilen
  1. 54 0
      lib/single-file/processors/hooks/content/content-hooks-frames.js

+ 54 - 0
lib/single-file/processors/hooks/content/content-hooks-frames.js

@@ -41,6 +41,8 @@ this.singlefile.lib.processors.hooks.content.frames = this.singlefile.lib.proces
 	const CustomEvent = window.CustomEvent;
 	const document = window.document;
 	const HTMLDocument = window.HTMLDocument;
+	const FileReader = window.FileReader;
+	const Blob = window.Blob;
 
 	const fontFaces = [];
 
@@ -54,6 +56,9 @@ this.singlefile.lib.processors.hooks.content.frames = this.singlefile.lib.proces
 		}
 		(document.documentElement || document).appendChild(scriptElement);
 		scriptElement.remove();
+		scriptElement = document.createElement("script");
+		scriptElement.textContent = "(" + injectedScript.toString() + ")()";
+		(document.documentElement || document).appendChild(scriptElement);
 		addEventListener.call(window, NEW_FONT_FACE_EVENT, event => fontFaces.push(event.detail));
 	}
 
@@ -81,4 +86,53 @@ this.singlefile.lib.processors.hooks.content.frames = this.singlefile.lib.proces
 		IMAGE_LOADED_EVENT
 	};
 
+	function injectedScript() {
+		const console = window.console;
+		const warn = (console && console.warn) || (() => { });
+		const NEW_FONT_FACE_EVENT = "single-file-new-font-face";
+		const FONT_STYLE_PROPERTIES = {
+			family: "font-family",
+			style: "font-style",
+			weight: "font-weight",
+			stretch: "font-stretch",
+			unicodeRange: "unicode-range",
+			variant: "font-variant",
+			featureSettings: "font-feature-settings"
+		};
+
+		if (window.FontFace) {
+			const FontFace = window.FontFace;
+			let warningFontFaceDisplayed;
+			window.FontFace = function () {
+				if (!warningFontFaceDisplayed) {
+					warn.call(console, "SingleFile is hooking the FontFace constructor to get font URLs."); // eslint-disable-line no-console
+					warningFontFaceDisplayed = true;
+				}
+				const detail = {};
+				detail["font-family"] = arguments[0];
+				detail.src = arguments[1];
+				const descriptors = arguments[2];
+				if (descriptors) {
+					Object.keys(descriptors).forEach(descriptor => {
+						if (FONT_STYLE_PROPERTIES[descriptor]) {
+							detail[FONT_STYLE_PROPERTIES[descriptor]] = descriptors[descriptor];
+						}
+					});
+				}
+				if (detail.src instanceof ArrayBuffer) {
+					const reader = new FileReader();
+					reader.readAsDataURL(new Blob([detail.src]));
+					reader.addEventListener("load", () => {
+						detail.src = "url(" + reader.result + ")";
+						dispatchEvent.call(window, new CustomEvent(NEW_FONT_FACE_EVENT, { detail }));
+					});
+				} else {
+					dispatchEvent.call(window, new CustomEvent(NEW_FONT_FACE_EVENT, { detail }));
+				}
+				return new FontFace(...arguments);
+			};
+			window.FontFace.toString = function () { return "function FontFace() { [native code] }"; };
+		}
+	}
+
 })();