@pi-r/chrome 0.11.2 → 0.12.0
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 +423 -0
- package/index.d.ts +1 -1
- package/index.js +428 -813
- package/package.json +5 -5
- package/types/index.d.ts +40 -11
- package/types/squared.d.ts +2 -1
- package/util.d.ts +20 -0
- package/util.js +49 -0
package/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const { randomUUID } = require('node:crypto');
|
|
6
|
+
const { imageSize } = require('image-size');
|
|
7
|
+
const Cloud = require('@e-mc/cloud');
|
|
8
|
+
const { ClientDb } = require('@e-mc/core');
|
|
9
|
+
const { DomWriter, HtmlElement, IGNORE_FLAG } = require('@e-mc/document/parse/dom');
|
|
10
|
+
const { ERR_CODE, FILE_TYPE, WATCH_EVENT, asExt, asFunction, cascadeObject, cloneFlag, cloneObject, coerceObject, createAbortError, errorMessage, errorValue, escapePattern, existsFlag, getEncoding, ignoreFlag, isArray, isEmpty, isError, isErrorCode, isFunction, isObject, isPlainObject, isString, modifiedFlag, processFlag, randomString, renameExt, requireESM, watchFlag } = require('@e-mc/types');
|
|
11
|
+
const { isEqual, setInitialValue } = require('@e-mc/document/asset');
|
|
12
|
+
const { appendSuffix, getHashData, getModuleName, getNewline, hasValue, spliceString, trimQuote } = require('@e-mc/document/util');
|
|
13
|
+
const { SourceMap } = require('@e-mc/document/transform');
|
|
14
|
+
const { PATTERN_PARENTHESIS, findClosingIndex, getNewlineString, isSpace, replaceMatch } = require('@pi-r/chrome/util');
|
|
13
15
|
const Document = require('@e-mc/document');
|
|
14
16
|
const kChrome = Symbol.for('chrome:constructor');
|
|
15
17
|
const CACHE_DBRESULT = new Map();
|
|
@@ -19,62 +21,40 @@ const CACHE_SELECTOR = new Map();
|
|
|
19
21
|
const CACHE_ETAG = new Map();
|
|
20
22
|
const CACHE_CONTENT = new Map();
|
|
21
23
|
const CACHE_FORMAT = new Map();
|
|
22
|
-
const CACHE_DATASET =
|
|
23
|
-
const CACHE_ATRULES = {};
|
|
24
|
-
const PATTERN_STRING_SOME = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}`)*';
|
|
25
|
-
const PATTERN_STRING_MANY = PATTERN_STRING_SOME.slice(0, -1) + '+';
|
|
26
|
-
const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE, REGEXP_REPLACECSS] = (function () {
|
|
27
|
-
const parenthesis = '(?:,[^()]+(?=\\))|[^()]|\\([^()]*\\(+|\\([^()]*\\)|(?:\\)[^()]+)?\\)*?)+';
|
|
28
|
-
return [
|
|
29
|
-
new RegExp(`\\(${PATTERN_STRING_SOME}([+-])?(?:(\\d*)[nN]|(0))?${PATTERN_STRING_SOME}([+-])?${PATTERN_STRING_SOME}(\\d*)(?:${PATTERN_STRING_MANY}[oO][fF]${PATTERN_STRING_MANY}(${parenthesis})${PATTERN_STRING_SOME}\\)|${PATTERN_STRING_SOME}\\))`, 'g'),
|
|
30
|
-
new RegExp(`\\(\\s*([+-])?(?:(\\d*)[nN]|(0))?\\s*([+-])?\\s*(\\d*)(?:\\s+[oO][fF]\\s+(${parenthesis})\\s*\\)|\\s*\\))`, 'g'),
|
|
31
|
-
new RegExp(`^@import\\s+(?:url\\((?:[^)]|(?<=\\\\)\\))+\\)|"(?:[^"]|(?<=\\\\)")+"|'(?:[^']|(?<=\\\\)')+')(\\s*layer(?:\\(([^)]+)\\))?)?(?:\\s*supports\\((${parenthesis})\\))?(.*)$`)
|
|
32
|
-
];
|
|
33
|
-
})();
|
|
24
|
+
const CACHE_DATASET = Object.create(null);
|
|
34
25
|
const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
|
|
35
|
-
const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{\s*if\s+((?:[^}]|}(?!}))
|
|
36
|
-
const REGEXP_TEMPLATEELSEIF = /\{\{\s*else if\s+((?:[^}]|}(?!}))
|
|
26
|
+
const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{\s*if\s+((?:[^}]|}(?!}))+)\}\}(\s*)(.*?)((?:\s*\{\{\s*else if\s+(?:(?:[^}]|}(?!}))+)\}\}.*?)*)(?:\s*\{\{\s*else\s*\}\}(\s*)(.*?))?\s*\{\{\s*end\s*\}\}/gs;
|
|
27
|
+
const REGEXP_TEMPLATEELSEIF = /\{\{\s*else if\s+((?:[^}]|}(?!}))+)\}\}(\s*)((?:.(?!\{\{\s*else if))*)/gs;
|
|
37
28
|
const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
|
|
38
|
-
const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s]
|
|
39
|
-
const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("
|
|
40
|
-
const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` +
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const REGEXP_STYLE = new RegExp(`(<style${dom_1.DomWriter.PATTERN_TAGOPEN}*>)([\\S\\s]*?)(<\\/style\\s*>)`, 'gi');
|
|
44
|
-
const REGEXP_VARIABLES = new RegExp(`(?<!style\\()(\\s*)(--[^\\s:]*)${PATTERN_STRING_SOME}:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
45
|
-
const REGEXP_FONTFACE = new RegExp(`(\\s*)@font-face${PATTERN_STRING_SOME}{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
46
|
-
const REGEXP_FONTFAMILY = new RegExp(`\\bfont-family${PATTERN_STRING_SOME}:([^;}]+)`, 'i');
|
|
47
|
-
const REGEXP_KEYFRAMES = new RegExp(`(\\s*)@keyframes${PATTERN_STRING_MANY}([^{]+){`, 'gi');
|
|
48
|
-
const REGEXP_PROPERTY = new RegExp(`(\\s*)@property${PATTERN_STRING_MANY}(--[^\\s]+)${PATTERN_STRING_SOME}{`, 'gi');
|
|
49
|
-
const REGEXP_VARIABLES_UNSAFE = new RegExp(`(?<!style\\()(\\s*)(--[^\\s:]+)\\s*:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
50
|
-
const REGEXP_FONTFACE_UNSAFE = new RegExp(`(\\s*)@font-face\\s*{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
51
|
-
const REGEXP_FONTFAMILY_UNSAFE = /\bfont-family\s*:([^;}]+)/i;
|
|
52
|
-
const REGEXP_KEYFRAMES_UNSAFE = /(\s*)@keyframes\s+([^{]+){/gi;
|
|
53
|
-
const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--\S+)\s*{/gi;
|
|
29
|
+
const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s].*)$`, 's');
|
|
30
|
+
const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("[^"]+"|'[^']+')|.+from\s+("[^"]+"|'[^']+')(?:[ \t]+with[ \t]+\{((?:"[^"]+"|'[^']+'|`[^`]+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("[^"]+"|'[^']+')\s*(?:,\s*\{((?:"[^"]+"|'[^']+'|`[^`]+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/gd;
|
|
31
|
+
const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` + DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
32
|
+
const REGEXP_STYLE = new RegExp(`(<style${DomWriter.PATTERN_TAGOPEN}*>)(.*?)(<\\/style\\s*>)`, 'gsi');
|
|
33
|
+
const REGEXP_SANITIZEALL = new RegExp(`(?:\\s+|\\b)data-(?:pathname|filename|intl-locales|(?:use|exclude)-[^=\\s]+)\\s*${DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g');
|
|
54
34
|
const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/gd;
|
|
55
|
-
const
|
|
35
|
+
const REGEXP_REPLACECSS = new RegExp(`^@import\\s+(?:url\\((?:[^)]|(?<=\\\\)\\))+\\)|"(?:[^"]|(?<=\\\\)")+"|'(?:[^']|(?<=\\\\)')+')(\\s*layer(\\([^)]*\\))?)?(?:\\s*supports\\((${PATTERN_PARENTHESIS})\\))?(.*)$`, 'si');
|
|
56
36
|
function removeNamespace(name, source, newline, comments) {
|
|
57
37
|
if (source.includes('-' + name)) {
|
|
58
38
|
const [a, b, c, d, e] = CACHE_DATASET[name] ||= [
|
|
59
|
-
new RegExp(`(\\s*)<(script|style)(${
|
|
60
|
-
new RegExp(`(\\s*)<link(${
|
|
61
|
-
new RegExp(`\\s+data-${name}-[a-z-]+\\s*` +
|
|
39
|
+
new RegExp(`(\\s*)<(script|style)(${DomWriter.PATTERN_TAGOPEN}+)>.*?<\\/\\2\\s*>` + DomWriter.PATTERN_TRAILINGSPACE, 'gsi'),
|
|
40
|
+
new RegExp(`(\\s*)<link(${DomWriter.PATTERN_TAGOPEN}+)>` + DomWriter.PATTERN_TRAILINGSPACE, 'gi'),
|
|
41
|
+
new RegExp(`\\s+data-${name}-[a-z-]+\\s*` + DomWriter.PATTERN_ATTRVALUE, 'g'),
|
|
62
42
|
new RegExp(`data-${name}-file\\s*=\\s*(["'])?exclude\\1`),
|
|
63
|
-
new RegExp(`data-${name}-template\\s*` +
|
|
43
|
+
new RegExp(`data-${name}-template\\s*` + DomWriter.PATTERN_ATTRVALUE)
|
|
64
44
|
];
|
|
65
45
|
source = source
|
|
66
46
|
.replace(a, (...capture) => d.test(capture[3]) || e.test(capture[3]) ? getNewlineString(capture[1], capture[7], newline) : capture[0])
|
|
67
47
|
.replace(b, (...capture) => d.test(capture[2]) ? getNewlineString(capture[1], capture[6], newline) : capture[0])
|
|
68
48
|
.replace(c, '');
|
|
69
49
|
}
|
|
70
|
-
return
|
|
50
|
+
return isArray(comments) ? source.replace(REGEXP_BLOCKEXCLUDE, (...capture) => getNewlineString(capture[1], capture[2], newline)) : source;
|
|
71
51
|
}
|
|
72
52
|
function getObjectValue(value, key) {
|
|
73
53
|
const objectName = /([^[.\s]+)((?:\s*\[[^\]]+\]\s*)+)?\s*\.?\s*/g;
|
|
74
54
|
const subscript = /\[\s*(["'])?(.+?)\1\s*\]/g;
|
|
75
55
|
let found = false, match;
|
|
76
56
|
while (match = objectName.exec(key)) {
|
|
77
|
-
if (
|
|
57
|
+
if (isObject(value)) {
|
|
78
58
|
value = value[match[1]];
|
|
79
59
|
const name = match[2];
|
|
80
60
|
if (name) {
|
|
@@ -83,7 +63,7 @@ function getObjectValue(value, key) {
|
|
|
83
63
|
while (index = subscript.exec(name)) {
|
|
84
64
|
const quote = index[1];
|
|
85
65
|
const attr = quote ? index[2] : index[2].trim();
|
|
86
|
-
if (quote &&
|
|
66
|
+
if (quote && isObject(value) || /^\d+$/.test(attr) && (typeof value === 'string' || isObject(value))) {
|
|
87
67
|
value = value[attr];
|
|
88
68
|
}
|
|
89
69
|
else {
|
|
@@ -101,8 +81,8 @@ function getObjectValue(value, key) {
|
|
|
101
81
|
return found ? value : null;
|
|
102
82
|
}
|
|
103
83
|
function trimTemplate(value) {
|
|
104
|
-
const opening = /\s*\{\{- \s*((?:[^}]|}(?!}))
|
|
105
|
-
const closing = /\{\{((?:[^}]|}(?!}))
|
|
84
|
+
const opening = /\s*\{\{- \s*((?:[^}]|}(?!}))+)\}\}/g;
|
|
85
|
+
const closing = /\{\{((?:[^}]|}(?!}))+)\s* -\}\}\s*/g;
|
|
106
86
|
let match;
|
|
107
87
|
while (match = opening.exec(value)) {
|
|
108
88
|
value = replaceMatch(match, value, 1, opening);
|
|
@@ -112,35 +92,9 @@ function trimTemplate(value) {
|
|
|
112
92
|
}
|
|
113
93
|
return value;
|
|
114
94
|
}
|
|
115
|
-
function findClosingIndex(source, lastIndex, char) {
|
|
116
|
-
const pattern = char === '{' ? /[{}]/g : /[()]/g;
|
|
117
|
-
pattern.lastIndex = lastIndex;
|
|
118
|
-
let opened = 1, closed = 0, endIndex = -1, trailing = '', match;
|
|
119
|
-
while (match = pattern.exec(source)) {
|
|
120
|
-
if (match[0] === char) {
|
|
121
|
-
++opened;
|
|
122
|
-
}
|
|
123
|
-
else if (++closed === opened) {
|
|
124
|
-
if (char === '(') {
|
|
125
|
-
return match.index;
|
|
126
|
-
}
|
|
127
|
-
endIndex = match.index + 1;
|
|
128
|
-
let ch;
|
|
129
|
-
while (isSpace(ch = source[endIndex])) {
|
|
130
|
-
trailing += ch;
|
|
131
|
-
++endIndex;
|
|
132
|
-
if (ch === '\n') {
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return [endIndex, trailing];
|
|
140
|
-
}
|
|
141
95
|
function getPackageName(err) {
|
|
142
|
-
if (
|
|
143
|
-
return
|
|
96
|
+
if (isErrorCode(err, ERR_CODE.MODULE_NOT_FOUND)) {
|
|
97
|
+
return getModuleName(err);
|
|
144
98
|
}
|
|
145
99
|
}
|
|
146
100
|
function getCacheItem(map, key) {
|
|
@@ -154,9 +108,7 @@ function addCacheItem(map, key, data, timeout) {
|
|
|
154
108
|
map.set(key, [
|
|
155
109
|
Date.now(),
|
|
156
110
|
data,
|
|
157
|
-
setTimeout(() =>
|
|
158
|
-
deleteCacheItem(map, key);
|
|
159
|
-
}, timeout * 1000)
|
|
111
|
+
setTimeout(() => deleteCacheItem(map, key), timeout * 1000)
|
|
160
112
|
]);
|
|
161
113
|
}
|
|
162
114
|
function deleteCacheItem(map, key) {
|
|
@@ -166,21 +118,11 @@ function deleteCacheItem(map, key) {
|
|
|
166
118
|
map.delete(key);
|
|
167
119
|
}
|
|
168
120
|
}
|
|
169
|
-
function spliceSource(source, startIndex, endIndex, pattern, leading = '', trailing = '', content = '') {
|
|
170
|
-
if (leading || trailing) {
|
|
171
|
-
content += getNewlineString(leading, trailing);
|
|
172
|
-
}
|
|
173
|
-
return (0, util_1.spliceString)(source, startIndex, endIndex, content, pattern);
|
|
174
|
-
}
|
|
175
121
|
function parseArg(data, value) {
|
|
176
122
|
const n = +value;
|
|
177
123
|
if (!isNaN(n)) {
|
|
178
124
|
return n;
|
|
179
125
|
}
|
|
180
|
-
const match = /^(["'])(.*)\1$/s.exec(value);
|
|
181
|
-
if (match) {
|
|
182
|
-
return match[2];
|
|
183
|
-
}
|
|
184
126
|
return getObjectValue(data, value);
|
|
185
127
|
}
|
|
186
128
|
function hasCondition(data, condition) {
|
|
@@ -197,7 +139,7 @@ function hasCondition(data, condition) {
|
|
|
197
139
|
if (items.length > 0 && !isSpace(match[0][0])) {
|
|
198
140
|
return false;
|
|
199
141
|
}
|
|
200
|
-
items.push([match[1],
|
|
142
|
+
items.push([match[1], trimQuote(match[2]), match[3] ? trimQuote(match[3]) : '']);
|
|
201
143
|
}
|
|
202
144
|
REGEXP_TEMPLATECOMPARISON.lastIndex = 0;
|
|
203
145
|
const length = items.length;
|
|
@@ -205,12 +147,10 @@ function hasCondition(data, condition) {
|
|
|
205
147
|
return false;
|
|
206
148
|
}
|
|
207
149
|
for (let i = 0; i < length; ++i) {
|
|
208
|
-
const
|
|
209
|
-
const arg1 = item[1];
|
|
210
|
-
const arg2 = item[2];
|
|
150
|
+
const [cmp, arg1, arg2] = items[i];
|
|
211
151
|
let valid = false;
|
|
212
152
|
if (arg2) {
|
|
213
|
-
switch (
|
|
153
|
+
switch (cmp) {
|
|
214
154
|
case 'eq':
|
|
215
155
|
valid = parseArg(data, arg1) == parseArg(data, arg2);
|
|
216
156
|
break;
|
|
@@ -233,7 +173,7 @@ function hasCondition(data, condition) {
|
|
|
233
173
|
return false;
|
|
234
174
|
}
|
|
235
175
|
}
|
|
236
|
-
else if (
|
|
176
|
+
else if (cmp) {
|
|
237
177
|
return false;
|
|
238
178
|
}
|
|
239
179
|
else {
|
|
@@ -262,9 +202,7 @@ function hasCondition(data, condition) {
|
|
|
262
202
|
return false;
|
|
263
203
|
}
|
|
264
204
|
function checkConditionBranch(data, value) {
|
|
265
|
-
REGEXP_TEMPLATEELSEIF
|
|
266
|
-
let match;
|
|
267
|
-
while (match = REGEXP_TEMPLATEELSEIF.exec(value)) {
|
|
205
|
+
for (const match of value.matchAll(REGEXP_TEMPLATEELSEIF)) {
|
|
268
206
|
if (hasCondition(data, match[1])) {
|
|
269
207
|
return match;
|
|
270
208
|
}
|
|
@@ -363,109 +301,43 @@ function collectBaseUrl(asset, baseUrl) {
|
|
|
363
301
|
}
|
|
364
302
|
return result;
|
|
365
303
|
}
|
|
366
|
-
function createHash(host, file, hash, bufferMap) {
|
|
367
|
-
const { filename, localUri } = file;
|
|
368
|
-
try {
|
|
369
|
-
const buffer = localUri && bufferMap[localUri] || getBuffer(file, localUri);
|
|
370
|
-
if (buffer) {
|
|
371
|
-
const [algorithm, length] = (0, util_1.getHashData)(hash);
|
|
372
|
-
const value = algorithm ? Document.asHash(buffer, algorithm, { encoding: file.encoding }) : '';
|
|
373
|
-
if (value) {
|
|
374
|
-
if (localUri) {
|
|
375
|
-
bufferMap[localUri] = buffer;
|
|
376
|
-
}
|
|
377
|
-
host.rename(file, (0, util_1.appendSuffix)(filename, length > 0 ? value.substring(0, length) : value));
|
|
378
|
-
return file.filename;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
throw (0, types_1.errorMessage)('hash', 'Source not found', filename);
|
|
382
|
-
}
|
|
383
|
-
catch (err) {
|
|
384
|
-
host.writeFail(["Unable to read file", filename], err, 32);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function replaceCss(instance, file) {
|
|
388
|
-
if (file.inlineUrlMap) {
|
|
389
|
-
sanitizeCss(instance, file.inlineUrlMap);
|
|
390
|
-
}
|
|
391
|
-
if (file.inlineUrlCloudMap) {
|
|
392
|
-
sanitizeCss(instance, file.inlineUrlCloudMap);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
function sanitizeCss(instance, map) {
|
|
396
|
-
for (const id in map) {
|
|
397
|
-
map[id] = instance.removeServerRoot(map[id]);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
function replaceHtml(instance, source, { productionRelease, contentMap }, cssMap) {
|
|
401
|
-
if (cssMap) {
|
|
402
|
-
source = finalizeHtml(source, cssMap);
|
|
403
|
-
}
|
|
404
|
-
source = finalizeHtml(source, contentMap);
|
|
405
|
-
return productionRelease ? instance.removeServerRoot(source) : source;
|
|
406
|
-
}
|
|
407
|
-
function finalizeHtml(value, data) {
|
|
408
|
-
for (const id in data) {
|
|
409
|
-
value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
|
|
410
|
-
}
|
|
411
|
-
return value;
|
|
412
|
-
}
|
|
413
|
-
function loadLocalFile(instance, pathname, encoding, out) {
|
|
414
|
-
let content;
|
|
415
|
-
if (out) {
|
|
416
|
-
content = fs.readFileSync(pathname, (0, types_1.getEncoding)(encoding));
|
|
417
|
-
out.content = content;
|
|
418
|
-
}
|
|
419
|
-
const ext = path.extname(pathname).substring(1).toLowerCase();
|
|
420
|
-
if (ext === 'cjs') {
|
|
421
|
-
return require(pathname);
|
|
422
|
-
}
|
|
423
|
-
const result = instance.tryParse(content || fs.readFileSync(pathname, (0, types_1.getEncoding)(encoding)), ext);
|
|
424
|
-
if (result != null) {
|
|
425
|
-
return result;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
function removeElement(instance, domBase, item, element) {
|
|
429
|
-
if (item.removeEmpty || item.type === 'display') {
|
|
430
|
-
element ||= new dom_1.HtmlElement(instance.moduleName, item.element);
|
|
431
|
-
element.remove = true;
|
|
432
|
-
if (!domBase.write(element)) {
|
|
433
|
-
instance.writeFail('Unable to remove element', errorHtml(item.element), { type: 4 });
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
304
|
function removeWatchReload(item) {
|
|
438
|
-
if (
|
|
305
|
+
if (isObject(item.watch) && 'reload' in item.watch) {
|
|
439
306
|
delete item.watch.reload;
|
|
440
307
|
}
|
|
441
308
|
}
|
|
442
|
-
|
|
443
|
-
removeElement(instance, domBase, item);
|
|
444
|
-
const pkg = getPackageName(err);
|
|
445
|
-
if (pkg && instance.checkPackage(err, pkg)) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
instance.writeFail(["Invalid credentials", item.source], err);
|
|
449
|
-
}
|
|
450
|
-
const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
|
|
451
|
-
const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
|
|
452
|
-
const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
|
|
453
|
-
const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && Document.isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
|
|
454
|
-
const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
|
|
309
|
+
const hasSourceMap = (metadata, value) => isObject(metadata) && metadata.__sourcemap__ === value;
|
|
455
310
|
const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
|
|
456
311
|
const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
|
|
457
312
|
const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== "image/svg+xml";
|
|
458
313
|
const isRemoved = (item) => item.exclude === true || isBundled(item.bundleIndex);
|
|
459
|
-
const isUnedited = (item) => !item.attributes && !item.inlineContent && !item.srcSet && !item.element.dynamic && item.element.textContent === undefined && (!item.uri && !isBundled(item.bundleIndex, true) ||
|
|
460
|
-
const isIgnored = (item, exists) => item.invalid ||
|
|
314
|
+
const isUnedited = (item) => !item.attributes && !item.inlineContent && !item.srcSet && !item.element.dynamic && item.element.textContent === undefined && (!item.uri && !isBundled(item.bundleIndex, true) || hasValue(item.format, 'crossorigin'));
|
|
315
|
+
const isIgnored = (item, exists) => item.invalid || ignoreFlag(item.flags) || !exists && existsFlag(item.flags);
|
|
461
316
|
const findFont = (value) => value && (Array.isArray(value) ? value : [value]).find(format => isFont(format));
|
|
462
|
-
const getEndIndex = (match) => match.index + match[0].length;
|
|
463
317
|
const getRelativeUrl = (file) => Document.joinPath(file.moveTo, file.pathname, file.inlineFilename || file.filename) + (!file.static ? restoreSearchParams(file.url?.search) : '');
|
|
318
|
+
const normalizeSpace = (value) => value.replace(/\s+/g, ' ');
|
|
464
319
|
const validateDir = (value) => path.isAbsolute(value) && Document.isDir(value) ? value : '';
|
|
465
320
|
const valueAsString = (value, delimiter) => Array.isArray(value) && !value.some(child => typeof child === 'object') ? value.join(delimiter) : Document.asString(value);
|
|
466
|
-
const errorHtml = ({ tagName, tagIndex = -1 }) =>
|
|
467
|
-
const errorDataSource = (value, hint) =>
|
|
321
|
+
const errorHtml = ({ tagName, tagIndex = -1 }) => errorMessage('dom-writer', 'Location did not resolve', tagName.toLowerCase() + (tagIndex >= 0 ? ': ' + tagIndex : ''));
|
|
322
|
+
const errorDataSource = (value, hint) => errorMessage('data-source', value, hint);
|
|
468
323
|
const isHtmlOnly = (assets, items, htmlFile) => !items.find(item => item !== htmlFile && assets.includes(item));
|
|
324
|
+
class SessionOutput {
|
|
325
|
+
host;
|
|
326
|
+
startTime;
|
|
327
|
+
contentMap = {};
|
|
328
|
+
bufferMap = {};
|
|
329
|
+
cacheMiss = [];
|
|
330
|
+
hashed = new Set();
|
|
331
|
+
productionRelease;
|
|
332
|
+
constructor(host, startTime, productionRelease) {
|
|
333
|
+
this.host = host;
|
|
334
|
+
this.startTime = startTime;
|
|
335
|
+
this.productionRelease = productionRelease ? true : undefined;
|
|
336
|
+
}
|
|
337
|
+
getBuffer(item, localUri = item.localUri) {
|
|
338
|
+
return item.sourceUTF8 || item.buffer || (localUri && Document.isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
469
341
|
class ChromeDocument extends Document {
|
|
470
342
|
static [kChrome] = true;
|
|
471
343
|
static INTERNAL_ASSIGNUUID = "__assign__";
|
|
@@ -507,21 +379,20 @@ class ChromeDocument extends Document {
|
|
|
507
379
|
}
|
|
508
380
|
static async finalize(instance) {
|
|
509
381
|
if (instance.aborted) {
|
|
510
|
-
return
|
|
382
|
+
return createAbortError(true);
|
|
511
383
|
}
|
|
512
384
|
const startTime = process.hrtime();
|
|
513
385
|
if (instance.Db && await instance.Db.commit()) {
|
|
514
386
|
instance.Db.writeTimeElapsed('DB', ["Transactions were committed", instance.Db.moduleName], startTime, { ...Document.LOG_STYLE_SUCCESS, type: 65536 });
|
|
515
387
|
}
|
|
516
|
-
const
|
|
517
|
-
const processing = { host: this, startTime, hashed: new Set(), contentMap: {}, bufferMap: {}, cacheMiss: [], productionRelease: productionRelease ? true : undefined };
|
|
388
|
+
const processing = new SessionOutput(this, startTime, instance.productionRelease);
|
|
518
389
|
const htmlFile = instance.htmlFile;
|
|
519
390
|
const outHtml = !!htmlFile && !isIgnored(htmlFile, true);
|
|
520
391
|
if (instance.dataSource.length === 0 && outHtml) {
|
|
521
392
|
const incremental = htmlFile.incremental ?? this.incremental;
|
|
522
393
|
if (incremental === 'etag' || incremental === 'exists') {
|
|
523
394
|
const fetched = this.fetchedAssets;
|
|
524
|
-
if (!productionRelease || instance.productionIncremental && (isHtmlOnly(instance.assets, fetched, htmlFile) || !fetched.find(item => item.hash))) {
|
|
395
|
+
if (!processing.productionRelease || instance.productionIncremental && (isHtmlOnly(instance.assets, fetched, htmlFile) || !fetched.find(item => item.hash))) {
|
|
525
396
|
let hint = '';
|
|
526
397
|
switch (incremental) {
|
|
527
398
|
case 'etag': {
|
|
@@ -548,7 +419,7 @@ class ChromeDocument extends Document {
|
|
|
548
419
|
break;
|
|
549
420
|
}
|
|
550
421
|
try {
|
|
551
|
-
fs.writeFileSync(htmlFile.localUri, buffer,
|
|
422
|
+
fs.writeFileSync(htmlFile.localUri, buffer, getEncoding(htmlFile.encoding));
|
|
552
423
|
htmlFile.buffer = buffer;
|
|
553
424
|
htmlFile.sourceUTF8 = undefined;
|
|
554
425
|
}
|
|
@@ -584,7 +455,7 @@ class ChromeDocument extends Document {
|
|
|
584
455
|
}
|
|
585
456
|
}
|
|
586
457
|
}
|
|
587
|
-
return result || this.copiedAssets.includes(item) && (!
|
|
458
|
+
return result || this.copiedAssets.includes(item) && (!isEmpty(item.bundleId) || !isEmpty(item.trailingContent));
|
|
588
459
|
};
|
|
589
460
|
const js = instance.jsFiles.filter(item => wasModified(item) || !!item.imports);
|
|
590
461
|
const css = instance.cssFiles.filter(wasModified);
|
|
@@ -611,27 +482,27 @@ class ChromeDocument extends Document {
|
|
|
611
482
|
if (instance.editing.length > 0) {
|
|
612
483
|
await instance.applyTransforms(processing);
|
|
613
484
|
if (instance.aborted) {
|
|
614
|
-
return
|
|
485
|
+
return createAbortError(true);
|
|
615
486
|
}
|
|
616
487
|
}
|
|
617
|
-
if (productionRelease) {
|
|
488
|
+
if (processing.productionRelease) {
|
|
618
489
|
instance.setProductionAttributes(processing);
|
|
619
490
|
}
|
|
620
491
|
if (outHtml) {
|
|
621
492
|
await instance.rewriteHtml(processing);
|
|
622
493
|
}
|
|
623
|
-
return this.aborted ? Promise.reject(
|
|
494
|
+
return this.aborted ? Promise.reject(createAbortError()) : super.finalize.call(this, instance);
|
|
624
495
|
}
|
|
625
496
|
static async cleanup(instance) {
|
|
626
497
|
if (instance.aborted) {
|
|
627
|
-
return
|
|
498
|
+
return createAbortError(true);
|
|
628
499
|
}
|
|
629
500
|
if (this.Watch) {
|
|
630
501
|
const related = instance.related;
|
|
631
502
|
let includes;
|
|
632
503
|
for (const asset of instance.assets) {
|
|
633
504
|
if (asset.watch && (includes = related.get(asset))) {
|
|
634
|
-
if (!
|
|
505
|
+
if (!isPlainObject(asset.watch)) {
|
|
635
506
|
asset.watch = {};
|
|
636
507
|
}
|
|
637
508
|
const items = new Set((asset.watch.assets || []));
|
|
@@ -654,12 +525,12 @@ class ChromeDocument extends Document {
|
|
|
654
525
|
}
|
|
655
526
|
}
|
|
656
527
|
const productionRelease = instance.productionRelease;
|
|
657
|
-
if (
|
|
528
|
+
if (isString(productionRelease)) {
|
|
658
529
|
const errorDirectory = (value) => {
|
|
659
|
-
instance.writeFail(["Unable to read directory", instance.moduleName],
|
|
530
|
+
instance.writeFail(["Unable to read directory", instance.moduleName], errorMessage('production', 'Invalid directory', value), 32);
|
|
660
531
|
};
|
|
661
532
|
const errorAccess = (value) => {
|
|
662
|
-
instance.writeFail(["Unable to write directory", instance.moduleName],
|
|
533
|
+
instance.writeFail(["Unable to write directory", instance.moduleName], errorMessage('production', "Unsupported access", value), 8192);
|
|
663
534
|
};
|
|
664
535
|
const errorMove = (err) => {
|
|
665
536
|
instance.writeFail(["Unable to move file", instance.moduleName], err, { type: 32, fatal: true });
|
|
@@ -702,7 +573,7 @@ class ChromeDocument extends Document {
|
|
|
702
573
|
try {
|
|
703
574
|
let destDir = target[1];
|
|
704
575
|
if (i !== start && !Document.createDir(destDir = path.join(destDir, ...subDir.slice(i, start)))) {
|
|
705
|
-
throw
|
|
576
|
+
throw errorMessage('production', destDir, 'create');
|
|
706
577
|
}
|
|
707
578
|
const dest = path.join(destDir, subDir.at(-1));
|
|
708
579
|
Document.renameFile(src, dest);
|
|
@@ -750,7 +621,7 @@ class ChromeDocument extends Document {
|
|
|
750
621
|
this.delete(value);
|
|
751
622
|
}
|
|
752
623
|
else {
|
|
753
|
-
errorMove(
|
|
624
|
+
errorMove(errorMessage('production', path.join(this.baseDirectory, value), 'move'));
|
|
754
625
|
}
|
|
755
626
|
}
|
|
756
627
|
}
|
|
@@ -767,7 +638,7 @@ class ChromeDocument extends Document {
|
|
|
767
638
|
}
|
|
768
639
|
static sanitizeAssets(assets, exclusions = []) {
|
|
769
640
|
for (const item of assets) {
|
|
770
|
-
if (
|
|
641
|
+
if (ignoreFlag(item.flags)) {
|
|
771
642
|
continue;
|
|
772
643
|
}
|
|
773
644
|
for (const attr in item) {
|
|
@@ -833,20 +704,18 @@ class ChromeDocument extends Document {
|
|
|
833
704
|
_cloudUrlMap;
|
|
834
705
|
_cloudUploaded;
|
|
835
706
|
_cloudEndpoint;
|
|
836
|
-
_idMap =
|
|
707
|
+
_idMap = Object.create(null);
|
|
837
708
|
_editing = [];
|
|
838
|
-
_queryMap = new Map();
|
|
839
|
-
_selectorMap = new Map();
|
|
840
709
|
init(assets, config) {
|
|
841
710
|
assets.sort((a, b) => {
|
|
842
|
-
if (!
|
|
711
|
+
if (!isEmpty(a.bundleId) && a.bundleId === b.bundleId) {
|
|
843
712
|
return b.bundleIndex - a.bundleIndex;
|
|
844
713
|
}
|
|
845
714
|
return 0;
|
|
846
715
|
});
|
|
847
716
|
const cloud = [];
|
|
848
717
|
for (const item of assets) {
|
|
849
|
-
if (
|
|
718
|
+
if (ignoreFlag(item.flags)) {
|
|
850
719
|
continue;
|
|
851
720
|
}
|
|
852
721
|
if (item.trailingContent) {
|
|
@@ -910,7 +779,7 @@ class ChromeDocument extends Document {
|
|
|
910
779
|
target.useUnsafeHtmlReplace = useUnsafeReplace;
|
|
911
780
|
target.useUnsafeCssReplace = useUnsafeReplace;
|
|
912
781
|
}
|
|
913
|
-
else if (
|
|
782
|
+
else if (isArray(useUnsafeReplace)) {
|
|
914
783
|
target.useUnsafeHtmlReplace = useUnsafeReplace.includes('html');
|
|
915
784
|
target.useUnsafeCssReplace = useUnsafeReplace.includes('css');
|
|
916
785
|
}
|
|
@@ -919,26 +788,26 @@ class ChromeDocument extends Document {
|
|
|
919
788
|
if (baseUrl) {
|
|
920
789
|
try {
|
|
921
790
|
const { origin, pathname } = new URL(this.baseUrl = baseUrl);
|
|
922
|
-
this.baseDirectory = origin + pathname.
|
|
791
|
+
this.baseDirectory = origin + pathname.slice(0, pathname.lastIndexOf('/') + 1);
|
|
923
792
|
}
|
|
924
793
|
catch {
|
|
925
794
|
}
|
|
926
795
|
}
|
|
927
|
-
if (
|
|
796
|
+
if (isString(productionRelease)) {
|
|
928
797
|
this.productionRelease = Document.normalizePath(productionRelease, 2);
|
|
929
798
|
const baseDir = Document.normalizePath(this.productionRelease, 1 | 2);
|
|
930
799
|
let baseMap;
|
|
931
800
|
found: {
|
|
932
801
|
for (const map of [this.getUserSettings()?.server_root, this.settings.server_root]) {
|
|
933
802
|
for (const pathname in map) {
|
|
934
|
-
if (Document.normalizePath(pathname, 1 | 2) === baseDir &&
|
|
803
|
+
if (Document.normalizePath(pathname, 1 | 2) === baseDir && map[pathname]) {
|
|
935
804
|
baseMap = map[pathname];
|
|
936
805
|
break found;
|
|
937
806
|
}
|
|
938
807
|
}
|
|
939
808
|
}
|
|
940
809
|
}
|
|
941
|
-
this.serverRootMapping =
|
|
810
|
+
this.serverRootMapping = serverRootMapping ? baseMap ? Object.assign(baseMap, serverRootMapping) : serverRootMapping : baseMap;
|
|
942
811
|
}
|
|
943
812
|
else if (productionRelease) {
|
|
944
813
|
this.productionRelease = true;
|
|
@@ -946,35 +815,33 @@ class ChromeDocument extends Document {
|
|
|
946
815
|
if (productionIncremental) {
|
|
947
816
|
this.productionIncremental = true;
|
|
948
817
|
}
|
|
949
|
-
if (
|
|
818
|
+
if (sanitizeFramework) {
|
|
950
819
|
this.sanitizeFramework = sanitizeFramework;
|
|
951
820
|
}
|
|
952
|
-
if (
|
|
821
|
+
if (templateMap) {
|
|
953
822
|
this.templateMap = templateMap;
|
|
954
823
|
}
|
|
955
|
-
if (
|
|
824
|
+
if (userAgentData) {
|
|
956
825
|
this.userAgentData = userAgentData;
|
|
957
826
|
}
|
|
958
|
-
if (
|
|
827
|
+
if (isObject(cache) && 'transform' in cache) {
|
|
959
828
|
this.customize({ transform: cache.transform });
|
|
960
829
|
}
|
|
961
|
-
|
|
962
|
-
imports = undefined;
|
|
963
|
-
}
|
|
830
|
+
imports = config.imports;
|
|
964
831
|
}
|
|
965
832
|
super.init(assets, config);
|
|
966
833
|
const mimeMap = this._mimeMap;
|
|
967
834
|
if (mimeMap) {
|
|
968
835
|
if ('imports' in mimeMap) {
|
|
969
836
|
const imported = mimeMap.imports;
|
|
970
|
-
if (
|
|
837
|
+
if (isPlainObject(imported)) {
|
|
971
838
|
imports = imports ? Object.assign(imported, imports) : imported;
|
|
972
839
|
}
|
|
973
840
|
delete mimeMap.imports;
|
|
974
841
|
}
|
|
975
842
|
if ('format' in mimeMap) {
|
|
976
843
|
const format = mimeMap.format;
|
|
977
|
-
if (
|
|
844
|
+
if (isObject(format)) {
|
|
978
845
|
this.formatMap = 'pathname' in format || 'filename' in format || 'dictionary' in format ? { uuid: format } : format;
|
|
979
846
|
}
|
|
980
847
|
else {
|
|
@@ -1003,7 +870,7 @@ class ChromeDocument extends Document {
|
|
|
1003
870
|
const settings = this.templateMap[type];
|
|
1004
871
|
for (const attr in settings) {
|
|
1005
872
|
const item = settings[attr];
|
|
1006
|
-
if (
|
|
873
|
+
if (isObject(item) && name in item) {
|
|
1007
874
|
const options = this.loadConfig(item, name);
|
|
1008
875
|
if (options) {
|
|
1009
876
|
return [attr, options, this.loadConfig(item, name + '-output')];
|
|
@@ -1029,11 +896,12 @@ class ChromeDocument extends Document {
|
|
|
1029
896
|
restart() {
|
|
1030
897
|
ChromeDocument.sanitizeAssets(this.assets);
|
|
1031
898
|
this._elements = null;
|
|
899
|
+
this._idMap = Object.create(null);
|
|
1032
900
|
this._dataSource = null;
|
|
1033
901
|
}
|
|
1034
902
|
async using(data) {
|
|
1035
903
|
if (this.aborted) {
|
|
1036
|
-
return
|
|
904
|
+
return createAbortError(true);
|
|
1037
905
|
}
|
|
1038
906
|
const file = data.file;
|
|
1039
907
|
if (file.editing) {
|
|
@@ -1061,7 +929,7 @@ class ChromeDocument extends Document {
|
|
|
1061
929
|
if (output.map) {
|
|
1062
930
|
const uri = Document.writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
1063
931
|
if (uri) {
|
|
1064
|
-
host.add(uri, file,
|
|
932
|
+
host.add(uri, file, FILE_TYPE.SOURCEMAP);
|
|
1065
933
|
}
|
|
1066
934
|
}
|
|
1067
935
|
file.modified = true;
|
|
@@ -1091,7 +959,7 @@ class ChromeDocument extends Document {
|
|
|
1091
959
|
}
|
|
1092
960
|
case "image/svg+xml": {
|
|
1093
961
|
const source = host.getUTF8String(file, localUri);
|
|
1094
|
-
if (/\
|
|
962
|
+
if (/\b(?<!-)url\(/i.test(source)) {
|
|
1095
963
|
file.editing = true;
|
|
1096
964
|
this.editing.push(file);
|
|
1097
965
|
this.svgFiles.push(file);
|
|
@@ -1122,20 +990,20 @@ class ChromeDocument extends Document {
|
|
|
1122
990
|
};
|
|
1123
991
|
let to;
|
|
1124
992
|
if (mimeType.includes('woff')) {
|
|
1125
|
-
if (
|
|
993
|
+
if (hasValue(format, 'truetype')) {
|
|
1126
994
|
to = 'ttf';
|
|
1127
995
|
}
|
|
1128
|
-
else if (
|
|
996
|
+
else if (hasValue(format, 'opentype')) {
|
|
1129
997
|
to = 'otf';
|
|
1130
998
|
}
|
|
1131
999
|
else {
|
|
1132
1000
|
return;
|
|
1133
1001
|
}
|
|
1134
1002
|
}
|
|
1135
|
-
else if (
|
|
1003
|
+
else if (hasValue(format, 'woff')) {
|
|
1136
1004
|
to = 'woff';
|
|
1137
1005
|
}
|
|
1138
|
-
else if (
|
|
1006
|
+
else if (hasValue(format, 'woff2')) {
|
|
1139
1007
|
to = 'woff2';
|
|
1140
1008
|
}
|
|
1141
1009
|
else {
|
|
@@ -1152,7 +1020,7 @@ class ChromeDocument extends Document {
|
|
|
1152
1020
|
if (ext) {
|
|
1153
1021
|
setFormat(ext.startsWith('woff') ? ext : ext === 'otf' ? 'opentype' : 'truetype');
|
|
1154
1022
|
}
|
|
1155
|
-
const output =
|
|
1023
|
+
const output = renameExt(localUri, ext ||= to);
|
|
1156
1024
|
file.mimeType = 'font/' + ext;
|
|
1157
1025
|
fs.writeFile(output, result, err => {
|
|
1158
1026
|
if (!err) {
|
|
@@ -1180,7 +1048,7 @@ class ChromeDocument extends Document {
|
|
|
1180
1048
|
if (trailing) {
|
|
1181
1049
|
let index = trailing.indexOf('?');
|
|
1182
1050
|
if (index !== -1 || (index = trailing.indexOf('#')) !== -1) {
|
|
1183
|
-
trailing = trailing.
|
|
1051
|
+
trailing = trailing.slice(index);
|
|
1184
1052
|
}
|
|
1185
1053
|
else {
|
|
1186
1054
|
trailing = '';
|
|
@@ -1193,12 +1061,12 @@ class ChromeDocument extends Document {
|
|
|
1193
1061
|
this.replaced.push(file);
|
|
1194
1062
|
}
|
|
1195
1063
|
else {
|
|
1196
|
-
const modified = this.processLocation(file,
|
|
1064
|
+
const modified = this.processLocation(file, asExt(file.filename));
|
|
1197
1065
|
if (modified.length > 0) {
|
|
1198
1066
|
if (modified.includes('filename')) {
|
|
1199
1067
|
file.inlineFilename = file.filename;
|
|
1200
1068
|
}
|
|
1201
|
-
|
|
1069
|
+
setInitialValue(file, false);
|
|
1202
1070
|
if (file.hash) {
|
|
1203
1071
|
delete file.hash;
|
|
1204
1072
|
}
|
|
@@ -1216,7 +1084,7 @@ class ChromeDocument extends Document {
|
|
|
1216
1084
|
let localFile;
|
|
1217
1085
|
if (uri && code && (localFile = this.findSourceRoot(uri))) {
|
|
1218
1086
|
const { exported, bundleId } = file;
|
|
1219
|
-
const bundleMain = !
|
|
1087
|
+
const bundleMain = !isEmpty(bundleId) && this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
|
|
1220
1088
|
let output;
|
|
1221
1089
|
if ((index === 1 || exported) && Array.isArray(file.imports)) {
|
|
1222
1090
|
output = this.resolveImports(file, code, bundleMain || file);
|
|
@@ -1232,7 +1100,7 @@ class ChromeDocument extends Document {
|
|
|
1232
1100
|
const type = match[3] || match[5];
|
|
1233
1101
|
const idx = match[1] ? 1 : match[2] ? 2 : 4;
|
|
1234
1102
|
const [a, b] = match.indices[idx];
|
|
1235
|
-
const from =
|
|
1103
|
+
const from = trimQuote(match[idx]);
|
|
1236
1104
|
const quote = output[a];
|
|
1237
1105
|
const relative = /^\.{0,2}\//.test(from);
|
|
1238
1106
|
if (type && /\btype\s*:\s*(["'`])(?:css|json)\1/.test(type)) {
|
|
@@ -1241,7 +1109,7 @@ class ChromeDocument extends Document {
|
|
|
1241
1109
|
if (asset) {
|
|
1242
1110
|
const [relativeUrl, sameDir] = this.getSrcUrl(bundleMain || file, asset);
|
|
1243
1111
|
if (relativeUrl) {
|
|
1244
|
-
output =
|
|
1112
|
+
output = spliceString(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
|
|
1245
1113
|
}
|
|
1246
1114
|
}
|
|
1247
1115
|
}
|
|
@@ -1263,7 +1131,7 @@ class ChromeDocument extends Document {
|
|
|
1263
1131
|
pathname = asset.localUri;
|
|
1264
1132
|
}
|
|
1265
1133
|
if (pathname && Document.isPath(pathname)) {
|
|
1266
|
-
output =
|
|
1134
|
+
output = spliceString(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
|
|
1267
1135
|
}
|
|
1268
1136
|
}
|
|
1269
1137
|
REGEXP_IMPORTMODULE.lastIndex = 0;
|
|
@@ -1283,7 +1151,7 @@ class ChromeDocument extends Document {
|
|
|
1283
1151
|
case "text/css":
|
|
1284
1152
|
if (file.editing) {
|
|
1285
1153
|
const bundleId = file.bundleId;
|
|
1286
|
-
if (!
|
|
1154
|
+
if (!isEmpty(bundleId)) {
|
|
1287
1155
|
for (const asset of this.assets) {
|
|
1288
1156
|
if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
|
|
1289
1157
|
const output = this.processUrl(host, file, source, 'css', asset);
|
|
@@ -1311,12 +1179,12 @@ class ChromeDocument extends Document {
|
|
|
1311
1179
|
return;
|
|
1312
1180
|
}
|
|
1313
1181
|
let bundleMain, modified = false;
|
|
1314
|
-
if (
|
|
1182
|
+
if (isPlainObject(baseFile)) {
|
|
1315
1183
|
bundleMain = baseFile;
|
|
1316
1184
|
}
|
|
1317
1185
|
else {
|
|
1318
1186
|
const bundleId = file.bundleId;
|
|
1319
|
-
if (!
|
|
1187
|
+
if (!isEmpty(bundleId)) {
|
|
1320
1188
|
bundleMain = this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
|
|
1321
1189
|
}
|
|
1322
1190
|
}
|
|
@@ -1352,7 +1220,7 @@ class ChromeDocument extends Document {
|
|
|
1352
1220
|
}
|
|
1353
1221
|
value = found || original;
|
|
1354
1222
|
}
|
|
1355
|
-
code =
|
|
1223
|
+
code = spliceString(code, index, index + placeholder.length, value);
|
|
1356
1224
|
modified = true;
|
|
1357
1225
|
break;
|
|
1358
1226
|
}
|
|
@@ -1371,14 +1239,14 @@ class ChromeDocument extends Document {
|
|
|
1371
1239
|
const supports = match[3]?.trim();
|
|
1372
1240
|
const query = match[4].trim().replace(/;+$/, '');
|
|
1373
1241
|
if (layer || supports || query) {
|
|
1374
|
-
const newline =
|
|
1375
|
-
let result = supports ? `@supports (${supports}) {` + newline : '';
|
|
1242
|
+
const newline = getNewline(source);
|
|
1243
|
+
let result = supports ? `@supports (${normalizeSpace(supports)}) {` + newline : '';
|
|
1376
1244
|
if (query) {
|
|
1377
|
-
result += `@media ${query} {` + newline;
|
|
1245
|
+
result += `@media ${normalizeSpace(query)} {` + newline;
|
|
1378
1246
|
}
|
|
1379
1247
|
if (layer) {
|
|
1380
|
-
const name = match[2]?.
|
|
1381
|
-
result += '@layer ' + (name ? name + ' ' : '') + `{${newline + source + newline}}` + (query ? newline + '}' : '');
|
|
1248
|
+
const name = match[2]?.replace(/\s+/g, '');
|
|
1249
|
+
result += '@layer ' + (name ? name.slice(1, -1) + ' ' : '') + `{${newline + source + newline}}` + (query ? newline + '}' : '');
|
|
1382
1250
|
}
|
|
1383
1251
|
else if (query) {
|
|
1384
1252
|
result += source + newline + '}';
|
|
@@ -1394,13 +1262,13 @@ class ChromeDocument extends Document {
|
|
|
1394
1262
|
}
|
|
1395
1263
|
}
|
|
1396
1264
|
removeServerRoot(value) {
|
|
1397
|
-
return value.replace(new RegExp('(\\.\\./)*' +
|
|
1265
|
+
return value.replace(new RegExp('(\\.\\./)*' + escapePattern(ChromeDocument.INTERNAL_SERVERROOT), 'g'), '');
|
|
1398
1266
|
}
|
|
1399
1267
|
addCopy(data, saveAs) {
|
|
1400
1268
|
if (data.command && this.host) {
|
|
1401
1269
|
const match = REGEXP_SRCSETSIZE.exec(data.command);
|
|
1402
1270
|
if (match) {
|
|
1403
|
-
return
|
|
1271
|
+
return renameExt(this.host.getLocalUri(data), match[1] + match[2].toLowerCase() + '.' + saveAs);
|
|
1404
1272
|
}
|
|
1405
1273
|
}
|
|
1406
1274
|
}
|
|
@@ -1409,7 +1277,7 @@ class ChromeDocument extends Document {
|
|
|
1409
1277
|
if (output && command && file.element?.outerXml) {
|
|
1410
1278
|
const match = REGEXP_SRCSETSIZE.exec(command);
|
|
1411
1279
|
if (match) {
|
|
1412
|
-
(file.srcSet ||= []).push(Document.toPosix(data.baseDirectory ? output.
|
|
1280
|
+
(file.srcSet ||= []).push(Document.toPosix(data.baseDirectory ? output.slice(data.baseDirectory.length + 1) : output), match[1] + match[2].toLowerCase());
|
|
1413
1281
|
file.modified = true;
|
|
1414
1282
|
return true;
|
|
1415
1283
|
}
|
|
@@ -1423,7 +1291,7 @@ class ChromeDocument extends Document {
|
|
|
1423
1291
|
if (this.htmlFile) {
|
|
1424
1292
|
const endpoint = instance.getStorage('upload', this.htmlFile.cloudStorage)?.upload?.endpoint;
|
|
1425
1293
|
if (endpoint) {
|
|
1426
|
-
this._cloudEndpoint = new RegExp(
|
|
1294
|
+
this._cloudEndpoint = new RegExp(escapePattern(Document.toPosix(endpoint)) + '/', 'g');
|
|
1427
1295
|
}
|
|
1428
1296
|
}
|
|
1429
1297
|
}
|
|
@@ -1440,7 +1308,7 @@ class ChromeDocument extends Document {
|
|
|
1440
1308
|
const cloudUrl = endpoint ? url.replace(endpoint, '') : url;
|
|
1441
1309
|
file.cloudUrl = cloudUrl;
|
|
1442
1310
|
if (inlineUrlCloud) {
|
|
1443
|
-
const pattern = new RegExp(
|
|
1311
|
+
const pattern = new RegExp(escapePattern(inlineUrlCloud), 'g');
|
|
1444
1312
|
for (const item of this.editing) {
|
|
1445
1313
|
if (item.inlineUrlCloudMap?.[inlineUrlCloud]) {
|
|
1446
1314
|
const source = host.getUTF8String(item);
|
|
@@ -1458,7 +1326,7 @@ class ChromeDocument extends Document {
|
|
|
1458
1326
|
}
|
|
1459
1327
|
async cloudFinalize(state) {
|
|
1460
1328
|
if (this.aborted) {
|
|
1461
|
-
return
|
|
1329
|
+
return createAbortError(true);
|
|
1462
1330
|
}
|
|
1463
1331
|
const { host, instance } = state;
|
|
1464
1332
|
const htmlFile = this.htmlFile;
|
|
@@ -1470,7 +1338,7 @@ class ChromeDocument extends Document {
|
|
|
1470
1338
|
for (const id in this._cloudUrlMap) {
|
|
1471
1339
|
const inlineUrlCloud = item.inlineUrlCloudMap[id];
|
|
1472
1340
|
if (inlineUrlCloud && !this._cloudUploaded.has(id)) {
|
|
1473
|
-
output = (output || source).replace(new RegExp(
|
|
1341
|
+
output = (output || source).replace(new RegExp(escapePattern(id), 'g'), inlineUrlCloud);
|
|
1474
1342
|
state.localStorage.delete(this._cloudUrlMap[id]);
|
|
1475
1343
|
}
|
|
1476
1344
|
}
|
|
@@ -1496,18 +1364,18 @@ class ChromeDocument extends Document {
|
|
|
1496
1364
|
}
|
|
1497
1365
|
}
|
|
1498
1366
|
if (this.aborted) {
|
|
1499
|
-
return
|
|
1367
|
+
return createAbortError(true);
|
|
1500
1368
|
}
|
|
1501
1369
|
}
|
|
1502
1370
|
if (htmlFile) {
|
|
1503
1371
|
checkDocument(htmlFile);
|
|
1504
1372
|
const cloudStorage = htmlFile.cloudStorage;
|
|
1505
|
-
if (
|
|
1373
|
+
if (isArray(cloudStorage)) {
|
|
1506
1374
|
for (const storage of cloudStorage) {
|
|
1507
1375
|
if (instance.hasCredential('storage', storage)) {
|
|
1508
1376
|
const { admin, bucket, upload } = storage;
|
|
1509
1377
|
const website = admin?.configBucket?.website;
|
|
1510
|
-
if (
|
|
1378
|
+
if (isPlainObject(website) && bucket && upload) {
|
|
1511
1379
|
let filename = Document.joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
|
|
1512
1380
|
if (website.indexPage === true) {
|
|
1513
1381
|
website.indexPage = filename;
|
|
@@ -1551,17 +1419,17 @@ class ChromeDocument extends Document {
|
|
|
1551
1419
|
if (asset.element && isUnedited(asset)) {
|
|
1552
1420
|
continue;
|
|
1553
1421
|
}
|
|
1554
|
-
if (!found &&
|
|
1422
|
+
if (!found && isEqual(main, asset)) {
|
|
1555
1423
|
found = true;
|
|
1556
1424
|
using.push(asset);
|
|
1557
1425
|
}
|
|
1558
1426
|
else if (this.isWatched(asset) ||
|
|
1559
|
-
|
|
1560
|
-
asset.base64 && watch.related.find(item =>
|
|
1561
|
-
|
|
1427
|
+
watchFlag(asset.flags) ||
|
|
1428
|
+
asset.base64 && watch.related.find(item => isEqual(item, asset)) ||
|
|
1429
|
+
isArray(asset.cloudStorage) && asset.cloudStorage.some(item => item.upload?.active)) {
|
|
1562
1430
|
using.push(asset);
|
|
1563
1431
|
}
|
|
1564
|
-
else if (current = watch.assets.find(item =>
|
|
1432
|
+
else if (current = watch.assets.find(item => isEqual(item, asset))) {
|
|
1565
1433
|
const { inlineUrlCloud: inlineUrlCloud, initialValue = {} } = current;
|
|
1566
1434
|
if (inlineUrlCloud && inlineUrlCloudMap[inlineUrlCloud] || path.join(initialValue.pathname || asset.pathname, initialValue.filename || asset.filename).includes(ChromeDocument.INTERNAL_ASSIGNUUID)) {
|
|
1567
1435
|
using.push(asset);
|
|
@@ -1584,7 +1452,7 @@ class ChromeDocument extends Document {
|
|
|
1584
1452
|
}
|
|
1585
1453
|
const asset = watch.bundleMain || watch.assets[0];
|
|
1586
1454
|
const pathname = (asset.cloudUrl || asset.relativeUrl || '').split('?')[0];
|
|
1587
|
-
const next = assets?.find(item =>
|
|
1455
|
+
const next = assets?.find(item => isEqual(item, asset));
|
|
1588
1456
|
let value, search;
|
|
1589
1457
|
if (next) {
|
|
1590
1458
|
if (next.cloudUrl) {
|
|
@@ -1601,7 +1469,7 @@ class ChromeDocument extends Document {
|
|
|
1601
1469
|
}
|
|
1602
1470
|
search ??= restoreSearchParams(asset.url?.search);
|
|
1603
1471
|
status &&= status.filter(item => item.type >= 1 && item.type <= 3);
|
|
1604
|
-
watch.send(
|
|
1472
|
+
watch.send(WATCH_EVENT.MODIFIED, {
|
|
1605
1473
|
action: pathname && watch.hot && !watch.main ? 'hot' : '',
|
|
1606
1474
|
type: asset.mimeType,
|
|
1607
1475
|
value,
|
|
@@ -1631,7 +1499,7 @@ class ChromeDocument extends Document {
|
|
|
1631
1499
|
break;
|
|
1632
1500
|
case 'img':
|
|
1633
1501
|
case 'source':
|
|
1634
|
-
if (
|
|
1502
|
+
if (hasValue(file.format, 'srcset')) {
|
|
1635
1503
|
const srcset = element.getAttribute('srcset');
|
|
1636
1504
|
if (srcset) {
|
|
1637
1505
|
const uri = Document.toPosix(file.uri);
|
|
@@ -1645,13 +1513,13 @@ class ChromeDocument extends Document {
|
|
|
1645
1513
|
if (src && uri === Document.resolvePath(url = Document.toPosix(src), baseUri)) {
|
|
1646
1514
|
items.add(url);
|
|
1647
1515
|
}
|
|
1648
|
-
items.add(uri.startsWith(this.baseDirectory) ? uri.
|
|
1516
|
+
items.add(uri.startsWith(this.baseDirectory) ? uri.slice(this.baseDirectory.length) : uri.replace(baseUri.origin, ''));
|
|
1649
1517
|
}
|
|
1650
1518
|
}
|
|
1651
1519
|
let current = srcset, match;
|
|
1652
1520
|
for (const url of items) {
|
|
1653
1521
|
const resolve = sameOrigin && !Document.isURL(url);
|
|
1654
|
-
const pathname = url.split('/').map(seg =>
|
|
1522
|
+
const pathname = url.split('/').map(seg => escapePattern(seg)).join('/');
|
|
1655
1523
|
const pattern = new RegExp(`(,?\\s*)(${(resolve && !url.startsWith('.') ? `(?:\\.\\./)*\\.\\.${pathname}|` : '') + pathname})(` + (!url.includes('?') ? '(?:(?!,)(?:[^?]|$)[^,]*)|(?!\\?)[^,]*)' : '[^,]*)'), 'g');
|
|
1656
1524
|
while (match = pattern.exec(current)) {
|
|
1657
1525
|
const partial = match[2];
|
|
@@ -1674,7 +1542,8 @@ class ChromeDocument extends Document {
|
|
|
1674
1542
|
return this.templateMap.data?.[name];
|
|
1675
1543
|
}
|
|
1676
1544
|
}
|
|
1677
|
-
setInlinedAttributes(
|
|
1545
|
+
setInlinedAttributes(processing) {
|
|
1546
|
+
const { host, startTime, hashed, contentMap, productionRelease } = processing;
|
|
1678
1547
|
const readBase64 = (item, uuid) => {
|
|
1679
1548
|
if (!contentMap[uuid]) {
|
|
1680
1549
|
try {
|
|
@@ -1692,8 +1561,8 @@ class ChromeDocument extends Document {
|
|
|
1692
1561
|
if (item.inlineBase64) {
|
|
1693
1562
|
readBase64(item, item.inlineBase64);
|
|
1694
1563
|
}
|
|
1695
|
-
else if (!item.invalid &&
|
|
1696
|
-
const uuid =
|
|
1564
|
+
else if (!item.invalid && hasValue(item.format, 'base64')) {
|
|
1565
|
+
const uuid = randomUUID();
|
|
1697
1566
|
if (readBase64(item, uuid)) {
|
|
1698
1567
|
item.inlineBase64 = uuid;
|
|
1699
1568
|
}
|
|
@@ -1701,20 +1570,20 @@ class ChromeDocument extends Document {
|
|
|
1701
1570
|
if (productionRelease) {
|
|
1702
1571
|
const { inlineUrl, inlineUrlCloud, hash } = item;
|
|
1703
1572
|
if (inlineUrl || inlineUrlCloud) {
|
|
1704
|
-
const filename = hash && createHash(
|
|
1573
|
+
const filename = hash && this.createHash(processing, item, hash);
|
|
1705
1574
|
if (filename) {
|
|
1706
1575
|
for (const asset of this.assets) {
|
|
1707
1576
|
const url = inlineUrl ? asset.inlineUrlMap?.[inlineUrl] : asset.inlineUrlCloudMap?.[inlineUrlCloud];
|
|
1708
1577
|
if (url) {
|
|
1709
1578
|
const search = url.indexOf('?');
|
|
1710
|
-
const index = (search !== -1 ? url.
|
|
1579
|
+
const index = (search !== -1 ? url.slice(0, search) : url).lastIndexOf('/');
|
|
1711
1580
|
let result = '';
|
|
1712
1581
|
if (index !== -1) {
|
|
1713
|
-
result = url.
|
|
1582
|
+
result = url.slice(0, index + 1);
|
|
1714
1583
|
}
|
|
1715
1584
|
result += filename;
|
|
1716
1585
|
if (search !== -1) {
|
|
1717
|
-
result += url.
|
|
1586
|
+
result += url.slice(search);
|
|
1718
1587
|
}
|
|
1719
1588
|
if (inlineUrl) {
|
|
1720
1589
|
asset.inlineUrlMap[inlineUrl] = result;
|
|
@@ -1727,7 +1596,7 @@ class ChromeDocument extends Document {
|
|
|
1727
1596
|
}
|
|
1728
1597
|
hashed.add(item);
|
|
1729
1598
|
}
|
|
1730
|
-
else if (hash && (!item.editing || item.imported) && createHash(
|
|
1599
|
+
else if (hash && (!item.editing || item.imported) && this.createHash(processing, item, hash)) {
|
|
1731
1600
|
hashed.add(item);
|
|
1732
1601
|
}
|
|
1733
1602
|
}
|
|
@@ -1737,9 +1606,9 @@ class ChromeDocument extends Document {
|
|
|
1737
1606
|
const host = processing.host;
|
|
1738
1607
|
const sanitizeSource = (item, source) => {
|
|
1739
1608
|
if (processing.productionRelease) {
|
|
1740
|
-
replaceCss(
|
|
1609
|
+
this.#replaceCss(item);
|
|
1741
1610
|
}
|
|
1742
|
-
const output = replaceHtml(
|
|
1611
|
+
const output = this.#replaceHtml(source, processing, item.inlineUrlMap);
|
|
1743
1612
|
if (source !== output) {
|
|
1744
1613
|
item.modified = true;
|
|
1745
1614
|
return output;
|
|
@@ -1774,16 +1643,15 @@ class ChromeDocument extends Document {
|
|
|
1774
1643
|
item.modified = true;
|
|
1775
1644
|
}
|
|
1776
1645
|
source = sanitizeSource(item, source);
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
const result = await this.transform('html', source, format, this.createTransformOptions(host, item, "image/svg+xml"));
|
|
1646
|
+
if (item.format) {
|
|
1647
|
+
const result = await this.transform('html', source, item.format, this.createTransformOptions(host, item, "image/svg+xml"));
|
|
1780
1648
|
if (result) {
|
|
1781
1649
|
item.modified = true;
|
|
1782
1650
|
source = result.code;
|
|
1783
1651
|
}
|
|
1784
1652
|
}
|
|
1785
1653
|
item.sourceUTF8 = source;
|
|
1786
|
-
if (processing.productionRelease && item.hash && !processing.hashed.has(item) && createHash(
|
|
1654
|
+
if (processing.productionRelease && item.hash && !processing.hashed.has(item) && this.createHash(processing, item, item.hash)) {
|
|
1787
1655
|
processing.hashed.add(item);
|
|
1788
1656
|
}
|
|
1789
1657
|
}
|
|
@@ -1799,7 +1667,7 @@ class ChromeDocument extends Document {
|
|
|
1799
1667
|
source = output;
|
|
1800
1668
|
item.modified = true;
|
|
1801
1669
|
}
|
|
1802
|
-
if (
|
|
1670
|
+
if (output = await this.transformCss(processing, item, source)) {
|
|
1803
1671
|
source = output;
|
|
1804
1672
|
item.modified = true;
|
|
1805
1673
|
}
|
|
@@ -1827,6 +1695,10 @@ class ChromeDocument extends Document {
|
|
|
1827
1695
|
source = output;
|
|
1828
1696
|
item.modified = true;
|
|
1829
1697
|
}
|
|
1698
|
+
if (output = await this.transformJs(processing, item, source)) {
|
|
1699
|
+
source = output;
|
|
1700
|
+
item.modified = true;
|
|
1701
|
+
}
|
|
1830
1702
|
if (output = this.processUrl(host, item, source, 'js')) {
|
|
1831
1703
|
source = output;
|
|
1832
1704
|
item.modified = true;
|
|
@@ -1848,7 +1720,7 @@ class ChromeDocument extends Document {
|
|
|
1848
1720
|
if (value.map && !target.bundleReplace) {
|
|
1849
1721
|
const output = Document.writeSourceMap(target.localUri, value, { mimeType: "text/css", hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
|
|
1850
1722
|
if (output) {
|
|
1851
|
-
host.add(output, target,
|
|
1723
|
+
host.add(output, target, FILE_TYPE.SOURCEMAP);
|
|
1852
1724
|
}
|
|
1853
1725
|
}
|
|
1854
1726
|
target.modified = true;
|
|
@@ -1868,28 +1740,28 @@ class ChromeDocument extends Document {
|
|
|
1868
1740
|
const localUri = htmlFile.localUri;
|
|
1869
1741
|
this.formatMessage(4, 'HTML', ['Rewriting content...', path.dirname(localUri)]);
|
|
1870
1742
|
let source = host.getUTF8String(htmlFile, localUri), output;
|
|
1871
|
-
const domBase = new
|
|
1743
|
+
const domBase = new DomWriter(moduleName, source, this.elements, { normalize: config.normalizeHtmlOutput, stripComments: config.stripCommentsAndCDATA, ignoreTagGroup: config.ignoreServerCodeBlocks, escapeEntities: config.escapeReservedCharacters });
|
|
1872
1744
|
if (config.useUnsafeHtmlReplace) {
|
|
1873
|
-
domBase.ignoreFlag(
|
|
1745
|
+
domBase.ignoreFlag(IGNORE_FLAG.INTERIOR);
|
|
1874
1746
|
}
|
|
1875
1747
|
if (this.watching) {
|
|
1876
|
-
domBase.ignoreFlag(
|
|
1748
|
+
domBase.ignoreFlag(IGNORE_FLAG.LOCATOR);
|
|
1877
1749
|
}
|
|
1878
|
-
if (
|
|
1750
|
+
if (isString(config.useOriginalHtmlPage)) {
|
|
1879
1751
|
domBase.ignoreTag(config.useOriginalHtmlPage);
|
|
1880
1752
|
}
|
|
1881
|
-
if (
|
|
1753
|
+
if (isArray(config.ignoreServerCodeBlocks)) {
|
|
1882
1754
|
domBase.ignoreTag(config.ignoreServerCodeBlocks);
|
|
1883
1755
|
}
|
|
1884
1756
|
if (processing.productionRelease) {
|
|
1885
|
-
replaceCss(
|
|
1757
|
+
this.#replaceCss(htmlFile);
|
|
1886
1758
|
}
|
|
1887
1759
|
await this.setElementAttributes(processing, domBase);
|
|
1888
1760
|
await this.applyDataSource(processing, domBase);
|
|
1889
1761
|
for (const item of this.assets) {
|
|
1890
1762
|
const element = item.element;
|
|
1891
|
-
if (element && isRemoved(item) && !
|
|
1892
|
-
const domElement = new
|
|
1763
|
+
if (element && isRemoved(item) && !ignoreFlag(item.flags)) {
|
|
1764
|
+
const domElement = new HtmlElement(moduleName, element, item.attributes);
|
|
1893
1765
|
domElement.remove = true;
|
|
1894
1766
|
if (!domBase.write(domElement)) {
|
|
1895
1767
|
this.writeFail('Unable to exclude HTML element', errorHtml(element), 4);
|
|
@@ -1899,13 +1771,13 @@ class ChromeDocument extends Document {
|
|
|
1899
1771
|
source = removeNamespace(moduleName, domBase.modified ? domBase.close() : source, domBase.newline, domBase.getComments());
|
|
1900
1772
|
if (this.sanitizeFramework) {
|
|
1901
1773
|
for (const name of this.sanitizeFramework) {
|
|
1902
|
-
source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${
|
|
1774
|
+
source = source.replace(name === '*' ? REGEXP_SANITIZEALL : new RegExp(`(?:\\s+|\\b)data-(?:${escapePattern(name)}-[^=\\s]+|.+-${escapePattern(name)})\\s*${DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g'), '');
|
|
1903
1775
|
}
|
|
1904
1776
|
}
|
|
1905
1777
|
if (!htmlFile.preserve) {
|
|
1906
1778
|
let match;
|
|
1907
1779
|
while (match = REGEXP_STYLE.exec(source)) {
|
|
1908
|
-
if (output = this.
|
|
1780
|
+
if (output = await this.transformCss(processing, htmlFile, match[5])) {
|
|
1909
1781
|
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1910
1782
|
}
|
|
1911
1783
|
}
|
|
@@ -1914,9 +1786,9 @@ class ChromeDocument extends Document {
|
|
|
1914
1786
|
if (output = this.processUrl(host, htmlFile, source, 'html')) {
|
|
1915
1787
|
source = output;
|
|
1916
1788
|
}
|
|
1917
|
-
source = replaceHtml(
|
|
1918
|
-
if (
|
|
1919
|
-
source =
|
|
1789
|
+
source = this.#replaceHtml(source, processing, htmlFile.inlineUrlMap);
|
|
1790
|
+
if (isString(config.stripCommentsAndCDATA)) {
|
|
1791
|
+
source = DomWriter.getCommentsAndCDATA(source, config.stripCommentsAndCDATA, true, true);
|
|
1920
1792
|
}
|
|
1921
1793
|
if (htmlFile.format) {
|
|
1922
1794
|
const { filename, uri, encoding, metadata } = htmlFile;
|
|
@@ -1938,7 +1810,7 @@ class ChromeDocument extends Document {
|
|
|
1938
1810
|
}
|
|
1939
1811
|
}
|
|
1940
1812
|
if (domBase.failCount > 0) {
|
|
1941
|
-
this.writeFail(['Unable to update document', moduleName],
|
|
1813
|
+
this.writeFail(['Unable to update document', moduleName], errorMessage('dom-writer', domBase.failCount + ' failed', domBase.modifyCount + ' modified'), { type: 4, startTime });
|
|
1942
1814
|
}
|
|
1943
1815
|
else {
|
|
1944
1816
|
this.writeTimeProcess('html', `dom-writer: ${domBase.modifyCount} modified (${path.basename(localUri)})`, startTime);
|
|
@@ -1960,12 +1832,12 @@ class ChromeDocument extends Document {
|
|
|
1960
1832
|
async setElementAttributes({ host, startTime, productionRelease }, domBase) {
|
|
1961
1833
|
for (const item of this.assets) {
|
|
1962
1834
|
const { element, inlineContent } = item;
|
|
1963
|
-
if (!element || element.removed || isRemoved(item) || isUnedited(item) ||
|
|
1835
|
+
if (!element || element.removed || isRemoved(item) || isUnedited(item) || ignoreFlag(item.flags) && !processFlag(item.flags)) {
|
|
1964
1836
|
continue;
|
|
1965
1837
|
}
|
|
1966
|
-
const domElement = new
|
|
1838
|
+
const domElement = new HtmlElement(this.moduleName, element, item.attributes);
|
|
1967
1839
|
if (inlineContent) {
|
|
1968
|
-
let [innerXml, sourceMappingURL, inlineMap] =
|
|
1840
|
+
let [innerXml, sourceMappingURL, inlineMap] = SourceMap.removeSourceMappingURL(host.getUTF8String(item).trim());
|
|
1969
1841
|
if (sourceMappingURL && !inlineMap && item.localUri) {
|
|
1970
1842
|
let mapUri = path.resolve(sourceMappingURL = decodeURIComponent(sourceMappingURL));
|
|
1971
1843
|
if (!Document.isPath(mapUri)) {
|
|
@@ -1979,7 +1851,7 @@ class ChromeDocument extends Document {
|
|
|
1979
1851
|
}
|
|
1980
1852
|
else {
|
|
1981
1853
|
let uri = item.relativeUrl;
|
|
1982
|
-
if (
|
|
1854
|
+
if (hasValue(item.format, 'base64')) {
|
|
1983
1855
|
if (item.invalid) {
|
|
1984
1856
|
continue;
|
|
1985
1857
|
}
|
|
@@ -1989,13 +1861,13 @@ class ChromeDocument extends Document {
|
|
|
1989
1861
|
uri = '';
|
|
1990
1862
|
}
|
|
1991
1863
|
}
|
|
1992
|
-
if (uri && !
|
|
1864
|
+
if (uri && !hasValue(item.format, 'crossorigin') && item !== this.htmlFile) {
|
|
1993
1865
|
if (host.Cloud?.getStorage('upload', item.cloudStorage)) {
|
|
1994
|
-
const inlineUrlCloud = item.inlineUrlCloud ||=
|
|
1866
|
+
const inlineUrlCloud = item.inlineUrlCloud ||= randomUUID();
|
|
1995
1867
|
(this.htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
|
|
1996
1868
|
uri = inlineUrlCloud;
|
|
1997
1869
|
}
|
|
1998
|
-
if (!
|
|
1870
|
+
if (!hasValue(item.format, 'webbundle')) {
|
|
1999
1871
|
const { bundleIndex, srcSet } = item;
|
|
2000
1872
|
if (bundleIndex === 0 || bundleIndex === -1) {
|
|
2001
1873
|
switch (element.tagName) {
|
|
@@ -2025,7 +1897,7 @@ class ChromeDocument extends Document {
|
|
|
2025
1897
|
const addLog = (suffix, err) => this.addLog(3, err || ('Not detectable image ' + suffix), { source: item.localUri ? path.basename(item.localUri) : item.filename });
|
|
2026
1898
|
if (isImage(item.mimeType) && (buffer = host.getBuffer(item))) {
|
|
2027
1899
|
try {
|
|
2028
|
-
({ width, height } =
|
|
1900
|
+
({ width, height } = imageSize(buffer));
|
|
2029
1901
|
}
|
|
2030
1902
|
catch (err) {
|
|
2031
1903
|
addLog('from buffer', err);
|
|
@@ -2075,21 +1947,56 @@ class ChromeDocument extends Document {
|
|
|
2075
1947
|
dataItems.push(item);
|
|
2076
1948
|
}
|
|
2077
1949
|
}
|
|
1950
|
+
const loadLocalFile = (pathname, encoding, out) => {
|
|
1951
|
+
if (out) {
|
|
1952
|
+
out.content = fs.readFileSync(pathname, getEncoding(encoding));
|
|
1953
|
+
}
|
|
1954
|
+
const ext = asExt(pathname);
|
|
1955
|
+
switch (ext) {
|
|
1956
|
+
case 'cjs':
|
|
1957
|
+
return require(pathname);
|
|
1958
|
+
case 'mjs':
|
|
1959
|
+
return requireESM(pathname);
|
|
1960
|
+
default: {
|
|
1961
|
+
const result = this.tryParse(out?.content || fs.readFileSync(pathname, getEncoding(encoding)), ext);
|
|
1962
|
+
if (result != null) {
|
|
1963
|
+
return result;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
};
|
|
1968
|
+
const removeElement = (item, element) => {
|
|
1969
|
+
if (item.removeEmpty || item.type === 'display') {
|
|
1970
|
+
element ||= new HtmlElement(this.moduleName, item.element);
|
|
1971
|
+
element.remove = true;
|
|
1972
|
+
if (!domBase.write(element)) {
|
|
1973
|
+
this.writeFail('Unable to remove element', errorHtml(item.element), { type: 4 });
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
};
|
|
1977
|
+
const errorCredential = (item, err) => {
|
|
1978
|
+
removeElement(item);
|
|
1979
|
+
const pkg = getPackageName(err);
|
|
1980
|
+
if (pkg && this.checkPackage(err, pkg)) {
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
this.writeFail(["Invalid credentials", item.source], err);
|
|
1984
|
+
};
|
|
2078
1985
|
const checkObject = (item, data, type) => {
|
|
2079
1986
|
if (item.cascade) {
|
|
2080
|
-
const result = data &&
|
|
1987
|
+
const result = data && cascadeObject(data, item.cascade, data);
|
|
2081
1988
|
if (result !== data) {
|
|
2082
1989
|
data = result;
|
|
2083
1990
|
}
|
|
2084
1991
|
else if (item.fallback !== undefined) {
|
|
2085
1992
|
data = item.fallback;
|
|
2086
1993
|
}
|
|
2087
|
-
else if (!
|
|
1994
|
+
else if (!item.query) {
|
|
2088
1995
|
return null;
|
|
2089
1996
|
}
|
|
2090
1997
|
}
|
|
2091
1998
|
if (data) {
|
|
2092
|
-
if (
|
|
1999
|
+
if (isString(item.query)) {
|
|
2093
2000
|
const pkg = item.query.startsWith('$') ? Document.checkSemVer('jsonpath-plus', 5) ? null : 'jsonpath' : 'jmespath';
|
|
2094
2001
|
try {
|
|
2095
2002
|
if (pkg === 'jmespath') {
|
|
@@ -2111,10 +2018,10 @@ class ChromeDocument extends Document {
|
|
|
2111
2018
|
}
|
|
2112
2019
|
}
|
|
2113
2020
|
if (type && !item.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
|
|
2114
|
-
|
|
2021
|
+
coerceObject(data);
|
|
2115
2022
|
}
|
|
2116
2023
|
}
|
|
2117
|
-
return Array.isArray(data) ? data :
|
|
2024
|
+
return Array.isArray(data) ? data : isObject(data) ? [data] : null;
|
|
2118
2025
|
};
|
|
2119
2026
|
const setElements = async (sourceSet) => {
|
|
2120
2027
|
const db = this.Db;
|
|
@@ -2135,7 +2042,7 @@ class ChromeDocument extends Document {
|
|
|
2135
2042
|
(batchMap[key] ||= []).push(item);
|
|
2136
2043
|
}
|
|
2137
2044
|
else {
|
|
2138
|
-
errorCredential(
|
|
2045
|
+
errorCredential(item, errorValue("Cloud module not installed", service));
|
|
2139
2046
|
}
|
|
2140
2047
|
break;
|
|
2141
2048
|
}
|
|
@@ -2153,23 +2060,23 @@ class ChromeDocument extends Document {
|
|
|
2153
2060
|
let key;
|
|
2154
2061
|
switch (type) {
|
|
2155
2062
|
case 'mongodb':
|
|
2156
|
-
key =
|
|
2063
|
+
key = ClientDb.keyOfResult(item.uri || type, credential);
|
|
2157
2064
|
break;
|
|
2158
2065
|
case 'redis':
|
|
2159
|
-
key = credential && (key =
|
|
2066
|
+
key = credential && (key = ClientDb.keyOfResult(type, credential, true)) ? key : JSON.stringify(item.options.client);
|
|
2160
2067
|
break;
|
|
2161
2068
|
default:
|
|
2162
|
-
key =
|
|
2069
|
+
key = ClientDb.keyOfResult(type, credential);
|
|
2163
2070
|
break;
|
|
2164
2071
|
}
|
|
2165
2072
|
(batchMap[key] ||= []).push(item);
|
|
2166
2073
|
}
|
|
2167
2074
|
catch (err) {
|
|
2168
|
-
errorCredential(
|
|
2075
|
+
errorCredential(item, err);
|
|
2169
2076
|
}
|
|
2170
2077
|
}
|
|
2171
2078
|
else {
|
|
2172
|
-
errorCredential(
|
|
2079
|
+
errorCredential(item, errorValue(db ? "Database provider not found" : "Db module not installed", type));
|
|
2173
2080
|
}
|
|
2174
2081
|
break;
|
|
2175
2082
|
}
|
|
@@ -2180,11 +2087,11 @@ class ChromeDocument extends Document {
|
|
|
2180
2087
|
return this.allSettled(batchGroup.map(async (batch) => {
|
|
2181
2088
|
return new Promise(async (resolve, reject) => {
|
|
2182
2089
|
const errorRemove = (item, reason) => {
|
|
2183
|
-
removeElement(
|
|
2090
|
+
removeElement(item);
|
|
2184
2091
|
reject(reason);
|
|
2185
2092
|
};
|
|
2186
2093
|
const errorClient = (item, reason) => {
|
|
2187
|
-
removeElement(
|
|
2094
|
+
removeElement(item);
|
|
2188
2095
|
if (reason) {
|
|
2189
2096
|
this.writeFail(["Unable to configure client", item.source], reason);
|
|
2190
2097
|
}
|
|
@@ -2198,7 +2105,7 @@ class ChromeDocument extends Document {
|
|
|
2198
2105
|
case 'cloud':
|
|
2199
2106
|
result = await cloud.getDatabaseBatchRows(batch, true, this.sessionKey).catch((err) => {
|
|
2200
2107
|
this.abort(type);
|
|
2201
|
-
if (err
|
|
2108
|
+
if (isError(err)) {
|
|
2202
2109
|
cloud.addLog(this.aborted ? 2 : 3, errors = err, { source: batch[0].service });
|
|
2203
2110
|
}
|
|
2204
2111
|
return [];
|
|
@@ -2217,7 +2124,7 @@ class ChromeDocument extends Document {
|
|
|
2217
2124
|
let content, target, data, cacheKey;
|
|
2218
2125
|
if (type === 'local') {
|
|
2219
2126
|
let location;
|
|
2220
|
-
if (!(
|
|
2127
|
+
if (!(target = current.pathname) || !((location = this.resolveDir('data', target)) || host.canRead(location = path.resolve(target), { ownPermissionOnly: true }))) {
|
|
2221
2128
|
this.abort(type);
|
|
2222
2129
|
errorRemove(current, target ? errorDataSource('Not found', target) : errorDataSource('Not defined - ' + (this.settings.directory?.data ? 'file' : 'directory'), type));
|
|
2223
2130
|
return;
|
|
@@ -2243,7 +2150,7 @@ class ChromeDocument extends Document {
|
|
|
2243
2150
|
}
|
|
2244
2151
|
}
|
|
2245
2152
|
}
|
|
2246
|
-
else if (!(
|
|
2153
|
+
else if (!(target = current.uri)) {
|
|
2247
2154
|
this.abort(type);
|
|
2248
2155
|
errorRemove(current, errorDataSource('Not defined', type));
|
|
2249
2156
|
return;
|
|
@@ -2251,7 +2158,7 @@ class ChromeDocument extends Document {
|
|
|
2251
2158
|
else if (Document.isURL(target, 'file')) {
|
|
2252
2159
|
let { format, contentType, body } = current;
|
|
2253
2160
|
if (body) {
|
|
2254
|
-
if (!format && !contentType &&
|
|
2161
|
+
if (!format && !contentType && isPlainObject(body)) {
|
|
2255
2162
|
format = 'json';
|
|
2256
2163
|
}
|
|
2257
2164
|
try {
|
|
@@ -2316,8 +2223,8 @@ class ChromeDocument extends Document {
|
|
|
2316
2223
|
if (Buffer.isBuffer(content)) {
|
|
2317
2224
|
content = content.toString('utf8');
|
|
2318
2225
|
}
|
|
2319
|
-
if (
|
|
2320
|
-
const { format =
|
|
2226
|
+
if (isString(content)) {
|
|
2227
|
+
const { format = asExt(target) } = current;
|
|
2321
2228
|
try {
|
|
2322
2229
|
data = this.tryParse(content, format, current.options);
|
|
2323
2230
|
}
|
|
@@ -2362,13 +2269,13 @@ class ChromeDocument extends Document {
|
|
|
2362
2269
|
else {
|
|
2363
2270
|
const { pathname, execute, params } = current;
|
|
2364
2271
|
let data, target, getData, hint;
|
|
2365
|
-
if (
|
|
2272
|
+
if (isFunction(execute)) {
|
|
2366
2273
|
target = execute;
|
|
2367
2274
|
}
|
|
2368
|
-
else if (
|
|
2275
|
+
else if (isFunction(pathname)) {
|
|
2369
2276
|
target = pathname;
|
|
2370
2277
|
}
|
|
2371
|
-
else if (
|
|
2278
|
+
else if (isString(pathname)) {
|
|
2372
2279
|
if (pathname.startsWith('npm:')) {
|
|
2373
2280
|
target = pathname;
|
|
2374
2281
|
hint = pathname;
|
|
@@ -2383,24 +2290,24 @@ class ChromeDocument extends Document {
|
|
|
2383
2290
|
if (!getData) {
|
|
2384
2291
|
const settings = current.settings;
|
|
2385
2292
|
target ||= settings && this.settings.export?.[settings] || pathname;
|
|
2386
|
-
if (
|
|
2293
|
+
if (isFunction(target)) {
|
|
2387
2294
|
getData = target;
|
|
2388
2295
|
hint = target.name;
|
|
2389
2296
|
}
|
|
2390
|
-
else if (
|
|
2297
|
+
else if (isString(target)) {
|
|
2391
2298
|
getData = this.asSourceFile(target, { encoding: current.encoding });
|
|
2392
2299
|
hint = target;
|
|
2393
2300
|
}
|
|
2394
2301
|
}
|
|
2395
|
-
if (!
|
|
2302
|
+
if (!isFunction(getData)) {
|
|
2396
2303
|
errorRemove(current, target ? errorDataSource('Not a function', hint) : errorDataSource('Not defined - pathname', type));
|
|
2397
2304
|
return;
|
|
2398
2305
|
}
|
|
2399
2306
|
try {
|
|
2400
2307
|
if (params && !current.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
|
|
2401
|
-
|
|
2308
|
+
coerceObject(params);
|
|
2402
2309
|
}
|
|
2403
|
-
if (
|
|
2310
|
+
if (isFunction(getData, true)) {
|
|
2404
2311
|
data = await getData(params);
|
|
2405
2312
|
}
|
|
2406
2313
|
else {
|
|
@@ -2455,8 +2362,8 @@ class ChromeDocument extends Document {
|
|
|
2455
2362
|
case 'redis':
|
|
2456
2363
|
for (let j = 0; j < length; ++j) {
|
|
2457
2364
|
const cmd = batch[j];
|
|
2458
|
-
const
|
|
2459
|
-
if (
|
|
2365
|
+
const search = cmd.search;
|
|
2366
|
+
if (isObject(search) && typeof search.schema === 'string') {
|
|
2460
2367
|
const pathname = this.resolveDir('schema', search.schema);
|
|
2461
2368
|
if (pathname) {
|
|
2462
2369
|
if (!cmd.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
|
|
@@ -2468,11 +2375,11 @@ class ChromeDocument extends Document {
|
|
|
2468
2375
|
}
|
|
2469
2376
|
if (!(search.schema = this._sessionData[pathname])) {
|
|
2470
2377
|
try {
|
|
2471
|
-
search.schema = loadLocalFile(
|
|
2378
|
+
search.schema = loadLocalFile(pathname, cmd.encoding);
|
|
2472
2379
|
this.addSessionData(current, pathname, search.schema, { template: true });
|
|
2473
2380
|
}
|
|
2474
2381
|
catch (err) {
|
|
2475
|
-
this.writeFail(['Unable to parse document', path.basename(pathname)], err
|
|
2382
|
+
this.writeFail(['Unable to parse document', path.basename(pathname)], isError(err) ? errors = err : err, 32);
|
|
2476
2383
|
search.schema = undefined;
|
|
2477
2384
|
}
|
|
2478
2385
|
}
|
|
@@ -2482,8 +2389,8 @@ class ChromeDocument extends Document {
|
|
|
2482
2389
|
search.schema = undefined;
|
|
2483
2390
|
}
|
|
2484
2391
|
}
|
|
2485
|
-
if (key) {
|
|
2486
|
-
cmd.cacheObjectKey = (
|
|
2392
|
+
if (cmd.key) {
|
|
2393
|
+
cmd.cacheObjectKey = (cmd.cascade ? cmd.cascade : '') + '_' + (cmd.query ? Document.asString(cmd.query, true) : '');
|
|
2487
2394
|
}
|
|
2488
2395
|
}
|
|
2489
2396
|
break;
|
|
@@ -2506,7 +2413,7 @@ class ChromeDocument extends Document {
|
|
|
2506
2413
|
if (!(cmd.query = this._sessionData[pathname])) {
|
|
2507
2414
|
const out = { content: '' };
|
|
2508
2415
|
try {
|
|
2509
|
-
cmd.query = loadLocalFile(
|
|
2416
|
+
cmd.query = loadLocalFile(pathname, cmd.encoding, out);
|
|
2510
2417
|
}
|
|
2511
2418
|
catch {
|
|
2512
2419
|
cmd.query = out.content;
|
|
@@ -2516,7 +2423,7 @@ class ChromeDocument extends Document {
|
|
|
2516
2423
|
}
|
|
2517
2424
|
}
|
|
2518
2425
|
else {
|
|
2519
|
-
throw
|
|
2426
|
+
throw errorMessage(type, "File not found", query);
|
|
2520
2427
|
}
|
|
2521
2428
|
}
|
|
2522
2429
|
catch (err) {
|
|
@@ -2540,7 +2447,7 @@ class ChromeDocument extends Document {
|
|
|
2540
2447
|
aborting = commandType !== db.commandType.UPDATE;
|
|
2541
2448
|
message = Document.asString(data.search || data.key);
|
|
2542
2449
|
}
|
|
2543
|
-
else if (
|
|
2450
|
+
else if (isObject(data.credential)) {
|
|
2544
2451
|
message = data.credential.database;
|
|
2545
2452
|
}
|
|
2546
2453
|
if (data.willAbort) {
|
|
@@ -2550,7 +2457,7 @@ class ChromeDocument extends Document {
|
|
|
2550
2457
|
this.abort(type, err);
|
|
2551
2458
|
}
|
|
2552
2459
|
if (err) {
|
|
2553
|
-
this.writeFail(["Unable to execute query", message || "Unknown"], err
|
|
2460
|
+
this.writeFail(["Unable to execute query", message || "Unknown"], isError(err) ? errors = err : err, { type: 65536, startTime });
|
|
2554
2461
|
}
|
|
2555
2462
|
return this.aborted;
|
|
2556
2463
|
};
|
|
@@ -2599,7 +2506,7 @@ class ChromeDocument extends Document {
|
|
|
2599
2506
|
}
|
|
2600
2507
|
if (items.length > 0 && !item.transactionFail) {
|
|
2601
2508
|
const element = item.element;
|
|
2602
|
-
const domElement = new
|
|
2509
|
+
const domElement = new HtmlElement(this.moduleName, element);
|
|
2603
2510
|
let value = '';
|
|
2604
2511
|
const checkValue = async (name) => {
|
|
2605
2512
|
const data = await this.processData(item, value, name, row => typeof row === 'string');
|
|
@@ -2642,7 +2549,7 @@ class ChromeDocument extends Document {
|
|
|
2642
2549
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2643
2550
|
if (content === null) {
|
|
2644
2551
|
++domBase.failCount;
|
|
2645
|
-
removeElement(
|
|
2552
|
+
removeElement(item, domElement);
|
|
2646
2553
|
if (length === 1) {
|
|
2647
2554
|
resolve();
|
|
2648
2555
|
return;
|
|
@@ -2654,7 +2561,7 @@ class ChromeDocument extends Document {
|
|
|
2654
2561
|
else {
|
|
2655
2562
|
for (let j = 0, match; j < items.length; ++j) {
|
|
2656
2563
|
const row = items[j];
|
|
2657
|
-
if (
|
|
2564
|
+
if (isPlainObject(row)) {
|
|
2658
2565
|
row.__index__ ??= j + 1;
|
|
2659
2566
|
}
|
|
2660
2567
|
let segment = template;
|
|
@@ -2674,30 +2581,30 @@ class ChromeDocument extends Document {
|
|
|
2674
2581
|
segment = replaceMatch(match, segment, target[col] ? (!match[1] || target[col - 1].includes('\n') ? '' : match[1]) + target[col - 1] + target[col] : '', REGEXP_TEMPLATECONDITIONAL);
|
|
2675
2582
|
}
|
|
2676
2583
|
const literal = segment.trim();
|
|
2677
|
-
if (literal.
|
|
2584
|
+
if (literal.at(0) === '`' && literal.at(-1) === '`') {
|
|
2678
2585
|
if (!this.hasEval('function')) {
|
|
2679
|
-
errors =
|
|
2586
|
+
errors = errorMessage('eval', "Unsupported access", 'function');
|
|
2680
2587
|
continue;
|
|
2681
2588
|
}
|
|
2682
2589
|
try {
|
|
2683
|
-
let
|
|
2590
|
+
let unsafe = new Function('return ' + literal + ';').call(row);
|
|
2684
2591
|
if (!segment.startsWith('`')) {
|
|
2685
|
-
|
|
2592
|
+
unsafe = segment.slice(0, segment.indexOf('`')) + unsafe;
|
|
2686
2593
|
}
|
|
2687
2594
|
if (!segment.endsWith('`')) {
|
|
2688
|
-
|
|
2595
|
+
unsafe += segment.slice(segment.lastIndexOf('`') + 1);
|
|
2689
2596
|
}
|
|
2690
|
-
segment =
|
|
2597
|
+
segment = unsafe;
|
|
2691
2598
|
}
|
|
2692
2599
|
catch (err) {
|
|
2693
|
-
errors = err
|
|
2600
|
+
errors = isError(err) ? err : true;
|
|
2694
2601
|
continue;
|
|
2695
2602
|
}
|
|
2696
2603
|
}
|
|
2697
2604
|
else {
|
|
2698
2605
|
const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
|
|
2699
2606
|
while (match = pattern.exec(segment)) {
|
|
2700
|
-
segment = replaceMatch(match, segment, match[1] === "__index__" && !
|
|
2607
|
+
segment = replaceMatch(match, segment, match[1] === "__index__" && !isObject(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
|
|
2701
2608
|
}
|
|
2702
2609
|
}
|
|
2703
2610
|
value += trimTemplate(segment);
|
|
@@ -2713,7 +2620,7 @@ class ChromeDocument extends Document {
|
|
|
2713
2620
|
if (trailingText) {
|
|
2714
2621
|
value += trailingText;
|
|
2715
2622
|
}
|
|
2716
|
-
domElement.innerXml = domBase.initOpts.normalize ?
|
|
2623
|
+
domElement.innerXml = domBase.initOpts.normalize ? DomWriter.normalize(value, { newline: domBase.newline, escapeEntities: domBase.initOpts.escapeEntities }) : value;
|
|
2717
2624
|
}
|
|
2718
2625
|
else {
|
|
2719
2626
|
errors = true;
|
|
@@ -2722,12 +2629,12 @@ class ChromeDocument extends Document {
|
|
|
2722
2629
|
}
|
|
2723
2630
|
case 'attribute': {
|
|
2724
2631
|
const map = item.value;
|
|
2725
|
-
if (
|
|
2632
|
+
if (isPlainObject(map)) {
|
|
2726
2633
|
for (const attr in map) {
|
|
2727
2634
|
value = '';
|
|
2728
2635
|
let segment = map[attr], valid = false;
|
|
2729
2636
|
if (item.viewEngine) {
|
|
2730
|
-
if (!
|
|
2637
|
+
if (!isString(segment)) {
|
|
2731
2638
|
errors = true;
|
|
2732
2639
|
continue;
|
|
2733
2640
|
}
|
|
@@ -2740,10 +2647,10 @@ class ChromeDocument extends Document {
|
|
|
2740
2647
|
valid = true;
|
|
2741
2648
|
}
|
|
2742
2649
|
else {
|
|
2743
|
-
if (
|
|
2650
|
+
if (isString(segment)) {
|
|
2744
2651
|
segment = [segment];
|
|
2745
2652
|
}
|
|
2746
|
-
else if (!
|
|
2653
|
+
else if (!isArray(segment)) {
|
|
2747
2654
|
errors = true;
|
|
2748
2655
|
continue;
|
|
2749
2656
|
}
|
|
@@ -2802,10 +2709,10 @@ class ChromeDocument extends Document {
|
|
|
2802
2709
|
if (template) {
|
|
2803
2710
|
if (item.viewEngine) {
|
|
2804
2711
|
errors = true;
|
|
2805
|
-
if (
|
|
2712
|
+
if (isString(template)) {
|
|
2806
2713
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2807
2714
|
if (content !== null) {
|
|
2808
|
-
if (
|
|
2715
|
+
if (isString(content) && content.trim() === '') {
|
|
2809
2716
|
domElement.remove = true;
|
|
2810
2717
|
}
|
|
2811
2718
|
errors = false;
|
|
@@ -2813,10 +2720,10 @@ class ChromeDocument extends Document {
|
|
|
2813
2720
|
}
|
|
2814
2721
|
}
|
|
2815
2722
|
else {
|
|
2816
|
-
if (
|
|
2723
|
+
if (isString(template)) {
|
|
2817
2724
|
template = [template];
|
|
2818
2725
|
}
|
|
2819
|
-
else if (!
|
|
2726
|
+
else if (!isArray(template)) {
|
|
2820
2727
|
errors = true;
|
|
2821
2728
|
continue;
|
|
2822
2729
|
}
|
|
@@ -2856,7 +2763,7 @@ class ChromeDocument extends Document {
|
|
|
2856
2763
|
}
|
|
2857
2764
|
const sign = seg[0];
|
|
2858
2765
|
if (sign === '+' || sign === '-') {
|
|
2859
|
-
seg = seg.
|
|
2766
|
+
seg = seg.slice(1);
|
|
2860
2767
|
}
|
|
2861
2768
|
const data = getObjectValue(row, seg);
|
|
2862
2769
|
let keep = true;
|
|
@@ -2905,7 +2812,7 @@ class ChromeDocument extends Document {
|
|
|
2905
2812
|
break;
|
|
2906
2813
|
}
|
|
2907
2814
|
default:
|
|
2908
|
-
removeElement(
|
|
2815
|
+
removeElement(item, domElement);
|
|
2909
2816
|
if (length === 1) {
|
|
2910
2817
|
reject(errorDataSource('Invalid action', item.type || "Unknown"));
|
|
2911
2818
|
return;
|
|
@@ -2913,7 +2820,7 @@ class ChromeDocument extends Document {
|
|
|
2913
2820
|
break invalid;
|
|
2914
2821
|
}
|
|
2915
2822
|
if (!domBase.write(domElement) || errors) {
|
|
2916
|
-
this.writeFail(item.type === 'display' ? domElement.remove && errors !== 1 ? errors ? 'Element was removed with errors' : 'Unable to remove element' : 'Unable to determine display conditional' : 'Unable to replace ' + item.type, errors
|
|
2823
|
+
this.writeFail(item.type === 'display' ? domElement.remove && errors !== 1 ? errors ? 'Element was removed with errors' : 'Unable to remove element' : 'Unable to determine display conditional' : 'Unable to replace ' + item.type, isError(errors) ? errors : errorHtml(element), { type: 4, startTime });
|
|
2917
2824
|
}
|
|
2918
2825
|
}
|
|
2919
2826
|
}
|
|
@@ -2921,7 +2828,7 @@ class ChromeDocument extends Document {
|
|
|
2921
2828
|
if (!empty && item.type !== 'display' || item.transactionFail) {
|
|
2922
2829
|
const emptyResponse = (value, service = item.source) => {
|
|
2923
2830
|
value ||= "Unknown";
|
|
2924
|
-
return errorDataSource(
|
|
2831
|
+
return errorDataSource(isError(errors) ? errors.message : service + ': Empty', value);
|
|
2925
2832
|
};
|
|
2926
2833
|
switch (item.source) {
|
|
2927
2834
|
case 'cloud': {
|
|
@@ -2931,12 +2838,12 @@ class ChromeDocument extends Document {
|
|
|
2931
2838
|
break;
|
|
2932
2839
|
}
|
|
2933
2840
|
case 'uri': {
|
|
2934
|
-
const { uri, format = uri &&
|
|
2841
|
+
const { uri, format = uri && asExt(uri) } = item;
|
|
2935
2842
|
this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri));
|
|
2936
2843
|
break;
|
|
2937
2844
|
}
|
|
2938
2845
|
case 'local': {
|
|
2939
|
-
const { pathname, format = pathname &&
|
|
2846
|
+
const { pathname, format = pathname && asExt(pathname) } = item;
|
|
2940
2847
|
this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname));
|
|
2941
2848
|
break;
|
|
2942
2849
|
}
|
|
@@ -2951,7 +2858,7 @@ class ChromeDocument extends Document {
|
|
|
2951
2858
|
}
|
|
2952
2859
|
}
|
|
2953
2860
|
}
|
|
2954
|
-
removeElement(
|
|
2861
|
+
removeElement(item);
|
|
2955
2862
|
}
|
|
2956
2863
|
}
|
|
2957
2864
|
resolve();
|
|
@@ -2965,13 +2872,51 @@ class ChromeDocument extends Document {
|
|
|
2965
2872
|
await setElements(displayItems);
|
|
2966
2873
|
}
|
|
2967
2874
|
}
|
|
2968
|
-
|
|
2875
|
+
async transformJs(processing, file, source) {
|
|
2876
|
+
const options = { file };
|
|
2877
|
+
let modified = false;
|
|
2878
|
+
for (const method of this.extensionsOf('js')) {
|
|
2879
|
+
try {
|
|
2880
|
+
const output = await method.call(this, source, options);
|
|
2881
|
+
if (isString(output)) {
|
|
2882
|
+
source = output;
|
|
2883
|
+
modified = true;
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
catch (err) {
|
|
2887
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
if (modified) {
|
|
2891
|
+
return source;
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
async transformCss(processing, file, source) {
|
|
2895
|
+
const options = { file, config: this.config };
|
|
2896
|
+
let modified = false;
|
|
2897
|
+
for (const method of this.extensionsOf('css')) {
|
|
2898
|
+
try {
|
|
2899
|
+
const output = await method.call(this, source, options);
|
|
2900
|
+
if (isString(output)) {
|
|
2901
|
+
source = output;
|
|
2902
|
+
modified = true;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
catch (err) {
|
|
2906
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
if (modified) {
|
|
2910
|
+
return source;
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
setProductionAttributes(processing) {
|
|
2969
2914
|
for (const item of this.assets) {
|
|
2970
2915
|
if (isIgnored(item, true)) {
|
|
2971
2916
|
continue;
|
|
2972
2917
|
}
|
|
2973
|
-
if (item.hash && !hashed.has(item)) {
|
|
2974
|
-
createHash(
|
|
2918
|
+
if (item.hash && !processing.hashed.has(item)) {
|
|
2919
|
+
this.createHash(processing, item, item.hash);
|
|
2975
2920
|
}
|
|
2976
2921
|
switch (item.element?.tagName.toLowerCase()) {
|
|
2977
2922
|
case 'style':
|
|
@@ -2982,23 +2927,23 @@ class ChromeDocument extends Document {
|
|
|
2982
2927
|
case 'script': {
|
|
2983
2928
|
const attributes = item.attributes;
|
|
2984
2929
|
if (attributes) {
|
|
2985
|
-
const algorithm =
|
|
2930
|
+
const algorithm = isString(attributes.integrity) ? attributes.integrity.toLowerCase() : '';
|
|
2986
2931
|
switch (algorithm) {
|
|
2987
2932
|
case 'sha256':
|
|
2988
2933
|
case 'sha384':
|
|
2989
2934
|
case 'sha512':
|
|
2990
2935
|
try {
|
|
2991
|
-
const data = getBuffer(item);
|
|
2992
|
-
|
|
2993
|
-
if (
|
|
2936
|
+
const data = processing.getBuffer(item);
|
|
2937
|
+
const value = data && Document.asHash(data, { algorithm, digestEncoding: 'base64', encoding: item.encoding });
|
|
2938
|
+
if (value) {
|
|
2994
2939
|
attributes.integrity = algorithm + '-' + value;
|
|
2995
2940
|
attributes.crossorigin ||= 'anonymous';
|
|
2996
2941
|
break;
|
|
2997
2942
|
}
|
|
2998
|
-
throw
|
|
2943
|
+
throw errorMessage('hash', 'Source not found', item.filename);
|
|
2999
2944
|
}
|
|
3000
2945
|
catch (err) {
|
|
3001
|
-
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime });
|
|
2946
|
+
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime: processing.startTime });
|
|
3002
2947
|
}
|
|
3003
2948
|
default:
|
|
3004
2949
|
if (algorithm) {
|
|
@@ -3012,391 +2957,26 @@ class ChromeDocument extends Document {
|
|
|
3012
2957
|
}
|
|
3013
2958
|
}
|
|
3014
2959
|
}
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
const revised = value.replace(useUnsafeCssReplace ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
|
|
3027
|
-
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) + '`';
|
|
3028
|
-
});
|
|
3029
|
-
let selector = '';
|
|
3030
|
-
for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
|
|
3031
|
-
let ch = revised[i], space = 0;
|
|
3032
|
-
switch (ch) {
|
|
3033
|
-
case '.':
|
|
3034
|
-
case '#':
|
|
3035
|
-
if (!attr) {
|
|
3036
|
-
casing = true;
|
|
3037
|
-
}
|
|
3038
|
-
break;
|
|
3039
|
-
case '[':
|
|
3040
|
-
if (!quote) {
|
|
3041
|
-
attr = true;
|
|
3042
|
-
casing = false;
|
|
3043
|
-
space = 2;
|
|
3044
|
-
}
|
|
3045
|
-
break;
|
|
3046
|
-
case ']':
|
|
3047
|
-
if (!quote || attr && revised[i - 1] === '"' && revised[i - 2] === '\\') {
|
|
3048
|
-
if (quote) {
|
|
3049
|
-
selector = selector.substring(0, selector.length - 1) + '`%%%`';
|
|
3050
|
-
quote = false;
|
|
3051
|
-
}
|
|
3052
|
-
attr = false;
|
|
3053
|
-
casing = false;
|
|
3054
|
-
space = 1;
|
|
3055
|
-
}
|
|
3056
|
-
break;
|
|
3057
|
-
case '=':
|
|
3058
|
-
if (attr && !quote) {
|
|
3059
|
-
casing = true;
|
|
3060
|
-
space = 3;
|
|
3061
|
-
}
|
|
3062
|
-
break;
|
|
3063
|
-
case '\\':
|
|
3064
|
-
ch = '`%%%%`';
|
|
3065
|
-
break;
|
|
3066
|
-
case '"':
|
|
3067
|
-
if (attr) {
|
|
3068
|
-
if (!quote) {
|
|
3069
|
-
ch = '`%%%`';
|
|
3070
|
-
quote = true;
|
|
3071
|
-
}
|
|
3072
|
-
else if (revised[i - 1] !== '\\') {
|
|
3073
|
-
ch = '`%%%`';
|
|
3074
|
-
quote = false;
|
|
3075
|
-
casing = false;
|
|
3076
|
-
}
|
|
3077
|
-
}
|
|
3078
|
-
break;
|
|
3079
|
-
case '~':
|
|
3080
|
-
case '^':
|
|
3081
|
-
case '$':
|
|
3082
|
-
case '*':
|
|
3083
|
-
case '|':
|
|
3084
|
-
if (attr && !quote) {
|
|
3085
|
-
space = 1;
|
|
3086
|
-
}
|
|
3087
|
-
break;
|
|
3088
|
-
case ' ':
|
|
3089
|
-
if (attr && !quote) {
|
|
3090
|
-
ch = '`%%`';
|
|
3091
|
-
break;
|
|
3092
|
-
}
|
|
3093
|
-
case ':':
|
|
3094
|
-
case ',':
|
|
3095
|
-
if (!attr) {
|
|
3096
|
-
casing = false;
|
|
3097
|
-
}
|
|
3098
|
-
break;
|
|
3099
|
-
}
|
|
3100
|
-
selector += (space & 1 ? '`%%`' : '') + (!casing && ch >= 'a' && ch <= 'z' ? '`' + ch + ch.toUpperCase() + '`' : ch) + (space & 2 ? '`%%`' : '');
|
|
3101
|
-
}
|
|
3102
|
-
selector = (0, types_1.escapePattern)(selector)
|
|
3103
|
-
.replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3104
|
-
.replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
|
|
3105
|
-
switch (capture[1]) {
|
|
3106
|
-
case '%%':
|
|
3107
|
-
return stringSome;
|
|
3108
|
-
case '%%%':
|
|
3109
|
-
return `(?:["']|${stringSome})`;
|
|
3110
|
-
case '%%%%':
|
|
3111
|
-
return '\\\\{0,}';
|
|
3112
|
-
default:
|
|
3113
|
-
return `[${capture[1]}]`;
|
|
3114
|
-
}
|
|
3115
|
-
});
|
|
3116
|
-
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
3117
|
-
selector = selector.replace('`%' + i + '`', items[i]);
|
|
3118
|
-
}
|
|
3119
|
-
return selector.replace(/ +/g, stringMany) + stringSome;
|
|
3120
|
-
};
|
|
3121
|
-
const replaceUnunsed = (name, items, nesting, increment = 1) => {
|
|
3122
|
-
for (let i = 0; i < items.length; i += increment) {
|
|
3123
|
-
const value = items[i].trim();
|
|
3124
|
-
let valueTo;
|
|
3125
|
-
const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (useUnsafeCssReplace ? '_1' : '');
|
|
3126
|
-
let pattern = queryMap.get(key), rule;
|
|
3127
|
-
if (!pattern) {
|
|
3128
|
-
let flags = 'gi', selector = '', revised = false;
|
|
3129
|
-
if (name === 'container') {
|
|
3130
|
-
for (let j = 0, length = value.length, casing = true; j < length; j++) {
|
|
3131
|
-
let ch = value[j];
|
|
3132
|
-
if (!casing) {
|
|
3133
|
-
ch = ch.toLowerCase();
|
|
3134
|
-
}
|
|
3135
|
-
else if (ch === '(') {
|
|
3136
|
-
casing = false;
|
|
3137
|
-
}
|
|
3138
|
-
if (casing || ch < 'a' || ch > 'z') {
|
|
3139
|
-
selector += value[j];
|
|
3140
|
-
if (selector.endsWith(' not ')) {
|
|
3141
|
-
selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
|
|
3142
|
-
}
|
|
3143
|
-
}
|
|
3144
|
-
else {
|
|
3145
|
-
selector += '`' + ch + ch.toUpperCase() + '`';
|
|
3146
|
-
}
|
|
3147
|
-
}
|
|
3148
|
-
flags = 'g';
|
|
3149
|
-
}
|
|
3150
|
-
else if (name === 'scope') {
|
|
3151
|
-
selector = `\\(${stringSome + parseSelector(value)}\\)`;
|
|
3152
|
-
if (valueTo) {
|
|
3153
|
-
selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo)}\\)`;
|
|
3154
|
-
}
|
|
3155
|
-
flags = 'g';
|
|
3156
|
-
revised = true;
|
|
3157
|
-
}
|
|
3158
|
-
else if (name === 'supports' && /^selector\(/i.test(value)) {
|
|
3159
|
-
const startIndex = value.indexOf('(');
|
|
3160
|
-
const endIndex = value.lastIndexOf(')');
|
|
3161
|
-
if (startIndex !== -1 && endIndex !== -1) {
|
|
3162
|
-
selector = '[sS][eE][lL][eE][cC][tT][oO][rR]\\(' + stringSome + parseSelector(value.substring(startIndex + 1, endIndex)) + '\\)';
|
|
3163
|
-
flags = 'g';
|
|
3164
|
-
revised = true;
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
if (!revised) {
|
|
3168
|
-
selector = (0, types_1.escapePattern)(selector || value)
|
|
3169
|
-
.replace(/\s*(\\[()])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3170
|
-
.replace(/:\s+/g, stringSome + ':' + stringSome)
|
|
3171
|
-
.replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3172
|
-
.replace(/ +/g, stringMany);
|
|
3173
|
-
if (flags === 'g') {
|
|
3174
|
-
selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + stringMany + selector + stringSome + '{', flags);
|
|
3178
|
-
queryMap.set(key, pattern);
|
|
3179
|
-
}
|
|
3180
|
-
else {
|
|
3181
|
-
pattern.lastIndex = 0;
|
|
3182
|
-
}
|
|
3183
|
-
while (rule = pattern.exec(current)) {
|
|
3184
|
-
if (!nesting) {
|
|
3185
|
-
const block = Array.from(current.substring(0, rule.index).matchAll(/[{}]/g));
|
|
3186
|
-
if (block.filter(open => open[0] === '{').length !== block.filter(close => close[0] === '}').length) {
|
|
3187
|
-
continue;
|
|
3188
|
-
}
|
|
3189
|
-
}
|
|
3190
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
|
|
3191
|
-
if (endIndex !== -1) {
|
|
3192
|
-
current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
|
|
3193
|
-
(checkEmpty ||= {})[name] = true;
|
|
3194
|
-
modified = true;
|
|
3195
|
-
}
|
|
3196
|
-
}
|
|
3197
|
-
}
|
|
3198
|
-
};
|
|
3199
|
-
if (!useUnsafeCssReplace) {
|
|
3200
|
-
const replaceBracket = (pattern) => {
|
|
3201
|
-
let bracket;
|
|
3202
|
-
while (bracket = pattern.exec(current)) {
|
|
3203
|
-
const segment = bracket[0];
|
|
3204
|
-
if (/[{}]/.test(segment)) {
|
|
3205
|
-
const placeholder = '`' + (0, node_crypto_1.randomUUID)().substring(0, 18) + '`';
|
|
3206
|
-
replaceMap.push([placeholder, segment]);
|
|
3207
|
-
current = replaceMatch(bracket, current, placeholder, pattern);
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
pattern.lastIndex = 0;
|
|
3211
|
-
};
|
|
3212
|
-
replaceBracket(REGEXP_COMMENT);
|
|
3213
|
-
replaceBracket(REGEXP_QUOTEDVALUE);
|
|
3214
|
-
const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
|
|
3215
|
-
for (let i = 0, length = values.length; i < length; ++i) {
|
|
3216
|
-
const seg = values[i];
|
|
3217
|
-
if (/^url\([^{}]*[{}].*\)$/is.test(seg)) {
|
|
3218
|
-
replaceMap.push([values[i] = (0, node_crypto_1.randomUUID)().substring(0, 18), seg]);
|
|
3219
|
-
}
|
|
3220
|
-
}
|
|
3221
|
-
if (replaceMap.length > 0) {
|
|
3222
|
-
current = values.join('');
|
|
3223
|
-
}
|
|
3224
|
-
}
|
|
3225
|
-
if (unusedMedia) {
|
|
3226
|
-
replaceUnunsed('media', unusedMedia, true);
|
|
3227
|
-
}
|
|
3228
|
-
if (unusedSupports) {
|
|
3229
|
-
replaceUnunsed('supports', unusedSupports, true);
|
|
3230
|
-
}
|
|
3231
|
-
if (unusedContainer) {
|
|
3232
|
-
replaceUnunsed('container', unusedContainer, false);
|
|
3233
|
-
}
|
|
3234
|
-
if (unusedScope) {
|
|
3235
|
-
replaceUnunsed('scope', unusedScope.map(item => [item.start || '', item.end || '']).flat(), false, 2);
|
|
3236
|
-
}
|
|
3237
|
-
if (unusedStyles) {
|
|
3238
|
-
current = (function recurse(target, child) {
|
|
3239
|
-
let output = '', index = 0, pendingStart = 0, pendingEnd = 0, found = -1;
|
|
3240
|
-
while ((found = target.indexOf('{', index)) !== -1) {
|
|
3241
|
-
++found;
|
|
3242
|
-
const closing = findClosingIndex(target, found, '{')[0];
|
|
3243
|
-
if (closing === -1) {
|
|
3244
|
-
break;
|
|
3245
|
-
}
|
|
3246
|
-
let header = target.substring(index, found), invalid = 0, content;
|
|
3247
|
-
for (const value of unusedStyles) {
|
|
3248
|
-
const key = value + (child ? '_1' : '') + (useUnsafeCssReplace ? '_2' : '');
|
|
3249
|
-
const pattern = selectorMap.get(key);
|
|
3250
|
-
let single, group;
|
|
3251
|
-
if (!pattern) {
|
|
3252
|
-
const selector = parseSelector(value) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
3253
|
-
single = new RegExp(`(^|;)(${stringSome})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
|
|
3254
|
-
group = new RegExp(`((?:^|;)[^{]*?${stringSome}(,${stringSome}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
|
|
3255
|
-
selectorMap.set(key, [single, group]);
|
|
3256
|
-
}
|
|
3257
|
-
else {
|
|
3258
|
-
[single, group] = pattern;
|
|
3259
|
-
}
|
|
3260
|
-
if (match = single.exec(header)) {
|
|
3261
|
-
content = match[1] === ';' ? header.substring(0, match.index + 1) + match[2].replace(/[^\n]+$/, '') : undefined;
|
|
3262
|
-
invalid = 1;
|
|
3263
|
-
break;
|
|
3264
|
-
}
|
|
3265
|
-
let leading = -1, first = true;
|
|
3266
|
-
while (match = group.exec(header)) {
|
|
3267
|
-
const start = match.index + match[1].length;
|
|
3268
|
-
if (!child && first) {
|
|
3269
|
-
if (match[1].trimEnd().endsWith(';')) {
|
|
3270
|
-
leading = start;
|
|
3271
|
-
}
|
|
3272
|
-
first = false;
|
|
3273
|
-
}
|
|
3274
|
-
const sibling = match[2].startsWith(',');
|
|
3275
|
-
const trailing = match[4];
|
|
3276
|
-
const offset = trailing && !sibling ? /^,\s*/.exec(trailing)[0].length : 1;
|
|
3277
|
-
header = header.substring(0, start - (sibling ? match[2].length : 0)) + header.substring(start + match[3].length + (trailing ? sibling ? 0 : offset : /\s$/.test(match[3]) ? -1 : 0));
|
|
3278
|
-
group.lastIndex = match.index;
|
|
3279
|
-
invalid = 2;
|
|
3280
|
-
}
|
|
3281
|
-
if (invalid) {
|
|
3282
|
-
group.lastIndex = 0;
|
|
3283
|
-
const empty = /(.)\s*{$/.exec(header);
|
|
3284
|
-
if (empty) {
|
|
3285
|
-
if (header.trim() === '{') {
|
|
3286
|
-
content = undefined;
|
|
3287
|
-
invalid = 1;
|
|
3288
|
-
break;
|
|
3289
|
-
}
|
|
3290
|
-
if (leading !== -1 && empty[1] === ';') {
|
|
3291
|
-
content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
|
|
3292
|
-
invalid = 1;
|
|
3293
|
-
break;
|
|
3294
|
-
}
|
|
3295
|
-
}
|
|
3296
|
-
}
|
|
3297
|
-
}
|
|
3298
|
-
if (invalid === 0 || invalid === 2) {
|
|
3299
|
-
const trailing = target.substring(found, closing);
|
|
3300
|
-
if (content = recurse(trailing, true)) {
|
|
3301
|
-
content = header + content;
|
|
3302
|
-
}
|
|
3303
|
-
else if (invalid === 2) {
|
|
3304
|
-
content = header + trailing;
|
|
3305
|
-
}
|
|
3306
|
-
}
|
|
3307
|
-
if (content) {
|
|
3308
|
-
if (pendingEnd) {
|
|
3309
|
-
output = target.substring(pendingStart, pendingEnd) + content;
|
|
3310
|
-
pendingEnd = 0;
|
|
3311
|
-
}
|
|
3312
|
-
else {
|
|
3313
|
-
output += content;
|
|
3314
|
-
}
|
|
3315
|
-
}
|
|
3316
|
-
else if (!invalid) {
|
|
3317
|
-
if (output) {
|
|
3318
|
-
output += target.substring(index, closing);
|
|
3319
|
-
}
|
|
3320
|
-
else {
|
|
3321
|
-
pendingEnd = closing;
|
|
3322
|
-
}
|
|
3323
|
-
}
|
|
3324
|
-
else if (pendingEnd) {
|
|
3325
|
-
output = target.substring(pendingStart, pendingEnd);
|
|
3326
|
-
pendingEnd = 0;
|
|
3327
|
-
}
|
|
3328
|
-
else {
|
|
3329
|
-
pendingStart = closing;
|
|
3330
|
-
}
|
|
3331
|
-
index = closing;
|
|
3332
|
-
}
|
|
3333
|
-
if (output) {
|
|
3334
|
-
modified = true;
|
|
3335
|
-
return output + target.substring(index);
|
|
3336
|
-
}
|
|
3337
|
-
return child ? '' : target;
|
|
3338
|
-
})(current, false);
|
|
3339
|
-
}
|
|
3340
|
-
if (usedVariables) {
|
|
3341
|
-
let pattern = useUnsafeCssReplace ? REGEXP_VARIABLES_UNSAFE : REGEXP_VARIABLES;
|
|
3342
|
-
while (match = pattern.exec(current)) {
|
|
3343
|
-
if (!usedVariables.includes(match[2])) {
|
|
3344
|
-
current = replaceMatch(match, current, match[3] === ';' ? getNewlineString(match[1], match[4]) : '', pattern);
|
|
3345
|
-
modified = true;
|
|
3346
|
-
}
|
|
3347
|
-
}
|
|
3348
|
-
pattern.lastIndex = 0;
|
|
3349
|
-
pattern = useUnsafeCssReplace ? REGEXP_PROPERTY_UNSAFE : REGEXP_PROPERTY;
|
|
3350
|
-
while (match = pattern.exec(current)) {
|
|
3351
|
-
if (!usedVariables.includes(match[2])) {
|
|
3352
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3353
|
-
if (endIndex !== -1) {
|
|
3354
|
-
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3355
|
-
modified = true;
|
|
3356
|
-
}
|
|
3357
|
-
}
|
|
3358
|
-
}
|
|
3359
|
-
pattern.lastIndex = 0;
|
|
3360
|
-
}
|
|
3361
|
-
if (usedFontFace) {
|
|
3362
|
-
const pattern = useUnsafeCssReplace ? REGEXP_FONTFACE_UNSAFE : REGEXP_FONTFACE;
|
|
3363
|
-
const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
|
|
3364
|
-
while (match = pattern.exec(current)) {
|
|
3365
|
-
const font = fontFamily.exec(match[0]);
|
|
3366
|
-
if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])(.+)\1$/s, (...content) => content[2]))) {
|
|
3367
|
-
current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
|
|
3368
|
-
modified = true;
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
pattern.lastIndex = 0;
|
|
3372
|
-
}
|
|
3373
|
-
if (usedKeyframes) {
|
|
3374
|
-
const pattern = useUnsafeCssReplace ? REGEXP_KEYFRAMES_UNSAFE : REGEXP_KEYFRAMES;
|
|
3375
|
-
while (match = pattern.exec(current)) {
|
|
3376
|
-
if (!usedKeyframes.includes(match[2].trim())) {
|
|
3377
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3378
|
-
if (endIndex !== -1) {
|
|
3379
|
-
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3380
|
-
modified = true;
|
|
2960
|
+
createHash(processing, file, hash) {
|
|
2961
|
+
const { host, bufferMap } = processing;
|
|
2962
|
+
const { filename, localUri } = file;
|
|
2963
|
+
try {
|
|
2964
|
+
const buffer = localUri && bufferMap[localUri] || processing.getBuffer(file, localUri);
|
|
2965
|
+
if (buffer) {
|
|
2966
|
+
const [algorithm, length] = getHashData(hash);
|
|
2967
|
+
const value = algorithm ? Document.asHash(buffer, algorithm, { encoding: file.encoding }) : '';
|
|
2968
|
+
if (value) {
|
|
2969
|
+
if (localUri) {
|
|
2970
|
+
bufferMap[localUri] = buffer;
|
|
3381
2971
|
}
|
|
2972
|
+
host.rename(file, appendSuffix(filename, length > 0 ? value.slice(0, length) : value));
|
|
2973
|
+
return file.filename;
|
|
3382
2974
|
}
|
|
3383
2975
|
}
|
|
3384
|
-
|
|
2976
|
+
throw errorMessage('hash', 'Source not found', filename);
|
|
3385
2977
|
}
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
const pattern = CACHE_ATRULES[name + (useUnsafeCssReplace ? '_1' : '')] ||= new RegExp(`(\\s*)@${name}[^{]*{${stringSome}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
3389
|
-
while (match = pattern.exec(current)) {
|
|
3390
|
-
current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[2]);
|
|
3391
|
-
}
|
|
3392
|
-
pattern.lastIndex = 0;
|
|
3393
|
-
}
|
|
3394
|
-
if (replaceMap.length > 0) {
|
|
3395
|
-
for (const [placeholder, content] of replaceMap.reverse()) {
|
|
3396
|
-
current = current.replace(placeholder, content);
|
|
3397
|
-
}
|
|
3398
|
-
}
|
|
3399
|
-
return current;
|
|
2978
|
+
catch (err) {
|
|
2979
|
+
host.writeFail(["Unable to read file", filename], err, 32);
|
|
3400
2980
|
}
|
|
3401
2981
|
}
|
|
3402
2982
|
getSrcUrl(parent, file) {
|
|
@@ -3441,13 +3021,13 @@ class ChromeDocument extends Document {
|
|
|
3441
3021
|
file.inlineBase64 ||
|
|
3442
3022
|
this.replaced.includes(file) ||
|
|
3443
3023
|
initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) ||
|
|
3444
|
-
format && (
|
|
3024
|
+
format && (hasValue(format, 'base64') || hasValue(format, 'woff') || hasValue(format, 'woff2')) ? true : false);
|
|
3445
3025
|
}
|
|
3446
3026
|
async processData(item, result, method, validate) {
|
|
3447
3027
|
let callback;
|
|
3448
3028
|
if (typeof method === 'string') {
|
|
3449
3029
|
const template = this.findDataValue(method) || method;
|
|
3450
|
-
callback = this.hasEval('userconfig') ? Document.parseFunction(template, this.hasEval('absolute')) :
|
|
3030
|
+
callback = this.hasEval('userconfig') ? Document.parseFunction(template, { absolute: this.hasEval('absolute'), default: true }) : asFunction(template);
|
|
3451
3031
|
}
|
|
3452
3032
|
else {
|
|
3453
3033
|
callback = method;
|
|
@@ -3456,7 +3036,7 @@ class ChromeDocument extends Document {
|
|
|
3456
3036
|
if (typeof callback === 'function') {
|
|
3457
3037
|
try {
|
|
3458
3038
|
let output;
|
|
3459
|
-
if (
|
|
3039
|
+
if (isFunction(callback, true)) {
|
|
3460
3040
|
output = await callback(result, item);
|
|
3461
3041
|
}
|
|
3462
3042
|
else {
|
|
@@ -3477,14 +3057,8 @@ class ChromeDocument extends Document {
|
|
|
3477
3057
|
}
|
|
3478
3058
|
}
|
|
3479
3059
|
processJs(host, file, output) {
|
|
3480
|
-
const writeSourceMap = (uri, data, hash) => {
|
|
3481
|
-
const value = Document.writeSourceMap(uri, data, { hash, emptySources: !!this.productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
3482
|
-
if (value) {
|
|
3483
|
-
host.add(value, file, types_1.FILE_TYPE.SOURCEMAP);
|
|
3484
|
-
}
|
|
3485
|
-
};
|
|
3486
3060
|
if (output.map) {
|
|
3487
|
-
writeSourceMap(file
|
|
3061
|
+
this.writeSourceMap(host, file, output);
|
|
3488
3062
|
}
|
|
3489
3063
|
if (output.chunks) {
|
|
3490
3064
|
const elements = this.elements;
|
|
@@ -3496,7 +3070,7 @@ class ChromeDocument extends Document {
|
|
|
3496
3070
|
if (element) {
|
|
3497
3071
|
for (const item of elements) {
|
|
3498
3072
|
const append = item.append;
|
|
3499
|
-
if (append && !append.prepend &&
|
|
3073
|
+
if (append && !append.prepend && DomWriter.isEqual(item, element, host.moduleName, true)) {
|
|
3500
3074
|
(appending ||= []).push(append);
|
|
3501
3075
|
}
|
|
3502
3076
|
}
|
|
@@ -3509,7 +3083,7 @@ class ChromeDocument extends Document {
|
|
|
3509
3083
|
}
|
|
3510
3084
|
const chunkUri = path.join(localDir, chunkName);
|
|
3511
3085
|
if (chunk.map) {
|
|
3512
|
-
writeSourceMap(
|
|
3086
|
+
this.writeSourceMap(host, file, chunk, chunkUri);
|
|
3513
3087
|
}
|
|
3514
3088
|
try {
|
|
3515
3089
|
fs.writeFileSync(chunkUri, chunk.code);
|
|
@@ -3523,11 +3097,11 @@ class ChromeDocument extends Document {
|
|
|
3523
3097
|
elements.push({
|
|
3524
3098
|
...element,
|
|
3525
3099
|
attributes,
|
|
3526
|
-
append: { tagName: 'script', tagCount: element.tagCount, nextSibling:
|
|
3100
|
+
append: { tagName: 'script', tagCount: element.tagCount, nextSibling: DomWriter.isIndex(element.index) ? element.index + 1 : undefined, order: ++order }
|
|
3527
3101
|
});
|
|
3528
3102
|
}
|
|
3529
3103
|
else {
|
|
3530
|
-
this.writeFail(['Unable to create entry point', path.basename(chunkUri)],
|
|
3104
|
+
this.writeFail(['Unable to create entry point', path.basename(chunkUri)], errorMessage('js', 'Element not found', chunkUri), 4);
|
|
3531
3105
|
}
|
|
3532
3106
|
}
|
|
3533
3107
|
}
|
|
@@ -3539,7 +3113,7 @@ class ChromeDocument extends Document {
|
|
|
3539
3113
|
item.order += order;
|
|
3540
3114
|
});
|
|
3541
3115
|
}
|
|
3542
|
-
if (
|
|
3116
|
+
if (isArray(output.sourceFiles)) {
|
|
3543
3117
|
file.sourceFiles = output.sourceFiles;
|
|
3544
3118
|
}
|
|
3545
3119
|
file.modified = true;
|
|
@@ -3550,23 +3124,23 @@ class ChromeDocument extends Document {
|
|
|
3550
3124
|
const baseHref = collectBaseUrl(importFile || file, this.baseUrl);
|
|
3551
3125
|
const isHtml = type === 'html';
|
|
3552
3126
|
const isJs = type === 'js';
|
|
3553
|
-
const imageSet =
|
|
3554
|
-
const pattern = isJs ? /\
|
|
3127
|
+
const imageSet = /(?:\b(?<!-)|(?<!-)-webkit-)image-set\(/gi;
|
|
3128
|
+
const pattern = isJs ? /\b(?<!-)import\(/g : type === 'svg' ? /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi : /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi;
|
|
3555
3129
|
let length = source.length, modified = false, match;
|
|
3556
3130
|
while (match = imageSet.exec(source)) {
|
|
3557
3131
|
const startIndex = match.index + match[0].length;
|
|
3558
3132
|
const endIndex = findClosingIndex(source, startIndex, '(');
|
|
3559
3133
|
if (endIndex !== -1) {
|
|
3560
3134
|
REGEXP_IMAGESET_URL.lastIndex = 0;
|
|
3561
|
-
let content = source.
|
|
3135
|
+
let content = source.slice(startIndex, endIndex), url;
|
|
3562
3136
|
while (url = REGEXP_IMAGESET_URL.exec(content)) {
|
|
3563
3137
|
const quote = url[2] ? '"' : "'";
|
|
3564
3138
|
const [a, b] = url.indices[1];
|
|
3565
|
-
content =
|
|
3139
|
+
content = spliceString(content, a, b, `url(${quote + (url[2] || url[3]).trim() + quote})`, REGEXP_IMAGESET_URL);
|
|
3566
3140
|
modified = true;
|
|
3567
3141
|
}
|
|
3568
3142
|
if (modified) {
|
|
3569
|
-
source =
|
|
3143
|
+
source = spliceString(source, startIndex, endIndex, content, imageSet);
|
|
3570
3144
|
modified = false;
|
|
3571
3145
|
}
|
|
3572
3146
|
}
|
|
@@ -3621,7 +3195,8 @@ class ChromeDocument extends Document {
|
|
|
3621
3195
|
i = closed;
|
|
3622
3196
|
}
|
|
3623
3197
|
else {
|
|
3624
|
-
|
|
3198
|
+
i = j;
|
|
3199
|
+
content = content.slice(0, i);
|
|
3625
3200
|
}
|
|
3626
3201
|
break;
|
|
3627
3202
|
}
|
|
@@ -3636,12 +3211,12 @@ class ChromeDocument extends Document {
|
|
|
3636
3211
|
if (asset) {
|
|
3637
3212
|
if (!asset.inlineBase64) {
|
|
3638
3213
|
if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
|
|
3639
|
-
const inlineUrlCloud = asset.inlineUrlCloud ||=
|
|
3214
|
+
const inlineUrlCloud = asset.inlineUrlCloud ||= randomUUID();
|
|
3640
3215
|
(file.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
|
|
3641
3216
|
value = inlineUrlCloud;
|
|
3642
3217
|
}
|
|
3643
3218
|
else if (asset.hash && this.productionRelease) {
|
|
3644
|
-
const inlineUrl = asset.inlineUrl ||=
|
|
3219
|
+
const inlineUrl = asset.inlineUrl ||= randomUUID();
|
|
3645
3220
|
(file.inlineUrlMap ||= {})[inlineUrl] = value;
|
|
3646
3221
|
value = inlineUrl;
|
|
3647
3222
|
}
|
|
@@ -3652,7 +3227,7 @@ class ChromeDocument extends Document {
|
|
|
3652
3227
|
for (let k = i + 1; k < length; ++k) {
|
|
3653
3228
|
switch (source[k]) {
|
|
3654
3229
|
case ')': {
|
|
3655
|
-
const component = source.
|
|
3230
|
+
const component = source.slice(i + 1, k + 1);
|
|
3656
3231
|
const format = /\s+format\([^)]+\)$/i.exec(component);
|
|
3657
3232
|
if (format) {
|
|
3658
3233
|
trailing = component.replace(format[0], ` format("${font}")`);
|
|
@@ -3686,14 +3261,14 @@ class ChromeDocument extends Document {
|
|
|
3686
3261
|
if (isUrl) {
|
|
3687
3262
|
const index = value.indexOf('#');
|
|
3688
3263
|
if (index !== -1) {
|
|
3689
|
-
value = value.
|
|
3264
|
+
value = value.slice(0, index);
|
|
3690
3265
|
}
|
|
3691
3266
|
}
|
|
3692
3267
|
if (quote) {
|
|
3693
3268
|
value = quote + value + quote;
|
|
3694
3269
|
}
|
|
3695
3270
|
const revised = isJs ? `import(${value + trailing})` : isHref ? 'href=' + value : (isText ? '@import ' + value : `url(${value})`) + trailing;
|
|
3696
|
-
source =
|
|
3271
|
+
source = spliceString(source, startIndex, i + 1, revised, pattern);
|
|
3697
3272
|
length = source.length;
|
|
3698
3273
|
modified = true;
|
|
3699
3274
|
};
|
|
@@ -3708,11 +3283,11 @@ class ChromeDocument extends Document {
|
|
|
3708
3283
|
trailing = target[2].trim();
|
|
3709
3284
|
}
|
|
3710
3285
|
else {
|
|
3711
|
-
url =
|
|
3286
|
+
url = trimQuote(content);
|
|
3712
3287
|
}
|
|
3713
3288
|
}
|
|
3714
3289
|
else {
|
|
3715
|
-
url =
|
|
3290
|
+
url = trimQuote(content);
|
|
3716
3291
|
}
|
|
3717
3292
|
if (url.startsWith('data:')) {
|
|
3718
3293
|
const base64 = url.split(',')[1]?.trim();
|
|
@@ -3738,34 +3313,35 @@ class ChromeDocument extends Document {
|
|
|
3738
3313
|
}
|
|
3739
3314
|
}
|
|
3740
3315
|
if (asset && asset !== importFile) {
|
|
3741
|
-
if (!
|
|
3316
|
+
if (!hasValue(asset.format, 'base64')) {
|
|
3742
3317
|
if (asset.bundleReplace) {
|
|
3743
3318
|
let k = 0, valid = true;
|
|
3744
3319
|
if (!isText) {
|
|
3745
3320
|
let j = startIndex;
|
|
3746
3321
|
while (isSpace(source[--j])) { }
|
|
3747
|
-
|
|
3322
|
+
k = j - 6;
|
|
3323
|
+
valid = source.slice(k, j + 1).toLowerCase() === '@import';
|
|
3748
3324
|
}
|
|
3749
3325
|
else {
|
|
3750
3326
|
k = startIndex;
|
|
3751
3327
|
}
|
|
3752
3328
|
if (valid) {
|
|
3753
|
-
let l = i, revised =
|
|
3329
|
+
let l = i, revised = SourceMap.removeSourceMappingURL(host.getUTF8String(asset))[0];
|
|
3754
3330
|
for (let ch; l < length; ++l) {
|
|
3755
3331
|
if ((ch = source[l]) === ';' || ch === '\n') {
|
|
3756
3332
|
break;
|
|
3757
3333
|
}
|
|
3758
3334
|
}
|
|
3759
|
-
const layer = this.replaceContent(revised, source.
|
|
3335
|
+
const layer = this.replaceContent(revised, source.slice(k, l + 1), "text/css");
|
|
3760
3336
|
if (layer) {
|
|
3761
3337
|
revised = layer;
|
|
3762
3338
|
}
|
|
3763
3339
|
revised = this.processUrl(host, file, this.removeServerRoot(revised), type, asset) || revised;
|
|
3764
|
-
source =
|
|
3340
|
+
source = spliceString(source, k, l + 1, revised, pattern);
|
|
3765
3341
|
length = source.length;
|
|
3766
3342
|
if (file.watch) {
|
|
3767
3343
|
related.push(asset);
|
|
3768
|
-
if (!
|
|
3344
|
+
if (!existsFlag(asset.flags)) {
|
|
3769
3345
|
asset.flags |= 8;
|
|
3770
3346
|
}
|
|
3771
3347
|
}
|
|
@@ -3791,7 +3367,7 @@ class ChromeDocument extends Document {
|
|
|
3791
3367
|
}
|
|
3792
3368
|
}
|
|
3793
3369
|
else if (!asset.invalid) {
|
|
3794
|
-
fullUrl = asset.inlineBase64 ||=
|
|
3370
|
+
fullUrl = asset.inlineBase64 ||= randomUUID();
|
|
3795
3371
|
}
|
|
3796
3372
|
if (url !== fullUrl) {
|
|
3797
3373
|
setOutputURL(fullUrl, asset);
|
|
@@ -3824,7 +3400,7 @@ class ChromeDocument extends Document {
|
|
|
3824
3400
|
if (value) {
|
|
3825
3401
|
const index = value.indexOf(ChromeDocument.INTERNAL_ASSIGNUUID);
|
|
3826
3402
|
if (index !== -1) {
|
|
3827
|
-
target[attr] =
|
|
3403
|
+
target[attr] = spliceString(value, index, index + ChromeDocument.INTERNAL_ASSIGNUUID.length, this.formatLocation(attr, nameExt));
|
|
3828
3404
|
modified.push(attr);
|
|
3829
3405
|
return true;
|
|
3830
3406
|
}
|
|
@@ -3835,15 +3411,27 @@ class ChromeDocument extends Document {
|
|
|
3835
3411
|
checkAttribute('pathname');
|
|
3836
3412
|
return modified;
|
|
3837
3413
|
}
|
|
3414
|
+
writeSourceMap(host, file, data, uri, hash) {
|
|
3415
|
+
if (!uri && (uri = file.localUri)) {
|
|
3416
|
+
hash ||= file.hash;
|
|
3417
|
+
}
|
|
3418
|
+
else {
|
|
3419
|
+
return;
|
|
3420
|
+
}
|
|
3421
|
+
const value = Document.writeSourceMap(uri, data, { hash, emptySources: !!this.productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
3422
|
+
if (value) {
|
|
3423
|
+
host.add(value, file, FILE_TYPE.SOURCEMAP);
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3838
3426
|
formatLocation(attr, nameExt) {
|
|
3839
3427
|
const format = this.formatMap || this.module.format;
|
|
3840
|
-
if (
|
|
3428
|
+
if (format) {
|
|
3841
3429
|
const pattern = nameExt && nameExt in format ? format[nameExt] : format.uuid;
|
|
3842
|
-
if (
|
|
3843
|
-
return
|
|
3430
|
+
if (pattern && isString(pattern[attr])) {
|
|
3431
|
+
return randomString(pattern[attr], pattern.dictionary);
|
|
3844
3432
|
}
|
|
3845
3433
|
}
|
|
3846
|
-
return
|
|
3434
|
+
return randomUUID();
|
|
3847
3435
|
}
|
|
3848
3436
|
createTransformOptions(host, file, mimeType, source = {}) {
|
|
3849
3437
|
if (typeof source === 'string') {
|
|
@@ -3856,7 +3444,7 @@ class ChromeDocument extends Document {
|
|
|
3856
3444
|
case "text/css":
|
|
3857
3445
|
Object.assign(metadata, this.config);
|
|
3858
3446
|
default:
|
|
3859
|
-
if ((
|
|
3447
|
+
if (isPlainObject(file.metadata)) {
|
|
3860
3448
|
Object.assign(metadata, file.metadata);
|
|
3861
3449
|
}
|
|
3862
3450
|
break;
|
|
@@ -3876,17 +3464,17 @@ class ChromeDocument extends Document {
|
|
|
3876
3464
|
options.getSourceFiles = this.locateSourceFiles(file, source.code, source.contentFiles || (localUri ? host.contentToAppend.get(localUri) : undefined));
|
|
3877
3465
|
}
|
|
3878
3466
|
}
|
|
3879
|
-
if ((!this.productionRelease || this.productionIncremental) && !
|
|
3467
|
+
if ((!this.productionRelease || this.productionIncremental) && !modifiedFlag(file.flags)) {
|
|
3880
3468
|
options.cacheData = { uri: !file.exported ? uri : undefined, etag: !file.modified ? file.etag : undefined, encoding: file.encoding };
|
|
3881
3469
|
}
|
|
3882
3470
|
return options;
|
|
3883
3471
|
}
|
|
3884
3472
|
addSessionData(item, key, data, { timeout = 0, template = false } = {}) {
|
|
3885
|
-
if (
|
|
3473
|
+
if (isObject(data) || template && data != null) {
|
|
3886
3474
|
if (timeout === 0) {
|
|
3887
3475
|
const cache = this.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
|
|
3888
3476
|
if (cache) {
|
|
3889
|
-
timeout =
|
|
3477
|
+
timeout = ClientDb.getTimeout(cache);
|
|
3890
3478
|
}
|
|
3891
3479
|
}
|
|
3892
3480
|
if (timeout > 0) {
|
|
@@ -3897,6 +3485,32 @@ class ChromeDocument extends Document {
|
|
|
3897
3485
|
}
|
|
3898
3486
|
}
|
|
3899
3487
|
}
|
|
3488
|
+
#replaceCss(file) {
|
|
3489
|
+
const sanitizeCss = (map) => {
|
|
3490
|
+
for (const id in map) {
|
|
3491
|
+
map[id] = this.removeServerRoot(map[id]);
|
|
3492
|
+
}
|
|
3493
|
+
};
|
|
3494
|
+
if (file.inlineUrlMap) {
|
|
3495
|
+
sanitizeCss(file.inlineUrlMap);
|
|
3496
|
+
}
|
|
3497
|
+
if (file.inlineUrlCloudMap) {
|
|
3498
|
+
sanitizeCss(file.inlineUrlCloudMap);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
#replaceHtml(source, { productionRelease, contentMap }, cssMap) {
|
|
3502
|
+
const finalizeHtml = (value, data) => {
|
|
3503
|
+
for (const id in data) {
|
|
3504
|
+
value = value.replace(new RegExp(escapePattern(id), 'g'), data[id]);
|
|
3505
|
+
}
|
|
3506
|
+
return value;
|
|
3507
|
+
};
|
|
3508
|
+
if (cssMap) {
|
|
3509
|
+
source = finalizeHtml(source, cssMap);
|
|
3510
|
+
}
|
|
3511
|
+
source = finalizeHtml(source, contentMap);
|
|
3512
|
+
return productionRelease ? this.removeServerRoot(source) : source;
|
|
3513
|
+
}
|
|
3900
3514
|
get elements() {
|
|
3901
3515
|
if (this._elements) {
|
|
3902
3516
|
return this._elements;
|
|
@@ -3908,13 +3522,13 @@ class ChromeDocument extends Document {
|
|
|
3908
3522
|
for (const item of this.assets) {
|
|
3909
3523
|
const { element, id, flags } = item;
|
|
3910
3524
|
if (element) {
|
|
3911
|
-
if (restartable && id && !
|
|
3525
|
+
if (restartable && id && !cloneFlag(flags)) {
|
|
3912
3526
|
const backup = idMap[id];
|
|
3913
3527
|
if (backup) {
|
|
3914
|
-
elements.add(item.element =
|
|
3528
|
+
elements.add(item.element = cloneObject(backup, true));
|
|
3915
3529
|
continue;
|
|
3916
3530
|
}
|
|
3917
|
-
idMap[id] =
|
|
3531
|
+
idMap[id] = cloneObject(element, true);
|
|
3918
3532
|
}
|
|
3919
3533
|
elements.add(element);
|
|
3920
3534
|
}
|
|
@@ -3939,15 +3553,16 @@ class ChromeDocument extends Document {
|
|
|
3939
3553
|
const host = this.host;
|
|
3940
3554
|
if (host) {
|
|
3941
3555
|
const items = host.getDataSourceItems(this);
|
|
3942
|
-
return this._dataSource = host.restartable || this.watching ? items.map(item =>
|
|
3556
|
+
return this._dataSource = host.restartable || this.watching ? items.map(item => cloneObject(item, true)) : items;
|
|
3943
3557
|
}
|
|
3944
3558
|
return [];
|
|
3945
3559
|
}
|
|
3946
3560
|
get sessionKey() {
|
|
3947
|
-
return this._sessionKey ||=
|
|
3561
|
+
return this._sessionKey ||= randomUUID();
|
|
3948
3562
|
}
|
|
3949
3563
|
get settings() {
|
|
3950
3564
|
return this.module.settings ||= {};
|
|
3951
3565
|
}
|
|
3952
3566
|
}
|
|
3567
|
+
|
|
3953
3568
|
module.exports = ChromeDocument;
|