@pi-r/chrome 0.12.1 → 0.12.3
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 +208 -190
- package/index.js +6 -7
- package/package.json +5 -5
- package/types/squared.d.ts +1 -0
|
@@ -5,7 +5,7 @@ const Document = require('@e-mc/document');
|
|
|
5
5
|
const { DomWriter } = require('@e-mc/document/parse/dom');
|
|
6
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);
|
|
@@ -31,211 +31,231 @@ manageGlobalObject(CACHE_ATRULES);
|
|
|
31
31
|
manageGlobalObject(CACHE_QUERY);
|
|
32
32
|
manageGlobalObject(CACHE_SELECTOR);
|
|
33
33
|
const getEndIndex = (match) => match.index + match[0].length;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
+
pattern.lastIndex = 0;
|
|
38
|
+
let match;
|
|
39
|
+
while (match = pattern.exec(current)) {
|
|
40
|
+
const seg = match[0];
|
|
41
|
+
if (hasBracket(seg)) {
|
|
42
|
+
const placeholder = '`' + randomUUID().slice(0, 23) + '`';
|
|
43
|
+
replaceMap.push([placeholder, seg]);
|
|
44
|
+
current = replaceMatch(match, current, placeholder, pattern);
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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;
|
|
55
77
|
}
|
|
56
|
-
|
|
57
|
-
|
|
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) {
|
|
58
94
|
if (!quote) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
space = 2;
|
|
95
|
+
ch = '`%%%`';
|
|
96
|
+
quote = true;
|
|
62
97
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (quote) {
|
|
67
|
-
selector = selector.slice(0, -1) + '`%%%`';
|
|
68
|
-
quote = false;
|
|
69
|
-
}
|
|
70
|
-
attr = false;
|
|
98
|
+
else if (revised[i - 1] !== '\\') {
|
|
99
|
+
ch = '`%%%`';
|
|
100
|
+
quote = false;
|
|
71
101
|
casing = false;
|
|
72
|
-
space = 1;
|
|
73
|
-
}
|
|
74
|
-
break;
|
|
75
|
-
case '=':
|
|
76
|
-
if (attr && !quote) {
|
|
77
|
-
casing = true;
|
|
78
|
-
space = 3;
|
|
79
|
-
}
|
|
80
|
-
break;
|
|
81
|
-
case '\\':
|
|
82
|
-
ch = '`%%%%`';
|
|
83
|
-
break;
|
|
84
|
-
case '"':
|
|
85
|
-
if (attr) {
|
|
86
|
-
if (!quote) {
|
|
87
|
-
ch = '`%%%`';
|
|
88
|
-
quote = true;
|
|
89
|
-
}
|
|
90
|
-
else if (revised[i - 1] !== '\\') {
|
|
91
|
-
ch = '`%%%`';
|
|
92
|
-
quote = false;
|
|
93
|
-
casing = false;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
break;
|
|
97
|
-
case '~':
|
|
98
|
-
case '^':
|
|
99
|
-
case '$':
|
|
100
|
-
case '*':
|
|
101
|
-
case '|':
|
|
102
|
-
if (attr && !quote) {
|
|
103
|
-
space = 1;
|
|
104
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 = '`%%`';
|
|
105
117
|
break;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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();
|
|
110
163
|
}
|
|
111
|
-
|
|
112
|
-
case ',':
|
|
113
|
-
if (!attr) {
|
|
164
|
+
else if (ch === '(') {
|
|
114
165
|
casing = false;
|
|
115
166
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
selector = escapePattern(selector)
|
|
121
|
-
.replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
122
|
-
.replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
|
|
123
|
-
switch (capture[1]) {
|
|
124
|
-
case '%%':
|
|
125
|
-
return stringSome;
|
|
126
|
-
case '%%%':
|
|
127
|
-
return `(?:["']|${stringSome})`;
|
|
128
|
-
case '%%%%':
|
|
129
|
-
return '\\\\{0,}';
|
|
130
|
-
default:
|
|
131
|
-
return `[${capture[1]}]`;
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
135
|
-
selector = selector.replace('`%' + i + '`', items[i]);
|
|
136
|
-
}
|
|
137
|
-
return selector.replace(/ +/g, stringMany) + stringSome;
|
|
138
|
-
};
|
|
139
|
-
const replaceUnunsed = (name, items, nesting, increment = 1) => {
|
|
140
|
-
for (let i = 0; i < items.length; i += increment) {
|
|
141
|
-
const value = items[i].trim();
|
|
142
|
-
let valueTo;
|
|
143
|
-
const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (useUnsafeCssReplace ? '_1' : '');
|
|
144
|
-
let pattern = CACHE_QUERY.get(key), rule;
|
|
145
|
-
if (!pattern) {
|
|
146
|
-
let flags = 'gi', selector = '', revised = false;
|
|
147
|
-
if (name === 'container') {
|
|
148
|
-
for (let j = 0, length = value.length, casing = true; j < length; j++) {
|
|
149
|
-
let ch = value[j];
|
|
150
|
-
if (!casing) {
|
|
151
|
-
ch = ch.toLowerCase();
|
|
152
|
-
}
|
|
153
|
-
else if (ch === '(') {
|
|
154
|
-
casing = false;
|
|
155
|
-
}
|
|
156
|
-
if (casing || ch < 'a' || ch > 'z') {
|
|
157
|
-
selector += value[j];
|
|
158
|
-
if (selector.endsWith(' not ')) {
|
|
159
|
-
selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
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` ');
|
|
164
171
|
}
|
|
165
172
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
else if (name === 'scope') {
|
|
169
|
-
selector = `\\(${stringSome + parseSelector(value)}\\)`;
|
|
170
|
-
if (valueTo) {
|
|
171
|
-
selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo)}\\)`;
|
|
173
|
+
else {
|
|
174
|
+
selector += '`' + ch + ch.toUpperCase() + '`';
|
|
172
175
|
}
|
|
173
|
-
flags = 'g';
|
|
174
|
-
revised = true;
|
|
175
176
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
revised = true;
|
|
183
|
-
}
|
|
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)}\\)`;
|
|
184
183
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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;
|
|
194
194
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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]}]`);
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
|
-
|
|
201
|
-
|
|
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);
|
|
202
209
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
|
|
213
|
-
(checkEmpty ||= {})[name] = true;
|
|
214
|
-
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;
|
|
215
219
|
}
|
|
216
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, stripStyleComments, 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 = stripStyleComments ? source.replace(REGEXP_COMMENT, '') : source, modified = source !== current, match;
|
|
242
|
+
const setModified = (args) => {
|
|
243
|
+
if (args[0]) {
|
|
244
|
+
current = args[1];
|
|
245
|
+
checkEmpty[args[2]] = true;
|
|
246
|
+
modified = true;
|
|
217
247
|
}
|
|
218
248
|
};
|
|
219
249
|
if (!useUnsafeCssReplace) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if (/[{}]/.test(segment)) {
|
|
225
|
-
const placeholder = '`' + randomUUID().slice(0, 18) + '`';
|
|
226
|
-
replaceMap.push([placeholder, segment]);
|
|
227
|
-
current = replaceMatch(bracket, current, placeholder, pattern);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
pattern.lastIndex = 0;
|
|
231
|
-
};
|
|
232
|
-
replaceBracket(REGEXP_COMMENT);
|
|
233
|
-
replaceBracket(REGEXP_QUOTEDVALUE);
|
|
250
|
+
if (!stripStyleComments) {
|
|
251
|
+
current = replaceBracket(REGEXP_COMMENT, current, replaceMap);
|
|
252
|
+
}
|
|
253
|
+
current = replaceBracket(REGEXP_QUOTEDVALUE, current, replaceMap);
|
|
234
254
|
const values = splitEnclosing(current, /\b(?<!-)url/gi);
|
|
235
255
|
for (let i = 0, length = values.length; i < length; ++i) {
|
|
236
256
|
const seg = values[i];
|
|
237
|
-
if (/^url\(
|
|
238
|
-
replaceMap.push([values[i] = randomUUID().slice(0,
|
|
257
|
+
if (/^url\(/i.test(seg) && hasBracket(seg)) {
|
|
258
|
+
replaceMap.push([values[i] = randomUUID().slice(0, 23), seg]);
|
|
239
259
|
}
|
|
240
260
|
}
|
|
241
261
|
if (replaceMap.length > 0) {
|
|
@@ -243,16 +263,16 @@ function cssUnused(source, options) {
|
|
|
243
263
|
}
|
|
244
264
|
}
|
|
245
265
|
if (unusedMedia) {
|
|
246
|
-
|
|
266
|
+
setModified(replaceRule('media', unusedMedia, current, 1, true, useUnsafeCssReplace, useSessionCache));
|
|
247
267
|
}
|
|
248
268
|
if (unusedSupports) {
|
|
249
|
-
|
|
269
|
+
setModified(replaceRule('supports', unusedSupports, current, 1, true, useUnsafeCssReplace, useSessionCache));
|
|
250
270
|
}
|
|
251
271
|
if (unusedContainer) {
|
|
252
|
-
|
|
272
|
+
setModified(replaceRule('container', unusedContainer, current, 1, false, useUnsafeCssReplace, useSessionCache));
|
|
253
273
|
}
|
|
254
274
|
if (unusedScope) {
|
|
255
|
-
|
|
275
|
+
setModified(replaceRule('scope', unusedScope.map(item => [item.start || '', item.end || '']).flat(), current, 2, false, useUnsafeCssReplace, useSessionCache));
|
|
256
276
|
}
|
|
257
277
|
if (unusedStyles) {
|
|
258
278
|
current = (function recurse(target, child) {
|
|
@@ -269,10 +289,10 @@ function cssUnused(source, options) {
|
|
|
269
289
|
const pattern = CACHE_SELECTOR.get(key);
|
|
270
290
|
let single, group;
|
|
271
291
|
if (!pattern) {
|
|
272
|
-
const selector = parseSelector(value) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
292
|
+
const selector = parseSelector(value, useUnsafeCssReplace) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
273
293
|
single = new RegExp(`(^|;)(${stringSome})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
|
|
274
294
|
group = new RegExp(`((?:^|;)[^{]*${stringSome}(,${stringSome}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
|
|
275
|
-
if (useSessionCache
|
|
295
|
+
if (useSessionCache) {
|
|
276
296
|
CACHE_SELECTOR.set(key, [single, group]);
|
|
277
297
|
}
|
|
278
298
|
}
|
|
@@ -413,14 +433,12 @@ function cssUnused(source, options) {
|
|
|
413
433
|
}
|
|
414
434
|
pattern.lastIndex = 0;
|
|
415
435
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
current = current.replace(placeholder, content);
|
|
419
|
-
}
|
|
436
|
+
for (const [placeholder, content] of replaceMap.reverse()) {
|
|
437
|
+
current = current.replace(placeholder, content);
|
|
420
438
|
}
|
|
421
439
|
return current;
|
|
422
440
|
}
|
|
423
441
|
}
|
|
424
|
-
var index = Document.signExtensionType(
|
|
442
|
+
var index = Document.signExtensionType(removeUnused, 'css');
|
|
425
443
|
|
|
426
444
|
module.exports = index;
|
package/index.js
CHANGED
|
@@ -675,6 +675,7 @@ class ChromeDocument extends Document {
|
|
|
675
675
|
useUnsafeCssReplace: undefined,
|
|
676
676
|
useSessionCache: undefined,
|
|
677
677
|
stripCommentsAndCDATA: undefined,
|
|
678
|
+
stripStyleComments: undefined,
|
|
678
679
|
normalizeHtmlOutput: undefined,
|
|
679
680
|
escapeReservedCharacters: undefined,
|
|
680
681
|
ignoreServerCodeBlocks: undefined
|
|
@@ -1774,15 +1775,13 @@ class ChromeDocument extends Document {
|
|
|
1774
1775
|
source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${escapePattern(name)}-[^=\\s]+|.+-${escapePattern(name)})\\s*${DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g'), '');
|
|
1775
1776
|
}
|
|
1776
1777
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1782
|
-
}
|
|
1778
|
+
let match;
|
|
1779
|
+
while (match = REGEXP_STYLE.exec(source)) {
|
|
1780
|
+
if (output = await this.transformCss(processing, htmlFile, match[5])) {
|
|
1781
|
+
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1783
1782
|
}
|
|
1784
|
-
REGEXP_STYLE.lastIndex = 0;
|
|
1785
1783
|
}
|
|
1784
|
+
REGEXP_STYLE.lastIndex = 0;
|
|
1786
1785
|
if (output = this.processUrl(host, htmlFile, source, 'html')) {
|
|
1787
1786
|
source = output;
|
|
1788
1787
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/chrome",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"description": "Chrome document constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@e-mc/cloud": "^0.14.
|
|
21
|
-
"@e-mc/core": "^0.14.
|
|
22
|
-
"@e-mc/document": "^0.14.
|
|
23
|
-
"@e-mc/types": "^0.14.
|
|
20
|
+
"@e-mc/cloud": "^0.14.4",
|
|
21
|
+
"@e-mc/core": "^0.14.4",
|
|
22
|
+
"@e-mc/document": "^0.14.4",
|
|
23
|
+
"@e-mc/types": "^0.14.4",
|
|
24
24
|
"image-size": "^2.0.2"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/types/squared.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export interface DocumentOutput {
|
|
|
50
50
|
/** @deprecated */
|
|
51
51
|
useSessionCache?: boolean;
|
|
52
52
|
stripCommentsAndCDATA?: boolean | string;
|
|
53
|
+
stripStyleComments?: boolean;
|
|
53
54
|
normalizeHtmlOutput?: boolean | string;
|
|
54
55
|
escapeReservedCharacters?: boolean;
|
|
55
56
|
ignoreServerCodeBlocks?: string[];
|