|
|
@@ -89,7 +89,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.processor.markPreservedElements();
|
|
|
}
|
|
|
}
|
|
|
- this.options.content = this.options.content || (this.options.doc ? DOMProcessor.serialize(this.options.doc, false) : null);
|
|
|
+ this.options.content = this.options.content || (this.options.doc ? DOM.serialize(this.options.doc, false) : null);
|
|
|
this.onprogress = options.onprogress || (() => { });
|
|
|
}
|
|
|
|
|
|
@@ -277,17 +277,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.baseURI = options.url;
|
|
|
}
|
|
|
|
|
|
- static serialize(doc, compressHTML) {
|
|
|
- return DOM.serialize(doc, compressHTML);
|
|
|
- }
|
|
|
-
|
|
|
async loadPage(pageContent) {
|
|
|
if (!pageContent || this.options.saveRawPage) {
|
|
|
pageContent = await Download.getContent(this.baseURI, { asDataURI: false, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled });
|
|
|
}
|
|
|
- this.dom = DOM.create(pageContent, this.baseURI);
|
|
|
- this.DOMParser = this.dom.DOMParser;
|
|
|
- this.doc = this.dom.document;
|
|
|
+ this.doc = DOM.createDoc(pageContent, this.baseURI);
|
|
|
if (!pageContent && this.doc.querySelector("meta[name=fragment][content=\"!\"]") && !this.baseURI.endsWith("?" + ESCAPED_FRAGMENT) && !this.baseURI.endsWith("&" + ESCAPED_FRAGMENT)) {
|
|
|
await DOMProcessor.loadEscapedFragmentPage();
|
|
|
}
|
|
|
@@ -329,7 +323,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (this.options.displayStats) {
|
|
|
size = new Blob([this.doc.documentElement.outerHTML]).size;
|
|
|
}
|
|
|
- const content = DOMProcessor.serialize(this.doc, this.options.compressHTML);
|
|
|
+ const content = DOM.serialize(this.doc, this.options.compressHTML);
|
|
|
if (this.options.displayStats) {
|
|
|
this.stats.processed.htmlBytes = new Blob([content]).size;
|
|
|
this.stats.discarded.htmlBytes += size - this.stats.processed.htmlBytes;
|
|
|
@@ -423,11 +417,12 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
insertNoscriptContents() {
|
|
|
- if (this.DOMParser) {
|
|
|
+ const DOMParser = DOM.getParser();
|
|
|
+ if (DOMParser) {
|
|
|
this.doc.querySelectorAll("noscript").forEach(element => {
|
|
|
const fragment = this.doc.createDocumentFragment();
|
|
|
Array.from(element.childNodes).forEach(node => {
|
|
|
- const parsedNode = new this.DOMParser().parseFromString(node.nodeValue, "text/html");
|
|
|
+ const parsedNode = new DOMParser().parseFromString(node.nodeValue, "text/html");
|
|
|
Array.from(parsedNode.head.childNodes).concat(Array.from(parsedNode.body.childNodes)).forEach(node => {
|
|
|
this.doc.importNode(node);
|
|
|
fragment.appendChild(node);
|
|
|
@@ -439,7 +434,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
lazyLoadImages() {
|
|
|
- this.dom.lazyLoader.process(this.doc);
|
|
|
+ DOM.lazyLoader(this.doc);
|
|
|
}
|
|
|
|
|
|
removeDiscardedResources() {
|
|
|
@@ -529,7 +524,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
removeUnusedCSSRules() {
|
|
|
- const stats = this.dom.rulesMinifier(this.doc);
|
|
|
+ const stats = DOM.rulesMinifier(this.doc);
|
|
|
if (this.options.displayStats) {
|
|
|
this.stats.processed.cssRules = stats.processed;
|
|
|
this.stats.discarded.cssRules = stats.discarded;
|
|
|
@@ -550,7 +545,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (this.options.displayStats) {
|
|
|
size = new Blob([this.doc.documentElement.outerHTML]).size;
|
|
|
}
|
|
|
- this.dom.htmlmini.postProcess(this.doc);
|
|
|
+ DOM.htmlminiPostProcess(this.doc);
|
|
|
if (this.options.displayStats) {
|
|
|
this.stats.discarded.htmlBytes += size - (new Blob([this.doc.documentElement.outerHTML]).size);
|
|
|
}
|
|
|
@@ -559,7 +554,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (this.options.displayStats) {
|
|
|
size = new Blob([this.doc.documentElement.outerHTML]).size;
|
|
|
}
|
|
|
- this.dom.htmlmini.process(this.doc, { preservedSpaceAttributeName: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME });
|
|
|
+ DOM.htmlminiProcess(this.doc, { preservedSpaceAttributeName: PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME });
|
|
|
if (this.options.displayStats) {
|
|
|
this.stats.discarded.htmlBytes += size - (new Blob([this.doc.documentElement.outerHTML]).size);
|
|
|
}
|
|
|
@@ -618,7 +613,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", this.baseURI),
|
|
|
DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", this.baseURI),
|
|
|
DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image, use"), "xlink:href", this.baseURI),
|
|
|
- DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI, this.dom.parseSrcset)
|
|
|
+ DomProcessorHelper.processSrcset(this.doc.querySelectorAll("[srcset]"), "srcset", this.baseURI)
|
|
|
];
|
|
|
if (!this.options.removeAudioSrc) {
|
|
|
resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", this.baseURI));
|
|
|
@@ -627,9 +622,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", this.baseURI));
|
|
|
}
|
|
|
if (this.options.lazyLoadImages) {
|
|
|
- const imageSelectors = this.dom.lazyLoader.imageSelectors;
|
|
|
+ const imageSelectors = DOM.lazyLoaderImageSelectors();
|
|
|
Object.keys(imageSelectors.src).forEach(selector => resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), imageSelectors.src[selector], this.baseURI)));
|
|
|
- Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI, this.dom.parseSrcset)));
|
|
|
+ Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI)));
|
|
|
}
|
|
|
await resourcePromises;
|
|
|
}
|
|
|
@@ -640,7 +635,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.stats.processed.styleSheets++;
|
|
|
}
|
|
|
const stylesheetContent = initialization ? await DomProcessorHelper.resolveImportURLs(styleElement.textContent, this.baseURI, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled }) : await DomProcessorHelper.processStylesheet(styleElement.textContent, this.baseURI);
|
|
|
- styleElement.textContent = !initialization && this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
+ styleElement.textContent = !initialization && this.options.compressCSS ? DOM.uglifycss(stylesheetContent) : stylesheetContent;
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
@@ -747,7 +742,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
async attributeStyles(initialization) {
|
|
|
await Promise.all(Array.from(this.doc.querySelectorAll("[style]")).map(async element => {
|
|
|
const stylesheetContent = initialization ? await DomProcessorHelper.resolveImportURLs(element.getAttribute("style"), this.baseURI, { maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled }) : await DomProcessorHelper.processStylesheet(element.getAttribute("style"), this.baseURI);
|
|
|
- element.setAttribute("style", this.options.compressCSS ? this.dom.uglifycss(stylesheetContent) : stylesheetContent);
|
|
|
+ element.setAttribute("style", this.options.compressCSS ? DOM.uglifycss(stylesheetContent) : stylesheetContent);
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
@@ -884,9 +879,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- static async processSrcset(resourceElements, attributeName, baseURI, parseSrcset) {
|
|
|
+ static async processSrcset(resourceElements, attributeName, baseURI) {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
- const srcset = parseSrcset(resourceElement.getAttribute(attributeName));
|
|
|
+ const srcset = DOM.parseSrcset(resourceElement.getAttribute(attributeName));
|
|
|
const srcsetValues = await Promise.all(srcset.map(async srcsetValue => {
|
|
|
const resourceURL = DomUtil.normalizeURL(srcsetValue.url);
|
|
|
if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|