@pi-r/chrome 0.12.0 → 0.12.2
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/extensions/css/remove-unused/index.js +210 -191
- package/index.js +13 -10
- package/package.json +5 -8
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
const { randomUUID } = require('node:crypto');
|
|
4
4
|
const Document = require('@e-mc/document');
|
|
5
5
|
const { DomWriter } = require('@e-mc/document/parse/dom');
|
|
6
|
-
const { escapePattern } = require('@e-mc/types');
|
|
6
|
+
const { escapePattern, manageGlobalObject } = require('@e-mc/types');
|
|
7
7
|
const { PATTERN_PARENTHESIS, findClosingIndex, getNewlineString, replaceMatch, spliceSource, splitEnclosing } = require('@pi-r/chrome/util');
|
|
8
|
-
const PATTERN_STRING_SOME = '(?:\\s|' + DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}`)*';
|
|
8
|
+
const PATTERN_STRING_SOME = '(?:\\s|' + DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}`)*';
|
|
9
9
|
const PATTERN_STRING_MANY = PATTERN_STRING_SOME.slice(0, -1) + '+';
|
|
10
10
|
const PATTERN_VARIABLE = '--(?:[-\\w]+|\\\\\\S|[^\\u0000-\\u007F]+)+';
|
|
11
11
|
const CACHE_ATRULES = Object.create(null);
|
|
@@ -27,212 +27,233 @@ const REGEXP_KEYFRAMES_UNSAFE = /(\s*)@keyframes\s+([^{]+){/gi;
|
|
|
27
27
|
const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--\S+)\s*{/gi;
|
|
28
28
|
const REGEXP_NTHCHILD_UNSAFE = new RegExp(`\\(\\s*([+-])?(?:(\\d*)[nN]|(0))?\\s*([+-])?\\s*(\\d*)(?:\\s+[oO][fF]\\s+(${PATTERN_PARENTHESIS})\\s*\\)|\\s*\\))`, 'g');
|
|
29
29
|
const REGEXP_LEADINGBRACE_UNSAFE = /(.)\s*{$/;
|
|
30
|
+
manageGlobalObject(CACHE_ATRULES);
|
|
31
|
+
manageGlobalObject(CACHE_QUERY);
|
|
32
|
+
manageGlobalObject(CACHE_SELECTOR);
|
|
30
33
|
const getEndIndex = (match) => match.index + match[0].length;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const hasBracket = (value) => value.includes('{') || value.includes('}');
|
|
35
|
+
const getWhiteSpace = (unsafe) => unsafe ? ['\\s*', '\\s+'] : [PATTERN_STRING_SOME, PATTERN_STRING_MANY];
|
|
36
|
+
function replaceBracket(pattern, current, replaceMap) {
|
|
37
|
+
let match;
|
|
38
|
+
while (match = pattern.exec(current)) {
|
|
39
|
+
const seg = match[0];
|
|
40
|
+
if (hasBracket(seg)) {
|
|
41
|
+
const placeholder = '`' + randomUUID().slice(0, 23) + '`';
|
|
42
|
+
replaceMap.push([placeholder, seg]);
|
|
43
|
+
current = replaceMatch(match, current, placeholder, pattern);
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
pattern.lastIndex = 0;
|
|
47
|
+
return current;
|
|
48
|
+
}
|
|
49
|
+
function parseSelector(value, unsafe) {
|
|
50
|
+
const [stringSome, stringMany] = getWhiteSpace(unsafe);
|
|
51
|
+
const items = [];
|
|
52
|
+
const revised = value.replace(unsafe ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
|
|
53
|
+
return '`%' + (items.push('\\(' + stringSome + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]?') + stringSome + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b?') + stringSome + capture[5] : `(?:[+-]${stringSome}0)?`) + (capture[6] ? stringMany + '[oO][fF]' + stringMany + capture[6].trim() : '') + stringSome + '\\)') - 1) + '`';
|
|
54
|
+
});
|
|
55
|
+
let selector = '';
|
|
56
|
+
for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
|
|
57
|
+
let ch = revised[i], space = 0;
|
|
58
|
+
switch (ch) {
|
|
59
|
+
case '.':
|
|
60
|
+
case '#':
|
|
61
|
+
if (!attr) {
|
|
62
|
+
casing = true;
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case '[':
|
|
66
|
+
if (!quote) {
|
|
67
|
+
attr = true;
|
|
68
|
+
casing = false;
|
|
69
|
+
space = 2;
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case ']':
|
|
73
|
+
if (!quote || attr && revised[i - 1] === '"' && revised[i - 2] === '\\') {
|
|
74
|
+
if (quote) {
|
|
75
|
+
selector = selector.slice(0, -1) + '`%%%`';
|
|
76
|
+
quote = false;
|
|
52
77
|
}
|
|
53
|
-
|
|
54
|
-
|
|
78
|
+
attr = false;
|
|
79
|
+
casing = false;
|
|
80
|
+
space = 1;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case '=':
|
|
84
|
+
if (attr && !quote) {
|
|
85
|
+
casing = true;
|
|
86
|
+
space = 3;
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
case '\\':
|
|
90
|
+
ch = '`%%%%`';
|
|
91
|
+
break;
|
|
92
|
+
case '"':
|
|
93
|
+
if (attr) {
|
|
55
94
|
if (!quote) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
space = 2;
|
|
95
|
+
ch = '`%%%`';
|
|
96
|
+
quote = true;
|
|
59
97
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (quote) {
|
|
64
|
-
selector = selector.slice(0, -1) + '`%%%`';
|
|
65
|
-
quote = false;
|
|
66
|
-
}
|
|
67
|
-
attr = false;
|
|
98
|
+
else if (revised[i - 1] !== '\\') {
|
|
99
|
+
ch = '`%%%`';
|
|
100
|
+
quote = false;
|
|
68
101
|
casing = false;
|
|
69
|
-
space = 1;
|
|
70
|
-
}
|
|
71
|
-
break;
|
|
72
|
-
case '=':
|
|
73
|
-
if (attr && !quote) {
|
|
74
|
-
casing = true;
|
|
75
|
-
space = 3;
|
|
76
|
-
}
|
|
77
|
-
break;
|
|
78
|
-
case '\\':
|
|
79
|
-
ch = '`%%%%`';
|
|
80
|
-
break;
|
|
81
|
-
case '"':
|
|
82
|
-
if (attr) {
|
|
83
|
-
if (!quote) {
|
|
84
|
-
ch = '`%%%`';
|
|
85
|
-
quote = true;
|
|
86
|
-
}
|
|
87
|
-
else if (revised[i - 1] !== '\\') {
|
|
88
|
-
ch = '`%%%`';
|
|
89
|
-
quote = false;
|
|
90
|
-
casing = false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
break;
|
|
94
|
-
case '~':
|
|
95
|
-
case '^':
|
|
96
|
-
case '$':
|
|
97
|
-
case '*':
|
|
98
|
-
case '|':
|
|
99
|
-
if (attr && !quote) {
|
|
100
|
-
space = 1;
|
|
101
102
|
}
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case '~':
|
|
106
|
+
case '^':
|
|
107
|
+
case '$':
|
|
108
|
+
case '*':
|
|
109
|
+
case '|':
|
|
110
|
+
if (attr && !quote) {
|
|
111
|
+
space = 1;
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
case ' ':
|
|
115
|
+
if (attr && !quote) {
|
|
116
|
+
ch = '`%%`';
|
|
102
117
|
break;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
}
|
|
119
|
+
case ':':
|
|
120
|
+
case ',':
|
|
121
|
+
if (!attr) {
|
|
122
|
+
casing = false;
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
selector += (space & 1 ? '`%%`' : '') + (!casing && ch >= 'a' && ch <= 'z' ? '`' + ch + ch.toUpperCase() + '`' : ch) + (space & 2 ? '`%%`' : '');
|
|
127
|
+
}
|
|
128
|
+
selector = escapePattern(selector)
|
|
129
|
+
.replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
130
|
+
.replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
|
|
131
|
+
switch (capture[1]) {
|
|
132
|
+
case '%%':
|
|
133
|
+
return stringSome;
|
|
134
|
+
case '%%%':
|
|
135
|
+
return `(?:["']|${stringSome})`;
|
|
136
|
+
case '%%%%':
|
|
137
|
+
return '\\\\{0,}';
|
|
138
|
+
default:
|
|
139
|
+
return `[${capture[1]}]`;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
143
|
+
selector = selector.replace('`%' + i + '`', items[i]);
|
|
144
|
+
}
|
|
145
|
+
return selector.replace(/ +/g, stringMany) + stringSome;
|
|
146
|
+
}
|
|
147
|
+
function replaceRule(name, items, current, increment, ...args) {
|
|
148
|
+
const [nesting, unsafe, cache] = args;
|
|
149
|
+
const [stringSome, stringMany] = getWhiteSpace(unsafe);
|
|
150
|
+
let modified = false;
|
|
151
|
+
for (let i = 0; i < items.length; i += increment) {
|
|
152
|
+
const value = items[i].trim();
|
|
153
|
+
let valueTo;
|
|
154
|
+
const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (unsafe ? '_1' : '');
|
|
155
|
+
let pattern = CACHE_QUERY.get(key), match;
|
|
156
|
+
if (!pattern) {
|
|
157
|
+
let flags = 'gi', selector = '', revised = false;
|
|
158
|
+
if (name === 'container') {
|
|
159
|
+
for (let j = 0, length = value.length, casing = true; j < length; j++) {
|
|
160
|
+
let ch = value[j];
|
|
161
|
+
if (!casing) {
|
|
162
|
+
ch = ch.toLowerCase();
|
|
107
163
|
}
|
|
108
|
-
|
|
109
|
-
case ',':
|
|
110
|
-
if (!attr) {
|
|
164
|
+
else if (ch === '(') {
|
|
111
165
|
casing = false;
|
|
112
166
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
selector = escapePattern(selector)
|
|
118
|
-
.replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
119
|
-
.replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
|
|
120
|
-
switch (capture[1]) {
|
|
121
|
-
case '%%':
|
|
122
|
-
return stringSome;
|
|
123
|
-
case '%%%':
|
|
124
|
-
return `(?:["']|${stringSome})`;
|
|
125
|
-
case '%%%%':
|
|
126
|
-
return '\\\\{0,}';
|
|
127
|
-
default:
|
|
128
|
-
return `[${capture[1]}]`;
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
132
|
-
selector = selector.replace('`%' + i + '`', items[i]);
|
|
133
|
-
}
|
|
134
|
-
return selector.replace(/ +/g, stringMany) + stringSome;
|
|
135
|
-
};
|
|
136
|
-
const replaceUnunsed = (name, items, nesting, increment = 1) => {
|
|
137
|
-
for (let i = 0; i < items.length; i += increment) {
|
|
138
|
-
const value = items[i].trim();
|
|
139
|
-
let valueTo;
|
|
140
|
-
const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (useUnsafeCssReplace ? '_1' : '');
|
|
141
|
-
let pattern = CACHE_QUERY.get(key), rule;
|
|
142
|
-
if (!pattern) {
|
|
143
|
-
let flags = 'gi', selector = '', revised = false;
|
|
144
|
-
if (name === 'container') {
|
|
145
|
-
for (let j = 0, length = value.length, casing = true; j < length; j++) {
|
|
146
|
-
let ch = value[j];
|
|
147
|
-
if (!casing) {
|
|
148
|
-
ch = ch.toLowerCase();
|
|
149
|
-
}
|
|
150
|
-
else if (ch === '(') {
|
|
151
|
-
casing = false;
|
|
152
|
-
}
|
|
153
|
-
if (casing || ch < 'a' || ch > 'z') {
|
|
154
|
-
selector += value[j];
|
|
155
|
-
if (selector.endsWith(' not ')) {
|
|
156
|
-
selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
selector += '`' + ch + ch.toUpperCase() + '`';
|
|
167
|
+
if (casing || ch < 'a' || ch > 'z') {
|
|
168
|
+
selector += value[j];
|
|
169
|
+
if (selector.endsWith(' not ')) {
|
|
170
|
+
selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
|
|
161
171
|
}
|
|
162
172
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
else if (name === 'scope') {
|
|
166
|
-
selector = `\\(${stringSome + parseSelector(value)}\\)`;
|
|
167
|
-
if (valueTo) {
|
|
168
|
-
selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo)}\\)`;
|
|
173
|
+
else {
|
|
174
|
+
selector += '`' + ch + ch.toUpperCase() + '`';
|
|
169
175
|
}
|
|
170
|
-
flags = 'g';
|
|
171
|
-
revised = true;
|
|
172
176
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
revised = true;
|
|
180
|
-
}
|
|
177
|
+
flags = 'g';
|
|
178
|
+
}
|
|
179
|
+
else if (name === 'scope') {
|
|
180
|
+
selector = `\\(${stringSome + parseSelector(value, unsafe)}\\)`;
|
|
181
|
+
if (valueTo) {
|
|
182
|
+
selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo, unsafe)}\\)`;
|
|
181
183
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
flags = 'g';
|
|
185
|
+
revised = true;
|
|
186
|
+
}
|
|
187
|
+
else if (name === 'supports' && /^selector\(/i.test(value)) {
|
|
188
|
+
const startIndex = value.indexOf('(');
|
|
189
|
+
const endIndex = value.lastIndexOf(')');
|
|
190
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
191
|
+
selector = '[sS][eE][lL][eE][cC][tT][oO][rR]\\(' + stringSome + parseSelector(value.slice(startIndex + 1, endIndex), unsafe) + '\\)';
|
|
192
|
+
flags = 'g';
|
|
193
|
+
revised = true;
|
|
191
194
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
}
|
|
196
|
+
if (!revised) {
|
|
197
|
+
selector = escapePattern(selector || value)
|
|
198
|
+
.replace(/\s*(\\[()])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
199
|
+
.replace(/:\s+/g, stringSome + ':' + stringSome)
|
|
200
|
+
.replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
201
|
+
.replace(/ +/g, stringMany);
|
|
202
|
+
if (flags === 'g') {
|
|
203
|
+
selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
|
|
195
204
|
}
|
|
196
205
|
}
|
|
197
|
-
|
|
198
|
-
|
|
206
|
+
pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + stringMany + selector + stringSome + '{', flags);
|
|
207
|
+
if (cache) {
|
|
208
|
+
CACHE_QUERY.set(key, pattern);
|
|
199
209
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
|
|
210
|
-
(checkEmpty ||= {})[name] = true;
|
|
211
|
-
modified = true;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
pattern.lastIndex = 0;
|
|
213
|
+
}
|
|
214
|
+
while (match = pattern.exec(current)) {
|
|
215
|
+
if (!nesting) {
|
|
216
|
+
const block = Array.from(current.slice(0, match.index).matchAll(/[{}]/g));
|
|
217
|
+
if (block.filter(open => open[0] === '{').length !== block.filter(close => close[0] === '}').length) {
|
|
218
|
+
continue;
|
|
212
219
|
}
|
|
213
220
|
}
|
|
221
|
+
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
222
|
+
if (endIndex !== -1) {
|
|
223
|
+
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
224
|
+
modified = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return [modified, current, name];
|
|
229
|
+
}
|
|
230
|
+
function removeUnused(source, options) {
|
|
231
|
+
if (options.file?.preserve) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const { usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedSupports, unusedContainer, unusedScope, useUnsafeCssReplace = false, useSessionCache = true } = options.config;
|
|
235
|
+
if (!usedVariables && !usedFontFace && !usedKeyframes && !unusedStyles && !unusedMedia && !unusedSupports && !unusedContainer && !unusedScope) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const stringSome = getWhiteSpace(useUnsafeCssReplace)[0];
|
|
239
|
+
const replaceMap = [];
|
|
240
|
+
const checkEmpty = {};
|
|
241
|
+
let current = source, modified = false, match;
|
|
242
|
+
const setModified = (args) => {
|
|
243
|
+
if (args[0]) {
|
|
244
|
+
current = args[1];
|
|
245
|
+
checkEmpty[args[2]] = true;
|
|
246
|
+
modified = true;
|
|
214
247
|
}
|
|
215
248
|
};
|
|
216
249
|
if (!useUnsafeCssReplace) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
while (bracket = pattern.exec(current)) {
|
|
220
|
-
const segment = bracket[0];
|
|
221
|
-
if (/[{}]/.test(segment)) {
|
|
222
|
-
const placeholder = '`' + randomUUID().slice(0, 18) + '`';
|
|
223
|
-
replaceMap.push([placeholder, segment]);
|
|
224
|
-
current = replaceMatch(bracket, current, placeholder, pattern);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
pattern.lastIndex = 0;
|
|
228
|
-
};
|
|
229
|
-
replaceBracket(REGEXP_COMMENT);
|
|
230
|
-
replaceBracket(REGEXP_QUOTEDVALUE);
|
|
250
|
+
current = replaceBracket(REGEXP_COMMENT, current, replaceMap);
|
|
251
|
+
current = replaceBracket(REGEXP_QUOTEDVALUE, current, replaceMap);
|
|
231
252
|
const values = splitEnclosing(current, /\b(?<!-)url/gi);
|
|
232
253
|
for (let i = 0, length = values.length; i < length; ++i) {
|
|
233
254
|
const seg = values[i];
|
|
234
|
-
if (/^url\(
|
|
235
|
-
replaceMap.push([values[i] = randomUUID().slice(0,
|
|
255
|
+
if (/^url\(/i.test(seg) && hasBracket(seg)) {
|
|
256
|
+
replaceMap.push([values[i] = randomUUID().slice(0, 23), seg]);
|
|
236
257
|
}
|
|
237
258
|
}
|
|
238
259
|
if (replaceMap.length > 0) {
|
|
@@ -240,16 +261,16 @@ function cssUnused(source, options) {
|
|
|
240
261
|
}
|
|
241
262
|
}
|
|
242
263
|
if (unusedMedia) {
|
|
243
|
-
|
|
264
|
+
setModified(replaceRule('media', unusedMedia, current, 1, true, useUnsafeCssReplace, useSessionCache));
|
|
244
265
|
}
|
|
245
266
|
if (unusedSupports) {
|
|
246
|
-
|
|
267
|
+
setModified(replaceRule('supports', unusedSupports, current, 1, true, useUnsafeCssReplace, useSessionCache));
|
|
247
268
|
}
|
|
248
269
|
if (unusedContainer) {
|
|
249
|
-
|
|
270
|
+
setModified(replaceRule('container', unusedContainer, current, 1, false, useUnsafeCssReplace, useSessionCache));
|
|
250
271
|
}
|
|
251
272
|
if (unusedScope) {
|
|
252
|
-
|
|
273
|
+
setModified(replaceRule('scope', unusedScope.map(item => [item.start || '', item.end || '']).flat(), current, 2, false, useUnsafeCssReplace, useSessionCache));
|
|
253
274
|
}
|
|
254
275
|
if (unusedStyles) {
|
|
255
276
|
current = (function recurse(target, child) {
|
|
@@ -266,10 +287,10 @@ function cssUnused(source, options) {
|
|
|
266
287
|
const pattern = CACHE_SELECTOR.get(key);
|
|
267
288
|
let single, group;
|
|
268
289
|
if (!pattern) {
|
|
269
|
-
const selector = parseSelector(value) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
290
|
+
const selector = parseSelector(value, useUnsafeCssReplace) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
270
291
|
single = new RegExp(`(^|;)(${stringSome})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
|
|
271
292
|
group = new RegExp(`((?:^|;)[^{]*${stringSome}(,${stringSome}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
|
|
272
|
-
if (useSessionCache
|
|
293
|
+
if (useSessionCache) {
|
|
273
294
|
CACHE_SELECTOR.set(key, [single, group]);
|
|
274
295
|
}
|
|
275
296
|
}
|
|
@@ -410,14 +431,12 @@ function cssUnused(source, options) {
|
|
|
410
431
|
}
|
|
411
432
|
pattern.lastIndex = 0;
|
|
412
433
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
current = current.replace(placeholder, content);
|
|
416
|
-
}
|
|
434
|
+
for (const [placeholder, content] of replaceMap.reverse()) {
|
|
435
|
+
current = current.replace(placeholder, content);
|
|
417
436
|
}
|
|
418
437
|
return current;
|
|
419
438
|
}
|
|
420
439
|
}
|
|
421
|
-
var index = Document.signExtensionType(
|
|
440
|
+
var index = Document.signExtensionType(removeUnused, 'css');
|
|
422
441
|
|
|
423
442
|
module.exports = index;
|
package/index.js
CHANGED
|
@@ -1774,15 +1774,13 @@ class ChromeDocument extends Document {
|
|
|
1774
1774
|
source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${escapePattern(name)}-[^=\\s]+|.+-${escapePattern(name)})\\s*${DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g'), '');
|
|
1775
1775
|
}
|
|
1776
1776
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1782
|
-
}
|
|
1777
|
+
let match;
|
|
1778
|
+
while (match = REGEXP_STYLE.exec(source)) {
|
|
1779
|
+
if (output = await this.transformCss(processing, htmlFile, match[5])) {
|
|
1780
|
+
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1783
1781
|
}
|
|
1784
|
-
REGEXP_STYLE.lastIndex = 0;
|
|
1785
1782
|
}
|
|
1783
|
+
REGEXP_STYLE.lastIndex = 0;
|
|
1786
1784
|
if (output = this.processUrl(host, htmlFile, source, 'html')) {
|
|
1787
1785
|
source = output;
|
|
1788
1786
|
}
|
|
@@ -2356,7 +2354,9 @@ class ChromeDocument extends Document {
|
|
|
2356
2354
|
case 'mongodb':
|
|
2357
2355
|
for (let j = 0; j < length; ++j) {
|
|
2358
2356
|
const cmd = batch[j];
|
|
2359
|
-
|
|
2357
|
+
if (cmd.cascade) {
|
|
2358
|
+
cmd.cacheObjectKey ||= cmd.cascade;
|
|
2359
|
+
}
|
|
2360
2360
|
}
|
|
2361
2361
|
break;
|
|
2362
2362
|
case 'redis':
|
|
@@ -2390,7 +2390,10 @@ class ChromeDocument extends Document {
|
|
|
2390
2390
|
}
|
|
2391
2391
|
}
|
|
2392
2392
|
if (cmd.key) {
|
|
2393
|
-
|
|
2393
|
+
const { cascade, query } = cmd;
|
|
2394
|
+
if (cascade || query) {
|
|
2395
|
+
cmd.cacheObjectKey ||= (cascade ? cascade : '') + '_' + (query ? Document.asString(query, true) : '');
|
|
2396
|
+
}
|
|
2394
2397
|
}
|
|
2395
2398
|
}
|
|
2396
2399
|
break;
|
|
@@ -3427,7 +3430,7 @@ class ChromeDocument extends Document {
|
|
|
3427
3430
|
const format = this.formatMap || this.module.format;
|
|
3428
3431
|
if (format) {
|
|
3429
3432
|
const pattern = nameExt && nameExt in format ? format[nameExt] : format.uuid;
|
|
3430
|
-
if (
|
|
3433
|
+
if (isString(pattern?.[attr])) {
|
|
3431
3434
|
return randomString(pattern[attr], pattern.dictionary);
|
|
3432
3435
|
}
|
|
3433
3436
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/chrome",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Chrome document constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
-
"publishConfig": {
|
|
8
|
-
"access": "public"
|
|
9
|
-
},
|
|
10
7
|
"repository": {
|
|
11
8
|
"type": "git",
|
|
12
9
|
"url": "git+https://github.com/anpham6/pi-r.git",
|
|
@@ -20,10 +17,10 @@
|
|
|
20
17
|
"license": "MIT",
|
|
21
18
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
19
|
"dependencies": {
|
|
23
|
-
"@e-mc/cloud": "^0.14.
|
|
24
|
-
"@e-mc/core": "^0.14.
|
|
25
|
-
"@e-mc/document": "^0.14.
|
|
26
|
-
"@e-mc/types": "^0.14.
|
|
20
|
+
"@e-mc/cloud": "^0.14.3",
|
|
21
|
+
"@e-mc/core": "^0.14.3",
|
|
22
|
+
"@e-mc/document": "^0.14.3",
|
|
23
|
+
"@e-mc/types": "^0.14.3",
|
|
27
24
|
"image-size": "^2.0.2"
|
|
28
25
|
}
|
|
29
26
|
}
|