|
|
@@ -317,7 +317,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
// ---------
|
|
|
// Processor
|
|
|
// ---------
|
|
|
- const PREFIX_DATA_URI_IMAGE = "data:image/";
|
|
|
+ const PREFIXES_DATA_URI_IMAGE = ["data:image/", "data:application/"];
|
|
|
const PREFIX_DATA_URI_AUDIO = "data:audio/";
|
|
|
const PREFIX_DATA_URI_VIDEO = "data:video/";
|
|
|
const PREFIX_DATA_URI_IMAGE_SVG = "data:image/svg+xml";
|
|
|
@@ -923,26 +923,26 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
|
|
|
async processPageResources() {
|
|
|
const processAttributeArgs = [
|
|
|
- ["link[href][rel*=\"icon\"]", "href", "data:", false, true],
|
|
|
- ["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]", "data", PREFIX_DATA_URI_IMAGE_SVG],
|
|
|
- ["img[src], input[src][type=image]", "src", PREFIX_DATA_URI_IMAGE, true],
|
|
|
+ ["link[href][rel*=\"icon\"]", "href", ["data:"], false, true],
|
|
|
+ ["object[type=\"image/svg+xml\"], object[type=\"image/svg-xml\"]", "data", [PREFIX_DATA_URI_IMAGE_SVG]],
|
|
|
+ ["img[src], input[src][type=image]", "src", PREFIXES_DATA_URI_IMAGE, true],
|
|
|
["embed[src*=\".svg\"], embed[src*=\".pdf\"]", "src", "data:"],
|
|
|
- ["video[poster]", "poster", PREFIX_DATA_URI_IMAGE],
|
|
|
- ["*[background]", "background", PREFIX_DATA_URI_IMAGE],
|
|
|
- ["image", "xlink:href", PREFIX_DATA_URI_IMAGE]
|
|
|
+ ["video[poster]", "poster", PREFIXES_DATA_URI_IMAGE],
|
|
|
+ ["*[background]", "background", PREFIXES_DATA_URI_IMAGE],
|
|
|
+ ["image", "xlink:href", PREFIXES_DATA_URI_IMAGE]
|
|
|
];
|
|
|
let resourcePromises = processAttributeArgs.map(([selector, attributeName, prefixDataURI, processDuplicates, removeElementIfMissing]) =>
|
|
|
ProcessorHelper.processAttribute(this.doc.querySelectorAll(selector), attributeName, prefixDataURI, this.baseURI, this.options, this.cssVariables, this.styles, this.batchRequest, processDuplicates, removeElementIfMissing)
|
|
|
);
|
|
|
resourcePromises = resourcePromises.concat([
|
|
|
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)
|
|
|
+ ProcessorHelper.processSrcset(this.doc.querySelectorAll("img[srcset], source[srcset]"), "srcset", PREFIXES_DATA_URI_IMAGE, this.baseURI, this.options, this.batchRequest)
|
|
|
]);
|
|
|
if (!this.options.removeAudioSrc) {
|
|
|
- resourcePromises.push(ProcessorHelper.processAttribute(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.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(ProcessorHelper.processAttribute(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.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);
|
|
|
ProcessorHelper.processShortcutIcons(this.doc);
|
|
|
@@ -1404,7 +1404,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- static async processAttribute(resourceElements, attributeName, prefixDataURI, baseURI, options, cssVariables, styles, batchRequest, processDuplicates, removeElementIfMissing) {
|
|
|
+ static async processAttribute(resourceElements, attributeName, prefixesDataURI, baseURI, options, cssVariables, styles, batchRequest, processDuplicates, removeElementIfMissing) {
|
|
|
await Promise.all(Array.from(resourceElements).map(async resourceElement => {
|
|
|
let resourceURL = resourceElement.getAttribute(attributeName);
|
|
|
resourceURL = Util.normalizeURL(resourceURL);
|
|
|
@@ -1421,7 +1421,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
if (removeElementIfMissing && content == EMPTY_DATA_URI) {
|
|
|
resourceElement.remove();
|
|
|
} else {
|
|
|
- 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 prefixFound = prefixesDataURI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
|
|
|
+ if (prefixFound || 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 (ProcessorHelper.replaceImageSource(resourceElement, SINGLE_FILE_VARIABLE_NAME_PREFIX + indexResource, options)) {
|
|
|
@@ -1478,7 +1479,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
- static async processSrcset(resourceElements, attributeName, prefixDataURI, baseURI, options, batchRequest) {
|
|
|
+ static async processSrcset(resourceElements, attributeName, prefixesDataURI, baseURI, options, batchRequest) {
|
|
|
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 => {
|
|
|
@@ -1492,7 +1493,8 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
if (Util.testValidURL(resourceURL)) {
|
|
|
const { content } = await batchRequest.addURL(resourceURL, true);
|
|
|
- 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 prefixFound = prefixesDataURI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
|
|
|
+ if (prefixFound && !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);
|
|
|
}
|
|
|
return content + (srcsetValue.w ? " " + srcsetValue.w + "w" : srcsetValue.d ? " " + srcsetValue.d + "x" : "");
|