|
|
@@ -43,15 +43,15 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
}
|
|
|
async initialize() {
|
|
|
- this.processor = new PageProcessor(this.options, true);
|
|
|
- await this.processor.loadPage();
|
|
|
- await this.processor.initialize();
|
|
|
+ this.runner = new Runner(this.options, true);
|
|
|
+ await this.runner.loadPage();
|
|
|
+ await this.runner.initialize();
|
|
|
}
|
|
|
async run() {
|
|
|
- await this.processor.run();
|
|
|
+ await this.runner.run();
|
|
|
}
|
|
|
async getPageData() {
|
|
|
- return this.processor.getPageData();
|
|
|
+ return this.runner.getPageData();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -78,9 +78,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // -------------
|
|
|
- // PageProcessor
|
|
|
- // -------------
|
|
|
+ // ------
|
|
|
+ // Runner
|
|
|
+ // ------
|
|
|
const RESOLVE_URLS_STAGE = 0;
|
|
|
const REPLACE_DATA_STAGE = 1;
|
|
|
const REPLACE_DOCS_STAGE = 2;
|
|
|
@@ -140,14 +140,14 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
]
|
|
|
}];
|
|
|
|
|
|
- class PageProcessor {
|
|
|
+ class Runner {
|
|
|
constructor(options, root) {
|
|
|
this.root = root;
|
|
|
this.options = options;
|
|
|
this.options.url = this.options.url || this.options.doc.location.href;
|
|
|
this.options.baseURI = this.options.doc && this.options.doc.baseURI;
|
|
|
this.batchRequest = new BatchRequest();
|
|
|
- this.processor = new DOMProcessor(options, this.batchRequest);
|
|
|
+ this.processor = new Processor(options, this.batchRequest);
|
|
|
if (this.options.doc) {
|
|
|
const docData = docUtil.preProcessDoc(this.options.doc, this.options.win, this.options);
|
|
|
this.options.canvasData = docData.canvasData;
|
|
|
@@ -297,19 +297,19 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ------------
|
|
|
- // DOMProcessor
|
|
|
- // ------------
|
|
|
+ // ---------
|
|
|
+ // Processor
|
|
|
+ // ---------
|
|
|
const EMPTY_DATA_URI = "data:base64,";
|
|
|
const EMPTY_IMAGE = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
|
|
const SCRIPT_TAG_FOUND = /<script/gi;
|
|
|
const NOSCRIPT_TAG_FOUND = /<noscript/gi;
|
|
|
|
|
|
- class DOMProcessor {
|
|
|
+ class Processor {
|
|
|
constructor(options, batchRequest) {
|
|
|
this.options = options;
|
|
|
this.stats = new Stats(options);
|
|
|
- this.baseURI = DomUtil.normalizeURL(options.baseURI || options.url);
|
|
|
+ this.baseURI = Util.normalizeURL(options.baseURI || options.url);
|
|
|
this.batchRequest = batchRequest;
|
|
|
this.stylesheets = new Map();
|
|
|
this.styles = new Map();
|
|
|
@@ -356,7 +356,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.stats.set("processed", "HTML bytes", contentSize);
|
|
|
this.stats.add("discarded", "HTML bytes", size - contentSize);
|
|
|
}
|
|
|
- let filename = await DomProcessorHelper.evalTemplate(this.options.filenameTemplate, this.options, content);
|
|
|
+ let filename = await ProcessorHelper.evalTemplate(this.options.filenameTemplate, this.options, content);
|
|
|
filename = filename.replace(/[~\\?%*:|"<>\x00-\x1f\x7F]+/g, "_"); // eslint-disable-line no-control-regex
|
|
|
filename = filename.replace(/\.\.\//g, "").replace(/^\/+/, "").replace(/\/+/g, "/").replace(/\/$/, "");
|
|
|
if (!this.options.backgroundSave) {
|
|
|
@@ -382,7 +382,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
removeUnselectedElements() {
|
|
|
const rootElement = this.doc.querySelector("[" + SELECTED_CONTENT_ROOT_ATTRIBUTE_NAME + "]");
|
|
|
if (rootElement) {
|
|
|
- DomProcessorHelper.isolateElements(rootElement);
|
|
|
+ ProcessorHelper.isolateElements(rootElement);
|
|
|
rootElement.removeAttribute(SELECTED_CONTENT_ROOT_ATTRIBUTE_NAME);
|
|
|
rootElement.removeAttribute(SELECTED_CONTENT_ATTRIBUTE_NAME);
|
|
|
}
|
|
|
@@ -486,7 +486,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const creatorElement = this.doc.querySelector("meta[name=creator]");
|
|
|
const publisherElement = this.doc.querySelector("meta[name=publisher]");
|
|
|
this.options.title = titleElement ? titleElement.textContent.trim() : "";
|
|
|
- this.options.infobarContent = await DomProcessorHelper.evalTemplate(this.options.infobarTemplate, this.options, null, true);
|
|
|
+ this.options.infobarContent = await ProcessorHelper.evalTemplate(this.options.infobarTemplate, this.options, null, true);
|
|
|
this.options.info = {
|
|
|
description: descriptionElement ? descriptionElement.content.trim() : "",
|
|
|
lang: this.doc.documentElement.lang,
|
|
|
@@ -589,8 +589,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
resolveHrefs() {
|
|
|
this.doc.querySelectorAll("[href]").forEach(element => {
|
|
|
const href = element.getAttribute("href");
|
|
|
- if (!DomUtil.testIgnoredPath(href) && DomUtil.testValidPath(href, this.baseURI, this.options.url)) {
|
|
|
- const normalizedHref = DomUtil.normalizeURL(href);
|
|
|
+ if (!Util.testIgnoredPath(href) && Util.testValidPath(href, this.baseURI, this.options.url)) {
|
|
|
+ const normalizedHref = Util.normalizeURL(href);
|
|
|
if (element.tagName == "LINK") {
|
|
|
try {
|
|
|
element.setAttribute("href", docUtil.resolveURL(href, this.options.baseURI || this.options.url));
|
|
|
@@ -660,7 +660,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.doc.querySelectorAll("canvas").forEach((canvasElement, indexCanvasElement) => {
|
|
|
const canvasData = this.options.canvasData[indexCanvasElement];
|
|
|
if (canvasData) {
|
|
|
- DomProcessorHelper.setBackgroundImage(canvasElement, "url(" + canvasData.dataURI + ")");
|
|
|
+ ProcessorHelper.setBackgroundImage(canvasElement, "url(" + canvasData.dataURI + ")");
|
|
|
this.stats.add("processed", "canvas", 1);
|
|
|
}
|
|
|
});
|
|
|
@@ -750,20 +750,20 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
["image", "xlink:href", PREFIX_DATA_URI_IMAGE]
|
|
|
];
|
|
|
let resourcePromises = processAttributeArgs.map(([selector, attributeName, prefixDataURI, processDuplicates, removeElementIfMissing]) =>
|
|
|
- DomProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll(selector), attributeName, prefixDataURI, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest, processDuplicates, removeElementIfMissing)
|
|
|
+ ProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll(selector), attributeName, prefixDataURI, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest, processDuplicates, removeElementIfMissing)
|
|
|
);
|
|
|
resourcePromises = resourcePromises.concat([
|
|
|
- DomProcessorHelper.processXLinks(this.doc.querySelectorAll("use"), this.baseURI, this.options, this.batchRequest),
|
|
|
- DomProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", PREFIX_DATA_URI_IMAGE, this.baseURI, this.options, this.batchRequest)
|
|
|
+ ProcessorHelper.processXLinks(this.doc.querySelectorAll("use"), this.baseURI, this.options, this.batchRequest),
|
|
|
+ ProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", PREFIX_DATA_URI_IMAGE, this.baseURI, this.options, this.batchRequest)
|
|
|
]);
|
|
|
if (!this.options.removeAudioSrc) {
|
|
|
- resourcePromises.push(DomProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", PREFIX_DATA_URI_AUDIO, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
|
|
|
+ resourcePromises.push(ProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", PREFIX_DATA_URI_AUDIO, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
|
|
|
}
|
|
|
if (!this.options.removeVideoSrc) {
|
|
|
- resourcePromises.push(DomProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll("video[src], video > source[src]"), "src", PREFIX_DATA_URI_VIDEO, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
|
|
|
+ resourcePromises.push(ProcessorHelper.processAttribute(this.doc, this.doc.querySelectorAll("video[src], video > source[src]"), "src", PREFIX_DATA_URI_VIDEO, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest));
|
|
|
}
|
|
|
await Promise.all(resourcePromises);
|
|
|
- DomProcessorHelper.processShortcutIcons(this.doc);
|
|
|
+ ProcessorHelper.processShortcutIcons(this.doc);
|
|
|
}
|
|
|
|
|
|
async resolveStylesheetURLs() {
|
|
|
@@ -784,9 +784,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (element.charset) {
|
|
|
options.charset = element.charset;
|
|
|
}
|
|
|
- stylesheetContent = await DomProcessorHelper.resolveLinkStylesheetURLs(element.href, this.baseURI, options);
|
|
|
+ stylesheetContent = await ProcessorHelper.resolveLinkStylesheetURLs(element.href, this.baseURI, options);
|
|
|
} else {
|
|
|
- stylesheetContent = await DomProcessorHelper.resolveImportURLs(element.textContent, this.baseURI, options);
|
|
|
+ stylesheetContent = await ProcessorHelper.resolveImportURLs(element.textContent, this.baseURI, options);
|
|
|
}
|
|
|
let stylesheet;
|
|
|
try {
|
|
|
@@ -812,7 +812,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
|
|
|
async processStylesheets() {
|
|
|
await Promise.all(Array.from(this.stylesheets).map(([, stylesheetInfo]) =>
|
|
|
- DomProcessorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.cssVariables, this.batchRequest)
|
|
|
+ ProcessorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.cssVariables, this.batchRequest)
|
|
|
));
|
|
|
}
|
|
|
|
|
|
@@ -880,7 +880,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (this.options.framesData) {
|
|
|
const frameElements = Array.from(this.doc.querySelectorAll("iframe, frame, object[type=\"text/html\"][data]"));
|
|
|
await Promise.all(frameElements.map(async frameElement => {
|
|
|
- DomProcessorHelper.setFrameEmptySrc(frameElement);
|
|
|
+ ProcessorHelper.setFrameEmptySrc(frameElement);
|
|
|
const frameWindowId = frameElement.getAttribute(docUtil.windowIdAttributeName(this.options.sessionId));
|
|
|
if (frameWindowId) {
|
|
|
const frameData = this.options.framesData.find(frame => frame.windowId == frameWindowId);
|
|
|
@@ -905,7 +905,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
options.fontsData = frameData.fontsData;
|
|
|
options.imageData = frameData.imageData;
|
|
|
options.usedFonts = frameData.usedFonts;
|
|
|
- frameData.processor = new PageProcessor(options);
|
|
|
+ frameData.processor = new Runner(options);
|
|
|
frameData.frameElement = frameElement;
|
|
|
await frameData.processor.loadPage();
|
|
|
await frameData.processor.initialize();
|
|
|
@@ -932,7 +932,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
} else {
|
|
|
frameElement.setAttribute("sandbox", "");
|
|
|
}
|
|
|
- DomProcessorHelper.setFrameContent(frameElement, pageData.content);
|
|
|
+ ProcessorHelper.setFrameContent(frameElement, pageData.content);
|
|
|
this.stats.addAll(pageData);
|
|
|
} else {
|
|
|
this.stats.add("discarded", "frames", 1);
|
|
|
@@ -957,8 +957,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
options.doc = null;
|
|
|
options.win = null;
|
|
|
options.url = resourceURL;
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL) && DomUtil.testValidPath(resourceURL, this.baseURI, this.options.url)) {
|
|
|
- const processor = new PageProcessor(options);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL) && Util.testValidPath(resourceURL, this.baseURI, this.options.url)) {
|
|
|
+ const processor = new Runner(options);
|
|
|
this.relImportProcessors.set(linkElement, processor);
|
|
|
await processor.loadPage();
|
|
|
return processor.initialize();
|
|
|
@@ -988,7 +988,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (this.options.compressCSS) {
|
|
|
styleContent = docUtil.compressCSS(styleContent);
|
|
|
}
|
|
|
- styleContent = DomProcessorHelper.resolveStylesheetURLs(styleContent, this.baseURI, this.options);
|
|
|
+ styleContent = ProcessorHelper.resolveStylesheetURLs(styleContent, this.baseURI, this.options);
|
|
|
const declarationList = cssTree.parse(styleContent, { context: "declarationList" });
|
|
|
this.styles.set(element, declarationList);
|
|
|
});
|
|
|
@@ -996,7 +996,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
|
|
|
async processStyleAttributes() {
|
|
|
return Promise.all(Array.from(this.styles).map(([, declarationList]) =>
|
|
|
- DomProcessorHelper.processStyle(declarationList.children.toArray(), this.baseURI, this.options, this.cssVariables, this.batchRequest)
|
|
|
+ ProcessorHelper.processStyle(declarationList.children.toArray(), this.baseURI, this.options, this.cssVariables, this.batchRequest)
|
|
|
));
|
|
|
}
|
|
|
|
|
|
@@ -1013,9 +1013,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ---------
|
|
|
- // DomHelper
|
|
|
- // ---------
|
|
|
+ // ---------------
|
|
|
+ // ProcessorHelper
|
|
|
+ // ---------------
|
|
|
const REGEXP_AMP = /&/g;
|
|
|
const REGEXP_NBSP = /\u00a0/g;
|
|
|
const REGEXP_START_TAG = /</g;
|
|
|
@@ -1031,51 +1031,51 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const PREFIX_DATA_URI_VND = "data:application/vnd.";
|
|
|
const SINGLE_FILE_VARIABLE_NAME_PREFIX = "--sf-img-";
|
|
|
|
|
|
- class DomProcessorHelper {
|
|
|
+ class ProcessorHelper {
|
|
|
static async evalTemplate(template, options, content, dontReplaceSlash) {
|
|
|
const date = new Date();
|
|
|
const url = docUtil.parseURL(options.url);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-title", () => options.title || "No title", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-language", () => options.info.lang || "No language", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-description", () => options.info.description || "No description", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-author", () => options.info.author || "No author", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-creator", () => options.info.creator || "No creator", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "page-publisher", () => options.info.publisher || "No publisher", dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "datetime-iso", () => date.toISOString(), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "date-iso", () => date.toISOString().split("T")[0], dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "time-iso", () => date.toISOString().split("T")[1].split("Z")[0], dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "date-locale", () => date.toLocaleDateString(), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "time-locale", () => date.toLocaleTimeString(), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "day-locale", () => String(date.getDate()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "month-locale", () => String(date.getMonth() + 1).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "year-locale", () => String(date.getFullYear()), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "datetime-locale", () => date.toLocaleString(), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "datetime-utc", () => date.toUTCString(), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "day-utc", () => String(date.getUTCDate()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "month-utc", () => String(date.getUTCMonth() + 1).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "year-utc", () => String(date.getUTCFullYear()), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "hours-locale", () => String(date.getHours()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "minutes-locale", () => String(date.getMinutes()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "seconds-locale", () => String(date.getSeconds()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "hours-utc", () => String(date.getUTCHours()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "minutes-utc", () => String(date.getUTCMinutes()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "seconds-utc", () => String(date.getUTCSeconds()).padStart(2, "0"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-hash", () => url.hash.substring(1), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-host", () => url.host.replace(/\/$/, ""), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-hostname", () => url.hostname.replace(/\/$/, ""), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-href", () => url.href, dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-password", () => url.password, dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-pathname", () => url.pathname.replace(/^\//, "").replace(/\/$/, ""), dontReplaceSlash === undefined ? true : dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-port", () => url.port, dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-protocol", () => url.protocol, dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-search", () => url.search.substring(1), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-username", () => url.username, dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "tab-id", () => String(options.tabId || "No tab id"), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "url-last-segment", () => DomUtil.getLastSegment(url), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-title", () => options.title || "No title", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-language", () => options.info.lang || "No language", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-description", () => options.info.description || "No description", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-author", () => options.info.author || "No author", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-creator", () => options.info.creator || "No creator", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "page-publisher", () => options.info.publisher || "No publisher", dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "datetime-iso", () => date.toISOString(), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "date-iso", () => date.toISOString().split("T")[0], dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "time-iso", () => date.toISOString().split("T")[1].split("Z")[0], dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "date-locale", () => date.toLocaleDateString(), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "time-locale", () => date.toLocaleTimeString(), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "day-locale", () => String(date.getDate()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "month-locale", () => String(date.getMonth() + 1).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "year-locale", () => String(date.getFullYear()), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "datetime-locale", () => date.toLocaleString(), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "datetime-utc", () => date.toUTCString(), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "day-utc", () => String(date.getUTCDate()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "month-utc", () => String(date.getUTCMonth() + 1).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "year-utc", () => String(date.getUTCFullYear()), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "hours-locale", () => String(date.getHours()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "minutes-locale", () => String(date.getMinutes()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "seconds-locale", () => String(date.getSeconds()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "hours-utc", () => String(date.getUTCHours()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "minutes-utc", () => String(date.getUTCMinutes()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "seconds-utc", () => String(date.getUTCSeconds()).padStart(2, "0"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-hash", () => url.hash.substring(1), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-host", () => url.host.replace(/\/$/, ""), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-hostname", () => url.hostname.replace(/\/$/, ""), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-href", () => url.href, dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-password", () => url.password, dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-pathname", () => url.pathname.replace(/^\//, "").replace(/\/$/, ""), dontReplaceSlash === undefined ? true : dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-port", () => url.port, dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-protocol", () => url.protocol, dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-search", () => url.search.substring(1), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-username", () => url.username, dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "tab-id", () => String(options.tabId || "No tab id"), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "url-last-segment", () => Util.getLastSegment(url), dontReplaceSlash);
|
|
|
if (content) {
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "digest-sha-256", async () => docUtil.digest("SHA-256", content), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "digest-sha-384", async () => docUtil.digest("SHA-384", content), dontReplaceSlash);
|
|
|
- template = await DomUtil.evalTemplateVariable(template, "digest-sha-512", async () => docUtil.digest("SHA-512", content), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "digest-sha-256", async () => docUtil.digest("SHA-256", content), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "digest-sha-384", async () => docUtil.digest("SHA-384", content), dontReplaceSlash);
|
|
|
+ template = await Util.evalTemplateVariable(template, "digest-sha-512", async () => docUtil.digest("SHA-512", content), dontReplaceSlash);
|
|
|
}
|
|
|
return template;
|
|
|
}
|
|
|
@@ -1092,9 +1092,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static processShortcutIcons(doc) {
|
|
|
- let shortcutIcon = DomUtil.findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel=\"icon\"], link[href][rel=\"shortcut icon\"]")));
|
|
|
+ let shortcutIcon = Util.findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel=\"icon\"], link[href][rel=\"shortcut icon\"]")));
|
|
|
if (!shortcutIcon) {
|
|
|
- shortcutIcon = DomUtil.findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel*=\"icon\"]")));
|
|
|
+ shortcutIcon = Util.findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel*=\"icon\"]")));
|
|
|
if (shortcutIcon) {
|
|
|
shortcutIcon.rel = "icon";
|
|
|
}
|
|
|
@@ -1160,30 +1160,30 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static async resolveImportURLs(stylesheetContent, baseURI, options) {
|
|
|
- stylesheetContent = DomProcessorHelper.resolveStylesheetURLs(stylesheetContent, baseURI, options);
|
|
|
- const imports = DomUtil.getImportFunctions(stylesheetContent);
|
|
|
+ stylesheetContent = ProcessorHelper.resolveStylesheetURLs(stylesheetContent, baseURI, options);
|
|
|
+ const imports = Util.getImportFunctions(stylesheetContent);
|
|
|
await Promise.all(imports.map(async cssImport => {
|
|
|
- const match = DomUtil.matchImport(cssImport);
|
|
|
+ const match = Util.matchImport(cssImport);
|
|
|
if (match) {
|
|
|
- let resourceURL = DomUtil.normalizeURL(match.resourceURL);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL) && DomUtil.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
+ let resourceURL = Util.normalizeURL(match.resourceURL);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL) && Util.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
try {
|
|
|
resourceURL = docUtil.resolveURL(match.resourceURL, baseURI);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
const downloadOptions = { asDataURI: false, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled, validateTextContentType: true };
|
|
|
const content = await docUtil.getContent(resourceURL, downloadOptions);
|
|
|
resourceURL = content.resourceURL;
|
|
|
- let importedStylesheetContent = DomUtil.removeCssComments(content.data);
|
|
|
+ let importedStylesheetContent = Util.removeCssComments(content.data);
|
|
|
if (options.compressCSS) {
|
|
|
importedStylesheetContent = docUtil.compressCSS(importedStylesheetContent);
|
|
|
}
|
|
|
- importedStylesheetContent = DomUtil.wrapMediaQuery(importedStylesheetContent, match.media);
|
|
|
+ importedStylesheetContent = Util.wrapMediaQuery(importedStylesheetContent, match.media);
|
|
|
if (stylesheetContent.includes(cssImport)) {
|
|
|
- importedStylesheetContent = await DomProcessorHelper.resolveImportURLs(importedStylesheetContent, resourceURL, options);
|
|
|
- stylesheetContent = stylesheetContent.replace(DomUtil.getRegExp(cssImport), importedStylesheetContent);
|
|
|
+ importedStylesheetContent = await ProcessorHelper.resolveImportURLs(importedStylesheetContent, resourceURL, options);
|
|
|
+ stylesheetContent = stylesheetContent.replace(Util.getRegExp(cssImport), importedStylesheetContent);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1193,20 +1193,20 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static resolveStylesheetURLs(stylesheetContent, baseURI, options) {
|
|
|
- const urlFunctions = DomUtil.getUrlFunctions(stylesheetContent);
|
|
|
+ const urlFunctions = Util.getUrlFunctions(stylesheetContent);
|
|
|
urlFunctions.map(urlFunction => {
|
|
|
- const originalResourceURL = DomUtil.matchURL(urlFunction);
|
|
|
- const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
- if (DomUtil.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
+ const originalResourceURL = Util.matchURL(urlFunction);
|
|
|
+ const resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
+ if (Util.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
let resolvedURL;
|
|
|
try {
|
|
|
resolvedURL = docUtil.resolveURL(resourceURL, baseURI);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
- if (DomUtil.testValidURL(resolvedURL, baseURI, options.url) && resourceURL != resolvedURL && stylesheetContent.includes(urlFunction)) {
|
|
|
- stylesheetContent = stylesheetContent.replace(DomUtil.getRegExp(urlFunction), urlFunction.replace(originalResourceURL, resolvedURL));
|
|
|
+ if (Util.testValidURL(resolvedURL, baseURI, options.url) && resourceURL != resolvedURL && stylesheetContent.includes(urlFunction)) {
|
|
|
+ stylesheetContent = stylesheetContent.replace(Util.getRegExp(urlFunction), urlFunction.replace(originalResourceURL, resolvedURL));
|
|
|
}
|
|
|
} else {
|
|
|
let newUrlFunction;
|
|
|
@@ -1215,13 +1215,13 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
} else {
|
|
|
newUrlFunction = "url(" + EMPTY_DATA_URI + ")";
|
|
|
}
|
|
|
- stylesheetContent = stylesheetContent.replace(DomUtil.getRegExp(urlFunction), newUrlFunction);
|
|
|
+ stylesheetContent = stylesheetContent.replace(Util.getRegExp(urlFunction), newUrlFunction);
|
|
|
}
|
|
|
} else {
|
|
|
if (resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
const escapedResourceURL = resourceURL.replace(REGEXP_AMP, "&").replace(REGEXP_NBSP, " ").replace(REGEXP_START_TAG, "<").replace(REGEXP_END_TAG, ">");
|
|
|
if (escapedResourceURL != resourceURL && stylesheetContent.includes(urlFunction)) {
|
|
|
- stylesheetContent = stylesheetContent.replace(DomUtil.getRegExp(urlFunction), urlFunction.replace(originalResourceURL, escapedResourceURL));
|
|
|
+ stylesheetContent = stylesheetContent.replace(Util.getRegExp(urlFunction), urlFunction.replace(originalResourceURL, escapedResourceURL));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1230,16 +1230,16 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static async resolveLinkStylesheetURLs(resourceURL, baseURI, options) {
|
|
|
- resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
+ resourceURL = Util.normalizeURL(resourceURL);
|
|
|
if (resourceURL && resourceURL != baseURI && resourceURL != ABOUT_BLANK_URI) {
|
|
|
const downloadOptions = { asDataURI: false, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled, charset: options.charset };
|
|
|
const content = await docUtil.getContent(resourceURL, downloadOptions);
|
|
|
resourceURL = content.resourceURL;
|
|
|
- let stylesheetContent = DomUtil.removeCssComments(content.data);
|
|
|
+ let stylesheetContent = Util.removeCssComments(content.data);
|
|
|
if (options.compressCSS) {
|
|
|
stylesheetContent = docUtil.compressCSS(stylesheetContent);
|
|
|
}
|
|
|
- stylesheetContent = await DomProcessorHelper.resolveImportURLs(stylesheetContent, resourceURL, options);
|
|
|
+ stylesheetContent = await ProcessorHelper.resolveImportURLs(stylesheetContent, resourceURL, options);
|
|
|
return stylesheetContent;
|
|
|
}
|
|
|
}
|
|
|
@@ -1267,12 +1267,12 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
async function processFontFaceRule(cssRule) {
|
|
|
await Promise.all(cssRule.block.children.toArray().map(async declaration => {
|
|
|
if (declaration.type == "Declaration" && declaration.value.children) {
|
|
|
- const urlFunctions = DomUtil.getUrlFunctions(DomUtil.getCSSValue(declaration.value));
|
|
|
+ const urlFunctions = Util.getUrlFunctions(Util.getCSSValue(declaration.value));
|
|
|
await Promise.all(urlFunctions.map(async urlFunction => {
|
|
|
- const originalResourceURL = DomUtil.matchURL(urlFunction);
|
|
|
- const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ const originalResourceURL = Util.matchURL(urlFunction);
|
|
|
+ const resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
let { content } = await batchRequest.addURL(resourceURL);
|
|
|
let validResource = content == EMPTY_DATA_URI || content.startsWith(PREFIX_DATA_URI_VND) || content.startsWith(PREFIX_DATA_URI_IMAGE_SVG);
|
|
|
if (!validResource) {
|
|
|
@@ -1282,7 +1282,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
content = EMPTY_DATA_URI;
|
|
|
}
|
|
|
declaration.value.children.forEach(token => {
|
|
|
- if (token.type == "Url" && docUtil.removeQuotes(DomUtil.getCSSValue(token.value)) == originalResourceURL) {
|
|
|
+ if (token.type == "Url" && docUtil.removeQuotes(Util.getCSSValue(token.value)) == originalResourceURL) {
|
|
|
token.value.value = content;
|
|
|
}
|
|
|
});
|
|
|
@@ -1297,12 +1297,12 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
static async processStyle(declarations, baseURI, options, cssVariables, batchRequest) {
|
|
|
await Promise.all(declarations.map(async declaration => {
|
|
|
if (declaration.type == "Declaration" && declaration.value.children) {
|
|
|
- const urlFunctions = DomUtil.getUrlFunctions(DomUtil.getCSSValue(declaration.value));
|
|
|
+ const urlFunctions = Util.getUrlFunctions(Util.getCSSValue(declaration.value));
|
|
|
await Promise.all(urlFunctions.map(async urlFunction => {
|
|
|
- const originalResourceURL = DomUtil.matchURL(urlFunction);
|
|
|
- const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ const originalResourceURL = Util.matchURL(urlFunction);
|
|
|
+ const resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL);
|
|
|
if (duplicate && options.groupDuplicateImages) {
|
|
|
const tokens = [];
|
|
|
@@ -1326,7 +1326,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (token.data.children) {
|
|
|
findURLToken(url, token.data.children, callback);
|
|
|
}
|
|
|
- if (token.data.type == "Url" && docUtil.removeQuotes(DomUtil.getCSSValue(token.data.value)) == url) {
|
|
|
+ if (token.data.type == "Url" && docUtil.removeQuotes(Util.getCSSValue(token.data.value)) == url) {
|
|
|
callback(token, children);
|
|
|
}
|
|
|
}
|
|
|
@@ -1336,16 +1336,16 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
static async processAttribute(doc, resourceElements, attributeName, prefixDataURI, baseURI, options, cssVariables, styles, batchRequest, processDuplicates, removeElementIfMissing) {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
let resourceURL = resourceElement.getAttribute(attributeName);
|
|
|
- resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
+ resourceURL = Util.normalizeURL(resourceURL);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
resourceElement.setAttribute(attributeName, EMPTY_IMAGE);
|
|
|
- if (DomUtil.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
+ if (Util.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
try {
|
|
|
resourceURL = docUtil.resolveURL(resourceURL, baseURI);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
const { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL);
|
|
|
if (removeElementIfMissing && content == EMPTY_DATA_URI) {
|
|
|
resourceElement.remove();
|
|
|
@@ -1353,7 +1353,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (content.startsWith(prefixDataURI) || content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) || content.match(PREFIX_DATA_URI_OCTET_STREAM) || content.match(PREFIX_DATA_URI_NULL_STREAM)) {
|
|
|
const isSVG = content.startsWith(PREFIX_DATA_URI_IMAGE_SVG);
|
|
|
if (processDuplicates && duplicate && options.groupDuplicateImages && !isSVG) {
|
|
|
- if (DomUtil.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource, options)) {
|
|
|
+ if (Util.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource, options)) {
|
|
|
cssVariables.set(indexResource, content);
|
|
|
const declarationList = cssTree.parse(resourceElement.getAttribute("style"), { context: "declarationList" });
|
|
|
styles.set(resourceElement, declarationList);
|
|
|
@@ -1375,15 +1375,15 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const attributeName = "xlink:href";
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
const originalResourceURL = resourceElement.getAttribute(attributeName);
|
|
|
- let resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
- if (DomUtil.testValidPath(resourceURL, baseURI, options.url) && !DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
+ let resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
+ if (Util.testValidPath(resourceURL, baseURI, options.url) && !Util.testIgnoredPath(resourceURL)) {
|
|
|
resourceElement.setAttribute(attributeName, EMPTY_IMAGE);
|
|
|
try {
|
|
|
resourceURL = docUtil.resolveURL(resourceURL, baseURI);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
try {
|
|
|
const { content } = await batchRequest.addURL(resourceURL, false);
|
|
|
const DOMParser = docUtil.getParser();
|
|
|
@@ -1416,15 +1416,15 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
const srcset = docUtil.parseSrcset(resourceElement.getAttribute(attributeName));
|
|
|
const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
|
|
|
- let resourceURL = DomUtil.normalizeURL(srcsetValue.url);
|
|
|
- if (!DomUtil.testIgnoredPath(resourceURL)) {
|
|
|
- if (DomUtil.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
+ let resourceURL = Util.normalizeURL(srcsetValue.url);
|
|
|
+ if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
+ if (Util.testValidPath(resourceURL, baseURI, options.url)) {
|
|
|
try {
|
|
|
resourceURL = docUtil.resolveURL(resourceURL, baseURI);
|
|
|
} catch (error) {
|
|
|
// ignored
|
|
|
}
|
|
|
- if (DomUtil.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
+ if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
const { content } = await batchRequest.addURL(resourceURL);
|
|
|
if (!content.startsWith(prefixDataURI) && !content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) && !content.match(PREFIX_DATA_URI_OCTET_STREAM) && !content.match(PREFIX_DATA_URI_NULL_STREAM)) {
|
|
|
resourceElement.setAttribute(attributeName, EMPTY_IMAGE);
|
|
|
@@ -1446,9 +1446,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
|
|
|
}
|
|
|
|
|
|
- // -------
|
|
|
- // DomUtil
|
|
|
- // -------
|
|
|
+ // ----
|
|
|
+ // Util
|
|
|
+ // ----
|
|
|
const DATA_URI_PREFIX = "data:";
|
|
|
const BLOB_URI_PREFIX = "blob:";
|
|
|
const HTTP_URI_PREFIX = /^https?:\/\//;
|
|
|
@@ -1469,7 +1469,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const REGEXP_IMPORT_NO_QUOTES_FN = /@import\s*(.*?)\s*(.*?)(;|$|})/i;
|
|
|
const REGEXP_ESCAPE = /([{}()^$&.*?/+|[\\\\]|\]|-)/g;
|
|
|
|
|
|
- class DomUtil {
|
|
|
+ class Util {
|
|
|
static normalizeURL(url) {
|
|
|
if (!url || url.startsWith(DATA_URI_PREFIX)) {
|
|
|
return url;
|
|
|
@@ -1551,7 +1551,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static testValidURL(resourceURL, baseURI, docURL) {
|
|
|
- return DomUtil.testValidPath(resourceURL, baseURI, docURL) && (resourceURL.match(HTTP_URI_PREFIX) || resourceURL.match(FILE_URI_PREFIX) || resourceURL.startsWith(BLOB_URI_PREFIX)) && resourceURL.match(NOT_EMPTY_URL);
|
|
|
+ return Util.testValidPath(resourceURL, baseURI, docURL) && (resourceURL.match(HTTP_URI_PREFIX) || resourceURL.match(FILE_URI_PREFIX) || resourceURL.startsWith(BLOB_URI_PREFIX)) && resourceURL.match(NOT_EMPTY_URL);
|
|
|
}
|
|
|
|
|
|
static matchImport(stylesheetContent) {
|
|
|
@@ -1604,7 +1604,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (imgData.backgroundColor) {
|
|
|
backgroundStyle["background-color"] = imgData.backgroundColor;
|
|
|
}
|
|
|
- DomProcessorHelper.setBackgroundImage(imgElement, "var(" + variableName + ")", backgroundStyle);
|
|
|
+ ProcessorHelper.setBackgroundImage(imgElement, "var(" + variableName + ")", backgroundStyle);
|
|
|
imgElement.removeAttribute(dataAttributeName);
|
|
|
return true;
|
|
|
}
|