single-file-core 1.5.48 → 1.5.49
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 +1 -4
- package/core/lib/processor-helper-inline.js +24 -0
- package/core/lib/processor-helper.js +15 -2
- package/core/util.js +2 -5
- package/modules/css-media-query-utils.js +63 -0
- package/modules/css-medias-alt-minifier.js +26 -23
- package/modules/css-rules-minifier.js +904 -79
- package/modules/css-scope-prelude-parser.js +119 -0
- package/modules/css-selector-sanitizer.js +106 -0
- package/modules/css-specificity.js +211 -0
- package/modules/html-serializer.js +14 -9
- package/modules/index.js +0 -2
- package/package.json +2 -2
- package/processors/compression/compression.js +182 -20
- package/processors/hooks/content/content-hooks-frames-web.js +2 -4
- package/processors/hooks/content/content-hooks-frames.js +6 -8
- package/vendor/css-font-property-parser.js +87 -67
- package/vendor/css-tree.js +9 -9
- package/modules/css-matched-rules.js +0 -384
package/core/index.js
CHANGED
|
@@ -1404,10 +1404,7 @@ class Processor {
|
|
|
1404
1404
|
}
|
|
1405
1405
|
|
|
1406
1406
|
removeUnusedStyles() {
|
|
1407
|
-
|
|
1408
|
-
this.mediaAllInfo = util.getMediaAllInfo(this.doc, this.stylesheets, this.styles);
|
|
1409
|
-
}
|
|
1410
|
-
const stats = util.minifyCSSRules(this.stylesheets, this.styles, this.mediaAllInfo);
|
|
1407
|
+
const stats = util.minifyCSSRules(this.doc, this.stylesheets);
|
|
1411
1408
|
this.stats.set("processed", "CSS rules", stats.processed);
|
|
1412
1409
|
this.stats.set("discarded", "CSS rules", stats.discarded);
|
|
1413
1410
|
}
|
|
@@ -183,6 +183,22 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
183
183
|
if (mediaQueryListNode) {
|
|
184
184
|
content.data = this.wrapMediaQuery(content.data, cssTree.generate(mediaQueryListNode));
|
|
185
185
|
}
|
|
186
|
+
const layerListNode = cssTree.find(node, node => node.type == "LayerList");
|
|
187
|
+
if (layerListNode) {
|
|
188
|
+
const layerNames = [];
|
|
189
|
+
layerListNode.children.forEach(child => {
|
|
190
|
+
if (child.type == "Identifier") {
|
|
191
|
+
layerNames.push(child.name);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
if (layerNames.length == 1) {
|
|
195
|
+
content.data = this.wrapLayer(content.data, layerNames[0]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const supportsNode = cssTree.find(node, node => node.type == "Supports");
|
|
199
|
+
if (supportsNode) {
|
|
200
|
+
content.data = "@supports " + cssTree.generate(supportsNode) + " { " + content.data + " }";
|
|
201
|
+
}
|
|
186
202
|
const importedStylesheet = cssTree.parse(content.data, { context: "stylesheet", parseCustomProperty: true });
|
|
187
203
|
const ancestorStyleSheets = new Set(importedStyleSheets);
|
|
188
204
|
ancestorStyleSheets.add(resourceURL);
|
|
@@ -470,6 +486,14 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
470
486
|
}
|
|
471
487
|
}
|
|
472
488
|
|
|
489
|
+
wrapLayer(stylesheetContent, layerName) {
|
|
490
|
+
if (layerName) {
|
|
491
|
+
return "@layer " + layerName + " { " + stylesheetContent + " }";
|
|
492
|
+
} else {
|
|
493
|
+
return stylesheetContent;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
473
497
|
getAdditionalPageData() {
|
|
474
498
|
return {};
|
|
475
499
|
}
|
|
@@ -162,10 +162,18 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
162
162
|
}
|
|
163
163
|
if (testValidURL(resourceURL)) {
|
|
164
164
|
const mediaQueryListNode = cssTree.find(node, node => node.type == "MediaQueryList");
|
|
165
|
-
let mediaText;
|
|
165
|
+
let mediaText, layerName, supportsCondition;
|
|
166
166
|
if (mediaQueryListNode) {
|
|
167
167
|
mediaText = cssTree.generate(mediaQueryListNode);
|
|
168
168
|
}
|
|
169
|
+
const layerNode = cssTree.find(node, node => node.type == "Layer");
|
|
170
|
+
if (layerNode) {
|
|
171
|
+
layerName = layerNode.name;
|
|
172
|
+
}
|
|
173
|
+
const supportsNode = cssTree.find(node, node => node.type == "Supports");
|
|
174
|
+
if (supportsNode) {
|
|
175
|
+
supportsCondition = cssTree.generate(supportsNode);
|
|
176
|
+
}
|
|
169
177
|
const existingStylesheet = Array.from(stylesheets).find(([, stylesheetInfo]) => stylesheetInfo.resourceURL == resourceURL);
|
|
170
178
|
let stylesheet;
|
|
171
179
|
if (existingStylesheet) {
|
|
@@ -178,7 +186,9 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
178
186
|
} else {
|
|
179
187
|
const stylesheetInfo = {
|
|
180
188
|
scoped,
|
|
181
|
-
mediaText
|
|
189
|
+
mediaText,
|
|
190
|
+
layerName,
|
|
191
|
+
supportsCondition
|
|
182
192
|
};
|
|
183
193
|
const content = await this.getStylesheetContent(resourceURL, options);
|
|
184
194
|
stylesheetInfo.url = resourceURL = content.resourceURL;
|
|
@@ -189,6 +199,9 @@ function getProcessorHelperClass(utilInstance) {
|
|
|
189
199
|
stylesheets.set({ urlNode }, stylesheetInfo);
|
|
190
200
|
}
|
|
191
201
|
urlNode.importedChildren = stylesheet.children;
|
|
202
|
+
urlNode.importedMediaText = mediaText;
|
|
203
|
+
urlNode.importedLayerName = layerName;
|
|
204
|
+
urlNode.importedSupportsCondition = supportsCondition;
|
|
192
205
|
}
|
|
193
206
|
}
|
|
194
207
|
}
|
package/core/util.js
CHANGED
|
@@ -160,15 +160,12 @@ function getInstance(utilOptions) {
|
|
|
160
160
|
minifyHTML(doc, options) {
|
|
161
161
|
return modules.htmlMinifier.process(doc, options);
|
|
162
162
|
},
|
|
163
|
-
minifyCSSRules(
|
|
164
|
-
return modules.cssRulesMinifier.process(
|
|
163
|
+
minifyCSSRules(doc, stylesheets) {
|
|
164
|
+
return modules.cssRulesMinifier.process(doc, stylesheets);
|
|
165
165
|
},
|
|
166
166
|
removeUnusedFonts(doc, stylesheets, styles, options) {
|
|
167
167
|
return modules.fontsMinifier.process(doc, stylesheets, styles, options);
|
|
168
168
|
},
|
|
169
|
-
getMediaAllInfo(doc, stylesheets, styles) {
|
|
170
|
-
return modules.matchedRules.getMediaAllInfo(doc, stylesheets, styles);
|
|
171
|
-
},
|
|
172
169
|
compressCSS(content, options) {
|
|
173
170
|
return vendor.cssMinifier.processString(content, options);
|
|
174
171
|
},
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as mediaQueryParser from "../vendor/css-media-query-parser.js";
|
|
2
|
+
|
|
3
|
+
function parseMediaListSafe(mediaText) {
|
|
4
|
+
return mediaQueryParser.parseMediaList(mediaText);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function containsNotKeyword(node) {
|
|
8
|
+
if (!node || !node.nodes) return false;
|
|
9
|
+
for (const token of node.nodes) {
|
|
10
|
+
if (token && token.type === "keyword" && token.value && token.value.toLowerCase() === "not") {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isMediaTypeNegated(parentNode, index) {
|
|
18
|
+
for (let j = index - 1; j >= 0; j--) {
|
|
19
|
+
const prev = parentNode.nodes[j];
|
|
20
|
+
if (!prev) continue;
|
|
21
|
+
if (prev.type === "operator" && prev.value === ",") {
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
if (prev.type === "keyword" && prev.value && prev.value.toLowerCase() === "not") {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function extractMediaTypes(parentNode, mediaTypes = []) {
|
|
32
|
+
for (let index = 0; index < parentNode.nodes.length; index++) {
|
|
33
|
+
const node = parentNode.nodes[index];
|
|
34
|
+
if (node.type == "media-query") {
|
|
35
|
+
extractMediaTypes(node, mediaTypes);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (node.type == "media-type") {
|
|
39
|
+
const negated = isMediaTypeNegated(parentNode, index);
|
|
40
|
+
mediaTypes.push({ not: negated, value: node.value });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return mediaTypes;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isFeaturefulOrCompound(node) {
|
|
47
|
+
if (!node || !node.nodes) return false;
|
|
48
|
+
for (const token of node.nodes) {
|
|
49
|
+
if (!token) continue;
|
|
50
|
+
if (token.type === "media-feature-expression") return true;
|
|
51
|
+
if (token.type === "keyword" && token.value && token.value.toLowerCase() === "and") return true;
|
|
52
|
+
}
|
|
53
|
+
if (containsNotKeyword(node)) return true;
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
parseMediaListSafe,
|
|
59
|
+
containsNotKeyword,
|
|
60
|
+
isMediaTypeNegated,
|
|
61
|
+
extractMediaTypes,
|
|
62
|
+
isFeaturefulOrCompound
|
|
63
|
+
};
|
|
@@ -22,8 +22,13 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import * as cssTree from "./../vendor/css-tree.js";
|
|
25
|
-
import * as mediaQueryParser from "./../vendor/css-media-query-parser.js";
|
|
26
25
|
import { flatten } from "./../core/helper.js";
|
|
26
|
+
import {
|
|
27
|
+
parseMediaListSafe,
|
|
28
|
+
containsNotKeyword as utilContainsNotKeyword,
|
|
29
|
+
extractMediaTypes,
|
|
30
|
+
isFeaturefulOrCompound
|
|
31
|
+
} from "./css-media-query-utils.js";
|
|
27
32
|
|
|
28
33
|
const helper = {
|
|
29
34
|
flatten
|
|
@@ -72,28 +77,26 @@ function processRules(cssRules, stats, keepPrintStyleSheets, removedRules = [])
|
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
function matchesMediaType(mediaText, keepPrintStyleSheets) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
parentNode.nodes.map((node, indexNode) => {
|
|
83
|
-
if (node.type == "media-query") {
|
|
84
|
-
return getMediaTypes(node);
|
|
85
|
-
} else {
|
|
86
|
-
if (node.type == "media-type") {
|
|
87
|
-
const nodeMediaType = {
|
|
88
|
-
not: Boolean(indexNode && parentNode.nodes[0].type == "keyword" && parentNode.nodes[0].value == "not"),
|
|
89
|
-
value: node.value
|
|
90
|
-
};
|
|
91
|
-
mediaTypes.push(nodeMediaType);
|
|
92
|
-
}
|
|
80
|
+
let parsed;
|
|
81
|
+
try {
|
|
82
|
+
parsed = parseMediaListSafe(mediaText);
|
|
83
|
+
for (const node of parsed) {
|
|
84
|
+
if (!node || !node.nodes) continue;
|
|
85
|
+
if (isFeaturefulOrCompound(node)) return true;
|
|
86
|
+
if (utilContainsNotKeyword(node)) return true;
|
|
93
87
|
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
} catch {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
let foundMediaTypes = helper.flatten(parsed.filter(n => n && n.nodes).map(node => extractMediaTypes(node)));
|
|
92
|
+
if (!foundMediaTypes || !foundMediaTypes.length) {
|
|
93
|
+
foundMediaTypes = [{ not: false, value: MEDIA_ALL }];
|
|
97
94
|
}
|
|
98
|
-
return
|
|
95
|
+
return foundMediaTypes.some(mediaTypeInfo =>
|
|
96
|
+
!mediaTypeInfo.not && (
|
|
97
|
+
mediaTypeInfo.value == MEDIA_SCREEN ||
|
|
98
|
+
mediaTypeInfo.value == MEDIA_ALL ||
|
|
99
|
+
(keepPrintStyleSheets && mediaTypeInfo.value == MEDIA_PRINT)
|
|
100
|
+
)
|
|
101
|
+
);
|
|
99
102
|
}
|