single-file-core 1.5.17 → 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 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
- this.processorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.resources, this.batchRequest)
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
- const cssRules = stylesheetInfo.stylesheet.children;
406
- if (cssRules) {
407
- stats.rules.processed += cssRules.size;
408
- stats.rules.discarded += cssRules.size;
409
- if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
410
- const mediaFontsDetails = this.createFontsDetailsInfo();
411
- fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
412
- this.getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails);
413
- } else {
414
- this.getFontsDetails(doc, cssRules, sheetIndex, fontsDetails);
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
- const cssRules = stylesheetInfo.stylesheet.children;
422
- const media = stylesheetInfo.mediaText;
423
- if (cssRules) {
424
- if (media && media != MEDIA_ALL) {
425
- await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fonts, fontTests, stats);
426
- } else {
427
- await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails, fonts, fontTests, stats);
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.blockStylesheets) {
87
- if (element.tagName.toUpperCase() == "LINK") {
88
- stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
89
- } else {
90
- stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
91
- const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
92
- if (importFound) {
93
- stylesheet = cssTree.parse(cssTree.generate(stylesheet), { context: "stylesheet", parseCustomProperty: true });
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
- if (stylesheet && stylesheet.children) {
98
- if (options.compressCSS) {
99
- this.removeSingleLineCssComments(stylesheet);
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
- styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
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.blockStylesheets) {
80
- stylesheets.set({ element }, stylesheetInfo);
81
- if (element.tagName.toUpperCase() == "LINK") {
82
- await this.resolveLinkStylesheetURLs(stylesheetInfo, element, element.href, baseURI, options, workStyleElement, resources, stylesheets);
83
- } else {
84
- stylesheetInfo.stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
85
- await this.resolveImportURLs(stylesheetInfo, baseURI, options, workStyleElement, resources, stylesheets);
86
- }
87
- } else {
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.textContent = "";
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
- styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
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
- const cssRules = stylesheetInfo.stylesheet.children;
60
- if (cssRules) {
61
- stats.processed += cssRules.size;
62
- stats.discarded += cssRules.size;
63
- getFontsInfo(cssRules, fontsInfo, options);
64
- docContent = getRulesTextContent(doc, cssRules, workStyleElement, docContent);
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
- const cssRules = stylesheetInfo.stylesheet.children;
106
- if (cssRules) {
107
- filterUnusedFonts(cssRules, fontsInfo.declared, unusedFonts, filteredUsedFonts, docChars);
108
- stats.rules.discarded -= cssRules.size;
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 (matchesMediaType(stylesheetInfo.mediaText || MEDIA_ALL) && stylesheetInfo.stylesheet.children) {
43
- const removedRules = processRules(stylesheetInfo.stylesheet.children, stats);
44
- removedRules.forEach(({ cssRules, cssRule }) => cssRules.remove(cssRule));
45
- } else {
46
- stylesheets.delete(key);
47
- if (key.element) {
48
- key.element.remove();
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.5.17",
3
+ "version": "1.5.18",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",