|
|
@@ -258,16 +258,26 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
class BatchRequest {
|
|
|
constructor() {
|
|
|
this.requests = new Map();
|
|
|
+ this.duplicates = new Map();
|
|
|
}
|
|
|
|
|
|
- async addURL(resourceURL, asDataURI = true) {
|
|
|
+ async addURL(resourceURL, asDataURI, groupDuplicates) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
const requestKey = JSON.stringify([resourceURL, asDataURI]);
|
|
|
- const resourceRequests = this.requests.get(requestKey);
|
|
|
- if (resourceRequests) {
|
|
|
- resourceRequests.push({ resolve, reject });
|
|
|
- } else {
|
|
|
- this.requests.set(requestKey, [{ resolve, reject }]);
|
|
|
+ let resourceRequests = this.requests.get(requestKey);
|
|
|
+ if (!resourceRequests) {
|
|
|
+ resourceRequests = [];
|
|
|
+ this.requests.set(requestKey, resourceRequests);
|
|
|
+ }
|
|
|
+ const callbacks = { resolve, reject };
|
|
|
+ resourceRequests.push(callbacks);
|
|
|
+ if (groupDuplicates) {
|
|
|
+ let duplicateRequests = this.duplicates.get(requestKey);
|
|
|
+ if (!duplicateRequests) {
|
|
|
+ duplicateRequests = [];
|
|
|
+ this.duplicates.set(requestKey, duplicateRequests);
|
|
|
+ }
|
|
|
+ duplicateRequests.push(callbacks);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
@@ -286,7 +296,11 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const content = await DocUtil.getContent(resourceURL, { asDataURI, maxResourceSize: options.maxResourceSize, maxResourceSizeEnabled: options.maxResourceSizeEnabled });
|
|
|
indexResource = indexResource + 1;
|
|
|
onloadListener({ index: indexResource, url: resourceURL });
|
|
|
- resourceRequests.forEach(resourceRequest => resourceRequest.resolve({ content: content.data, indexResource, duplicate: Boolean(resourceRequests.length > 1) }));
|
|
|
+ resourceRequests.forEach(callbacks => {
|
|
|
+ const duplicateCallbacks = this.duplicates.get(requestKey);
|
|
|
+ const duplicate = duplicateCallbacks && duplicateCallbacks.length > 1 && duplicateCallbacks.includes(callbacks);
|
|
|
+ callbacks.resolve({ content: content.data, indexResource, duplicate });
|
|
|
+ });
|
|
|
} catch (error) {
|
|
|
indexResource = indexResource + 1;
|
|
|
onloadListener({ index: indexResource, url: resourceURL });
|
|
|
@@ -1272,7 +1286,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
- let { content } = await batchRequest.addURL(resourceURL);
|
|
|
+ let { content } = await batchRequest.addURL(resourceURL, true);
|
|
|
let validResource = content == EMPTY_DATA_URI || content.startsWith(PREFIX_DATA_URI_VND) || content.startsWith(PREFIX_DATA_URI_IMAGE_SVG);
|
|
|
if (!validResource) {
|
|
|
validResource = await DocUtil.validFont(urlFunction);
|
|
|
@@ -1302,7 +1316,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
const resourceURL = Util.normalizeURL(originalResourceURL);
|
|
|
if (!Util.testIgnoredPath(resourceURL)) {
|
|
|
if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
- let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL);
|
|
|
+ let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, true, true);
|
|
|
if (duplicate && options.groupDuplicateImages) {
|
|
|
const tokens = [];
|
|
|
findURLToken(originalResourceURL, declaration.value.children, (token, parent) => {
|
|
|
@@ -1345,7 +1359,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
// ignored
|
|
|
}
|
|
|
if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
- const { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL);
|
|
|
+ const { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, true, resourceElement.tagName == "IMG" && attributeName == "src");
|
|
|
if (removeElementIfMissing && content == EMPTY_DATA_URI) {
|
|
|
resourceElement.remove();
|
|
|
} else {
|
|
|
@@ -1384,7 +1398,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
}
|
|
|
if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
try {
|
|
|
- const { content } = await batchRequest.addURL(resourceURL, false);
|
|
|
+ const { content } = await batchRequest.addURL(resourceURL);
|
|
|
const DOMParser = DocUtil.getParser();
|
|
|
if (DOMParser) {
|
|
|
const svgDoc = new DOMParser().parseFromString(content, "image/svg+xml");
|
|
|
@@ -1424,7 +1438,7 @@ this.SingleFileCore = this.SingleFileCore || (() => {
|
|
|
// ignored
|
|
|
}
|
|
|
if (Util.testValidURL(resourceURL, baseURI, options.url)) {
|
|
|
- const { content } = await batchRequest.addURL(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)) {
|
|
|
resourceElement.setAttribute(attributeName, EMPTY_IMAGE);
|
|
|
}
|