|
|
@@ -19,21 +19,12 @@
|
|
|
*/
|
|
|
|
|
|
/* global
|
|
|
+ DocUtilCore,
|
|
|
crypto,
|
|
|
- cssMinifier,
|
|
|
- cssRulesMinifier,
|
|
|
cssTree,
|
|
|
docHelper,
|
|
|
fetch,
|
|
|
- fontsAltMinifier,
|
|
|
- fontsMinifier,
|
|
|
- htmlMinifier,
|
|
|
- imagesAltMinifier,
|
|
|
- matchedRules,
|
|
|
- mediasMinifier,
|
|
|
- serializer,
|
|
|
setTimeout,
|
|
|
- srcsetParser,
|
|
|
superFetch,
|
|
|
Blob,
|
|
|
DOMParser,
|
|
|
@@ -41,8 +32,7 @@
|
|
|
FontFace
|
|
|
SingleFileCore,
|
|
|
TextDecoder,
|
|
|
- TextEncoder,
|
|
|
- URL */
|
|
|
+ TextEncoder */
|
|
|
|
|
|
this.SingleFileBrowser = this.SingleFileBrowser || (() => {
|
|
|
|
|
|
@@ -51,33 +41,13 @@ this.SingleFileBrowser = this.SingleFileBrowser || (() => {
|
|
|
const PREFIX_CONTENT_TYPE_TEXT = "text/";
|
|
|
const FONT_FACE_TEST_MAX_DELAY = 1000;
|
|
|
|
|
|
- // --------
|
|
|
- // Download
|
|
|
- // --------
|
|
|
let fetchResource;
|
|
|
-
|
|
|
- if (this.serializer === undefined) {
|
|
|
- this.serializer = {
|
|
|
- process(doc) {
|
|
|
- const docType = doc.doctype;
|
|
|
- let docTypeString = "";
|
|
|
- if (docType) {
|
|
|
- docTypeString = "<!DOCTYPE " + docType.nodeName;
|
|
|
- if (docType.publicId) {
|
|
|
- docTypeString += " PUBLIC \"" + docType.publicId + "\"";
|
|
|
- if (docType.systemId)
|
|
|
- docTypeString += " \"" + docType.systemId + "\"";
|
|
|
- } else if (docType.systemId)
|
|
|
- docTypeString += " SYSTEM \"" + docType.systemId + "\"";
|
|
|
- if (docType.internalSubset)
|
|
|
- docTypeString += " [" + docType.internalSubset + "]";
|
|
|
- docTypeString += "> ";
|
|
|
- }
|
|
|
- return docTypeString + doc.documentElement.outerHTML;
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
+ return {
|
|
|
+ getClass: () => {
|
|
|
+ const DocUtil = DocUtilCore.getClass(getContent, parseDocContent, parseSVGContent, isValidFontUrl, getContentSize, digestText);
|
|
|
+ return SingleFileCore.getClass(DocUtil, cssTree);
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
async function getContent(resourceURL, options) {
|
|
|
let resourceContent, startTime;
|
|
|
@@ -182,137 +152,40 @@ this.SingleFileBrowser = this.SingleFileBrowser || (() => {
|
|
|
return hexCodes.join("");
|
|
|
}
|
|
|
|
|
|
- // ---
|
|
|
- // DocUtil
|
|
|
- // ---
|
|
|
- class DocUtil {
|
|
|
- static async getContent(resourceURL, options) {
|
|
|
- return getContent(resourceURL, options);
|
|
|
- }
|
|
|
-
|
|
|
- static parseURL(resourceURL, baseURI) {
|
|
|
- return new URL(resourceURL, baseURI);
|
|
|
- }
|
|
|
-
|
|
|
- static resolveURL(resourceURL, baseURI) {
|
|
|
- return this.parseURL(resourceURL, baseURI).href;
|
|
|
- }
|
|
|
-
|
|
|
- static parseDocContent(content, baseURI) {
|
|
|
- const doc = (new DOMParser()).parseFromString(content, "text/html");
|
|
|
- let baseElement = doc.querySelector("base");
|
|
|
- if (!baseElement || !baseElement.getAttribute("href")) {
|
|
|
- if (baseElement) {
|
|
|
- baseElement.remove();
|
|
|
- }
|
|
|
- baseElement = doc.createElement("base");
|
|
|
- baseElement.setAttribute("href", baseURI);
|
|
|
- doc.head.insertBefore(baseElement, doc.head.firstChild);
|
|
|
+ function parseDocContent(content, baseURI) {
|
|
|
+ const doc = (new DOMParser()).parseFromString(content, "text/html");
|
|
|
+ let baseElement = doc.querySelector("base");
|
|
|
+ if (!baseElement || !baseElement.getAttribute("href")) {
|
|
|
+ if (baseElement) {
|
|
|
+ baseElement.remove();
|
|
|
}
|
|
|
- return doc;
|
|
|
- }
|
|
|
-
|
|
|
- static parseSVGContent(content) {
|
|
|
- return (new DOMParser()).parseFromString(content, "image/svg+xml");
|
|
|
- }
|
|
|
-
|
|
|
- static async digest(algo, text) {
|
|
|
- const hash = await crypto.subtle.digest(algo, new TextEncoder("utf-8").encode(text));
|
|
|
- return (hex(hash));
|
|
|
- }
|
|
|
-
|
|
|
- static getContentSize(content) {
|
|
|
- return new Blob([content]).size;
|
|
|
- }
|
|
|
-
|
|
|
- static async validFont(urlFunction) {
|
|
|
- try {
|
|
|
- const font = new FontFace("font-test", urlFunction);
|
|
|
- await Promise.race([font.load(), new Promise(resolve => setTimeout(() => resolve(true), FONT_FACE_TEST_MAX_DELAY))]);
|
|
|
- return true;
|
|
|
- } catch (error) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- static minifyHTML(doc, options) {
|
|
|
- return htmlMinifier.process(doc, options);
|
|
|
- }
|
|
|
-
|
|
|
- static postMinifyHTML(doc) {
|
|
|
- return htmlMinifier.postProcess(doc);
|
|
|
- }
|
|
|
-
|
|
|
- static minifyCSSRules(stylesheets, styles, mediaAllInfo) {
|
|
|
- return cssRulesMinifier.process(stylesheets, styles, mediaAllInfo);
|
|
|
- }
|
|
|
-
|
|
|
- static removeUnusedFonts(doc, stylesheets, styles, options) {
|
|
|
- return fontsMinifier.process(doc, stylesheets, styles, options);
|
|
|
- }
|
|
|
-
|
|
|
- static removeAlternativeFonts(doc, stylesheets) {
|
|
|
- return fontsAltMinifier.process(doc, stylesheets);
|
|
|
- }
|
|
|
-
|
|
|
- static getMediaAllInfo(doc, stylesheets, styles) {
|
|
|
- return matchedRules.getMediaAllInfo(doc, stylesheets, styles);
|
|
|
- }
|
|
|
-
|
|
|
- static compressCSS(content, options) {
|
|
|
- return cssMinifier.processString(content, options);
|
|
|
- }
|
|
|
-
|
|
|
- static minifyMedias(stylesheets) {
|
|
|
- return mediasMinifier.process(stylesheets);
|
|
|
- }
|
|
|
-
|
|
|
- static removeAlternativeImages(doc, options) {
|
|
|
- return imagesAltMinifier.process(doc, options);
|
|
|
- }
|
|
|
-
|
|
|
- static parseSrcset(srcset) {
|
|
|
- return srcsetParser.process(srcset);
|
|
|
- }
|
|
|
-
|
|
|
- static preProcessDoc(doc, win, options) {
|
|
|
- return docHelper.preProcessDoc(doc, win, options);
|
|
|
- }
|
|
|
-
|
|
|
- static postProcessDoc(doc, options) {
|
|
|
- docHelper.postProcessDoc(doc, options);
|
|
|
- }
|
|
|
-
|
|
|
- static serialize(doc, compressHTML) {
|
|
|
- return serializer.process(doc, compressHTML);
|
|
|
- }
|
|
|
-
|
|
|
- static removeQuotes(string) {
|
|
|
- return docHelper.removeQuotes(string);
|
|
|
- }
|
|
|
-
|
|
|
- static windowIdAttributeName(sessionId) {
|
|
|
- return docHelper.windowIdAttributeName(sessionId);
|
|
|
- }
|
|
|
-
|
|
|
- static preservedSpaceAttributeName(sessionId) {
|
|
|
- return docHelper.preservedSpaceAttributeName(sessionId);
|
|
|
+ baseElement = doc.createElement("base");
|
|
|
+ baseElement.setAttribute("href", baseURI);
|
|
|
+ doc.head.insertBefore(baseElement, doc.head.firstChild);
|
|
|
}
|
|
|
+ return doc;
|
|
|
+ }
|
|
|
|
|
|
- static removedContentAttributeName(sessionId) {
|
|
|
- return docHelper.removedContentAttributeName(sessionId);
|
|
|
- }
|
|
|
+ function parseSVGContent(content) {
|
|
|
+ return (new DOMParser()).parseFromString(content, "image/svg+xml");
|
|
|
+ }
|
|
|
|
|
|
- static imagesAttributeName(sessionId) {
|
|
|
- return docHelper.imagesAttributeName(sessionId);
|
|
|
- }
|
|
|
+ async function digestText(algo, text) {
|
|
|
+ const hash = await crypto.subtle.digest(algo, new TextEncoder("utf-8").encode(text));
|
|
|
+ return (hex(hash));
|
|
|
+ }
|
|
|
|
|
|
- static inputValueAttributeName(sessionId) {
|
|
|
- return docHelper.inputValueAttributeName(sessionId);
|
|
|
- }
|
|
|
+ function getContentSize(content) {
|
|
|
+ return new Blob([content]).size;
|
|
|
+ }
|
|
|
|
|
|
- static shadowRootAttributeName(sessionId) {
|
|
|
- return docHelper.shadowRootAttributeName(sessionId);
|
|
|
+ async function isValidFontUrl(urlFunction) {
|
|
|
+ try {
|
|
|
+ const font = new FontFace("font-test", urlFunction);
|
|
|
+ await Promise.race([font.load(), new Promise(resolve => setTimeout(() => resolve(true), FONT_FACE_TEST_MAX_DELAY))]);
|
|
|
+ return true;
|
|
|
+ } catch (error) {
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -320,6 +193,4 @@ this.SingleFileBrowser = this.SingleFileBrowser || (() => {
|
|
|
console.log("S-File <browser>", ...args); // eslint-disable-line no-console
|
|
|
}
|
|
|
|
|
|
- return { getClass: () => SingleFileCore.getClass(DocUtil, cssTree) };
|
|
|
-
|
|
|
})();
|