single-file-core 1.5.16 → 1.5.18
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 +21 -3
- package/core/lib/processor-helper-common.js +22 -18
- package/core/lib/processor-helper-inline.js +25 -17
- package/core/lib/processor-helper.js +21 -13
- package/modules/css-fonts-minifier.js +14 -10
- package/modules/css-matched-rules.js +1 -1
- package/modules/css-medias-alt-minifier.js +9 -7
- package/modules/css-rules-minifier.js +1 -1
- package/modules/template-formatter.js +59 -1
- package/package.json +1 -1
package/core/index.js
CHANGED
|
@@ -1176,6 +1176,20 @@ class Processor {
|
|
|
1176
1176
|
}
|
|
1177
1177
|
|
|
1178
1178
|
async resolveStylesheetsURLs() {
|
|
1179
|
+
const scriptContents = [];
|
|
1180
|
+
this.options.inlineStylesheets = new Map();
|
|
1181
|
+
this.options.inlineStylesheetsRefs = new Map();
|
|
1182
|
+
this.doc.querySelectorAll("style").forEach(element => {
|
|
1183
|
+
if (element.textContent) {
|
|
1184
|
+
const indexContent = scriptContents.indexOf(element.textContent);
|
|
1185
|
+
if (indexContent == -1) {
|
|
1186
|
+
this.options.inlineStylesheets.set(scriptContents.length, element);
|
|
1187
|
+
scriptContents.push(element.textContent);
|
|
1188
|
+
} else {
|
|
1189
|
+
this.options.inlineStylesheetsRefs.set(element, indexContent);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1179
1193
|
await Promise.all(Array.from(this.doc.querySelectorAll("style, link[rel*=stylesheet]")).map(async element => {
|
|
1180
1194
|
const options = Object.assign({}, this.options, { charset: this.charset });
|
|
1181
1195
|
let mediaText;
|
|
@@ -1364,9 +1378,11 @@ class Processor {
|
|
|
1364
1378
|
}
|
|
1365
1379
|
|
|
1366
1380
|
async processStylesheets() {
|
|
1367
|
-
await Promise.all([...this.stylesheets].map(([, stylesheetInfo]) =>
|
|
1368
|
-
|
|
1369
|
-
|
|
1381
|
+
await Promise.all([...this.stylesheets].map(async ([, stylesheetInfo]) => {
|
|
1382
|
+
if (stylesheetInfo.stylesheet) {
|
|
1383
|
+
await this.processorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.resources, this.batchRequest);
|
|
1384
|
+
}
|
|
1385
|
+
}));
|
|
1370
1386
|
}
|
|
1371
1387
|
|
|
1372
1388
|
async processStyleAttributes() {
|
|
@@ -1457,6 +1473,8 @@ class Processor {
|
|
|
1457
1473
|
|
|
1458
1474
|
replaceStylesheets() {
|
|
1459
1475
|
this.processorHelper.replaceStylesheets(this.doc, this.stylesheets, this.options, this.resources);
|
|
1476
|
+
delete this.options.inlineStylesheetsRefs;
|
|
1477
|
+
delete this.options.inlineStylesheets;
|
|
1460
1478
|
}
|
|
1461
1479
|
|
|
1462
1480
|
replaceStyleAttributes() {
|
|
@@ -402,31 +402,35 @@ class ProcessorHelperCommon {
|
|
|
402
402
|
const stats = { rules: { processed: 0, discarded: 0 }, fonts: { processed: 0, discarded: 0 } };
|
|
403
403
|
let sheetIndex = 0;
|
|
404
404
|
stylesheets.forEach(stylesheetInfo => {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
405
|
+
if (stylesheetInfo.stylesheet) {
|
|
406
|
+
const cssRules = stylesheetInfo.stylesheet.children;
|
|
407
|
+
if (cssRules) {
|
|
408
|
+
stats.rules.processed += cssRules.size;
|
|
409
|
+
stats.rules.discarded += cssRules.size;
|
|
410
|
+
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
|
|
411
|
+
const mediaFontsDetails = this.createFontsDetailsInfo();
|
|
412
|
+
fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
|
|
413
|
+
this.getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails);
|
|
414
|
+
} else {
|
|
415
|
+
this.getFontsDetails(doc, cssRules, sheetIndex, fontsDetails);
|
|
416
|
+
}
|
|
415
417
|
}
|
|
416
418
|
}
|
|
417
419
|
sheetIndex++;
|
|
418
420
|
});
|
|
419
421
|
processFontDetails(fontsDetails);
|
|
420
422
|
await Promise.all([...stylesheets].map(async ([, stylesheetInfo], sheetIndex) => {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
423
|
+
if (stylesheetInfo.stylesheet) {
|
|
424
|
+
const cssRules = stylesheetInfo.stylesheet.children;
|
|
425
|
+
const media = stylesheetInfo.mediaText;
|
|
426
|
+
if (cssRules) {
|
|
427
|
+
if (media && media != MEDIA_ALL) {
|
|
428
|
+
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fonts, fontTests, stats);
|
|
429
|
+
} else {
|
|
430
|
+
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails, fonts, fontTests, stats);
|
|
431
|
+
}
|
|
432
|
+
stats.rules.discarded -= cssRules.size;
|
|
428
433
|
}
|
|
429
|
-
stats.rules.discarded -= cssRules.size;
|
|
430
434
|
}
|
|
431
435
|
}));
|
|
432
436
|
return stats;
|
|
@@ -83,25 +83,27 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
83
83
|
async resolveStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement) {
|
|
84
84
|
let stylesheet;
|
|
85
85
|
stylesheets.set(element, stylesheetInfo);
|
|
86
|
-
if (!options.
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
if (!options.inlineStylesheetsRefs.has(element)) {
|
|
87
|
+
if (!options.blockStylesheets) {
|
|
88
|
+
if (element.tagName.toUpperCase() == "LINK") {
|
|
89
|
+
stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
|
|
90
|
+
} else {
|
|
91
|
+
stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
|
|
92
|
+
const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
|
|
93
|
+
if (importFound) {
|
|
94
|
+
stylesheet = cssTree.parse(cssTree.generate(stylesheet), { context: "stylesheet", parseCustomProperty: true });
|
|
95
|
+
}
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
if (stylesheet && stylesheet.children) {
|
|
99
|
+
if (options.compressCSS) {
|
|
100
|
+
this.removeSingleLineCssComments(stylesheet);
|
|
101
|
+
}
|
|
102
|
+
this.replacePseudoClassDefined(stylesheet);
|
|
103
|
+
stylesheetInfo.stylesheet = stylesheet;
|
|
104
|
+
} else {
|
|
105
|
+
stylesheets.delete(element);
|
|
100
106
|
}
|
|
101
|
-
this.replacePseudoClassDefined(stylesheet);
|
|
102
|
-
stylesheetInfo.stylesheet = stylesheet;
|
|
103
|
-
} else {
|
|
104
|
-
stylesheets.delete(element);
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -110,7 +112,13 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
110
112
|
const stylesheetInfo = stylesheets.get(styleElement);
|
|
111
113
|
if (stylesheetInfo) {
|
|
112
114
|
stylesheets.delete(styleElement);
|
|
113
|
-
|
|
115
|
+
const styleSheetRefIndex = options.inlineStylesheetsRefs.get(styleElement);
|
|
116
|
+
if (styleSheetRefIndex === undefined) {
|
|
117
|
+
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
|
|
118
|
+
} else {
|
|
119
|
+
const styleElementRef = options.inlineStylesheets.get(styleSheetRefIndex);
|
|
120
|
+
styleElement.textContent = styleElementRef.textContent;
|
|
121
|
+
}
|
|
114
122
|
if (stylesheetInfo.mediaText) {
|
|
115
123
|
styleElement.media = stylesheetInfo.mediaText;
|
|
116
124
|
}
|
|
@@ -76,19 +76,21 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async resolveStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement, resources) {
|
|
79
|
-
if (!options.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (element.tagName.toUpperCase() == "LINK") {
|
|
89
|
-
element.href = util.EMPTY_RESOURCE;
|
|
79
|
+
if (!options.inlineStylesheetsRefs.has(element)) {
|
|
80
|
+
if (!options.blockStylesheets) {
|
|
81
|
+
stylesheets.set({ element }, stylesheetInfo);
|
|
82
|
+
if (element.tagName.toUpperCase() == "LINK") {
|
|
83
|
+
await this.resolveLinkStylesheetURLs(stylesheetInfo, element, element.href, baseURI, options, workStyleElement, resources, stylesheets);
|
|
84
|
+
} else {
|
|
85
|
+
stylesheetInfo.stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
|
|
86
|
+
await this.resolveImportURLs(stylesheetInfo, baseURI, options, workStyleElement, resources, stylesheets);
|
|
87
|
+
}
|
|
90
88
|
} else {
|
|
91
|
-
element.
|
|
89
|
+
if (element.tagName.toUpperCase() == "LINK") {
|
|
90
|
+
element.href = util.EMPTY_RESOURCE;
|
|
91
|
+
} else {
|
|
92
|
+
element.textContent = "";
|
|
93
|
+
}
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
}
|
|
@@ -112,7 +114,13 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
112
114
|
resources.stylesheets.set(resources.stylesheets.size, { name, stylesheet: stylesheetInfo.stylesheet });
|
|
113
115
|
} else {
|
|
114
116
|
const styleElement = key.element;
|
|
115
|
-
|
|
117
|
+
const styleSheetRefIndex = options.inlineStylesheetsRefs.get(styleElement);
|
|
118
|
+
if (styleSheetRefIndex === undefined) {
|
|
119
|
+
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
|
|
120
|
+
} else {
|
|
121
|
+
const styleElementRef = options.inlineStylesheets.get(styleSheetRefIndex);
|
|
122
|
+
styleElement.textContent = styleElementRef.textContent;
|
|
123
|
+
}
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
126
|
}
|
|
@@ -56,12 +56,14 @@ function process(doc, stylesheets, styles, options) {
|
|
|
56
56
|
let docContent = "";
|
|
57
57
|
doc.body.appendChild(workStyleElement);
|
|
58
58
|
stylesheets.forEach(stylesheetInfo => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
if (stylesheetInfo.stylesheet) {
|
|
60
|
+
const cssRules = stylesheetInfo.stylesheet.children;
|
|
61
|
+
if (cssRules) {
|
|
62
|
+
stats.processed += cssRules.size;
|
|
63
|
+
stats.discarded += cssRules.size;
|
|
64
|
+
getFontsInfo(cssRules, fontsInfo, options);
|
|
65
|
+
docContent = getRulesTextContent(doc, cssRules, workStyleElement, docContent);
|
|
66
|
+
}
|
|
65
67
|
}
|
|
66
68
|
});
|
|
67
69
|
styles.forEach(declarations => {
|
|
@@ -102,10 +104,12 @@ function process(doc, stylesheets, styles, options) {
|
|
|
102
104
|
}
|
|
103
105
|
const docChars = Array.from(new Set(docContent)).map(char => char.charCodeAt(0)).sort((value1, value2) => value1 - value2);
|
|
104
106
|
stylesheets.forEach(stylesheetInfo => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if (stylesheetInfo.stylesheet) {
|
|
108
|
+
const cssRules = stylesheetInfo.stylesheet.children;
|
|
109
|
+
if (cssRules) {
|
|
110
|
+
filterUnusedFonts(cssRules, fontsInfo.declared, unusedFonts, filteredUsedFonts, docChars);
|
|
111
|
+
stats.rules.discarded -= cssRules.size;
|
|
112
|
+
}
|
|
109
113
|
}
|
|
110
114
|
});
|
|
111
115
|
return stats;
|
|
@@ -41,7 +41,7 @@ class MatchedRules {
|
|
|
41
41
|
const workStyleElement = doc.createElement("span");
|
|
42
42
|
doc.body.appendChild(workStyleElement);
|
|
43
43
|
stylesheets.forEach((stylesheetInfo, key) => {
|
|
44
|
-
if (!stylesheetInfo.scoped && !key.urlNode) {
|
|
44
|
+
if (!stylesheetInfo.scoped && stylesheetInfo.stylesheet && !key.urlNode) {
|
|
45
45
|
const cssRules = stylesheetInfo.stylesheet.children;
|
|
46
46
|
if (cssRules) {
|
|
47
47
|
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
|
|
@@ -39,13 +39,15 @@ export {
|
|
|
39
39
|
function process(stylesheets) {
|
|
40
40
|
const stats = { processed: 0, discarded: 0 };
|
|
41
41
|
stylesheets.forEach((stylesheetInfo, key) => {
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
key.element
|
|
42
|
+
if (stylesheetInfo.stylesheet) {
|
|
43
|
+
if (matchesMediaType(stylesheetInfo.mediaText || MEDIA_ALL) && stylesheetInfo.stylesheet.children) {
|
|
44
|
+
const removedRules = processRules(stylesheetInfo.stylesheet.children, stats);
|
|
45
|
+
removedRules.forEach(({ cssRules, cssRule }) => cssRules.remove(cssRule));
|
|
46
|
+
} else {
|
|
47
|
+
stylesheets.delete(key);
|
|
48
|
+
if (key.element) {
|
|
49
|
+
key.element.remove();
|
|
50
|
+
}
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
});
|
|
@@ -33,7 +33,7 @@ function process(stylesheets, styles, mediaAllInfo) {
|
|
|
33
33
|
const stats = { processed: 0, discarded: 0 };
|
|
34
34
|
let sheetIndex = 0;
|
|
35
35
|
stylesheets.forEach((stylesheetInfo, key) => {
|
|
36
|
-
if (!stylesheetInfo.scoped && !key.urlNode) {
|
|
36
|
+
if (!stylesheetInfo.scoped && stylesheetInfo.stylesheet && !key.urlNode) {
|
|
37
37
|
const cssRules = stylesheetInfo.stylesheet.children;
|
|
38
38
|
if (cssRules) {
|
|
39
39
|
stats.processed += cssRules.size;
|
|
@@ -16953,7 +16953,9 @@ async function evalTemplate(template = "", options, content, doc, context = {})
|
|
|
16953
16953
|
"bookmark-pathname-flat": { getter: () => bookmarkFolder, dontReplaceSlash: false },
|
|
16954
16954
|
"profile-name": { getter: () => options.profileName },
|
|
16955
16955
|
"filename-extension": { getter: () => getFilenameExtension(options) },
|
|
16956
|
-
"save-action": { getter: () => options.selected ? "selection" : "page" }
|
|
16956
|
+
"save-action": { getter: () => options.selected ? "selection" : "page" },
|
|
16957
|
+
"options-json": { getter: () => JSON.stringify(getFilteredOptions(options)) },
|
|
16958
|
+
"options-text": { getter: () => optionsToText(getFilteredOptions(options)) }
|
|
16957
16959
|
};
|
|
16958
16960
|
if (content) {
|
|
16959
16961
|
variables["digest-sha-256"] = { getter: async () => digest("SHA-256", content) };
|
|
@@ -17050,6 +17052,14 @@ async function evalTemplate(template = "", options, content, doc, context = {})
|
|
|
17050
17052
|
options[name] = value;
|
|
17051
17053
|
}
|
|
17052
17054
|
}
|
|
17055
|
+
},
|
|
17056
|
+
"option-value": key => {
|
|
17057
|
+
const filteredValue = getFilteredOptions(options)[key];
|
|
17058
|
+
if (filteredValue === undefined || filteredValue === null) {
|
|
17059
|
+
return "";
|
|
17060
|
+
} else {
|
|
17061
|
+
return JSON.stringify(filteredValue);
|
|
17062
|
+
}
|
|
17053
17063
|
}
|
|
17054
17064
|
};
|
|
17055
17065
|
functions["date-locale"].dontReplaceSlash = true;
|
|
@@ -17251,4 +17261,52 @@ function getFilenameExtension(options) {
|
|
|
17251
17261
|
} else {
|
|
17252
17262
|
return "html";
|
|
17253
17263
|
}
|
|
17264
|
+
}
|
|
17265
|
+
|
|
17266
|
+
function getFilteredOptions(options) {
|
|
17267
|
+
const filteredOptions = Object.assign({}, options);
|
|
17268
|
+
delete filteredOptions.content;
|
|
17269
|
+
delete filteredOptions.usedFonts;
|
|
17270
|
+
delete filteredOptions.extensionScriptFiles;
|
|
17271
|
+
delete filteredOptions.taskId;
|
|
17272
|
+
delete filteredOptions.updatedResources;
|
|
17273
|
+
delete filteredOptions.visitDate;
|
|
17274
|
+
delete filteredOptions.keepFilename;
|
|
17275
|
+
delete filteredOptions.insertCanonicalLink;
|
|
17276
|
+
delete filteredOptions.frames;
|
|
17277
|
+
delete filteredOptions.win;
|
|
17278
|
+
delete filteredOptions.doc;
|
|
17279
|
+
delete filteredOptions.url;
|
|
17280
|
+
delete filteredOptions.resourceReferrer;
|
|
17281
|
+
delete filteredOptions.baseURI;
|
|
17282
|
+
delete filteredOptions.rootDocument;
|
|
17283
|
+
delete filteredOptions.fontTests;
|
|
17284
|
+
delete filteredOptions.canvases;
|
|
17285
|
+
delete filteredOptions.fonts;
|
|
17286
|
+
delete filteredOptions.worklets;
|
|
17287
|
+
delete filteredOptions.stylesheets;
|
|
17288
|
+
delete filteredOptions.images;
|
|
17289
|
+
delete filteredOptions.posters;
|
|
17290
|
+
delete filteredOptions.videos;
|
|
17291
|
+
delete filteredOptions.shadowRoots;
|
|
17292
|
+
delete filteredOptions.referrer;
|
|
17293
|
+
delete filteredOptions.adoptedStyleSheets;
|
|
17294
|
+
delete filteredOptions.tabId;
|
|
17295
|
+
delete filteredOptions.tabIndex;
|
|
17296
|
+
delete filteredOptions.saveDate;
|
|
17297
|
+
delete filteredOptions.saveUrl;
|
|
17298
|
+
delete filteredOptions.title;
|
|
17299
|
+
delete filteredOptions.info;
|
|
17300
|
+
return filteredOptions;
|
|
17301
|
+
}
|
|
17302
|
+
|
|
17303
|
+
function optionsToText(options) {
|
|
17304
|
+
const csv = [];
|
|
17305
|
+
for (const key in options) {
|
|
17306
|
+
const value = options[key];
|
|
17307
|
+
if (typeof value != "function" && value !== undefined && value !== null && value !== "") {
|
|
17308
|
+
csv.push(key + ": " + JSON.stringify(value));
|
|
17309
|
+
}
|
|
17310
|
+
}
|
|
17311
|
+
return csv.join("\n");
|
|
17254
17312
|
}
|