single-file-core 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/index.js
CHANGED
|
@@ -336,9 +336,9 @@ class BatchRequest {
|
|
|
336
336
|
this.duplicates = new Map();
|
|
337
337
|
}
|
|
338
338
|
|
|
339
|
-
addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent } = {}) {
|
|
339
|
+
addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent, contentType } = {}) {
|
|
340
340
|
return new Promise((resolve, reject) => {
|
|
341
|
-
const requestKey = JSON.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent]);
|
|
341
|
+
const requestKey = JSON.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType]);
|
|
342
342
|
let resourceRequests = this.requests.get(requestKey);
|
|
343
343
|
if (!resourceRequests) {
|
|
344
344
|
resourceRequests = [];
|
|
@@ -365,7 +365,7 @@ class BatchRequest {
|
|
|
365
365
|
const resourceURLs = [...this.requests.keys()];
|
|
366
366
|
let indexResource = 0;
|
|
367
367
|
return Promise.all(resourceURLs.map(async requestKey => {
|
|
368
|
-
const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent] = JSON.parse(requestKey);
|
|
368
|
+
const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType] = JSON.parse(requestKey);
|
|
369
369
|
const resourceRequests = this.requests.get(requestKey);
|
|
370
370
|
try {
|
|
371
371
|
const currentIndexResource = indexResource;
|
|
@@ -374,6 +374,7 @@ class BatchRequest {
|
|
|
374
374
|
asBinary,
|
|
375
375
|
inline: !options.compressContent,
|
|
376
376
|
expectedType,
|
|
377
|
+
contentType,
|
|
377
378
|
maxResourceSize: options.maxResourceSize,
|
|
378
379
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
379
380
|
frameId: options.windowId,
|
|
@@ -1343,7 +1344,7 @@ class Processor {
|
|
|
1343
1344
|
}
|
|
1344
1345
|
if (testValidURL(resourceURL)) {
|
|
1345
1346
|
element.removeAttribute("src");
|
|
1346
|
-
await this.processorHelper.processScript(element, resourceURL, this.options, this.charset);
|
|
1347
|
+
await this.processorHelper.processScript(element, resourceURL, this.options, this.charset, this.batchRequest, this.resources);
|
|
1347
1348
|
if (element.getAttribute("async") == "async" || element.getAttribute(util.ASYNC_SCRIPT_ATTRIBUTE_NAME) == "") {
|
|
1348
1349
|
element.setAttribute("async", "");
|
|
1349
1350
|
}
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
* Source.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
/* global globalThis */
|
|
25
|
+
|
|
24
26
|
import {
|
|
25
27
|
normalizeFontFamily,
|
|
26
28
|
getFontWeight
|
|
@@ -59,6 +61,8 @@ const FONT_STRETCHES = {
|
|
|
59
61
|
"extra-expanded": "150%",
|
|
60
62
|
"ultra-expanded": "200%"
|
|
61
63
|
};
|
|
64
|
+
const Blob = globalThis.Blob;
|
|
65
|
+
const FileReader = globalThis.FileReader;
|
|
62
66
|
|
|
63
67
|
let util, cssTree;
|
|
64
68
|
|
|
@@ -74,7 +78,8 @@ export {
|
|
|
74
78
|
replaceOriginalURLs,
|
|
75
79
|
testIgnoredPath,
|
|
76
80
|
testValidPath,
|
|
77
|
-
testValidURL
|
|
81
|
+
testValidURL,
|
|
82
|
+
toDataURI
|
|
78
83
|
};
|
|
79
84
|
|
|
80
85
|
function getProcessorHelperCommonClass(utilInstance, cssTreeInstance) {
|
|
@@ -575,12 +580,10 @@ function processFontDetails(fontsDetails, fontResources) {
|
|
|
575
580
|
}
|
|
576
581
|
}
|
|
577
582
|
|
|
578
|
-
function getUpdatedResourceContent(resourceURL,
|
|
583
|
+
function getUpdatedResourceContent(resourceURL, options) {
|
|
579
584
|
if (options.rootDocument && options.updatedResources[resourceURL]) {
|
|
580
585
|
options.updatedResources[resourceURL].retrieved = true;
|
|
581
586
|
return options.updatedResources[resourceURL].content;
|
|
582
|
-
} else {
|
|
583
|
-
return content.data || "";
|
|
584
587
|
}
|
|
585
588
|
}
|
|
586
589
|
|
|
@@ -652,4 +655,13 @@ function getURL(urlFunction) {
|
|
|
652
655
|
|
|
653
656
|
function getFontStretch(stretch) {
|
|
654
657
|
return FONT_STRETCHES[stretch] || stretch;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
function toDataURI(content, contentType, charset) {
|
|
661
|
+
return new Promise((resolve, reject) => {
|
|
662
|
+
const reader = new FileReader();
|
|
663
|
+
reader.onload = () => resolve(reader.result);
|
|
664
|
+
reader.onerror = () => reject(new Error(reader.error));
|
|
665
|
+
reader.readAsDataURL(new Blob([content], { type: (contentType || "") + (charset ? ";charset=" + charset : "") }));
|
|
666
|
+
});
|
|
655
667
|
}
|
|
@@ -59,7 +59,8 @@ import {
|
|
|
59
59
|
replaceOriginalURLs,
|
|
60
60
|
testIgnoredPath,
|
|
61
61
|
testValidPath,
|
|
62
|
-
testValidURL
|
|
62
|
+
testValidURL,
|
|
63
|
+
toDataURI
|
|
63
64
|
} from "./processor-helper-common.js";
|
|
64
65
|
|
|
65
66
|
export {
|
|
@@ -152,7 +153,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
152
153
|
options.inline = true;
|
|
153
154
|
const content = await this.getStylesheetContent(resourceURL, options);
|
|
154
155
|
resourceURL = content.resourceURL;
|
|
155
|
-
content.data = getUpdatedResourceContent(resourceURL,
|
|
156
|
+
content.data = getUpdatedResourceContent(resourceURL, options) || content.data;
|
|
156
157
|
if (content.data && content.data.match(/^<!doctype /i)) {
|
|
157
158
|
content.data = "";
|
|
158
159
|
}
|
|
@@ -200,13 +201,11 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
200
201
|
return this.resolveLinkStylesheetURLs(resourceURL, baseURI, options, workStylesheet);
|
|
201
202
|
}
|
|
202
203
|
resourceURL = content.resourceURL;
|
|
203
|
-
content.data = getUpdatedResourceContent(content.resourceURL,
|
|
204
|
+
content.data = getUpdatedResourceContent(content.resourceURL, options) || content.data;
|
|
204
205
|
if (content.data && content.data.match(/^<!doctype /i)) {
|
|
205
206
|
content.data = "";
|
|
206
207
|
}
|
|
207
|
-
|
|
208
208
|
content.data = content.data.replace(/:defined/gi, "*");
|
|
209
|
-
|
|
210
209
|
let stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
211
210
|
const importFound = await this.resolveImportURLs(stylesheet, resourceURL, options, workStylesheet);
|
|
212
211
|
if (importFound) {
|
|
@@ -305,9 +304,11 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
305
304
|
// ignored
|
|
306
305
|
}
|
|
307
306
|
if (testValidURL(resourceURL)) {
|
|
307
|
+
const declaredContentType = ["OBJECT", "EMBED"].includes(resourceElement.tagName.toUpperCase()) ? resourceElement.getAttribute("type") : "";
|
|
308
|
+
const groupDuplicates = options.groupDuplicateImages && resourceElement.tagName.toUpperCase() == "IMG" && attributeName == "src";
|
|
308
309
|
let { content, indexResource, duplicate } = await batchRequest.addURL(
|
|
309
310
|
resourceURL,
|
|
310
|
-
{ asBinary: true, expectedType,
|
|
311
|
+
{ asBinary: true, expectedType, contentType: declaredContentType, groupDuplicates });
|
|
311
312
|
if (originURL) {
|
|
312
313
|
if (this.testEmptyResource(content)) {
|
|
313
314
|
try {
|
|
@@ -321,6 +322,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
321
322
|
asBinary: true,
|
|
322
323
|
inline: true,
|
|
323
324
|
expectedType,
|
|
325
|
+
contentType: declaredContentType,
|
|
324
326
|
maxResourceSize: options.maxResourceSize,
|
|
325
327
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
326
328
|
frameId: options.windowId,
|
|
@@ -449,23 +451,28 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
449
451
|
return {};
|
|
450
452
|
}
|
|
451
453
|
|
|
452
|
-
async processScript(element, resourceURL, options, charset) {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
454
|
+
async processScript(element, resourceURL, options, charset, batchRequest) {
|
|
455
|
+
let content = getUpdatedResourceContent(resourceURL, options);
|
|
456
|
+
if (content) {
|
|
457
|
+
content = await toDataURI(content, "text/javascript", charset);
|
|
458
|
+
} else {
|
|
459
|
+
const result = await batchRequest.addURL(resourceURL, {
|
|
460
|
+
asBinary: true,
|
|
461
|
+
inline: true,
|
|
462
|
+
charset: charset != UTF8_CHARSET && charset,
|
|
463
|
+
maxResourceSize: options.maxResourceSize,
|
|
464
|
+
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
465
|
+
frameId: options.windowId,
|
|
466
|
+
resourceReferrer: options.resourceReferrer,
|
|
467
|
+
baseURI: options.baseURI,
|
|
468
|
+
blockMixedContent: options.blockMixedContent,
|
|
469
|
+
expectedType: "script",
|
|
470
|
+
acceptHeaders: options.acceptHeaders,
|
|
471
|
+
networkTimeout: options.networkTimeout
|
|
472
|
+
});
|
|
473
|
+
content = result.content;
|
|
474
|
+
}
|
|
475
|
+
element.setAttribute("src", content);
|
|
469
476
|
}
|
|
470
477
|
|
|
471
478
|
setMetaCSP(metaElement) {
|
|
@@ -154,7 +154,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
154
154
|
if (existingStylesheet) {
|
|
155
155
|
stylesheets.set({ urlNode }, { url: resourceURL, stylesheet: existingStylesheet[1].stylesheet, scoped });
|
|
156
156
|
} else {
|
|
157
|
-
content.data = getUpdatedResourceContent(resourceURL,
|
|
157
|
+
content.data = getUpdatedResourceContent(resourceURL, options) || content.data;
|
|
158
158
|
stylesheetInfo.stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
159
159
|
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets);
|
|
160
160
|
stylesheets.set({ urlNode }, stylesheetInfo);
|
|
@@ -202,7 +202,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
202
202
|
mediaText: stylesheetInfo.mediaText
|
|
203
203
|
});
|
|
204
204
|
} else {
|
|
205
|
-
content.data = getUpdatedResourceContent(content.resourceURL,
|
|
205
|
+
content.data = getUpdatedResourceContent(content.resourceURL, options) || content.data;
|
|
206
206
|
stylesheetInfo.stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
207
207
|
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets);
|
|
208
208
|
stylesheets.set({ element }, stylesheetInfo);
|
|
@@ -280,8 +280,9 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
280
280
|
// ignored
|
|
281
281
|
}
|
|
282
282
|
if (testValidURL(resourceURL)) {
|
|
283
|
+
const declaredContentType = ["OBJECT", "EMBED"].includes(resourceElement.tagName.toUpperCase()) ? resourceElement.getAttribute("type") : "";
|
|
283
284
|
let { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL,
|
|
284
|
-
{ asBinary: true, expectedType });
|
|
285
|
+
{ asBinary: true, expectedType, contentType: declaredContentType });
|
|
285
286
|
if (originURL) {
|
|
286
287
|
if (this.testEmptyResource(content)) {
|
|
287
288
|
try {
|
|
@@ -294,6 +295,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
294
295
|
content = (await util.getContent(resourceURL, {
|
|
295
296
|
asBinary: true,
|
|
296
297
|
expectedType,
|
|
298
|
+
contentType: declaredContentType,
|
|
297
299
|
maxResourceSize: options.maxResourceSize,
|
|
298
300
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
299
301
|
frameId: options.windowId,
|
|
@@ -376,8 +378,8 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
376
378
|
};
|
|
377
379
|
}
|
|
378
380
|
|
|
379
|
-
async processScript(element, resourceURL, options, charset) {
|
|
380
|
-
|
|
381
|
+
async processScript(element, resourceURL, options, charset, batchRequest, resources) {
|
|
382
|
+
let { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL, {
|
|
381
383
|
asBinary: true,
|
|
382
384
|
charset: charset != UTF8_CHARSET && charset,
|
|
383
385
|
maxResourceSize: options.maxResourceSize,
|
|
@@ -390,8 +392,10 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
390
392
|
acceptHeaders: options.acceptHeaders,
|
|
391
393
|
networkTimeout: options.networkTimeout
|
|
392
394
|
});
|
|
393
|
-
content
|
|
394
|
-
|
|
395
|
+
content = getUpdatedResourceContent(resourceURL, options) || content;
|
|
396
|
+
const name = "scripts/" + indexResource + extension;
|
|
397
|
+
element.setAttribute("src", name);
|
|
398
|
+
resources.scripts.set(indexResource, { name, content, extension, contentType, url: resourceURL });
|
|
395
399
|
}
|
|
396
400
|
|
|
397
401
|
setMetaCSP(metaElement) {
|
package/core/util.js
CHANGED
|
@@ -286,7 +286,10 @@ function getInstance(utilOptions) {
|
|
|
286
286
|
// ignored
|
|
287
287
|
}
|
|
288
288
|
if (!contentType || (contentType == CONTENT_TYPE_OCTET_STREAM && options.asBinary)) {
|
|
289
|
-
contentType = guessMIMEType(options.expectedType, buffer
|
|
289
|
+
contentType = guessMIMEType(options.expectedType, buffer);
|
|
290
|
+
if (!contentType) {
|
|
291
|
+
contentType = options.contentType ? options.contentType : options.asBinary ? CONTENT_TYPE_OCTET_STREAM : "";
|
|
292
|
+
}
|
|
290
293
|
}
|
|
291
294
|
if (!charset && options.charset) {
|
|
292
295
|
charset = options.charset;
|
|
@@ -366,7 +369,7 @@ async function getFetchResponse(resourceURL, options, data, charset, contentType
|
|
|
366
369
|
return { data, resourceURL, charset, contentType };
|
|
367
370
|
}
|
|
368
371
|
|
|
369
|
-
function guessMIMEType(expectedType, buffer
|
|
372
|
+
function guessMIMEType(expectedType, buffer) {
|
|
370
373
|
if (expectedType == "image") {
|
|
371
374
|
if (compareBytes([255, 255, 255, 255], [0, 0, 1, 0])) {
|
|
372
375
|
return "image/x-icon";
|
|
@@ -463,7 +466,6 @@ function guessMIMEType(expectedType, buffer, asBinary) {
|
|
|
463
466
|
return "audio/3gpp";
|
|
464
467
|
}
|
|
465
468
|
}
|
|
466
|
-
return asBinary ? CONTENT_TYPE_OCTET_STREAM : "";
|
|
467
469
|
|
|
468
470
|
function compareBytes(mask, pattern) {
|
|
469
471
|
let patternMatch = true, index = 0;
|
package/package.json
CHANGED
|
@@ -62,7 +62,8 @@ async function extract(content, { password, prompt = () => { }, shadowRootScript
|
|
|
62
62
|
"ttf": "font/ttf",
|
|
63
63
|
"woff": "font/woff",
|
|
64
64
|
"woff2": "font/woff2",
|
|
65
|
-
"eot": "application/vnd.ms-fontobject"
|
|
65
|
+
"eot": "application/vnd.ms-fontobject",
|
|
66
|
+
"pdf": "application/pdf"
|
|
66
67
|
};
|
|
67
68
|
const REGEXP_MATCH_STYLESHEET = /stylesheet_[0-9]+\.css/;
|
|
68
69
|
const REGEXP_MATCH_SCRIPT = /scripts\/[0-9]+\.js/;
|