single-file-core 1.6.17 → 1.6.19
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 +18 -3
- package/core/index.js +9 -3
- package/core/lib/processor-helper-common.js +51 -7
- package/core/lib/processor-helper-inline.js +26 -14
- package/core/lib/processor-helper.js +22 -10
- package/core/util.js +18 -6
- package/package.json +1 -1
package/core/helper.js
CHANGED
|
@@ -64,6 +64,7 @@ const INPUT_VALUE_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "input-value";
|
|
|
64
64
|
const INPUT_CHECKED_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "input-checked";
|
|
65
65
|
const LAZY_SRC_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "lazy-loaded-src";
|
|
66
66
|
const STYLESHEET_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "stylesheet";
|
|
67
|
+
const LINK_STYLESHEET_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "link-stylesheet";
|
|
67
68
|
const DISABLED_NOSCRIPT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "disabled-noscript";
|
|
68
69
|
const SELECTED_CONTENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "selected-content";
|
|
69
70
|
const INVALID_ELEMENT_ATTRIBUTE_NAME = "data-" + SINGLE_FILE_PREFIX + "invalid-element";
|
|
@@ -174,6 +175,7 @@ export {
|
|
|
174
175
|
STYLE_ATTRIBUTE_NAME,
|
|
175
176
|
LAZY_SRC_ATTRIBUTE_NAME,
|
|
176
177
|
STYLESHEET_ATTRIBUTE_NAME,
|
|
178
|
+
LINK_STYLESHEET_ATTRIBUTE_NAME,
|
|
177
179
|
SELECTED_CONTENT_ATTRIBUTE_NAME,
|
|
178
180
|
INVALID_ELEMENT_ATTRIBUTE_NAME,
|
|
179
181
|
ASYNC_SCRIPT_ATTRIBUTE_NAME,
|
|
@@ -330,6 +332,7 @@ function preProcessDoc(doc, win, options) {
|
|
|
330
332
|
};
|
|
331
333
|
}
|
|
332
334
|
setNestingMarkersData(doc);
|
|
335
|
+
const linkStylesheets = markLinkStylesheets(doc, elementsInfo.markedElements);
|
|
333
336
|
let referrer = "";
|
|
334
337
|
if (doc.referrer) {
|
|
335
338
|
try {
|
|
@@ -343,7 +346,8 @@ function preProcessDoc(doc, win, options) {
|
|
|
343
346
|
canvases: elementsInfo.canvases,
|
|
344
347
|
fonts: getFontsData(),
|
|
345
348
|
worklets: getWorkletsData(),
|
|
346
|
-
stylesheets: getStylesheetsData(doc),
|
|
349
|
+
stylesheets: getStylesheetsData(doc, elementsInfo.markedElements),
|
|
350
|
+
linkStylesheets,
|
|
347
351
|
images: elementsInfo.images,
|
|
348
352
|
posters: elementsInfo.posters,
|
|
349
353
|
videos: elementsInfo.videos,
|
|
@@ -1087,7 +1091,7 @@ function postProcessDoc(doc, markedElements, invalidElements) {
|
|
|
1087
1091
|
doc.head.querySelectorAll("*:not(base):not(link):not(meta):not(noscript):not(script):not(style):not(template):not(title)").forEach(element => element.removeAttribute("hidden"));
|
|
1088
1092
|
}
|
|
1089
1093
|
if (!markedElements) {
|
|
1090
|
-
const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, HIDDEN_FRAME_ATTRIBUTE_NAME, HIDDEN_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, VIDEO_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, INPUT_CHECKED_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, SLOT_ATTRIBUTE_NAME, ASSIGNED_SLOT_ATTRIBUTE_NAME, STYLESHEET_ATTRIBUTE_NAME, ASYNC_SCRIPT_ATTRIBUTE_NAME];
|
|
1094
|
+
const singleFileAttributes = [REMOVED_CONTENT_ATTRIBUTE_NAME, HIDDEN_FRAME_ATTRIBUTE_NAME, HIDDEN_CONTENT_ATTRIBUTE_NAME, PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME, IMAGE_ATTRIBUTE_NAME, POSTER_ATTRIBUTE_NAME, VIDEO_ATTRIBUTE_NAME, CANVAS_ATTRIBUTE_NAME, INPUT_VALUE_ATTRIBUTE_NAME, INPUT_CHECKED_ATTRIBUTE_NAME, SHADOW_ROOT_ATTRIBUTE_NAME, SLOT_ATTRIBUTE_NAME, ASSIGNED_SLOT_ATTRIBUTE_NAME, STYLESHEET_ATTRIBUTE_NAME, LINK_STYLESHEET_ATTRIBUTE_NAME, ASYNC_SCRIPT_ATTRIBUTE_NAME];
|
|
1091
1095
|
markedElements = doc.querySelectorAll(singleFileAttributes.map(name => "[" + name + "]").join(","));
|
|
1092
1096
|
}
|
|
1093
1097
|
markedElements.forEach(element => {
|
|
@@ -1106,6 +1110,7 @@ function postProcessDoc(doc, markedElements, invalidElements) {
|
|
|
1106
1110
|
element.removeAttribute(SLOT_ATTRIBUTE_NAME);
|
|
1107
1111
|
element.removeAttribute(ASSIGNED_SLOT_ATTRIBUTE_NAME);
|
|
1108
1112
|
element.removeAttribute(STYLESHEET_ATTRIBUTE_NAME);
|
|
1113
|
+
element.removeAttribute(LINK_STYLESHEET_ATTRIBUTE_NAME);
|
|
1109
1114
|
element.removeAttribute(ASYNC_SCRIPT_ATTRIBUTE_NAME);
|
|
1110
1115
|
element.removeAttribute(STYLE_ATTRIBUTE_NAME);
|
|
1111
1116
|
});
|
|
@@ -1114,7 +1119,16 @@ function postProcessDoc(doc, markedElements, invalidElements) {
|
|
|
1114
1119
|
}
|
|
1115
1120
|
}
|
|
1116
1121
|
|
|
1117
|
-
function
|
|
1122
|
+
function markLinkStylesheets(doc, markedElements) {
|
|
1123
|
+
const linkElements = Array.from(doc.querySelectorAll("link[rel*=stylesheet]"));
|
|
1124
|
+
linkElements.forEach((linkElement, linkIndex) => {
|
|
1125
|
+
linkElement.setAttribute(LINK_STYLESHEET_ATTRIBUTE_NAME, linkIndex);
|
|
1126
|
+
markedElements.push(linkElement);
|
|
1127
|
+
});
|
|
1128
|
+
return linkElements;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
function getStylesheetsData(doc, markedElements) {
|
|
1118
1132
|
if (doc) {
|
|
1119
1133
|
const contents = [];
|
|
1120
1134
|
doc.querySelectorAll("style").forEach((styleElement, styleIndex) => {
|
|
@@ -1129,6 +1143,7 @@ function getStylesheetsData(doc) {
|
|
|
1129
1143
|
const sheetStylesheet = Array.from(styleElement.sheet.cssRules).map(cssRule => cssRule.cssText).join("\n");
|
|
1130
1144
|
if (!stylesheet || textContentStylesheet != sheetStylesheet) {
|
|
1131
1145
|
styleElement.setAttribute(STYLESHEET_ATTRIBUTE_NAME, styleIndex);
|
|
1146
|
+
markedElements.push(styleElement);
|
|
1132
1147
|
contents[styleIndex] = Array.from(styleElement.sheet.cssRules).map(cssRule => cssRule.cssText).join("\n");
|
|
1133
1148
|
}
|
|
1134
1149
|
}
|
package/core/index.js
CHANGED
|
@@ -185,6 +185,7 @@ class Runner {
|
|
|
185
185
|
this.options.rootDocument = root;
|
|
186
186
|
this.options.updatedResources = this.options.updatedResources || {};
|
|
187
187
|
this.options.fontTests = new Map();
|
|
188
|
+
this.options.stylesheetReferrers = new Map();
|
|
188
189
|
if (root && !this.options.saveFilenameTemplateData && (this.options.openEditor || /{digest-sha-\d/.test(this.options.filenameTemplate))) {
|
|
189
190
|
this.options.saveFilenameTemplateData = true;
|
|
190
191
|
this.options.omitReferrerInTemplateData = !/{url-referrer/.test(this.options.filenameTemplate);
|
|
@@ -197,6 +198,7 @@ class Runner {
|
|
|
197
198
|
this.options.fonts = docData.fonts;
|
|
198
199
|
this.options.worklets = docData.worklets;
|
|
199
200
|
this.options.stylesheets = docData.stylesheets;
|
|
201
|
+
this.options.linkStylesheets = docData.linkStylesheets;
|
|
200
202
|
this.options.images = docData.images;
|
|
201
203
|
this.options.posters = docData.posters;
|
|
202
204
|
this.options.videos = docData.videos;
|
|
@@ -345,9 +347,9 @@ class BatchRequest {
|
|
|
345
347
|
this.duplicates = new Map();
|
|
346
348
|
}
|
|
347
349
|
|
|
348
|
-
addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent, contentType } = {}) {
|
|
350
|
+
addURL(resourceURL, { asBinary, expectedType, groupDuplicates, baseURI, blockMixedContent, contentType, referrerPolicy, stylesheetURL, stylesheetReferrerPolicy } = {}) {
|
|
349
351
|
return new Promise((resolve, reject) => {
|
|
350
|
-
const requestKey = JSON.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType]);
|
|
352
|
+
const requestKey = JSON.stringify([resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType, referrerPolicy, stylesheetURL, stylesheetReferrerPolicy]);
|
|
351
353
|
let resourceRequests = this.requests.get(requestKey);
|
|
352
354
|
if (this.cancelled) {
|
|
353
355
|
reject();
|
|
@@ -381,7 +383,7 @@ class BatchRequest {
|
|
|
381
383
|
const resourceURLs = [...this.requests.keys()];
|
|
382
384
|
let indexResource = 0;
|
|
383
385
|
return Promise.all(resourceURLs.map(async requestKey => {
|
|
384
|
-
const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType] = JSON.parse(requestKey);
|
|
386
|
+
const [resourceURL, asBinary, expectedType, baseURI, blockMixedContent, contentType, referrerPolicy, stylesheetURL, stylesheetReferrerPolicy] = JSON.parse(requestKey);
|
|
385
387
|
const resourceRequests = this.requests.get(requestKey);
|
|
386
388
|
try {
|
|
387
389
|
const currentIndexResource = indexResource;
|
|
@@ -395,6 +397,9 @@ class BatchRequest {
|
|
|
395
397
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
396
398
|
frameId: options.windowId,
|
|
397
399
|
resourceReferrer: options.resourceReferrer,
|
|
400
|
+
referrerPolicy,
|
|
401
|
+
stylesheetURL,
|
|
402
|
+
stylesheetReferrerPolicy,
|
|
398
403
|
baseURI,
|
|
399
404
|
blockMixedContent,
|
|
400
405
|
acceptHeaders: options.acceptHeaders,
|
|
@@ -1443,6 +1448,7 @@ class Processor {
|
|
|
1443
1448
|
options.fonts = frameData.fonts;
|
|
1444
1449
|
options.worklets = frameData.worklets;
|
|
1445
1450
|
options.stylesheets = frameData.stylesheets;
|
|
1451
|
+
options.linkStylesheets = null;
|
|
1446
1452
|
options.images = frameData.images;
|
|
1447
1453
|
options.posters = frameData.posters;
|
|
1448
1454
|
options.videos = frameData.videos;
|
|
@@ -37,6 +37,7 @@ const FILE_URI_PREFIX = /^file:\/\//;
|
|
|
37
37
|
const EMPTY_URL = /^https?:\/\/+\s*$/;
|
|
38
38
|
const NOT_EMPTY_URL = /^(https?:\/\/|file:\/\/|blob:).+/;
|
|
39
39
|
const PREFIX_DATA_URI_IMAGE_SVG = "data:image/svg+xml";
|
|
40
|
+
const REFERRER_POLICY_ELEMENTS = ["IMG", "LINK", "SCRIPT"];
|
|
40
41
|
const UTF8_CHARSET = "utf-8";
|
|
41
42
|
const REGEXP_URL_FUNCTION = /(url|local|-sf-url-original)\(.*?\)\s*(,|$)/g;
|
|
42
43
|
const REGEXP_URL_SIMPLE_QUOTES_FN = /url\s*\(\s*'(.*?)'\s*\)/i;
|
|
@@ -83,7 +84,9 @@ export {
|
|
|
83
84
|
testValidPath,
|
|
84
85
|
testValidURL,
|
|
85
86
|
resizeImage,
|
|
86
|
-
toDataURI
|
|
87
|
+
toDataURI,
|
|
88
|
+
getReferrerPolicy,
|
|
89
|
+
getStylesheetReferrer
|
|
87
90
|
};
|
|
88
91
|
|
|
89
92
|
function getProcessorHelperCommonClass(utilInstance, cssTreeInstance) {
|
|
@@ -290,7 +293,7 @@ class ProcessorHelperCommon {
|
|
|
290
293
|
element.style.setProperty("background-attachment", "scroll", "important");
|
|
291
294
|
}
|
|
292
295
|
|
|
293
|
-
async getStylesheetContent(resourceURL, options) {
|
|
296
|
+
async getStylesheetContent(resourceURL, options, stylesheetReferrer = {}) {
|
|
294
297
|
const content = await util.getContent(resourceURL, {
|
|
295
298
|
inline: !options.compressContent,
|
|
296
299
|
maxResourceSize: options.maxResourceSize,
|
|
@@ -299,6 +302,8 @@ class ProcessorHelperCommon {
|
|
|
299
302
|
frameId: options.frameId,
|
|
300
303
|
charset: options.charset,
|
|
301
304
|
resourceReferrer: options.resourceReferrer,
|
|
305
|
+
stylesheetURL: stylesheetReferrer.stylesheetURL,
|
|
306
|
+
stylesheetReferrerPolicy: stylesheetReferrer.stylesheetReferrerPolicy,
|
|
302
307
|
baseURI: options.baseURI,
|
|
303
308
|
blockMixedContent: options.blockMixedContent,
|
|
304
309
|
expectedType: "stylesheet",
|
|
@@ -315,6 +320,8 @@ class ProcessorHelperCommon {
|
|
|
315
320
|
frameId: options.frameId,
|
|
316
321
|
charset: options.charset,
|
|
317
322
|
resourceReferrer: options.resourceReferrer,
|
|
323
|
+
stylesheetURL: stylesheetReferrer.stylesheetURL,
|
|
324
|
+
stylesheetReferrerPolicy: stylesheetReferrer.stylesheetReferrerPolicy,
|
|
318
325
|
baseURI: options.baseURI,
|
|
319
326
|
blockMixedContent: options.blockMixedContent,
|
|
320
327
|
expectedType: "stylesheet",
|
|
@@ -326,6 +333,24 @@ class ProcessorHelperCommon {
|
|
|
326
333
|
}
|
|
327
334
|
}
|
|
328
335
|
|
|
336
|
+
getLiveStylesheetContent(element, options) {
|
|
337
|
+
const linkIndex = element.getAttribute(util.LINK_STYLESHEET_ATTRIBUTE_NAME);
|
|
338
|
+
if (options.linkStylesheets && linkIndex !== null) {
|
|
339
|
+
const liveElement = options.linkStylesheets[Number(linkIndex)];
|
|
340
|
+
if (liveElement && liveElement.href == element.href) {
|
|
341
|
+
try {
|
|
342
|
+
const cssRules = liveElement.sheet && liveElement.sheet.cssRules;
|
|
343
|
+
if (cssRules && cssRules.length) {
|
|
344
|
+
return Array.from(cssRules).map(cssRule => cssRule.cssText).join("\n");
|
|
345
|
+
}
|
|
346
|
+
// eslint-disable-next-line no-unused-vars
|
|
347
|
+
} catch (error) {
|
|
348
|
+
// ignored
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
329
354
|
processShortcutIcons(doc) {
|
|
330
355
|
let shortcutIcon = findShortcutIcon(Array.from(doc.querySelectorAll("link[href][rel=\"shortcut icon\"]")));
|
|
331
356
|
if (!shortcutIcon) {
|
|
@@ -360,7 +385,7 @@ class ProcessorHelperCommon {
|
|
|
360
385
|
});
|
|
361
386
|
}
|
|
362
387
|
|
|
363
|
-
resolveStylesheetURLs(stylesheet, baseURI, workStylesheet) {
|
|
388
|
+
resolveStylesheetURLs(stylesheet, baseURI, workStylesheet, stylesheetReferrer, stylesheetReferrers) {
|
|
364
389
|
const urls = getUrlFunctions(stylesheet);
|
|
365
390
|
urls.map(urlNode => {
|
|
366
391
|
const originalResourceURL = urlNode.value;
|
|
@@ -383,6 +408,9 @@ class ProcessorHelperCommon {
|
|
|
383
408
|
}
|
|
384
409
|
if (testValidURL(resolvedURL)) {
|
|
385
410
|
urlNode.value = resolvedURL;
|
|
411
|
+
if (stylesheetReferrer && stylesheetReferrers && !stylesheetReferrers.has(normalizeURL(resolvedURL))) {
|
|
412
|
+
stylesheetReferrers.set(normalizeURL(resolvedURL), stylesheetReferrer);
|
|
413
|
+
}
|
|
386
414
|
}
|
|
387
415
|
} else {
|
|
388
416
|
urlNode.value = util.EMPTY_RESOURCE;
|
|
@@ -670,6 +698,19 @@ function findShortcutIcon(shortcutIcons) {
|
|
|
670
698
|
return shortcutIcons[0];
|
|
671
699
|
}
|
|
672
700
|
|
|
701
|
+
function getStylesheetReferrer(resourceURL, options) {
|
|
702
|
+
return (options.stylesheetReferrers && options.stylesheetReferrers.get(normalizeURL(resourceURL))) || {};
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function getReferrerPolicy(element) {
|
|
706
|
+
if (element.tagName.toUpperCase() == "SOURCE" && element.parentElement && element.parentElement.tagName.toUpperCase() == "PICTURE") {
|
|
707
|
+
element = element.parentElement.querySelector("img");
|
|
708
|
+
}
|
|
709
|
+
if (element && REFERRER_POLICY_ELEMENTS.includes(element.tagName.toUpperCase()) && element.referrerPolicy) {
|
|
710
|
+
return element.referrerPolicy;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
673
714
|
function isDataURL(url) {
|
|
674
715
|
return url && (url.startsWith(DATA_URI_PREFIX) || url.startsWith(BLOB_URI_PREFIX));
|
|
675
716
|
}
|
|
@@ -739,10 +780,13 @@ async function resizeImage(doc, dataURI, { imageReductionFactor, imageQuality },
|
|
|
739
780
|
}, contentType, quality));
|
|
740
781
|
}
|
|
741
782
|
if (blob.type == contentType) {
|
|
742
|
-
|
|
743
|
-
if (
|
|
744
|
-
|
|
745
|
-
element
|
|
783
|
+
const resizedDataURI = await toDataURI(blob, contentType);
|
|
784
|
+
if (resizedDataURI.length < dataURI.length) {
|
|
785
|
+
dataURI = resizedDataURI;
|
|
786
|
+
if (element && isUnsizedSVGImage(element)) {
|
|
787
|
+
element.setAttribute("width", image.naturalWidth);
|
|
788
|
+
element.setAttribute("height", image.naturalHeight);
|
|
789
|
+
}
|
|
746
790
|
}
|
|
747
791
|
}
|
|
748
792
|
} catch {
|
|
@@ -71,6 +71,8 @@ import {
|
|
|
71
71
|
testIgnoredPath,
|
|
72
72
|
testValidPath,
|
|
73
73
|
testValidURL,
|
|
74
|
+
getReferrerPolicy,
|
|
75
|
+
getStylesheetReferrer,
|
|
74
76
|
resizeImage,
|
|
75
77
|
toDataURI
|
|
76
78
|
} from "./processor-helper-common.js";
|
|
@@ -99,7 +101,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
99
101
|
if (!options.inlineStylesheetsRefs.has(element)) {
|
|
100
102
|
if (!options.blockStylesheets || (options.keepPrintStyleSheets && stylesheetInfo.mediaText == "print")) {
|
|
101
103
|
if (element.tagName.toUpperCase() == "LINK") {
|
|
102
|
-
stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
|
|
104
|
+
stylesheet = await this.resolveLinkStylesheetURLs(element, element.href, baseURI, options, workStyleElement);
|
|
103
105
|
} else {
|
|
104
106
|
stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
|
|
105
107
|
const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
|
|
@@ -194,9 +196,9 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
194
196
|
});
|
|
195
197
|
}
|
|
196
198
|
|
|
197
|
-
async resolveImportURLs(stylesheet, baseURI, options, workStylesheet, importedStyleSheets = new Set()) {
|
|
199
|
+
async resolveImportURLs(stylesheet, baseURI, options, workStylesheet, importedStyleSheets = new Set(), stylesheetReferrer) {
|
|
198
200
|
let importFound;
|
|
199
|
-
this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet);
|
|
201
|
+
this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet, stylesheetReferrer, options.stylesheetReferrers);
|
|
200
202
|
const imports = getImportFunctions(stylesheet);
|
|
201
203
|
await Promise.all(imports.map(async node => {
|
|
202
204
|
const urlNode = cssTree.find(node, node => node.type == "Url") || cssTree.find(node, node => node.type == "String");
|
|
@@ -212,7 +214,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
212
214
|
}
|
|
213
215
|
if (testValidURL(resourceURL) && !importedStyleSheets.has(resourceURL)) {
|
|
214
216
|
options.inline = true;
|
|
215
|
-
const content = await this.getStylesheetContent(resourceURL, options);
|
|
217
|
+
const content = await this.getStylesheetContent(resourceURL, options, stylesheetReferrer);
|
|
216
218
|
resourceURL = content.resourceURL;
|
|
217
219
|
content.data = getUpdatedResourceContent(resourceURL, options) || content.data;
|
|
218
220
|
if (content.data && content.data.match(/^<!doctype /i)) {
|
|
@@ -233,7 +235,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
233
235
|
const importedStylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
234
236
|
const ancestorStyleSheets = new Set(importedStyleSheets);
|
|
235
237
|
ancestorStyleSheets.add(resourceURL);
|
|
236
|
-
await this.resolveImportURLs(importedStylesheet, resourceURL, options, workStylesheet, ancestorStyleSheets);
|
|
238
|
+
await this.resolveImportURLs(importedStylesheet, resourceURL, options, workStylesheet, ancestorStyleSheets, { stylesheetURL: resourceURL, stylesheetReferrerPolicy: content.referrerPolicy });
|
|
237
239
|
for (let keyName of Object.keys(importedStylesheet)) {
|
|
238
240
|
node[keyName] = importedStylesheet[keyName];
|
|
239
241
|
}
|
|
@@ -245,7 +247,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
245
247
|
return importFound;
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
async resolveLinkStylesheetURLs(resourceURL, baseURI, options, workStylesheet) {
|
|
250
|
+
async resolveLinkStylesheetURLs(element, resourceURL, baseURI, options, workStylesheet) {
|
|
249
251
|
resourceURL = normalizeURL(resourceURL);
|
|
250
252
|
if (resourceURL && resourceURL != baseURI && resourceURL != ABOUT_BLANK_URI) {
|
|
251
253
|
const content = await util.getContent(resourceURL, {
|
|
@@ -255,6 +257,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
255
257
|
charset: options.charset,
|
|
256
258
|
frameId: options.frameId,
|
|
257
259
|
resourceReferrer: options.resourceReferrer,
|
|
260
|
+
referrerPolicy: getReferrerPolicy(element),
|
|
258
261
|
validateTextContentType: true,
|
|
259
262
|
baseURI: baseURI,
|
|
260
263
|
blockMixedContent: options.blockMixedContent,
|
|
@@ -262,9 +265,15 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
262
265
|
acceptHeaders: options.acceptHeaders,
|
|
263
266
|
networkTimeout: options.networkTimeout
|
|
264
267
|
});
|
|
268
|
+
if (content.failed) {
|
|
269
|
+
const liveContent = this.getLiveStylesheetContent(element, options);
|
|
270
|
+
if (liveContent) {
|
|
271
|
+
content.data = liveContent;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
265
274
|
if (!(matchCharsetEquals(content.data, content.charset) || matchCharsetEquals(content.data, options.charset))) {
|
|
266
275
|
options = Object.assign({}, options, { charset: getCharset(content.data) });
|
|
267
|
-
return this.resolveLinkStylesheetURLs(resourceURL, baseURI, options, workStylesheet);
|
|
276
|
+
return this.resolveLinkStylesheetURLs(element, resourceURL, baseURI, options, workStylesheet);
|
|
268
277
|
}
|
|
269
278
|
resourceURL = content.resourceURL;
|
|
270
279
|
content.data = getUpdatedResourceContent(content.resourceURL, options) || content.data;
|
|
@@ -272,7 +281,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
272
281
|
content.data = "";
|
|
273
282
|
}
|
|
274
283
|
let stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
275
|
-
const importFound = await this.resolveImportURLs(stylesheet, resourceURL, options, workStylesheet);
|
|
284
|
+
const importFound = await this.resolveImportURLs(stylesheet, resourceURL, options, workStylesheet, undefined, { stylesheetURL: resourceURL, stylesheetReferrerPolicy: content.referrerPolicy });
|
|
276
285
|
if (importFound) {
|
|
277
286
|
stylesheet = cssTree.parse(cssTree.generate(stylesheet), { context: "stylesheet", parseCustomProperty: true });
|
|
278
287
|
}
|
|
@@ -302,7 +311,8 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
302
311
|
asBinary: true,
|
|
303
312
|
expectedType: "font",
|
|
304
313
|
baseURI,
|
|
305
|
-
blockMixedContent: options.blockMixedContent
|
|
314
|
+
blockMixedContent: options.blockMixedContent,
|
|
315
|
+
...getStylesheetReferrer(resourceURL, options)
|
|
306
316
|
});
|
|
307
317
|
let resourceURLs = resources.fonts.get(urlNode);
|
|
308
318
|
if (!resourceURLs) {
|
|
@@ -324,7 +334,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
324
334
|
if (!options.blockImages) {
|
|
325
335
|
const resourceURL = normalizeURL(originalResourceURL);
|
|
326
336
|
if (!testIgnoredPath(resourceURL) && testValidURL(resourceURL)) {
|
|
327
|
-
let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", groupDuplicates: options.groupDuplicateImages });
|
|
337
|
+
let { content, indexResource, duplicate } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", groupDuplicates: options.groupDuplicateImages, ...getStylesheetReferrer(resourceURL, options) });
|
|
328
338
|
if (!originalResourceURL.startsWith("#")) {
|
|
329
339
|
const maxSizeDuplicateImages = options.maxSizeDuplicateImages || SINGLE_FILE_VARIABLE_MAX_SIZE;
|
|
330
340
|
if (duplicate && options.groupDuplicateImages && util.getContentSize(content) < maxSizeDuplicateImages) {
|
|
@@ -373,7 +383,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
373
383
|
const groupDuplicates = options.groupDuplicateImages && resourceElement.tagName.toUpperCase() == "IMG" && attributeName == "src";
|
|
374
384
|
let { content, indexResource, duplicate } = await batchRequest.addURL(
|
|
375
385
|
resourceURL,
|
|
376
|
-
{ asBinary: true, expectedType, contentType: declaredContentType, groupDuplicates });
|
|
386
|
+
{ asBinary: true, expectedType, contentType: declaredContentType, groupDuplicates, referrerPolicy: getReferrerPolicy(resourceElement) });
|
|
377
387
|
if (originURL) {
|
|
378
388
|
if (this.testEmptyResource(content)) {
|
|
379
389
|
try {
|
|
@@ -393,6 +403,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
393
403
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
394
404
|
frameId: options.windowId,
|
|
395
405
|
resourceReferrer: options.resourceReferrer,
|
|
406
|
+
referrerPolicy: getReferrerPolicy(resourceElement),
|
|
396
407
|
acceptHeaders: options.acceptHeaders,
|
|
397
408
|
networkTimeout: options.networkTimeout
|
|
398
409
|
})).data;
|
|
@@ -402,7 +413,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
402
413
|
}
|
|
403
414
|
}
|
|
404
415
|
}
|
|
405
|
-
if (options.imageReductionFactor > 1 && expectedType == "image") {
|
|
416
|
+
if (options.imageReductionFactor > 1 && expectedType == "image" && attributeName != "background") {
|
|
406
417
|
content = await resizeImage(doc, content, options, resourceElement);
|
|
407
418
|
}
|
|
408
419
|
if (removeElementIfMissing && this.testEmptyResource(content)) {
|
|
@@ -453,8 +464,8 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
453
464
|
}));
|
|
454
465
|
}
|
|
455
466
|
|
|
456
|
-
async processImageSrcset(resourceURL, srcsetValue, resources, batchRequest) {
|
|
457
|
-
const { content } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image" });
|
|
467
|
+
async processImageSrcset(resourceURL, srcsetValue, resources, batchRequest, resourceElement) {
|
|
468
|
+
const { content } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", referrerPolicy: getReferrerPolicy(resourceElement) });
|
|
458
469
|
const forbiddenPrefixFound = PREFIXES_FORBIDDEN_DATA_URI.filter(prefixDataURI => content.startsWith(prefixDataURI)).length;
|
|
459
470
|
if (forbiddenPrefixFound) {
|
|
460
471
|
return "";
|
|
@@ -527,6 +538,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
527
538
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
528
539
|
frameId: options.windowId,
|
|
529
540
|
resourceReferrer: options.resourceReferrer,
|
|
541
|
+
referrerPolicy: getReferrerPolicy(element),
|
|
530
542
|
baseURI: options.baseURI,
|
|
531
543
|
blockMixedContent: options.blockMixedContent,
|
|
532
544
|
expectedType: "script",
|
|
@@ -60,6 +60,8 @@ import {
|
|
|
60
60
|
testIgnoredPath,
|
|
61
61
|
testValidPath,
|
|
62
62
|
testValidURL,
|
|
63
|
+
getReferrerPolicy,
|
|
64
|
+
getStylesheetReferrer,
|
|
63
65
|
resizeImage,
|
|
64
66
|
toDataURI
|
|
65
67
|
} from "./processor-helper-common.js";
|
|
@@ -212,10 +214,10 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
async resolveImportURLs(stylesheetInfo, baseURI, options, workStylesheet, resources, stylesheets, importedStyleSheets = new Set()) {
|
|
217
|
+
async resolveImportURLs(stylesheetInfo, baseURI, options, workStylesheet, resources, stylesheets, importedStyleSheets = new Set(), stylesheetReferrer) {
|
|
216
218
|
const stylesheet = stylesheetInfo.stylesheet;
|
|
217
219
|
const scoped = stylesheetInfo.scoped;
|
|
218
|
-
this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet);
|
|
220
|
+
this.resolveStylesheetURLs(stylesheet, baseURI, workStylesheet, stylesheetReferrer, options.stylesheetReferrers);
|
|
219
221
|
const imports = getImportFunctions(stylesheet);
|
|
220
222
|
await Promise.all(imports.map(async node => {
|
|
221
223
|
const urlNode = cssTree.find(node, node => node.type == "Url") || cssTree.find(node, node => node.type == "String");
|
|
@@ -252,14 +254,14 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
252
254
|
const importDeclaresLayer = Boolean(cssTree.find(node, node => node.type == "Layer" || ((node.type == "Identifier" || node.type == "Function") && node.name.toLowerCase() == "layer")));
|
|
253
255
|
stylesheets.set({ urlNode, importNode: node, importParent: stylesheet, importDeclaresLayer }, stylesheetInfo);
|
|
254
256
|
const requestedURL = resourceURL;
|
|
255
|
-
const content = await this.getStylesheetContent(resourceURL, options);
|
|
257
|
+
const content = await this.getStylesheetContent(resourceURL, options, stylesheetReferrer);
|
|
256
258
|
stylesheetInfo.url = resourceURL = content.resourceURL;
|
|
257
259
|
content.data = getUpdatedResourceContent(resourceURL, options) || content.data;
|
|
258
260
|
stylesheetInfo.stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
259
261
|
const ancestorStyleSheets = new Set(importedStyleSheets);
|
|
260
262
|
ancestorStyleSheets.add(requestedURL);
|
|
261
263
|
ancestorStyleSheets.add(resourceURL);
|
|
262
|
-
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets, ancestorStyleSheets);
|
|
264
|
+
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets, ancestorStyleSheets, { stylesheetURL: resourceURL, stylesheetReferrerPolicy: content.referrerPolicy });
|
|
263
265
|
urlNode.importedChildren = stylesheetInfo.stylesheet.children;
|
|
264
266
|
urlNode.importedMediaText = mediaText;
|
|
265
267
|
urlNode.importedLayerName = layerName;
|
|
@@ -279,6 +281,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
279
281
|
charset: options.charset,
|
|
280
282
|
frameId: options.frameId,
|
|
281
283
|
resourceReferrer: options.resourceReferrer,
|
|
284
|
+
referrerPolicy: getReferrerPolicy(element),
|
|
282
285
|
validateTextContentType: true,
|
|
283
286
|
baseURI: baseURI,
|
|
284
287
|
blockMixedContent: options.blockMixedContent,
|
|
@@ -286,6 +289,12 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
286
289
|
acceptHeaders: options.acceptHeaders,
|
|
287
290
|
networkTimeout: options.networkTimeout
|
|
288
291
|
});
|
|
292
|
+
if (content.failed) {
|
|
293
|
+
const liveContent = this.getLiveStylesheetContent(element, options);
|
|
294
|
+
if (liveContent) {
|
|
295
|
+
content.data = liveContent;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
289
298
|
if (!(matchCharsetEquals(content.data, content.charset) || matchCharsetEquals(content.data, options.charset))) {
|
|
290
299
|
options = Object.assign({}, options, { charset: getCharset(content.data) });
|
|
291
300
|
await this.resolveLinkStylesheetURLs(stylesheetInfo, element, resourceURL, baseURI, options, workStylesheet, resources, stylesheets);
|
|
@@ -293,7 +302,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
293
302
|
resourceURL = content.resourceURL;
|
|
294
303
|
content.data = getUpdatedResourceContent(content.resourceURL, options) || content.data;
|
|
295
304
|
stylesheetInfo.stylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
296
|
-
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets);
|
|
305
|
+
await this.resolveImportURLs(stylesheetInfo, resourceURL, options, workStylesheet, resources, stylesheets, undefined, { stylesheetURL: resourceURL, stylesheetReferrerPolicy: content.referrerPolicy });
|
|
297
306
|
}
|
|
298
307
|
}
|
|
299
308
|
}
|
|
@@ -318,7 +327,8 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
318
327
|
asBinary: true,
|
|
319
328
|
expectedType: "font",
|
|
320
329
|
baseURI,
|
|
321
|
-
blockMixedContent: options.blockMixedContent
|
|
330
|
+
blockMixedContent: options.blockMixedContent,
|
|
331
|
+
...getStylesheetReferrer(resourceURL, options)
|
|
322
332
|
});
|
|
323
333
|
const name = "fonts/" + indexResource + extension;
|
|
324
334
|
if (!isDataURL(resourceURL) && options.saveOriginalURLs) {
|
|
@@ -400,7 +410,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
400
410
|
const resourceURL = normalizeURL(originalResourceURL);
|
|
401
411
|
if ((!testIgnoredPath(resourceURL) && testValidURL(resourceURL)) || testGeneratedDataURI(resourceURL, options)) {
|
|
402
412
|
let { content, indexResource, contentType, extension } = await batchRequest.addURL(resourceURL,
|
|
403
|
-
{ asBinary: true, expectedType: "image" });
|
|
413
|
+
{ asBinary: true, expectedType: "image", ...getStylesheetReferrer(resourceURL, options) });
|
|
404
414
|
const name = "images/" + indexResource + extension;
|
|
405
415
|
if (!isDataURL(resourceURL) && options.saveOriginalURLs) {
|
|
406
416
|
urlNode.value = "-sf-url-original(" + JSON.stringify(originalResourceURL) + ") " + name;
|
|
@@ -441,7 +451,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
441
451
|
if (testValidURL(resourceURL) || generatedDataURI) {
|
|
442
452
|
const declaredContentType = ["OBJECT", "EMBED"].includes(resourceElement.tagName.toUpperCase()) ? resourceElement.getAttribute("type") : "";
|
|
443
453
|
let { content, indexResource, extension, contentType, charset } = await batchRequest.addURL(resourceURL,
|
|
444
|
-
{ asBinary: true, expectedType, contentType: declaredContentType });
|
|
454
|
+
{ asBinary: true, expectedType, contentType: declaredContentType, referrerPolicy: getReferrerPolicy(resourceElement) });
|
|
445
455
|
if (originURL) {
|
|
446
456
|
if (this.testEmptyResource(content)) {
|
|
447
457
|
try {
|
|
@@ -460,6 +470,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
460
470
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
461
471
|
frameId: options.windowId,
|
|
462
472
|
resourceReferrer: options.resourceReferrer,
|
|
473
|
+
referrerPolicy: getReferrerPolicy(resourceElement),
|
|
463
474
|
acceptHeaders: options.acceptHeaders,
|
|
464
475
|
networkTimeout: options.networkTimeout
|
|
465
476
|
})).data;
|
|
@@ -469,7 +480,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
469
480
|
}
|
|
470
481
|
}
|
|
471
482
|
}
|
|
472
|
-
if (options.imageReductionFactor > 1 && expectedType == "image") {
|
|
483
|
+
if (options.imageReductionFactor > 1 && expectedType == "image" && attributeName != "background") {
|
|
473
484
|
const dataURI = await resizeImage(doc, await toDataURI(new Blob([content], { type: contentType }), charset), options, resourceElement);
|
|
474
485
|
content = (await util.getContent(dataURI, { asBinary: true })).data;
|
|
475
486
|
}
|
|
@@ -492,7 +503,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
492
503
|
}
|
|
493
504
|
|
|
494
505
|
async processImageSrcset(resourceURL, srcsetValue, resources, batchRequest, resourceElement) {
|
|
495
|
-
const { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image" });
|
|
506
|
+
const { content, indexResource, extension, contentType } = await batchRequest.addURL(resourceURL, { asBinary: true, expectedType: "image", referrerPolicy: getReferrerPolicy(resourceElement) });
|
|
496
507
|
const name = "images/" + indexResource + extension;
|
|
497
508
|
resources.images.set(indexResource, { name, content, extension, contentType, url: resourceURL });
|
|
498
509
|
resourceElement.removeAttribute(CROSS_ORIGIN_ATTRIBUTE_NAME);
|
|
@@ -543,6 +554,7 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
543
554
|
maxResourceSizeEnabled: options.maxResourceSizeEnabled,
|
|
544
555
|
frameId: options.windowId,
|
|
545
556
|
resourceReferrer: options.resourceReferrer,
|
|
557
|
+
referrerPolicy: getReferrerPolicy(element),
|
|
546
558
|
baseURI: options.baseURI,
|
|
547
559
|
blockMixedContent: options.blockMixedContent,
|
|
548
560
|
expectedType: "script",
|
package/core/util.js
CHANGED
|
@@ -225,6 +225,7 @@ function getInstance(utilOptions) {
|
|
|
225
225
|
ASSIGNED_SLOT_SEPARATOR: helper.ASSIGNED_SLOT_SEPARATOR,
|
|
226
226
|
PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME: helper.PRESERVED_SPACE_ELEMENT_ATTRIBUTE_NAME,
|
|
227
227
|
STYLESHEET_ATTRIBUTE_NAME: helper.STYLESHEET_ATTRIBUTE_NAME,
|
|
228
|
+
LINK_STYLESHEET_ATTRIBUTE_NAME: helper.LINK_STYLESHEET_ATTRIBUTE_NAME,
|
|
228
229
|
SELECTED_CONTENT_ATTRIBUTE_NAME: helper.SELECTED_CONTENT_ATTRIBUTE_NAME,
|
|
229
230
|
INVALID_ELEMENT_ATTRIBUTE_NAME: helper.INVALID_ELEMENT_ATTRIBUTE_NAME,
|
|
230
231
|
COMMENT_HEADER: helper.COMMENT_HEADER,
|
|
@@ -267,25 +268,25 @@ function getInstance(utilOptions) {
|
|
|
267
268
|
if (options.frameId) {
|
|
268
269
|
try {
|
|
269
270
|
response = await Promise.race([
|
|
270
|
-
fetchFrameResource(resourceURL, { frameId: options.frameId, referrer: options.resourceReferrer, headers: { accept } }),
|
|
271
|
+
fetchFrameResource(resourceURL, { frameId: options.frameId, referrer: options.resourceReferrer, referrerPolicy: options.referrerPolicy || undefined, stylesheetURL: options.stylesheetURL || undefined, stylesheetReferrerPolicy: options.stylesheetReferrerPolicy || undefined, headers: { accept } }),
|
|
271
272
|
networkTimeoutPromise
|
|
272
273
|
]);
|
|
273
274
|
// eslint-disable-next-line no-unused-vars
|
|
274
275
|
} catch (error) {
|
|
275
276
|
response = await Promise.race([
|
|
276
|
-
fetchResource(resourceURL, { referrer: options.resourceReferrer, headers: { accept } }),
|
|
277
|
+
fetchResource(resourceURL, { referrer: options.resourceReferrer, referrerPolicy: options.referrerPolicy || undefined, stylesheetURL: options.stylesheetURL || undefined, stylesheetReferrerPolicy: options.stylesheetReferrerPolicy || undefined, headers: { accept } }),
|
|
277
278
|
networkTimeoutPromise
|
|
278
279
|
]);
|
|
279
280
|
}
|
|
280
281
|
} else {
|
|
281
282
|
response = await Promise.race([
|
|
282
|
-
fetchResource(resourceURL, { referrer: options.resourceReferrer, headers: { accept } }),
|
|
283
|
+
fetchResource(resourceURL, { referrer: options.resourceReferrer, referrerPolicy: options.referrerPolicy || undefined, stylesheetURL: options.stylesheetURL || undefined, stylesheetReferrerPolicy: options.stylesheetReferrerPolicy || undefined, headers: { accept } }),
|
|
283
284
|
networkTimeoutPromise
|
|
284
285
|
]);
|
|
285
286
|
}
|
|
286
287
|
// eslint-disable-next-line no-unused-vars
|
|
287
288
|
} catch (error) {
|
|
288
|
-
return
|
|
289
|
+
return getFailedFetchResponse(resourceURL, options);
|
|
289
290
|
} finally {
|
|
290
291
|
resolveNetworkTimeoutPromise();
|
|
291
292
|
if (options.networkTimeout) {
|
|
@@ -336,7 +337,10 @@ function getInstance(utilOptions) {
|
|
|
336
337
|
return getFetchResponse(resourceURL, options);
|
|
337
338
|
}
|
|
338
339
|
} else {
|
|
339
|
-
if (response.status >= 400
|
|
340
|
+
if (response.status >= 400) {
|
|
341
|
+
return getFailedFetchResponse(resourceURL, options);
|
|
342
|
+
}
|
|
343
|
+
if (options.validateTextContentType && contentType && !contentType.startsWith(PREFIX_CONTENT_TYPE_TEXT)) {
|
|
340
344
|
return getFetchResponse(resourceURL, options);
|
|
341
345
|
}
|
|
342
346
|
if (!charset) {
|
|
@@ -349,7 +353,9 @@ function getInstance(utilOptions) {
|
|
|
349
353
|
return getFetchResponse(resourceURL, options, null, charset);
|
|
350
354
|
} else {
|
|
351
355
|
try {
|
|
352
|
-
|
|
356
|
+
const fetchResponse = await getFetchResponse(resourceURL, options, buffer, charset, contentType);
|
|
357
|
+
fetchResponse.referrerPolicy = (response.headers && response.headers.get("referrer-policy")) || undefined;
|
|
358
|
+
return fetchResponse;
|
|
353
359
|
// eslint-disable-next-line no-unused-vars
|
|
354
360
|
} catch (error) {
|
|
355
361
|
return getFetchResponse(resourceURL, options, null, charset);
|
|
@@ -359,6 +365,12 @@ function getInstance(utilOptions) {
|
|
|
359
365
|
}
|
|
360
366
|
}
|
|
361
367
|
|
|
368
|
+
async function getFailedFetchResponse(resourceURL, options) {
|
|
369
|
+
const response = await getFetchResponse(resourceURL, options);
|
|
370
|
+
response.failed = true;
|
|
371
|
+
return response;
|
|
372
|
+
}
|
|
373
|
+
|
|
362
374
|
async function getFetchResponse(resourceURL, options, data, charset, contentType) {
|
|
363
375
|
if (data) {
|
|
364
376
|
if (options.asBinary) {
|