|
@@ -76,6 +76,10 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
// -------------
|
|
// -------------
|
|
|
// PageProcessor
|
|
// PageProcessor
|
|
|
// -------------
|
|
// -------------
|
|
|
|
|
+ const RESOLVE_URLS_STAGE = 0;
|
|
|
|
|
+ const REPLACE_DATA_STAGE = 1;
|
|
|
|
|
+ const REPLACE_DOCS_STAGE = 2;
|
|
|
|
|
+ const CLEANUP_STAGE = 3;
|
|
|
const STAGES = [{
|
|
const STAGES = [{
|
|
|
sequential: [
|
|
sequential: [
|
|
|
{ action: "preProcessPage" },
|
|
{ action: "preProcessPage" },
|
|
@@ -161,8 +165,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
async initialize() {
|
|
async initialize() {
|
|
|
this.onprogress(new ProgressEvent(RESOURCES_INITIALIZING, { pageURL: this.options.url }));
|
|
this.onprogress(new ProgressEvent(RESOURCES_INITIALIZING, { pageURL: this.options.url }));
|
|
|
|
|
|
|
|
- await this.executeStage(0);
|
|
|
|
|
- this.pendingPromises = this.executeStage(1);
|
|
|
|
|
|
|
+ await this.executeStage(RESOLVE_URLS_STAGE);
|
|
|
|
|
+ this.pendingPromises = this.executeStage(REPLACE_DATA_STAGE);
|
|
|
if (this.options.doc) {
|
|
if (this.options.doc) {
|
|
|
DOM.postProcessDoc(this.options.doc, this.options);
|
|
DOM.postProcessDoc(this.options.doc, this.options);
|
|
|
this.options.doc = null;
|
|
this.options.doc = null;
|
|
@@ -180,8 +184,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
this.onprogress(new ProgressEvent(RESOURCE_LOADED, details));
|
|
this.onprogress(new ProgressEvent(RESOURCE_LOADED, details));
|
|
|
}, this.options);
|
|
}, this.options);
|
|
|
await this.pendingPromises;
|
|
await this.pendingPromises;
|
|
|
- await this.executeStage(2);
|
|
|
|
|
- await this.executeStage(3);
|
|
|
|
|
|
|
+ await this.executeStage(REPLACE_DOCS_STAGE);
|
|
|
|
|
+ await this.executeStage(CLEANUP_STAGE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async getPageData() {
|
|
async getPageData() {
|
|
@@ -688,7 +692,12 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async resolveStylesheetURLs() {
|
|
async resolveStylesheetURLs() {
|
|
|
- await Promise.all(Array.from(this.doc.querySelectorAll("style")).map(async styleElement => styleElement.textContent = await DomProcessorHelper.resolveImportURLs(styleElement.textContent, this.baseURI, { url: this.options.url, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled })));
|
|
|
|
|
|
|
+ await Promise.all(Array.from(this.doc.querySelectorAll("style"))
|
|
|
|
|
+ .map(async styleElement => {
|
|
|
|
|
+ const options = { url: this.options.url, maxResourceSize: this.options.maxResourceSize, maxResourceSizeEnabled: this.options.maxResourceSizeEnabled };
|
|
|
|
|
+ const textContent = await DomProcessorHelper.resolveImportURLs(styleElement.textContent, this.baseURI, options);
|
|
|
|
|
+ styleElement.textContent = textContent;
|
|
|
|
|
+ }));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async processStylesheets() {
|
|
async processStylesheets() {
|
|
@@ -722,32 +731,36 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (frameWindowId) {
|
|
if (frameWindowId) {
|
|
|
const frameData = this.options.framesData.find(frame => frame.windowId == frameWindowId);
|
|
const frameData = this.options.framesData.find(frame => frame.windowId == frameWindowId);
|
|
|
if (frameData) {
|
|
if (frameData) {
|
|
|
- const options = Object.create(this.options);
|
|
|
|
|
- options.insertSingleFileComment = false;
|
|
|
|
|
- options.insertFaviconLink = false;
|
|
|
|
|
- options.doc = null;
|
|
|
|
|
- options.win = null;
|
|
|
|
|
- options.url = frameData.baseURI;
|
|
|
|
|
- options.windowId = frameWindowId;
|
|
|
|
|
- if (frameData.content) {
|
|
|
|
|
- options.content = frameData.content;
|
|
|
|
|
- options.canvasData = frameData.canvasData;
|
|
|
|
|
- options.stylesheetContents = frameData.stylesheetContents;
|
|
|
|
|
- options.currentSrcImages = frameData.currentSrcImages;
|
|
|
|
|
- options.fontsData = frameData.fontsData;
|
|
|
|
|
- options.imageData = frameData.imageData;
|
|
|
|
|
- options.responsiveImageData = frameData.responsiveImageData;
|
|
|
|
|
- options.usedFonts = frameData.usedFonts;
|
|
|
|
|
- frameData.processor = new PageProcessor(options);
|
|
|
|
|
- frameData.frameElement = frameElement;
|
|
|
|
|
- await frameData.processor.loadPage();
|
|
|
|
|
- await frameData.processor.initialize();
|
|
|
|
|
- frameData.maxResources = this.batchRequest.getMaxResources();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await initializeProcessor(frameData, frameElement, frameWindowId);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}));
|
|
}));
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ async function initializeProcessor(frameData, frameElement, frameWindowId) {
|
|
|
|
|
+ const options = Object.create(this.options);
|
|
|
|
|
+ options.insertSingleFileComment = false;
|
|
|
|
|
+ options.insertFaviconLink = false;
|
|
|
|
|
+ options.doc = null;
|
|
|
|
|
+ options.win = null;
|
|
|
|
|
+ options.url = frameData.baseURI;
|
|
|
|
|
+ options.windowId = frameWindowId;
|
|
|
|
|
+ if (frameData.content) {
|
|
|
|
|
+ options.content = frameData.content;
|
|
|
|
|
+ options.canvasData = frameData.canvasData;
|
|
|
|
|
+ options.stylesheetContents = frameData.stylesheetContents;
|
|
|
|
|
+ options.currentSrcImages = frameData.currentSrcImages;
|
|
|
|
|
+ options.fontsData = frameData.fontsData;
|
|
|
|
|
+ options.imageData = frameData.imageData;
|
|
|
|
|
+ options.responsiveImageData = frameData.responsiveImageData;
|
|
|
|
|
+ options.usedFonts = frameData.usedFonts;
|
|
|
|
|
+ frameData.processor = new PageProcessor(options);
|
|
|
|
|
+ frameData.frameElement = frameElement;
|
|
|
|
|
+ await frameData.processor.loadPage();
|
|
|
|
|
+ await frameData.processor.initialize();
|
|
|
|
|
+ frameData.maxResources = this.batchRequest.getMaxResources();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async processFrames() {
|
|
async processFrames() {
|
|
@@ -819,11 +832,17 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
resolveStyleAttributeURLs() {
|
|
resolveStyleAttributeURLs() {
|
|
|
- Array.from(this.doc.querySelectorAll("[style]")).map(element => element.setAttribute("style", DomProcessorHelper.resolveStylesheetURLs(element.getAttribute("style"), this.baseURI, this.options)));
|
|
|
|
|
|
|
+ Array.from(this.doc.querySelectorAll("[style]"))
|
|
|
|
|
+ .map(element => element.setAttribute("style", DomProcessorHelper.resolveStylesheetURLs(element.getAttribute("style"), this.baseURI, this.options)));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async processStyleAttributes() {
|
|
async processStyleAttributes() {
|
|
|
- await Promise.all(Array.from(this.doc.querySelectorAll("[style]")).map(async element => element.setAttribute("style", await DomProcessorHelper.processStylesheet(this.doc, element.getAttribute("style"), [{ type: CSSRule.STYLE_RULE, cssText: element.getAttribute("style") }], this.baseURI, this.options, this.batchRequest))));
|
|
|
|
|
|
|
+ await Promise.all(Array.from(this.doc.querySelectorAll("[style]"))
|
|
|
|
|
+ .map(async element => {
|
|
|
|
|
+ const rules = [{ type: CSSRule.STYLE_RULE, cssText: element.getAttribute("style") }];
|
|
|
|
|
+ const textContent = await DomProcessorHelper.processStylesheet(this.doc, element.getAttribute("style"), rules, this.baseURI, this.options, this.batchRequest);
|
|
|
|
|
+ element.setAttribute("style", textContent);
|
|
|
|
|
+ }));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async resolveLinkedStylesheetURLs() {
|
|
async resolveLinkedStylesheetURLs() {
|
|
@@ -1115,8 +1134,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
resourceElement.remove();
|
|
resourceElement.remove();
|
|
|
} else {
|
|
} else {
|
|
|
if (content.startsWith(prefixDataURI) || content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) || content.match(PREFIX_DATA_URI_OCTET_STREAM)) {
|
|
if (content.startsWith(prefixDataURI) || content.startsWith(PREFIX_DATA_URI_NO_MIMETYPE) || content.match(PREFIX_DATA_URI_OCTET_STREAM)) {
|
|
|
- if (processDuplicates && duplicate && options.groupDuplicateImages && !content.startsWith(PREFIX_DATA_URI_IMAGE_SVG) && DomUtil.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource, options)) {
|
|
|
|
|
- DomUtil.insertVariable(doc, indexResource, content, options);
|
|
|
|
|
|
|
+ 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)) {
|
|
|
|
|
+ DomUtil.insertVariable(doc, indexResource, content, options);
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
resourceElement.setAttribute(attributeName, content);
|
|
resourceElement.setAttribute(attributeName, content);
|
|
|
}
|
|
}
|