|
|
@@ -661,25 +661,25 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
|
|
|
async pageResources() {
|
|
|
const resourcePromises = [
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("link[href][rel*=\"icon\"]"), "href", this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]"), "data", this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[src], input[src][type=image], embed[src*=\".svg\"]"), "src", this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image"), "xlink:href", this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("link[href][rel*=\"icon\"]"), "href", PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]"), "data", PREFIX_DATA_URI_IMAGE_SVG, this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("img[src], input[src][type=image], embed[src*=\".svg\"]"), "src", PREFIX_DATA_URI_IMAGE_SVG, this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[poster]"), "poster", PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("*[background]"), "background", PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest),
|
|
|
+ DomProcessorHelper.processAttribute(this.doc.querySelectorAll("image"), "xlink:href", PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest),
|
|
|
DomProcessorHelper.processXLinks(this.doc.querySelectorAll("use"), this.baseURI, this.batchRequest),
|
|
|
- DomProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", this.baseURI, this.batchRequest)
|
|
|
+ DomProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest)
|
|
|
];
|
|
|
if (!this.options.removeAudioSrc) {
|
|
|
- resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", this.baseURI, this.batchRequest));
|
|
|
+ resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("audio[src], audio > source[src]"), "src", PREFIX_DATA_URI_AUDIO, this.baseURI, this.batchRequest));
|
|
|
}
|
|
|
if (!this.options.removeVideoSrc) {
|
|
|
- resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", this.baseURI, this.batchRequest));
|
|
|
+ resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll("video[src], video > source[src]"), "src", PREFIX_DATA_URI_VIDEO, this.baseURI, this.batchRequest));
|
|
|
}
|
|
|
if (this.options.lazyLoadImages) {
|
|
|
const imageSelectors = DOM.lazyLoaderImageSelectors();
|
|
|
- Object.keys(imageSelectors.src).forEach(selector => resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), imageSelectors.src[selector], this.baseURI, this.batchRequest)));
|
|
|
- Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], this.baseURI, this.batchRequest)));
|
|
|
+ Object.keys(imageSelectors.src).forEach(selector => resourcePromises.push(DomProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), imageSelectors.src[selector], PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest)));
|
|
|
+ Object.keys(imageSelectors.srcset).forEach(selector => resourcePromises.push(DomProcessorHelper.processSrcset(this.doc.querySelectorAll(selector), imageSelectors.srcset[selector], PREFIX_DATA_URI_IMAGE, this.baseURI, this.batchRequest)));
|
|
|
}
|
|
|
await resourcePromises;
|
|
|
}
|
|
|
@@ -826,6 +826,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const REGEXP_END_TAG = />/g;
|
|
|
const REGEXP_URL_HASH = /(#.+?)$/;
|
|
|
const PREFIX_DATA_URI_IMAGE = "data:image/";
|
|
|
+ const PREFIX_DATA_URI_AUDIO = "data:audio/";
|
|
|
+ const PREFIX_DATA_URI_VIDEO = "data:video/";
|
|
|
const PREFIX_DATA_URI_IMAGE_SVG = "data:image/svg+xml";
|
|
|
|
|
|
class DomProcessorHelper {
|
|
|
@@ -1011,7 +1013,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
return stylesheetContent;
|
|
|
}
|
|
|
|
|
|
- static async processAttribute(resourceElements, attributeName, baseURI, batchRequest) {
|
|
|
+ static async processAttribute(resourceElements, attributeName, prefixDataURI, baseURI, batchRequest) {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
let resourceURL = resourceElement.getAttribute(attributeName);
|
|
|
if (resourceURL) {
|
|
|
@@ -1019,9 +1021,13 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
try {
|
|
|
const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
|
- resourceElement.setAttribute(attributeName, dataURI);
|
|
|
+ if (dataURI.startsWith(prefixDataURI)) {
|
|
|
+ resourceElement.setAttribute(attributeName, dataURI);
|
|
|
+ } else {
|
|
|
+ resourceElement.setAttribute(attributeName, EMPTY_DATA_URI);
|
|
|
+ }
|
|
|
} catch (error) {
|
|
|
- /* ignored */
|
|
|
+ resourceElement.setAttribute(attributeName, EMPTY_DATA_URI);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1029,8 +1035,9 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
|
|
|
static async processXLinks(resourceElements, baseURI, batchRequest) {
|
|
|
+ const attributeName = "xlink:href";
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
- const originalResourceURL = resourceElement.getAttribute("xlink:href");
|
|
|
+ const originalResourceURL = resourceElement.getAttribute(attributeName);
|
|
|
if (originalResourceURL) {
|
|
|
const resourceURL = DomUtil.normalizeURL(originalResourceURL);
|
|
|
if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
@@ -1043,34 +1050,37 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (hashMatch && hashMatch[0]) {
|
|
|
const symbolElement = svgDoc.querySelector(hashMatch[0]);
|
|
|
if (symbolElement) {
|
|
|
- resourceElement.setAttribute("xlink:href", hashMatch[0]);
|
|
|
+ resourceElement.setAttribute(attributeName, hashMatch[0]);
|
|
|
resourceElement.parentElement.appendChild(symbolElement);
|
|
|
}
|
|
|
} else {
|
|
|
- resourceElement.setAttribute("xlink:href", "data:image/svg+xml," + content);
|
|
|
+ resourceElement.setAttribute(attributeName, "data:image/svg+xml," + content);
|
|
|
}
|
|
|
} else {
|
|
|
- resourceElement.setAttribute("xlink:href", "data:image/svg+xml," + content);
|
|
|
+ resourceElement.setAttribute(attributeName, "data:image/svg+xml," + content);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
- /* ignored */
|
|
|
+ resourceElement.setAttribute(attributeName, EMPTY_DATA_URI);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- static async processSrcset(resourceElements, attributeName, baseURI, batchRequest) {
|
|
|
+ static async processSrcset(resourceElements, attributeName, prefixDataURI, baseURI, batchRequest) {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
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)) {
|
|
|
try {
|
|
|
- const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
|
+ let dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
|
+ if (!dataURI.startsWith(prefixDataURI)) {
|
|
|
+ resourceElement.setAttribute(attributeName, EMPTY_DATA_URI);
|
|
|
+ }
|
|
|
return dataURI + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
|
|
|
} catch (error) {
|
|
|
- /* ignored */
|
|
|
+ resourceElement.setAttribute(attributeName, EMPTY_DATA_URI);
|
|
|
}
|
|
|
}
|
|
|
}));
|