single-file-core 1.6.24 → 1.6.25
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/helper.js +16 -0
- package/core/index.js +1 -0
- package/core/lib/processor-helper.js +12 -6
- package/core/util.js +5 -2
- package/package.json +1 -1
package/core/helper.js
CHANGED
|
@@ -69,6 +69,7 @@ const DISABLED_NOSCRIPT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "disable
|
|
|
69
69
|
const SELECTED_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "selected-content";
|
|
70
70
|
const INVALID_ELEMENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "invalid-element";
|
|
71
71
|
const ASYNC_SCRIPT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "async-script";
|
|
72
|
+
const CUSTOM_STYLESHEET_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "custom-stylesheet";
|
|
72
73
|
const FLOW_ELEMENTS_SELECTOR = "*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)";
|
|
73
74
|
const KEPT_TAG_NAMES = ["NOSCRIPT", "DISABLED-NOSCRIPT", "META", "LINK", "STYLE", "TITLE", "TEMPLATE", "SOURCE", "OBJECT", "SCRIPT", "HEAD", "BODY"];
|
|
74
75
|
const INVOKABLE_ELEMENTS_SELECTOR = "[popover][id], dialog[id]";
|
|
@@ -173,6 +174,7 @@ export {
|
|
|
173
174
|
WIN_ID_ATTRIBUTE_NAME,
|
|
174
175
|
PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
|
|
175
176
|
REMOVED_CONTENT_ATTRIBUTE_NAME,
|
|
177
|
+
CUSTOM_STYLESHEET_ATTRIBUTE_NAME,
|
|
176
178
|
HIDDEN_CONTENT_ATTRIBUTE_NAME,
|
|
177
179
|
HIDDEN_FRAME_ATTRIBUTE_NAME,
|
|
178
180
|
IMAGE_ATTRIBUTE_NAME,
|
|
@@ -305,6 +307,9 @@ function preProcessDoc(doc, win, options) {
|
|
|
305
307
|
element.textContent = "";
|
|
306
308
|
});
|
|
307
309
|
initDoc(doc);
|
|
310
|
+
if (options.customStylesheet) {
|
|
311
|
+
insertCustomStylesheet(doc, options.customStylesheet);
|
|
312
|
+
}
|
|
308
313
|
if (doc.head) {
|
|
309
314
|
doc.head.querySelectorAll(FLOW_ELEMENTS_SELECTOR).forEach(element => element.hidden = true);
|
|
310
315
|
}
|
|
@@ -375,6 +380,16 @@ function preProcessDoc(doc, win, options) {
|
|
|
375
380
|
};
|
|
376
381
|
}
|
|
377
382
|
|
|
383
|
+
function insertCustomStylesheet(doc, content) {
|
|
384
|
+
const parentElement = doc.body || doc.documentElement;
|
|
385
|
+
if (parentElement) {
|
|
386
|
+
const styleElement = doc.createElement("style");
|
|
387
|
+
styleElement.setAttribute(CUSTOM_STYLESHEET_ATTRIBUTE_NAME, "");
|
|
388
|
+
styleElement.textContent = content;
|
|
389
|
+
parentElement.appendChild(styleElement);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
378
393
|
function markInvalidNesting(doc) {
|
|
379
394
|
if (!doc.body) {
|
|
380
395
|
return;
|
|
@@ -1093,6 +1108,7 @@ function testHiddenElement(element, computedStyle) {
|
|
|
1093
1108
|
|
|
1094
1109
|
function postProcessDoc(doc, markedElements, invalidElements) {
|
|
1095
1110
|
removeNestingMarkers(doc);
|
|
1111
|
+
doc.querySelectorAll("style[" + CUSTOM_STYLESHEET_ATTRIBUTE_NAME + "]").forEach(element => element.remove());
|
|
1096
1112
|
doc.querySelectorAll("[" + DISABLED_NOSCRIPT_ATTRIBUTE_NAME + "]").forEach(element => {
|
|
1097
1113
|
element.textContent = element.getAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
|
|
1098
1114
|
element.removeAttribute(DISABLED_NOSCRIPT_ATTRIBUTE_NAME);
|
package/core/index.js
CHANGED
|
@@ -661,6 +661,7 @@ class Processor {
|
|
|
661
661
|
}
|
|
662
662
|
|
|
663
663
|
preProcessPage() {
|
|
664
|
+
this.doc.querySelectorAll("style[" + util.CUSTOM_STYLESHEET_ATTRIBUTE_NAME + "]").forEach(element => element.removeAttribute(util.CUSTOM_STYLESHEET_ATTRIBUTE_NAME));
|
|
664
665
|
this.doc.body.querySelectorAll(":not(svg) title, meta, link[href][rel*=\"icon\"]").forEach(element => {
|
|
665
666
|
if ((this.options.win && element instanceof this.options.win.HTMLElement) || element instanceof globalThis.HTMLElement) {
|
|
666
667
|
this.doc.head.appendChild(element);
|
|
@@ -331,13 +331,15 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
331
331
|
blockMixedContent: options.blockMixedContent,
|
|
332
332
|
...getStylesheetReferrer(resourceURL, options)
|
|
333
333
|
});
|
|
334
|
-
const name = "fonts/" + indexResource + extension;
|
|
334
|
+
const name = this.testEmptyResource(content) ? util.EMPTY_RESOURCE : "fonts/" + indexResource + extension;
|
|
335
335
|
if (!isDataURL(resourceURL) && options.saveOriginalURLs) {
|
|
336
336
|
urlNode.value = "-sf-url-original(" + JSON.stringify(originalResourceURL) + ") " + name;
|
|
337
337
|
} else {
|
|
338
338
|
urlNode.value = name;
|
|
339
339
|
}
|
|
340
|
-
|
|
340
|
+
if (!this.testEmptyResource(content)) {
|
|
341
|
+
resources.fonts.set(indexResource, { name, content, extension, contentType, url: resourceURL });
|
|
342
|
+
}
|
|
341
343
|
}
|
|
342
344
|
|
|
343
345
|
groupDuplicateFonts(stylesheets, fonts) {
|
|
@@ -412,13 +414,15 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
412
414
|
if ((!testIgnoredPath(resourceURL) && testValidURL(resourceURL)) || testGeneratedDataURI(resourceURL, options)) {
|
|
413
415
|
let { content, indexResource, contentType, extension } = await batchRequest.addURL(resourceURL,
|
|
414
416
|
{ asBinary: true, expectedType: "image", ...getStylesheetReferrer(resourceURL, options) });
|
|
415
|
-
const name = "images/" + indexResource + extension;
|
|
417
|
+
const name = this.testEmptyResource(content) ? util.EMPTY_RESOURCE : "images/" + indexResource + extension;
|
|
416
418
|
if (!isDataURL(resourceURL) && options.saveOriginalURLs) {
|
|
417
419
|
urlNode.value = "-sf-url-original(" + JSON.stringify(originalResourceURL) + ") " + name;
|
|
418
420
|
} else {
|
|
419
421
|
urlNode.value = name;
|
|
420
422
|
}
|
|
421
|
-
|
|
423
|
+
if (!this.testEmptyResource(content)) {
|
|
424
|
+
resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
|
|
425
|
+
}
|
|
422
426
|
}
|
|
423
427
|
} else {
|
|
424
428
|
urlNode.value = util.EMPTY_RESOURCE;
|
|
@@ -505,8 +509,10 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
505
509
|
|
|
506
510
|
async processImageSrcset(resourceURL, srcsetValue, resources, batchRequest, resourceElement) {
|
|
507
511
|
const { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", referrerPolicy: getReferrerPolicy(resourceElement) });
|
|
508
|
-
const name = "images/" + indexResource + extension;
|
|
509
|
-
|
|
512
|
+
const name = this.testEmptyResource(content) ? util.EMPTY_RESOURCE : "images/" + indexResource + extension;
|
|
513
|
+
if (!this.testEmptyResource(content)) {
|
|
514
|
+
resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
|
|
515
|
+
}
|
|
510
516
|
resourceElement.removeAttribute(CROSS_ORIGIN_ATTRIBUTE_NAME);
|
|
511
517
|
return serializeSrcset([Object.assign({}, srcsetValue, { url: name })]);
|
|
512
518
|
}
|
package/core/util.js
CHANGED
|
@@ -70,6 +70,8 @@ const ZIP_FILENAME_OFFSET = 30;
|
|
|
70
70
|
const USD_FILENAME_REGEXP = /\.usd[ac]?$/i;
|
|
71
71
|
const CONTENT_TYPES_HTML = ["text/html", "application/xhtml+xml"];
|
|
72
72
|
const EXPECTED_TYPES_MEDIA = ["font", "image", "video", "audio", "model"];
|
|
73
|
+
const EXPECTED_TYPE_IMAGE = "image";
|
|
74
|
+
const EXPECTED_TYPE_DOCUMENT = "document";
|
|
73
75
|
|
|
74
76
|
const URL = globalThis.URL;
|
|
75
77
|
const DOMParser = globalThis.DOMParser;
|
|
@@ -226,6 +228,7 @@ function getInstance(utilOptions) {
|
|
|
226
228
|
PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME: helper.PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
|
|
227
229
|
STYLESHEET_ATTRIBUTE_NAME: helper.STYLESHEET_ATTRIBUTE_NAME,
|
|
228
230
|
LINK_STYLESHEET_ATTRIBUTE_NAME: helper.LINK_STYLESHEET_ATTRIBUTE_NAME,
|
|
231
|
+
CUSTOM_STYLESHEET_ATTRIBUTE_NAME: helper.CUSTOM_STYLESHEET_ATTRIBUTE_NAME,
|
|
229
232
|
SELECTED_CONTENT_ATTRIBUTE_NAME: helper.SELECTED_CONTENT_ATTRIBUTE_NAME,
|
|
230
233
|
INVALID_ELEMENT_ATTRIBUTE_NAME: helper.INVALID_ELEMENT_ATTRIBUTE_NAME,
|
|
231
234
|
COMMENT_HEADER: helper.COMMENT_HEADER,
|
|
@@ -320,7 +323,7 @@ function getInstance(utilOptions) {
|
|
|
320
323
|
charset = options.charset;
|
|
321
324
|
}
|
|
322
325
|
if (options.asBinary) {
|
|
323
|
-
if (response.status >= 400 || (EXPECTED_TYPES_MEDIA.includes(options.expectedType) && CONTENT_TYPES_HTML.includes(contentType))) {
|
|
326
|
+
if ((response.status >= 400 && options.expectedType != EXPECTED_TYPE_IMAGE) || (EXPECTED_TYPES_MEDIA.includes(options.expectedType) && CONTENT_TYPES_HTML.includes(contentType))) {
|
|
324
327
|
return getFetchResponse(resourceURL, options);
|
|
325
328
|
}
|
|
326
329
|
try {
|
|
@@ -337,7 +340,7 @@ function getInstance(utilOptions) {
|
|
|
337
340
|
return getFetchResponse(resourceURL, options);
|
|
338
341
|
}
|
|
339
342
|
} else {
|
|
340
|
-
if (response.status >= 400) {
|
|
343
|
+
if (response.status >= 400 && options.expectedType != EXPECTED_TYPE_DOCUMENT) {
|
|
341
344
|
return getFailedFetchResponse(resourceURL, options);
|
|
342
345
|
}
|
|
343
346
|
if (options.validateTextContentType && contentType && !contentType.startsWith(PREFIX_CONTENT_TYPE_TEXT)) {
|