@pi-r/chrome 0.11.3 → 0.12.1
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 +426 -0
- package/index.d.ts +1 -1
- package/index.js +424 -798
- package/package.json +5 -8
- 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})\\))?(.*)$`, 'si')
|
|
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,12 +118,6 @@ 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)) {
|
|
@@ -193,7 +139,7 @@ function hasCondition(data, condition) {
|
|
|
193
139
|
if (items.length > 0 && !isSpace(match[0][0])) {
|
|
194
140
|
return false;
|
|
195
141
|
}
|
|
196
|
-
items.push([match[1],
|
|
142
|
+
items.push([match[1], trimQuote(match[2]), match[3] ? trimQuote(match[3]) : '']);
|
|
197
143
|
}
|
|
198
144
|
REGEXP_TEMPLATECOMPARISON.lastIndex = 0;
|
|
199
145
|
const length = items.length;
|
|
@@ -256,9 +202,7 @@ function hasCondition(data, condition) {
|
|
|
256
202
|
return false;
|
|
257
203
|
}
|
|
258
204
|
function checkConditionBranch(data, value) {
|
|
259
|
-
REGEXP_TEMPLATEELSEIF
|
|
260
|
-
let match;
|
|
261
|
-
while (match = REGEXP_TEMPLATEELSEIF.exec(value)) {
|
|
205
|
+
for (const match of value.matchAll(REGEXP_TEMPLATEELSEIF)) {
|
|
262
206
|
if (hasCondition(data, match[1])) {
|
|
263
207
|
return match;
|
|
264
208
|
}
|
|
@@ -357,109 +301,43 @@ function collectBaseUrl(asset, baseUrl) {
|
|
|
357
301
|
}
|
|
358
302
|
return result;
|
|
359
303
|
}
|
|
360
|
-
function createHash(host, file, hash, bufferMap) {
|
|
361
|
-
const { filename, localUri } = file;
|
|
362
|
-
try {
|
|
363
|
-
const buffer = localUri && bufferMap[localUri] || getBuffer(file, localUri);
|
|
364
|
-
if (buffer) {
|
|
365
|
-
const [algorithm, length] = (0, util_1.getHashData)(hash);
|
|
366
|
-
const value = algorithm ? Document.asHash(buffer, algorithm, { encoding: file.encoding }) : '';
|
|
367
|
-
if (value) {
|
|
368
|
-
if (localUri) {
|
|
369
|
-
bufferMap[localUri] = buffer;
|
|
370
|
-
}
|
|
371
|
-
host.rename(file, (0, util_1.appendSuffix)(filename, length > 0 ? value.substring(0, length) : value));
|
|
372
|
-
return file.filename;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
throw (0, types_1.errorMessage)('hash', 'Source not found', filename);
|
|
376
|
-
}
|
|
377
|
-
catch (err) {
|
|
378
|
-
host.writeFail(["Unable to read file", filename], err, 32);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
function replaceCss(instance, file) {
|
|
382
|
-
if (file.inlineUrlMap) {
|
|
383
|
-
sanitizeCss(instance, file.inlineUrlMap);
|
|
384
|
-
}
|
|
385
|
-
if (file.inlineUrlCloudMap) {
|
|
386
|
-
sanitizeCss(instance, file.inlineUrlCloudMap);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
function sanitizeCss(instance, map) {
|
|
390
|
-
for (const id in map) {
|
|
391
|
-
map[id] = instance.removeServerRoot(map[id]);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
function replaceHtml(instance, source, { productionRelease, contentMap }, cssMap) {
|
|
395
|
-
if (cssMap) {
|
|
396
|
-
source = finalizeHtml(source, cssMap);
|
|
397
|
-
}
|
|
398
|
-
source = finalizeHtml(source, contentMap);
|
|
399
|
-
return productionRelease ? instance.removeServerRoot(source) : source;
|
|
400
|
-
}
|
|
401
|
-
function finalizeHtml(value, data) {
|
|
402
|
-
for (const id in data) {
|
|
403
|
-
value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
|
|
404
|
-
}
|
|
405
|
-
return value;
|
|
406
|
-
}
|
|
407
|
-
function loadLocalFile(instance, pathname, encoding, out) {
|
|
408
|
-
let content;
|
|
409
|
-
if (out) {
|
|
410
|
-
content = fs.readFileSync(pathname, (0, types_1.getEncoding)(encoding));
|
|
411
|
-
out.content = content;
|
|
412
|
-
}
|
|
413
|
-
const ext = path.extname(pathname).substring(1).toLowerCase();
|
|
414
|
-
if (ext === 'cjs') {
|
|
415
|
-
return require(pathname);
|
|
416
|
-
}
|
|
417
|
-
const result = instance.tryParse(content || fs.readFileSync(pathname, (0, types_1.getEncoding)(encoding)), ext);
|
|
418
|
-
if (result != null) {
|
|
419
|
-
return result;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
function removeElement(instance, domBase, item, element) {
|
|
423
|
-
if (item.removeEmpty || item.type === 'display') {
|
|
424
|
-
element ||= new dom_1.HtmlElement(instance.moduleName, item.element);
|
|
425
|
-
element.remove = true;
|
|
426
|
-
if (!domBase.write(element)) {
|
|
427
|
-
instance.writeFail('Unable to remove element', errorHtml(item.element), { type: 4 });
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
304
|
function removeWatchReload(item) {
|
|
432
|
-
if (
|
|
305
|
+
if (isObject(item.watch) && 'reload' in item.watch) {
|
|
433
306
|
delete item.watch.reload;
|
|
434
307
|
}
|
|
435
308
|
}
|
|
436
|
-
|
|
437
|
-
removeElement(instance, domBase, item);
|
|
438
|
-
const pkg = getPackageName(err);
|
|
439
|
-
if (pkg && instance.checkPackage(err, pkg)) {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
instance.writeFail(["Invalid credentials", item.source], err);
|
|
443
|
-
}
|
|
444
|
-
const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
|
|
445
|
-
const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
|
|
446
|
-
const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
|
|
447
|
-
const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri ||= item.localUri) && Document.isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
|
|
448
|
-
const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
|
|
309
|
+
const hasSourceMap = (metadata, value) => isObject(metadata) && metadata.__sourcemap__ === value;
|
|
449
310
|
const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
|
|
450
311
|
const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
|
|
451
312
|
const isImage = (value) => typeof value === 'string' && value.startsWith('image/') && value !== "image/svg+xml";
|
|
452
313
|
const isRemoved = (item) => item.exclude === true || isBundled(item.bundleIndex);
|
|
453
|
-
const isUnedited = (item) => !item.attributes && !item.inlineContent && !item.srcSet && !item.element.dynamic && item.element.textContent === undefined && (!item.uri && !isBundled(item.bundleIndex, true) ||
|
|
454
|
-
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);
|
|
455
316
|
const findFont = (value) => value && (Array.isArray(value) ? value : [value]).find(format => isFont(format));
|
|
456
|
-
const getEndIndex = (match) => match.index + match[0].length;
|
|
457
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, ' ');
|
|
458
319
|
const validateDir = (value) => path.isAbsolute(value) && Document.isDir(value) ? value : '';
|
|
459
320
|
const valueAsString = (value, delimiter) => Array.isArray(value) && !value.some(child => typeof child === 'object') ? value.join(delimiter) : Document.asString(value);
|
|
460
|
-
const errorHtml = ({ tagName, tagIndex = -1 }) =>
|
|
461
|
-
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);
|
|
462
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
|
+
}
|
|
463
341
|
class ChromeDocument extends Document {
|
|
464
342
|
static [kChrome] = true;
|
|
465
343
|
static INTERNAL_ASSIGNUUID = "__assign__";
|
|
@@ -501,21 +379,20 @@ class ChromeDocument extends Document {
|
|
|
501
379
|
}
|
|
502
380
|
static async finalize(instance) {
|
|
503
381
|
if (instance.aborted) {
|
|
504
|
-
return
|
|
382
|
+
return createAbortError(true);
|
|
505
383
|
}
|
|
506
384
|
const startTime = process.hrtime();
|
|
507
385
|
if (instance.Db && await instance.Db.commit()) {
|
|
508
386
|
instance.Db.writeTimeElapsed('DB', ["Transactions were committed", instance.Db.moduleName], startTime, { ...Document.LOG_STYLE_SUCCESS, type: 65536 });
|
|
509
387
|
}
|
|
510
|
-
const
|
|
511
|
-
const processing = { host: this, startTime, hashed: new Set(), contentMap: {}, bufferMap: {}, cacheMiss: [], productionRelease: productionRelease ? true : undefined };
|
|
388
|
+
const processing = new SessionOutput(this, startTime, instance.productionRelease);
|
|
512
389
|
const htmlFile = instance.htmlFile;
|
|
513
390
|
const outHtml = !!htmlFile && !isIgnored(htmlFile, true);
|
|
514
391
|
if (instance.dataSource.length === 0 && outHtml) {
|
|
515
392
|
const incremental = htmlFile.incremental ?? this.incremental;
|
|
516
393
|
if (incremental === 'etag' || incremental === 'exists') {
|
|
517
394
|
const fetched = this.fetchedAssets;
|
|
518
|
-
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))) {
|
|
519
396
|
let hint = '';
|
|
520
397
|
switch (incremental) {
|
|
521
398
|
case 'etag': {
|
|
@@ -542,7 +419,7 @@ class ChromeDocument extends Document {
|
|
|
542
419
|
break;
|
|
543
420
|
}
|
|
544
421
|
try {
|
|
545
|
-
fs.writeFileSync(htmlFile.localUri, buffer,
|
|
422
|
+
fs.writeFileSync(htmlFile.localUri, buffer, getEncoding(htmlFile.encoding));
|
|
546
423
|
htmlFile.buffer = buffer;
|
|
547
424
|
htmlFile.sourceUTF8 = undefined;
|
|
548
425
|
}
|
|
@@ -578,7 +455,7 @@ class ChromeDocument extends Document {
|
|
|
578
455
|
}
|
|
579
456
|
}
|
|
580
457
|
}
|
|
581
|
-
return result || this.copiedAssets.includes(item) && (!
|
|
458
|
+
return result || this.copiedAssets.includes(item) && (!isEmpty(item.bundleId) || !isEmpty(item.trailingContent));
|
|
582
459
|
};
|
|
583
460
|
const js = instance.jsFiles.filter(item => wasModified(item) || !!item.imports);
|
|
584
461
|
const css = instance.cssFiles.filter(wasModified);
|
|
@@ -605,27 +482,27 @@ class ChromeDocument extends Document {
|
|
|
605
482
|
if (instance.editing.length > 0) {
|
|
606
483
|
await instance.applyTransforms(processing);
|
|
607
484
|
if (instance.aborted) {
|
|
608
|
-
return
|
|
485
|
+
return createAbortError(true);
|
|
609
486
|
}
|
|
610
487
|
}
|
|
611
|
-
if (productionRelease) {
|
|
488
|
+
if (processing.productionRelease) {
|
|
612
489
|
instance.setProductionAttributes(processing);
|
|
613
490
|
}
|
|
614
491
|
if (outHtml) {
|
|
615
492
|
await instance.rewriteHtml(processing);
|
|
616
493
|
}
|
|
617
|
-
return this.aborted ? Promise.reject(
|
|
494
|
+
return this.aborted ? Promise.reject(createAbortError()) : super.finalize.call(this, instance);
|
|
618
495
|
}
|
|
619
496
|
static async cleanup(instance) {
|
|
620
497
|
if (instance.aborted) {
|
|
621
|
-
return
|
|
498
|
+
return createAbortError(true);
|
|
622
499
|
}
|
|
623
500
|
if (this.Watch) {
|
|
624
501
|
const related = instance.related;
|
|
625
502
|
let includes;
|
|
626
503
|
for (const asset of instance.assets) {
|
|
627
504
|
if (asset.watch && (includes = related.get(asset))) {
|
|
628
|
-
if (!
|
|
505
|
+
if (!isPlainObject(asset.watch)) {
|
|
629
506
|
asset.watch = {};
|
|
630
507
|
}
|
|
631
508
|
const items = new Set((asset.watch.assets || []));
|
|
@@ -648,12 +525,12 @@ class ChromeDocument extends Document {
|
|
|
648
525
|
}
|
|
649
526
|
}
|
|
650
527
|
const productionRelease = instance.productionRelease;
|
|
651
|
-
if (
|
|
528
|
+
if (isString(productionRelease)) {
|
|
652
529
|
const errorDirectory = (value) => {
|
|
653
|
-
instance.writeFail(["Unable to read directory", instance.moduleName],
|
|
530
|
+
instance.writeFail(["Unable to read directory", instance.moduleName], errorMessage('production', 'Invalid directory', value), 32);
|
|
654
531
|
};
|
|
655
532
|
const errorAccess = (value) => {
|
|
656
|
-
instance.writeFail(["Unable to write directory", instance.moduleName],
|
|
533
|
+
instance.writeFail(["Unable to write directory", instance.moduleName], errorMessage('production', "Unsupported access", value), 8192);
|
|
657
534
|
};
|
|
658
535
|
const errorMove = (err) => {
|
|
659
536
|
instance.writeFail(["Unable to move file", instance.moduleName], err, { type: 32, fatal: true });
|
|
@@ -696,7 +573,7 @@ class ChromeDocument extends Document {
|
|
|
696
573
|
try {
|
|
697
574
|
let destDir = target[1];
|
|
698
575
|
if (i !== start && !Document.createDir(destDir = path.join(destDir, ...subDir.slice(i, start)))) {
|
|
699
|
-
throw
|
|
576
|
+
throw errorMessage('production', destDir, 'create');
|
|
700
577
|
}
|
|
701
578
|
const dest = path.join(destDir, subDir.at(-1));
|
|
702
579
|
Document.renameFile(src, dest);
|
|
@@ -744,7 +621,7 @@ class ChromeDocument extends Document {
|
|
|
744
621
|
this.delete(value);
|
|
745
622
|
}
|
|
746
623
|
else {
|
|
747
|
-
errorMove(
|
|
624
|
+
errorMove(errorMessage('production', path.join(this.baseDirectory, value), 'move'));
|
|
748
625
|
}
|
|
749
626
|
}
|
|
750
627
|
}
|
|
@@ -761,7 +638,7 @@ class ChromeDocument extends Document {
|
|
|
761
638
|
}
|
|
762
639
|
static sanitizeAssets(assets, exclusions = []) {
|
|
763
640
|
for (const item of assets) {
|
|
764
|
-
if (
|
|
641
|
+
if (ignoreFlag(item.flags)) {
|
|
765
642
|
continue;
|
|
766
643
|
}
|
|
767
644
|
for (const attr in item) {
|
|
@@ -827,20 +704,18 @@ class ChromeDocument extends Document {
|
|
|
827
704
|
_cloudUrlMap;
|
|
828
705
|
_cloudUploaded;
|
|
829
706
|
_cloudEndpoint;
|
|
830
|
-
_idMap =
|
|
707
|
+
_idMap = Object.create(null);
|
|
831
708
|
_editing = [];
|
|
832
|
-
_queryMap = new Map();
|
|
833
|
-
_selectorMap = new Map();
|
|
834
709
|
init(assets, config) {
|
|
835
710
|
assets.sort((a, b) => {
|
|
836
|
-
if (!
|
|
711
|
+
if (!isEmpty(a.bundleId) && a.bundleId === b.bundleId) {
|
|
837
712
|
return b.bundleIndex - a.bundleIndex;
|
|
838
713
|
}
|
|
839
714
|
return 0;
|
|
840
715
|
});
|
|
841
716
|
const cloud = [];
|
|
842
717
|
for (const item of assets) {
|
|
843
|
-
if (
|
|
718
|
+
if (ignoreFlag(item.flags)) {
|
|
844
719
|
continue;
|
|
845
720
|
}
|
|
846
721
|
if (item.trailingContent) {
|
|
@@ -904,7 +779,7 @@ class ChromeDocument extends Document {
|
|
|
904
779
|
target.useUnsafeHtmlReplace = useUnsafeReplace;
|
|
905
780
|
target.useUnsafeCssReplace = useUnsafeReplace;
|
|
906
781
|
}
|
|
907
|
-
else if (
|
|
782
|
+
else if (isArray(useUnsafeReplace)) {
|
|
908
783
|
target.useUnsafeHtmlReplace = useUnsafeReplace.includes('html');
|
|
909
784
|
target.useUnsafeCssReplace = useUnsafeReplace.includes('css');
|
|
910
785
|
}
|
|
@@ -913,26 +788,26 @@ class ChromeDocument extends Document {
|
|
|
913
788
|
if (baseUrl) {
|
|
914
789
|
try {
|
|
915
790
|
const { origin, pathname } = new URL(this.baseUrl = baseUrl);
|
|
916
|
-
this.baseDirectory = origin + pathname.
|
|
791
|
+
this.baseDirectory = origin + pathname.slice(0, pathname.lastIndexOf('/') + 1);
|
|
917
792
|
}
|
|
918
793
|
catch {
|
|
919
794
|
}
|
|
920
795
|
}
|
|
921
|
-
if (
|
|
796
|
+
if (isString(productionRelease)) {
|
|
922
797
|
this.productionRelease = Document.normalizePath(productionRelease, 2);
|
|
923
798
|
const baseDir = Document.normalizePath(this.productionRelease, 1 | 2);
|
|
924
799
|
let baseMap;
|
|
925
800
|
found: {
|
|
926
801
|
for (const map of [this.getUserSettings()?.server_root, this.settings.server_root]) {
|
|
927
802
|
for (const pathname in map) {
|
|
928
|
-
if (Document.normalizePath(pathname, 1 | 2) === baseDir &&
|
|
803
|
+
if (Document.normalizePath(pathname, 1 | 2) === baseDir && map[pathname]) {
|
|
929
804
|
baseMap = map[pathname];
|
|
930
805
|
break found;
|
|
931
806
|
}
|
|
932
807
|
}
|
|
933
808
|
}
|
|
934
809
|
}
|
|
935
|
-
this.serverRootMapping =
|
|
810
|
+
this.serverRootMapping = serverRootMapping ? baseMap ? Object.assign(baseMap, serverRootMapping) : serverRootMapping : baseMap;
|
|
936
811
|
}
|
|
937
812
|
else if (productionRelease) {
|
|
938
813
|
this.productionRelease = true;
|
|
@@ -940,35 +815,33 @@ class ChromeDocument extends Document {
|
|
|
940
815
|
if (productionIncremental) {
|
|
941
816
|
this.productionIncremental = true;
|
|
942
817
|
}
|
|
943
|
-
if (
|
|
818
|
+
if (sanitizeFramework) {
|
|
944
819
|
this.sanitizeFramework = sanitizeFramework;
|
|
945
820
|
}
|
|
946
|
-
if (
|
|
821
|
+
if (templateMap) {
|
|
947
822
|
this.templateMap = templateMap;
|
|
948
823
|
}
|
|
949
|
-
if (
|
|
824
|
+
if (userAgentData) {
|
|
950
825
|
this.userAgentData = userAgentData;
|
|
951
826
|
}
|
|
952
|
-
if (
|
|
827
|
+
if (isObject(cache) && 'transform' in cache) {
|
|
953
828
|
this.customize({ transform: cache.transform });
|
|
954
829
|
}
|
|
955
|
-
|
|
956
|
-
imports = undefined;
|
|
957
|
-
}
|
|
830
|
+
imports = config.imports;
|
|
958
831
|
}
|
|
959
832
|
super.init(assets, config);
|
|
960
833
|
const mimeMap = this._mimeMap;
|
|
961
834
|
if (mimeMap) {
|
|
962
835
|
if ('imports' in mimeMap) {
|
|
963
836
|
const imported = mimeMap.imports;
|
|
964
|
-
if (
|
|
837
|
+
if (isPlainObject(imported)) {
|
|
965
838
|
imports = imports ? Object.assign(imported, imports) : imported;
|
|
966
839
|
}
|
|
967
840
|
delete mimeMap.imports;
|
|
968
841
|
}
|
|
969
842
|
if ('format' in mimeMap) {
|
|
970
843
|
const format = mimeMap.format;
|
|
971
|
-
if (
|
|
844
|
+
if (isObject(format)) {
|
|
972
845
|
this.formatMap = 'pathname' in format || 'filename' in format || 'dictionary' in format ? { uuid: format } : format;
|
|
973
846
|
}
|
|
974
847
|
else {
|
|
@@ -997,7 +870,7 @@ class ChromeDocument extends Document {
|
|
|
997
870
|
const settings = this.templateMap[type];
|
|
998
871
|
for (const attr in settings) {
|
|
999
872
|
const item = settings[attr];
|
|
1000
|
-
if (
|
|
873
|
+
if (isObject(item) && name in item) {
|
|
1001
874
|
const options = this.loadConfig(item, name);
|
|
1002
875
|
if (options) {
|
|
1003
876
|
return [attr, options, this.loadConfig(item, name + '-output')];
|
|
@@ -1023,11 +896,12 @@ class ChromeDocument extends Document {
|
|
|
1023
896
|
restart() {
|
|
1024
897
|
ChromeDocument.sanitizeAssets(this.assets);
|
|
1025
898
|
this._elements = null;
|
|
899
|
+
this._idMap = Object.create(null);
|
|
1026
900
|
this._dataSource = null;
|
|
1027
901
|
}
|
|
1028
902
|
async using(data) {
|
|
1029
903
|
if (this.aborted) {
|
|
1030
|
-
return
|
|
904
|
+
return createAbortError(true);
|
|
1031
905
|
}
|
|
1032
906
|
const file = data.file;
|
|
1033
907
|
if (file.editing) {
|
|
@@ -1055,7 +929,7 @@ class ChromeDocument extends Document {
|
|
|
1055
929
|
if (output.map) {
|
|
1056
930
|
const uri = Document.writeSourceMap(localUri, output, { mimeType, hash, emptySources: productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
1057
931
|
if (uri) {
|
|
1058
|
-
host.add(uri, file,
|
|
932
|
+
host.add(uri, file, FILE_TYPE.SOURCEMAP);
|
|
1059
933
|
}
|
|
1060
934
|
}
|
|
1061
935
|
file.modified = true;
|
|
@@ -1116,20 +990,20 @@ class ChromeDocument extends Document {
|
|
|
1116
990
|
};
|
|
1117
991
|
let to;
|
|
1118
992
|
if (mimeType.includes('woff')) {
|
|
1119
|
-
if (
|
|
993
|
+
if (hasValue(format, 'truetype')) {
|
|
1120
994
|
to = 'ttf';
|
|
1121
995
|
}
|
|
1122
|
-
else if (
|
|
996
|
+
else if (hasValue(format, 'opentype')) {
|
|
1123
997
|
to = 'otf';
|
|
1124
998
|
}
|
|
1125
999
|
else {
|
|
1126
1000
|
return;
|
|
1127
1001
|
}
|
|
1128
1002
|
}
|
|
1129
|
-
else if (
|
|
1003
|
+
else if (hasValue(format, 'woff')) {
|
|
1130
1004
|
to = 'woff';
|
|
1131
1005
|
}
|
|
1132
|
-
else if (
|
|
1006
|
+
else if (hasValue(format, 'woff2')) {
|
|
1133
1007
|
to = 'woff2';
|
|
1134
1008
|
}
|
|
1135
1009
|
else {
|
|
@@ -1146,7 +1020,7 @@ class ChromeDocument extends Document {
|
|
|
1146
1020
|
if (ext) {
|
|
1147
1021
|
setFormat(ext.startsWith('woff') ? ext : ext === 'otf' ? 'opentype' : 'truetype');
|
|
1148
1022
|
}
|
|
1149
|
-
const output =
|
|
1023
|
+
const output = renameExt(localUri, ext ||= to);
|
|
1150
1024
|
file.mimeType = 'font/' + ext;
|
|
1151
1025
|
fs.writeFile(output, result, err => {
|
|
1152
1026
|
if (!err) {
|
|
@@ -1174,7 +1048,7 @@ class ChromeDocument extends Document {
|
|
|
1174
1048
|
if (trailing) {
|
|
1175
1049
|
let index = trailing.indexOf('?');
|
|
1176
1050
|
if (index !== -1 || (index = trailing.indexOf('#')) !== -1) {
|
|
1177
|
-
trailing = trailing.
|
|
1051
|
+
trailing = trailing.slice(index);
|
|
1178
1052
|
}
|
|
1179
1053
|
else {
|
|
1180
1054
|
trailing = '';
|
|
@@ -1187,12 +1061,12 @@ class ChromeDocument extends Document {
|
|
|
1187
1061
|
this.replaced.push(file);
|
|
1188
1062
|
}
|
|
1189
1063
|
else {
|
|
1190
|
-
const modified = this.processLocation(file,
|
|
1064
|
+
const modified = this.processLocation(file, asExt(file.filename));
|
|
1191
1065
|
if (modified.length > 0) {
|
|
1192
1066
|
if (modified.includes('filename')) {
|
|
1193
1067
|
file.inlineFilename = file.filename;
|
|
1194
1068
|
}
|
|
1195
|
-
|
|
1069
|
+
setInitialValue(file, false);
|
|
1196
1070
|
if (file.hash) {
|
|
1197
1071
|
delete file.hash;
|
|
1198
1072
|
}
|
|
@@ -1210,7 +1084,7 @@ class ChromeDocument extends Document {
|
|
|
1210
1084
|
let localFile;
|
|
1211
1085
|
if (uri && code && (localFile = this.findSourceRoot(uri))) {
|
|
1212
1086
|
const { exported, bundleId } = file;
|
|
1213
|
-
const bundleMain = !
|
|
1087
|
+
const bundleMain = !isEmpty(bundleId) && this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
|
|
1214
1088
|
let output;
|
|
1215
1089
|
if ((index === 1 || exported) && Array.isArray(file.imports)) {
|
|
1216
1090
|
output = this.resolveImports(file, code, bundleMain || file);
|
|
@@ -1226,7 +1100,7 @@ class ChromeDocument extends Document {
|
|
|
1226
1100
|
const type = match[3] || match[5];
|
|
1227
1101
|
const idx = match[1] ? 1 : match[2] ? 2 : 4;
|
|
1228
1102
|
const [a, b] = match.indices[idx];
|
|
1229
|
-
const from =
|
|
1103
|
+
const from = trimQuote(match[idx]);
|
|
1230
1104
|
const quote = output[a];
|
|
1231
1105
|
const relative = /^\.{0,2}\//.test(from);
|
|
1232
1106
|
if (type && /\btype\s*:\s*(["'`])(?:css|json)\1/.test(type)) {
|
|
@@ -1235,7 +1109,7 @@ class ChromeDocument extends Document {
|
|
|
1235
1109
|
if (asset) {
|
|
1236
1110
|
const [relativeUrl, sameDir] = this.getSrcUrl(bundleMain || file, asset);
|
|
1237
1111
|
if (relativeUrl) {
|
|
1238
|
-
output =
|
|
1112
|
+
output = spliceString(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
|
|
1239
1113
|
}
|
|
1240
1114
|
}
|
|
1241
1115
|
}
|
|
@@ -1257,7 +1131,7 @@ class ChromeDocument extends Document {
|
|
|
1257
1131
|
pathname = asset.localUri;
|
|
1258
1132
|
}
|
|
1259
1133
|
if (pathname && Document.isPath(pathname)) {
|
|
1260
|
-
output =
|
|
1134
|
+
output = spliceString(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
|
|
1261
1135
|
}
|
|
1262
1136
|
}
|
|
1263
1137
|
REGEXP_IMPORTMODULE.lastIndex = 0;
|
|
@@ -1277,7 +1151,7 @@ class ChromeDocument extends Document {
|
|
|
1277
1151
|
case "text/css":
|
|
1278
1152
|
if (file.editing) {
|
|
1279
1153
|
const bundleId = file.bundleId;
|
|
1280
|
-
if (!
|
|
1154
|
+
if (!isEmpty(bundleId)) {
|
|
1281
1155
|
for (const asset of this.assets) {
|
|
1282
1156
|
if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
|
|
1283
1157
|
const output = this.processUrl(host, file, source, 'css', asset);
|
|
@@ -1305,12 +1179,12 @@ class ChromeDocument extends Document {
|
|
|
1305
1179
|
return;
|
|
1306
1180
|
}
|
|
1307
1181
|
let bundleMain, modified = false;
|
|
1308
|
-
if (
|
|
1182
|
+
if (isPlainObject(baseFile)) {
|
|
1309
1183
|
bundleMain = baseFile;
|
|
1310
1184
|
}
|
|
1311
1185
|
else {
|
|
1312
1186
|
const bundleId = file.bundleId;
|
|
1313
|
-
if (!
|
|
1187
|
+
if (!isEmpty(bundleId)) {
|
|
1314
1188
|
bundleMain = this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
|
|
1315
1189
|
}
|
|
1316
1190
|
}
|
|
@@ -1346,7 +1220,7 @@ class ChromeDocument extends Document {
|
|
|
1346
1220
|
}
|
|
1347
1221
|
value = found || original;
|
|
1348
1222
|
}
|
|
1349
|
-
code =
|
|
1223
|
+
code = spliceString(code, index, index + placeholder.length, value);
|
|
1350
1224
|
modified = true;
|
|
1351
1225
|
break;
|
|
1352
1226
|
}
|
|
@@ -1365,10 +1239,10 @@ class ChromeDocument extends Document {
|
|
|
1365
1239
|
const supports = match[3]?.trim();
|
|
1366
1240
|
const query = match[4].trim().replace(/;+$/, '');
|
|
1367
1241
|
if (layer || supports || query) {
|
|
1368
|
-
const newline =
|
|
1369
|
-
let result = supports ? `@supports (${supports}) {` + newline : '';
|
|
1242
|
+
const newline = getNewline(source);
|
|
1243
|
+
let result = supports ? `@supports (${normalizeSpace(supports)}) {` + newline : '';
|
|
1370
1244
|
if (query) {
|
|
1371
|
-
result += `@media ${query} {` + newline;
|
|
1245
|
+
result += `@media ${normalizeSpace(query)} {` + newline;
|
|
1372
1246
|
}
|
|
1373
1247
|
if (layer) {
|
|
1374
1248
|
const name = match[2]?.replace(/\s+/g, '');
|
|
@@ -1388,13 +1262,13 @@ class ChromeDocument extends Document {
|
|
|
1388
1262
|
}
|
|
1389
1263
|
}
|
|
1390
1264
|
removeServerRoot(value) {
|
|
1391
|
-
return value.replace(new RegExp('(\\.\\./)*' +
|
|
1265
|
+
return value.replace(new RegExp('(\\.\\./)*' + escapePattern(ChromeDocument.INTERNAL_SERVERROOT), 'g'), '');
|
|
1392
1266
|
}
|
|
1393
1267
|
addCopy(data, saveAs) {
|
|
1394
1268
|
if (data.command && this.host) {
|
|
1395
1269
|
const match = REGEXP_SRCSETSIZE.exec(data.command);
|
|
1396
1270
|
if (match) {
|
|
1397
|
-
return
|
|
1271
|
+
return renameExt(this.host.getLocalUri(data), match[1] + match[2].toLowerCase() + '.' + saveAs);
|
|
1398
1272
|
}
|
|
1399
1273
|
}
|
|
1400
1274
|
}
|
|
@@ -1403,7 +1277,7 @@ class ChromeDocument extends Document {
|
|
|
1403
1277
|
if (output && command && file.element?.outerXml) {
|
|
1404
1278
|
const match = REGEXP_SRCSETSIZE.exec(command);
|
|
1405
1279
|
if (match) {
|
|
1406
|
-
(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());
|
|
1407
1281
|
file.modified = true;
|
|
1408
1282
|
return true;
|
|
1409
1283
|
}
|
|
@@ -1417,7 +1291,7 @@ class ChromeDocument extends Document {
|
|
|
1417
1291
|
if (this.htmlFile) {
|
|
1418
1292
|
const endpoint = instance.getStorage('upload', this.htmlFile.cloudStorage)?.upload?.endpoint;
|
|
1419
1293
|
if (endpoint) {
|
|
1420
|
-
this._cloudEndpoint = new RegExp(
|
|
1294
|
+
this._cloudEndpoint = new RegExp(escapePattern(Document.toPosix(endpoint)) + '/', 'g');
|
|
1421
1295
|
}
|
|
1422
1296
|
}
|
|
1423
1297
|
}
|
|
@@ -1434,7 +1308,7 @@ class ChromeDocument extends Document {
|
|
|
1434
1308
|
const cloudUrl = endpoint ? url.replace(endpoint, '') : url;
|
|
1435
1309
|
file.cloudUrl = cloudUrl;
|
|
1436
1310
|
if (inlineUrlCloud) {
|
|
1437
|
-
const pattern = new RegExp(
|
|
1311
|
+
const pattern = new RegExp(escapePattern(inlineUrlCloud), 'g');
|
|
1438
1312
|
for (const item of this.editing) {
|
|
1439
1313
|
if (item.inlineUrlCloudMap?.[inlineUrlCloud]) {
|
|
1440
1314
|
const source = host.getUTF8String(item);
|
|
@@ -1452,7 +1326,7 @@ class ChromeDocument extends Document {
|
|
|
1452
1326
|
}
|
|
1453
1327
|
async cloudFinalize(state) {
|
|
1454
1328
|
if (this.aborted) {
|
|
1455
|
-
return
|
|
1329
|
+
return createAbortError(true);
|
|
1456
1330
|
}
|
|
1457
1331
|
const { host, instance } = state;
|
|
1458
1332
|
const htmlFile = this.htmlFile;
|
|
@@ -1464,7 +1338,7 @@ class ChromeDocument extends Document {
|
|
|
1464
1338
|
for (const id in this._cloudUrlMap) {
|
|
1465
1339
|
const inlineUrlCloud = item.inlineUrlCloudMap[id];
|
|
1466
1340
|
if (inlineUrlCloud && !this._cloudUploaded.has(id)) {
|
|
1467
|
-
output = (output || source).replace(new RegExp(
|
|
1341
|
+
output = (output || source).replace(new RegExp(escapePattern(id), 'g'), inlineUrlCloud);
|
|
1468
1342
|
state.localStorage.delete(this._cloudUrlMap[id]);
|
|
1469
1343
|
}
|
|
1470
1344
|
}
|
|
@@ -1490,18 +1364,18 @@ class ChromeDocument extends Document {
|
|
|
1490
1364
|
}
|
|
1491
1365
|
}
|
|
1492
1366
|
if (this.aborted) {
|
|
1493
|
-
return
|
|
1367
|
+
return createAbortError(true);
|
|
1494
1368
|
}
|
|
1495
1369
|
}
|
|
1496
1370
|
if (htmlFile) {
|
|
1497
1371
|
checkDocument(htmlFile);
|
|
1498
1372
|
const cloudStorage = htmlFile.cloudStorage;
|
|
1499
|
-
if (
|
|
1373
|
+
if (isArray(cloudStorage)) {
|
|
1500
1374
|
for (const storage of cloudStorage) {
|
|
1501
1375
|
if (instance.hasCredential('storage', storage)) {
|
|
1502
1376
|
const { admin, bucket, upload } = storage;
|
|
1503
1377
|
const website = admin?.configBucket?.website;
|
|
1504
|
-
if (
|
|
1378
|
+
if (isPlainObject(website) && bucket && upload) {
|
|
1505
1379
|
let filename = Document.joinPath(upload.pathname, upload.filename || path.basename(htmlFile.localUri));
|
|
1506
1380
|
if (website.indexPage === true) {
|
|
1507
1381
|
website.indexPage = filename;
|
|
@@ -1545,17 +1419,17 @@ class ChromeDocument extends Document {
|
|
|
1545
1419
|
if (asset.element && isUnedited(asset)) {
|
|
1546
1420
|
continue;
|
|
1547
1421
|
}
|
|
1548
|
-
if (!found &&
|
|
1422
|
+
if (!found && isEqual(main, asset)) {
|
|
1549
1423
|
found = true;
|
|
1550
1424
|
using.push(asset);
|
|
1551
1425
|
}
|
|
1552
1426
|
else if (this.isWatched(asset) ||
|
|
1553
|
-
|
|
1554
|
-
asset.base64 && watch.related.find(item =>
|
|
1555
|
-
|
|
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)) {
|
|
1556
1430
|
using.push(asset);
|
|
1557
1431
|
}
|
|
1558
|
-
else if (current = watch.assets.find(item =>
|
|
1432
|
+
else if (current = watch.assets.find(item => isEqual(item, asset))) {
|
|
1559
1433
|
const { inlineUrlCloud: inlineUrlCloud, initialValue = {} } = current;
|
|
1560
1434
|
if (inlineUrlCloud && inlineUrlCloudMap[inlineUrlCloud] || path.join(initialValue.pathname || asset.pathname, initialValue.filename || asset.filename).includes(ChromeDocument.INTERNAL_ASSIGNUUID)) {
|
|
1561
1435
|
using.push(asset);
|
|
@@ -1578,7 +1452,7 @@ class ChromeDocument extends Document {
|
|
|
1578
1452
|
}
|
|
1579
1453
|
const asset = watch.bundleMain || watch.assets[0];
|
|
1580
1454
|
const pathname = (asset.cloudUrl || asset.relativeUrl || '').split('?')[0];
|
|
1581
|
-
const next = assets?.find(item =>
|
|
1455
|
+
const next = assets?.find(item => isEqual(item, asset));
|
|
1582
1456
|
let value, search;
|
|
1583
1457
|
if (next) {
|
|
1584
1458
|
if (next.cloudUrl) {
|
|
@@ -1595,7 +1469,7 @@ class ChromeDocument extends Document {
|
|
|
1595
1469
|
}
|
|
1596
1470
|
search ??= restoreSearchParams(asset.url?.search);
|
|
1597
1471
|
status &&= status.filter(item => item.type >= 1 && item.type <= 3);
|
|
1598
|
-
watch.send(
|
|
1472
|
+
watch.send(WATCH_EVENT.MODIFIED, {
|
|
1599
1473
|
action: pathname && watch.hot && !watch.main ? 'hot' : '',
|
|
1600
1474
|
type: asset.mimeType,
|
|
1601
1475
|
value,
|
|
@@ -1625,7 +1499,7 @@ class ChromeDocument extends Document {
|
|
|
1625
1499
|
break;
|
|
1626
1500
|
case 'img':
|
|
1627
1501
|
case 'source':
|
|
1628
|
-
if (
|
|
1502
|
+
if (hasValue(file.format, 'srcset')) {
|
|
1629
1503
|
const srcset = element.getAttribute('srcset');
|
|
1630
1504
|
if (srcset) {
|
|
1631
1505
|
const uri = Document.toPosix(file.uri);
|
|
@@ -1639,13 +1513,13 @@ class ChromeDocument extends Document {
|
|
|
1639
1513
|
if (src && uri === Document.resolvePath(url = Document.toPosix(src), baseUri)) {
|
|
1640
1514
|
items.add(url);
|
|
1641
1515
|
}
|
|
1642
|
-
items.add(uri.startsWith(this.baseDirectory) ? uri.
|
|
1516
|
+
items.add(uri.startsWith(this.baseDirectory) ? uri.slice(this.baseDirectory.length) : uri.replace(baseUri.origin, ''));
|
|
1643
1517
|
}
|
|
1644
1518
|
}
|
|
1645
1519
|
let current = srcset, match;
|
|
1646
1520
|
for (const url of items) {
|
|
1647
1521
|
const resolve = sameOrigin && !Document.isURL(url);
|
|
1648
|
-
const pathname = url.split('/').map(seg =>
|
|
1522
|
+
const pathname = url.split('/').map(seg => escapePattern(seg)).join('/');
|
|
1649
1523
|
const pattern = new RegExp(`(,?\\s*)(${(resolve && !url.startsWith('.') ? `(?:\\.\\./)*\\.\\.${pathname}|` : '') + pathname})(` + (!url.includes('?') ? '(?:(?!,)(?:[^?]|$)[^,]*)|(?!\\?)[^,]*)' : '[^,]*)'), 'g');
|
|
1650
1524
|
while (match = pattern.exec(current)) {
|
|
1651
1525
|
const partial = match[2];
|
|
@@ -1668,7 +1542,8 @@ class ChromeDocument extends Document {
|
|
|
1668
1542
|
return this.templateMap.data?.[name];
|
|
1669
1543
|
}
|
|
1670
1544
|
}
|
|
1671
|
-
setInlinedAttributes(
|
|
1545
|
+
setInlinedAttributes(processing) {
|
|
1546
|
+
const { host, startTime, hashed, contentMap, productionRelease } = processing;
|
|
1672
1547
|
const readBase64 = (item, uuid) => {
|
|
1673
1548
|
if (!contentMap[uuid]) {
|
|
1674
1549
|
try {
|
|
@@ -1686,8 +1561,8 @@ class ChromeDocument extends Document {
|
|
|
1686
1561
|
if (item.inlineBase64) {
|
|
1687
1562
|
readBase64(item, item.inlineBase64);
|
|
1688
1563
|
}
|
|
1689
|
-
else if (!item.invalid &&
|
|
1690
|
-
const uuid =
|
|
1564
|
+
else if (!item.invalid && hasValue(item.format, 'base64')) {
|
|
1565
|
+
const uuid = randomUUID();
|
|
1691
1566
|
if (readBase64(item, uuid)) {
|
|
1692
1567
|
item.inlineBase64 = uuid;
|
|
1693
1568
|
}
|
|
@@ -1695,20 +1570,20 @@ class ChromeDocument extends Document {
|
|
|
1695
1570
|
if (productionRelease) {
|
|
1696
1571
|
const { inlineUrl, inlineUrlCloud, hash } = item;
|
|
1697
1572
|
if (inlineUrl || inlineUrlCloud) {
|
|
1698
|
-
const filename = hash && createHash(
|
|
1573
|
+
const filename = hash && this.createHash(processing, item, hash);
|
|
1699
1574
|
if (filename) {
|
|
1700
1575
|
for (const asset of this.assets) {
|
|
1701
1576
|
const url = inlineUrl ? asset.inlineUrlMap?.[inlineUrl] : asset.inlineUrlCloudMap?.[inlineUrlCloud];
|
|
1702
1577
|
if (url) {
|
|
1703
1578
|
const search = url.indexOf('?');
|
|
1704
|
-
const index = (search !== -1 ? url.
|
|
1579
|
+
const index = (search !== -1 ? url.slice(0, search) : url).lastIndexOf('/');
|
|
1705
1580
|
let result = '';
|
|
1706
1581
|
if (index !== -1) {
|
|
1707
|
-
result = url.
|
|
1582
|
+
result = url.slice(0, index + 1);
|
|
1708
1583
|
}
|
|
1709
1584
|
result += filename;
|
|
1710
1585
|
if (search !== -1) {
|
|
1711
|
-
result += url.
|
|
1586
|
+
result += url.slice(search);
|
|
1712
1587
|
}
|
|
1713
1588
|
if (inlineUrl) {
|
|
1714
1589
|
asset.inlineUrlMap[inlineUrl] = result;
|
|
@@ -1721,7 +1596,7 @@ class ChromeDocument extends Document {
|
|
|
1721
1596
|
}
|
|
1722
1597
|
hashed.add(item);
|
|
1723
1598
|
}
|
|
1724
|
-
else if (hash && (!item.editing || item.imported) && createHash(
|
|
1599
|
+
else if (hash && (!item.editing || item.imported) && this.createHash(processing, item, hash)) {
|
|
1725
1600
|
hashed.add(item);
|
|
1726
1601
|
}
|
|
1727
1602
|
}
|
|
@@ -1731,9 +1606,9 @@ class ChromeDocument extends Document {
|
|
|
1731
1606
|
const host = processing.host;
|
|
1732
1607
|
const sanitizeSource = (item, source) => {
|
|
1733
1608
|
if (processing.productionRelease) {
|
|
1734
|
-
replaceCss(
|
|
1609
|
+
this.#replaceCss(item);
|
|
1735
1610
|
}
|
|
1736
|
-
const output = replaceHtml(
|
|
1611
|
+
const output = this.#replaceHtml(source, processing, item.inlineUrlMap);
|
|
1737
1612
|
if (source !== output) {
|
|
1738
1613
|
item.modified = true;
|
|
1739
1614
|
return output;
|
|
@@ -1768,16 +1643,15 @@ class ChromeDocument extends Document {
|
|
|
1768
1643
|
item.modified = true;
|
|
1769
1644
|
}
|
|
1770
1645
|
source = sanitizeSource(item, source);
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
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"));
|
|
1774
1648
|
if (result) {
|
|
1775
1649
|
item.modified = true;
|
|
1776
1650
|
source = result.code;
|
|
1777
1651
|
}
|
|
1778
1652
|
}
|
|
1779
1653
|
item.sourceUTF8 = source;
|
|
1780
|
-
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)) {
|
|
1781
1655
|
processing.hashed.add(item);
|
|
1782
1656
|
}
|
|
1783
1657
|
}
|
|
@@ -1793,7 +1667,7 @@ class ChromeDocument extends Document {
|
|
|
1793
1667
|
source = output;
|
|
1794
1668
|
item.modified = true;
|
|
1795
1669
|
}
|
|
1796
|
-
if (
|
|
1670
|
+
if (output = await this.transformCss(processing, item, source)) {
|
|
1797
1671
|
source = output;
|
|
1798
1672
|
item.modified = true;
|
|
1799
1673
|
}
|
|
@@ -1821,6 +1695,10 @@ class ChromeDocument extends Document {
|
|
|
1821
1695
|
source = output;
|
|
1822
1696
|
item.modified = true;
|
|
1823
1697
|
}
|
|
1698
|
+
if (output = await this.transformJs(processing, item, source)) {
|
|
1699
|
+
source = output;
|
|
1700
|
+
item.modified = true;
|
|
1701
|
+
}
|
|
1824
1702
|
if (output = this.processUrl(host, item, source, 'js')) {
|
|
1825
1703
|
source = output;
|
|
1826
1704
|
item.modified = true;
|
|
@@ -1842,7 +1720,7 @@ class ChromeDocument extends Document {
|
|
|
1842
1720
|
if (value.map && !target.bundleReplace) {
|
|
1843
1721
|
const output = Document.writeSourceMap(target.localUri, value, { mimeType: "text/css", hash: productionRelease ? target.hash : undefined, emptySources: productionRelease, inlineMap: hasSourceMap(target.metadata, 'inline') });
|
|
1844
1722
|
if (output) {
|
|
1845
|
-
host.add(output, target,
|
|
1723
|
+
host.add(output, target, FILE_TYPE.SOURCEMAP);
|
|
1846
1724
|
}
|
|
1847
1725
|
}
|
|
1848
1726
|
target.modified = true;
|
|
@@ -1862,28 +1740,28 @@ class ChromeDocument extends Document {
|
|
|
1862
1740
|
const localUri = htmlFile.localUri;
|
|
1863
1741
|
this.formatMessage(4, 'HTML', ['Rewriting content...', path.dirname(localUri)]);
|
|
1864
1742
|
let source = host.getUTF8String(htmlFile, localUri), output;
|
|
1865
|
-
const domBase = new
|
|
1743
|
+
const domBase = new DomWriter(moduleName, source, this.elements, { normalize: config.normalizeHtmlOutput, stripComments: config.stripCommentsAndCDATA, ignoreTagGroup: config.ignoreServerCodeBlocks, escapeEntities: config.escapeReservedCharacters });
|
|
1866
1744
|
if (config.useUnsafeHtmlReplace) {
|
|
1867
|
-
domBase.ignoreFlag(
|
|
1745
|
+
domBase.ignoreFlag(IGNORE_FLAG.INTERIOR);
|
|
1868
1746
|
}
|
|
1869
1747
|
if (this.watching) {
|
|
1870
|
-
domBase.ignoreFlag(
|
|
1748
|
+
domBase.ignoreFlag(IGNORE_FLAG.LOCATOR);
|
|
1871
1749
|
}
|
|
1872
|
-
if (
|
|
1750
|
+
if (isString(config.useOriginalHtmlPage)) {
|
|
1873
1751
|
domBase.ignoreTag(config.useOriginalHtmlPage);
|
|
1874
1752
|
}
|
|
1875
|
-
if (
|
|
1753
|
+
if (isArray(config.ignoreServerCodeBlocks)) {
|
|
1876
1754
|
domBase.ignoreTag(config.ignoreServerCodeBlocks);
|
|
1877
1755
|
}
|
|
1878
1756
|
if (processing.productionRelease) {
|
|
1879
|
-
replaceCss(
|
|
1757
|
+
this.#replaceCss(htmlFile);
|
|
1880
1758
|
}
|
|
1881
1759
|
await this.setElementAttributes(processing, domBase);
|
|
1882
1760
|
await this.applyDataSource(processing, domBase);
|
|
1883
1761
|
for (const item of this.assets) {
|
|
1884
1762
|
const element = item.element;
|
|
1885
|
-
if (element && isRemoved(item) && !
|
|
1886
|
-
const domElement = new
|
|
1763
|
+
if (element && isRemoved(item) && !ignoreFlag(item.flags)) {
|
|
1764
|
+
const domElement = new HtmlElement(moduleName, element, item.attributes);
|
|
1887
1765
|
domElement.remove = true;
|
|
1888
1766
|
if (!domBase.write(domElement)) {
|
|
1889
1767
|
this.writeFail('Unable to exclude HTML element', errorHtml(element), 4);
|
|
@@ -1893,13 +1771,13 @@ class ChromeDocument extends Document {
|
|
|
1893
1771
|
source = removeNamespace(moduleName, domBase.modified ? domBase.close() : source, domBase.newline, domBase.getComments());
|
|
1894
1772
|
if (this.sanitizeFramework) {
|
|
1895
1773
|
for (const name of this.sanitizeFramework) {
|
|
1896
|
-
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'), '');
|
|
1897
1775
|
}
|
|
1898
1776
|
}
|
|
1899
1777
|
if (!htmlFile.preserve) {
|
|
1900
1778
|
let match;
|
|
1901
1779
|
while (match = REGEXP_STYLE.exec(source)) {
|
|
1902
|
-
if (output = this.
|
|
1780
|
+
if (output = await this.transformCss(processing, htmlFile, match[5])) {
|
|
1903
1781
|
source = replaceMatch(match, source, match[1] + output + match[6], REGEXP_STYLE);
|
|
1904
1782
|
}
|
|
1905
1783
|
}
|
|
@@ -1908,9 +1786,9 @@ class ChromeDocument extends Document {
|
|
|
1908
1786
|
if (output = this.processUrl(host, htmlFile, source, 'html')) {
|
|
1909
1787
|
source = output;
|
|
1910
1788
|
}
|
|
1911
|
-
source = replaceHtml(
|
|
1912
|
-
if (
|
|
1913
|
-
source =
|
|
1789
|
+
source = this.#replaceHtml(source, processing, htmlFile.inlineUrlMap);
|
|
1790
|
+
if (isString(config.stripCommentsAndCDATA)) {
|
|
1791
|
+
source = DomWriter.getCommentsAndCDATA(source, config.stripCommentsAndCDATA, true, true);
|
|
1914
1792
|
}
|
|
1915
1793
|
if (htmlFile.format) {
|
|
1916
1794
|
const { filename, uri, encoding, metadata } = htmlFile;
|
|
@@ -1932,7 +1810,7 @@ class ChromeDocument extends Document {
|
|
|
1932
1810
|
}
|
|
1933
1811
|
}
|
|
1934
1812
|
if (domBase.failCount > 0) {
|
|
1935
|
-
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 });
|
|
1936
1814
|
}
|
|
1937
1815
|
else {
|
|
1938
1816
|
this.writeTimeProcess('html', `dom-writer: ${domBase.modifyCount} modified (${path.basename(localUri)})`, startTime);
|
|
@@ -1954,12 +1832,12 @@ class ChromeDocument extends Document {
|
|
|
1954
1832
|
async setElementAttributes({ host, startTime, productionRelease }, domBase) {
|
|
1955
1833
|
for (const item of this.assets) {
|
|
1956
1834
|
const { element, inlineContent } = item;
|
|
1957
|
-
if (!element || element.removed || isRemoved(item) || isUnedited(item) ||
|
|
1835
|
+
if (!element || element.removed || isRemoved(item) || isUnedited(item) || ignoreFlag(item.flags) && !processFlag(item.flags)) {
|
|
1958
1836
|
continue;
|
|
1959
1837
|
}
|
|
1960
|
-
const domElement = new
|
|
1838
|
+
const domElement = new HtmlElement(this.moduleName, element, item.attributes);
|
|
1961
1839
|
if (inlineContent) {
|
|
1962
|
-
let [innerXml, sourceMappingURL, inlineMap] =
|
|
1840
|
+
let [innerXml, sourceMappingURL, inlineMap] = SourceMap.removeSourceMappingURL(host.getUTF8String(item).trim());
|
|
1963
1841
|
if (sourceMappingURL && !inlineMap && item.localUri) {
|
|
1964
1842
|
let mapUri = path.resolve(sourceMappingURL = decodeURIComponent(sourceMappingURL));
|
|
1965
1843
|
if (!Document.isPath(mapUri)) {
|
|
@@ -1973,7 +1851,7 @@ class ChromeDocument extends Document {
|
|
|
1973
1851
|
}
|
|
1974
1852
|
else {
|
|
1975
1853
|
let uri = item.relativeUrl;
|
|
1976
|
-
if (
|
|
1854
|
+
if (hasValue(item.format, 'base64')) {
|
|
1977
1855
|
if (item.invalid) {
|
|
1978
1856
|
continue;
|
|
1979
1857
|
}
|
|
@@ -1983,13 +1861,13 @@ class ChromeDocument extends Document {
|
|
|
1983
1861
|
uri = '';
|
|
1984
1862
|
}
|
|
1985
1863
|
}
|
|
1986
|
-
if (uri && !
|
|
1864
|
+
if (uri && !hasValue(item.format, 'crossorigin') && item !== this.htmlFile) {
|
|
1987
1865
|
if (host.Cloud?.getStorage('upload', item.cloudStorage)) {
|
|
1988
|
-
const inlineUrlCloud = item.inlineUrlCloud ||=
|
|
1866
|
+
const inlineUrlCloud = item.inlineUrlCloud ||= randomUUID();
|
|
1989
1867
|
(this.htmlFile.inlineUrlCloudMap ||= {})[inlineUrlCloud] = productionRelease ? this.removeServerRoot(uri) : uri;
|
|
1990
1868
|
uri = inlineUrlCloud;
|
|
1991
1869
|
}
|
|
1992
|
-
if (!
|
|
1870
|
+
if (!hasValue(item.format, 'webbundle')) {
|
|
1993
1871
|
const { bundleIndex, srcSet } = item;
|
|
1994
1872
|
if (bundleIndex === 0 || bundleIndex === -1) {
|
|
1995
1873
|
switch (element.tagName) {
|
|
@@ -2019,7 +1897,7 @@ class ChromeDocument extends Document {
|
|
|
2019
1897
|
const addLog = (suffix, err) => this.addLog(3, err || ('Not detectable image ' + suffix), { source: item.localUri ? path.basename(item.localUri) : item.filename });
|
|
2020
1898
|
if (isImage(item.mimeType) && (buffer = host.getBuffer(item))) {
|
|
2021
1899
|
try {
|
|
2022
|
-
({ width, height } =
|
|
1900
|
+
({ width, height } = imageSize(buffer));
|
|
2023
1901
|
}
|
|
2024
1902
|
catch (err) {
|
|
2025
1903
|
addLog('from buffer', err);
|
|
@@ -2069,21 +1947,56 @@ class ChromeDocument extends Document {
|
|
|
2069
1947
|
dataItems.push(item);
|
|
2070
1948
|
}
|
|
2071
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
|
+
};
|
|
2072
1985
|
const checkObject = (item, data, type) => {
|
|
2073
1986
|
if (item.cascade) {
|
|
2074
|
-
const result = data &&
|
|
1987
|
+
const result = data && cascadeObject(data, item.cascade, data);
|
|
2075
1988
|
if (result !== data) {
|
|
2076
1989
|
data = result;
|
|
2077
1990
|
}
|
|
2078
1991
|
else if (item.fallback !== undefined) {
|
|
2079
1992
|
data = item.fallback;
|
|
2080
1993
|
}
|
|
2081
|
-
else if (!
|
|
1994
|
+
else if (!item.query) {
|
|
2082
1995
|
return null;
|
|
2083
1996
|
}
|
|
2084
1997
|
}
|
|
2085
1998
|
if (data) {
|
|
2086
|
-
if (
|
|
1999
|
+
if (isString(item.query)) {
|
|
2087
2000
|
const pkg = item.query.startsWith('$') ? Document.checkSemVer('jsonpath-plus', 5) ? null : 'jsonpath' : 'jmespath';
|
|
2088
2001
|
try {
|
|
2089
2002
|
if (pkg === 'jmespath') {
|
|
@@ -2105,10 +2018,10 @@ class ChromeDocument extends Document {
|
|
|
2105
2018
|
}
|
|
2106
2019
|
}
|
|
2107
2020
|
if (type && !item.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
|
|
2108
|
-
|
|
2021
|
+
coerceObject(data);
|
|
2109
2022
|
}
|
|
2110
2023
|
}
|
|
2111
|
-
return Array.isArray(data) ? data :
|
|
2024
|
+
return Array.isArray(data) ? data : isObject(data) ? [data] : null;
|
|
2112
2025
|
};
|
|
2113
2026
|
const setElements = async (sourceSet) => {
|
|
2114
2027
|
const db = this.Db;
|
|
@@ -2129,7 +2042,7 @@ class ChromeDocument extends Document {
|
|
|
2129
2042
|
(batchMap[key] ||= []).push(item);
|
|
2130
2043
|
}
|
|
2131
2044
|
else {
|
|
2132
|
-
errorCredential(
|
|
2045
|
+
errorCredential(item, errorValue("Cloud module not installed", service));
|
|
2133
2046
|
}
|
|
2134
2047
|
break;
|
|
2135
2048
|
}
|
|
@@ -2147,23 +2060,23 @@ class ChromeDocument extends Document {
|
|
|
2147
2060
|
let key;
|
|
2148
2061
|
switch (type) {
|
|
2149
2062
|
case 'mongodb':
|
|
2150
|
-
key =
|
|
2063
|
+
key = ClientDb.keyOfResult(item.uri || type, credential);
|
|
2151
2064
|
break;
|
|
2152
2065
|
case 'redis':
|
|
2153
|
-
key = credential && (key =
|
|
2066
|
+
key = credential && (key = ClientDb.keyOfResult(type, credential, true)) ? key : JSON.stringify(item.options.client);
|
|
2154
2067
|
break;
|
|
2155
2068
|
default:
|
|
2156
|
-
key =
|
|
2069
|
+
key = ClientDb.keyOfResult(type, credential);
|
|
2157
2070
|
break;
|
|
2158
2071
|
}
|
|
2159
2072
|
(batchMap[key] ||= []).push(item);
|
|
2160
2073
|
}
|
|
2161
2074
|
catch (err) {
|
|
2162
|
-
errorCredential(
|
|
2075
|
+
errorCredential(item, err);
|
|
2163
2076
|
}
|
|
2164
2077
|
}
|
|
2165
2078
|
else {
|
|
2166
|
-
errorCredential(
|
|
2079
|
+
errorCredential(item, errorValue(db ? "Database provider not found" : "Db module not installed", type));
|
|
2167
2080
|
}
|
|
2168
2081
|
break;
|
|
2169
2082
|
}
|
|
@@ -2174,11 +2087,11 @@ class ChromeDocument extends Document {
|
|
|
2174
2087
|
return this.allSettled(batchGroup.map(async (batch) => {
|
|
2175
2088
|
return new Promise(async (resolve, reject) => {
|
|
2176
2089
|
const errorRemove = (item, reason) => {
|
|
2177
|
-
removeElement(
|
|
2090
|
+
removeElement(item);
|
|
2178
2091
|
reject(reason);
|
|
2179
2092
|
};
|
|
2180
2093
|
const errorClient = (item, reason) => {
|
|
2181
|
-
removeElement(
|
|
2094
|
+
removeElement(item);
|
|
2182
2095
|
if (reason) {
|
|
2183
2096
|
this.writeFail(["Unable to configure client", item.source], reason);
|
|
2184
2097
|
}
|
|
@@ -2192,7 +2105,7 @@ class ChromeDocument extends Document {
|
|
|
2192
2105
|
case 'cloud':
|
|
2193
2106
|
result = await cloud.getDatabaseBatchRows(batch, true, this.sessionKey).catch((err) => {
|
|
2194
2107
|
this.abort(type);
|
|
2195
|
-
if (err
|
|
2108
|
+
if (isError(err)) {
|
|
2196
2109
|
cloud.addLog(this.aborted ? 2 : 3, errors = err, { source: batch[0].service });
|
|
2197
2110
|
}
|
|
2198
2111
|
return [];
|
|
@@ -2211,7 +2124,7 @@ class ChromeDocument extends Document {
|
|
|
2211
2124
|
let content, target, data, cacheKey;
|
|
2212
2125
|
if (type === 'local') {
|
|
2213
2126
|
let location;
|
|
2214
|
-
if (!(
|
|
2127
|
+
if (!(target = current.pathname) || !((location = this.resolveDir('data', target)) || host.canRead(location = path.resolve(target), { ownPermissionOnly: true }))) {
|
|
2215
2128
|
this.abort(type);
|
|
2216
2129
|
errorRemove(current, target ? errorDataSource('Not found', target) : errorDataSource('Not defined - ' + (this.settings.directory?.data ? 'file' : 'directory'), type));
|
|
2217
2130
|
return;
|
|
@@ -2237,7 +2150,7 @@ class ChromeDocument extends Document {
|
|
|
2237
2150
|
}
|
|
2238
2151
|
}
|
|
2239
2152
|
}
|
|
2240
|
-
else if (!(
|
|
2153
|
+
else if (!(target = current.uri)) {
|
|
2241
2154
|
this.abort(type);
|
|
2242
2155
|
errorRemove(current, errorDataSource('Not defined', type));
|
|
2243
2156
|
return;
|
|
@@ -2245,7 +2158,7 @@ class ChromeDocument extends Document {
|
|
|
2245
2158
|
else if (Document.isURL(target, 'file')) {
|
|
2246
2159
|
let { format, contentType, body } = current;
|
|
2247
2160
|
if (body) {
|
|
2248
|
-
if (!format && !contentType &&
|
|
2161
|
+
if (!format && !contentType && isPlainObject(body)) {
|
|
2249
2162
|
format = 'json';
|
|
2250
2163
|
}
|
|
2251
2164
|
try {
|
|
@@ -2310,8 +2223,8 @@ class ChromeDocument extends Document {
|
|
|
2310
2223
|
if (Buffer.isBuffer(content)) {
|
|
2311
2224
|
content = content.toString('utf8');
|
|
2312
2225
|
}
|
|
2313
|
-
if (
|
|
2314
|
-
const { format =
|
|
2226
|
+
if (isString(content)) {
|
|
2227
|
+
const { format = asExt(target) } = current;
|
|
2315
2228
|
try {
|
|
2316
2229
|
data = this.tryParse(content, format, current.options);
|
|
2317
2230
|
}
|
|
@@ -2356,13 +2269,13 @@ class ChromeDocument extends Document {
|
|
|
2356
2269
|
else {
|
|
2357
2270
|
const { pathname, execute, params } = current;
|
|
2358
2271
|
let data, target, getData, hint;
|
|
2359
|
-
if (
|
|
2272
|
+
if (isFunction(execute)) {
|
|
2360
2273
|
target = execute;
|
|
2361
2274
|
}
|
|
2362
|
-
else if (
|
|
2275
|
+
else if (isFunction(pathname)) {
|
|
2363
2276
|
target = pathname;
|
|
2364
2277
|
}
|
|
2365
|
-
else if (
|
|
2278
|
+
else if (isString(pathname)) {
|
|
2366
2279
|
if (pathname.startsWith('npm:')) {
|
|
2367
2280
|
target = pathname;
|
|
2368
2281
|
hint = pathname;
|
|
@@ -2377,24 +2290,24 @@ class ChromeDocument extends Document {
|
|
|
2377
2290
|
if (!getData) {
|
|
2378
2291
|
const settings = current.settings;
|
|
2379
2292
|
target ||= settings && this.settings.export?.[settings] || pathname;
|
|
2380
|
-
if (
|
|
2293
|
+
if (isFunction(target)) {
|
|
2381
2294
|
getData = target;
|
|
2382
2295
|
hint = target.name;
|
|
2383
2296
|
}
|
|
2384
|
-
else if (
|
|
2297
|
+
else if (isString(target)) {
|
|
2385
2298
|
getData = this.asSourceFile(target, { encoding: current.encoding });
|
|
2386
2299
|
hint = target;
|
|
2387
2300
|
}
|
|
2388
2301
|
}
|
|
2389
|
-
if (!
|
|
2302
|
+
if (!isFunction(getData)) {
|
|
2390
2303
|
errorRemove(current, target ? errorDataSource('Not a function', hint) : errorDataSource('Not defined - pathname', type));
|
|
2391
2304
|
return;
|
|
2392
2305
|
}
|
|
2393
2306
|
try {
|
|
2394
2307
|
if (params && !current.ignoreCoerce && this.settingsOf(type, 'coerce') === true) {
|
|
2395
|
-
|
|
2308
|
+
coerceObject(params);
|
|
2396
2309
|
}
|
|
2397
|
-
if (
|
|
2310
|
+
if (isFunction(getData, true)) {
|
|
2398
2311
|
data = await getData(params);
|
|
2399
2312
|
}
|
|
2400
2313
|
else {
|
|
@@ -2443,14 +2356,16 @@ class ChromeDocument extends Document {
|
|
|
2443
2356
|
case 'mongodb':
|
|
2444
2357
|
for (let j = 0; j < length; ++j) {
|
|
2445
2358
|
const cmd = batch[j];
|
|
2446
|
-
|
|
2359
|
+
if (cmd.cascade) {
|
|
2360
|
+
cmd.cacheObjectKey ||= cmd.cascade;
|
|
2361
|
+
}
|
|
2447
2362
|
}
|
|
2448
2363
|
break;
|
|
2449
2364
|
case 'redis':
|
|
2450
2365
|
for (let j = 0; j < length; ++j) {
|
|
2451
2366
|
const cmd = batch[j];
|
|
2452
|
-
const
|
|
2453
|
-
if (
|
|
2367
|
+
const search = cmd.search;
|
|
2368
|
+
if (isObject(search) && typeof search.schema === 'string') {
|
|
2454
2369
|
const pathname = this.resolveDir('schema', search.schema);
|
|
2455
2370
|
if (pathname) {
|
|
2456
2371
|
if (!cmd.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
|
|
@@ -2462,11 +2377,11 @@ class ChromeDocument extends Document {
|
|
|
2462
2377
|
}
|
|
2463
2378
|
if (!(search.schema = this._sessionData[pathname])) {
|
|
2464
2379
|
try {
|
|
2465
|
-
search.schema = loadLocalFile(
|
|
2380
|
+
search.schema = loadLocalFile(pathname, cmd.encoding);
|
|
2466
2381
|
this.addSessionData(current, pathname, search.schema, { template: true });
|
|
2467
2382
|
}
|
|
2468
2383
|
catch (err) {
|
|
2469
|
-
this.writeFail(['Unable to parse document', path.basename(pathname)], err
|
|
2384
|
+
this.writeFail(['Unable to parse document', path.basename(pathname)], isError(err) ? errors = err : err, 32);
|
|
2470
2385
|
search.schema = undefined;
|
|
2471
2386
|
}
|
|
2472
2387
|
}
|
|
@@ -2476,8 +2391,11 @@ class ChromeDocument extends Document {
|
|
|
2476
2391
|
search.schema = undefined;
|
|
2477
2392
|
}
|
|
2478
2393
|
}
|
|
2479
|
-
if (key) {
|
|
2480
|
-
|
|
2394
|
+
if (cmd.key) {
|
|
2395
|
+
const { cascade, query } = cmd;
|
|
2396
|
+
if (cascade || query) {
|
|
2397
|
+
cmd.cacheObjectKey ||= (cascade ? cascade : '') + '_' + (query ? Document.asString(query, true) : '');
|
|
2398
|
+
}
|
|
2481
2399
|
}
|
|
2482
2400
|
}
|
|
2483
2401
|
break;
|
|
@@ -2500,7 +2418,7 @@ class ChromeDocument extends Document {
|
|
|
2500
2418
|
if (!(cmd.query = this._sessionData[pathname])) {
|
|
2501
2419
|
const out = { content: '' };
|
|
2502
2420
|
try {
|
|
2503
|
-
cmd.query = loadLocalFile(
|
|
2421
|
+
cmd.query = loadLocalFile(pathname, cmd.encoding, out);
|
|
2504
2422
|
}
|
|
2505
2423
|
catch {
|
|
2506
2424
|
cmd.query = out.content;
|
|
@@ -2510,7 +2428,7 @@ class ChromeDocument extends Document {
|
|
|
2510
2428
|
}
|
|
2511
2429
|
}
|
|
2512
2430
|
else {
|
|
2513
|
-
throw
|
|
2431
|
+
throw errorMessage(type, "File not found", query);
|
|
2514
2432
|
}
|
|
2515
2433
|
}
|
|
2516
2434
|
catch (err) {
|
|
@@ -2534,7 +2452,7 @@ class ChromeDocument extends Document {
|
|
|
2534
2452
|
aborting = commandType !== db.commandType.UPDATE;
|
|
2535
2453
|
message = Document.asString(data.search || data.key);
|
|
2536
2454
|
}
|
|
2537
|
-
else if (
|
|
2455
|
+
else if (isObject(data.credential)) {
|
|
2538
2456
|
message = data.credential.database;
|
|
2539
2457
|
}
|
|
2540
2458
|
if (data.willAbort) {
|
|
@@ -2544,7 +2462,7 @@ class ChromeDocument extends Document {
|
|
|
2544
2462
|
this.abort(type, err);
|
|
2545
2463
|
}
|
|
2546
2464
|
if (err) {
|
|
2547
|
-
this.writeFail(["Unable to execute query", message || "Unknown"], err
|
|
2465
|
+
this.writeFail(["Unable to execute query", message || "Unknown"], isError(err) ? errors = err : err, { type: 65536, startTime });
|
|
2548
2466
|
}
|
|
2549
2467
|
return this.aborted;
|
|
2550
2468
|
};
|
|
@@ -2593,7 +2511,7 @@ class ChromeDocument extends Document {
|
|
|
2593
2511
|
}
|
|
2594
2512
|
if (items.length > 0 && !item.transactionFail) {
|
|
2595
2513
|
const element = item.element;
|
|
2596
|
-
const domElement = new
|
|
2514
|
+
const domElement = new HtmlElement(this.moduleName, element);
|
|
2597
2515
|
let value = '';
|
|
2598
2516
|
const checkValue = async (name) => {
|
|
2599
2517
|
const data = await this.processData(item, value, name, row => typeof row === 'string');
|
|
@@ -2636,7 +2554,7 @@ class ChromeDocument extends Document {
|
|
|
2636
2554
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2637
2555
|
if (content === null) {
|
|
2638
2556
|
++domBase.failCount;
|
|
2639
|
-
removeElement(
|
|
2557
|
+
removeElement(item, domElement);
|
|
2640
2558
|
if (length === 1) {
|
|
2641
2559
|
resolve();
|
|
2642
2560
|
return;
|
|
@@ -2648,7 +2566,7 @@ class ChromeDocument extends Document {
|
|
|
2648
2566
|
else {
|
|
2649
2567
|
for (let j = 0, match; j < items.length; ++j) {
|
|
2650
2568
|
const row = items[j];
|
|
2651
|
-
if (
|
|
2569
|
+
if (isPlainObject(row)) {
|
|
2652
2570
|
row.__index__ ??= j + 1;
|
|
2653
2571
|
}
|
|
2654
2572
|
let segment = template;
|
|
@@ -2670,28 +2588,28 @@ class ChromeDocument extends Document {
|
|
|
2670
2588
|
const literal = segment.trim();
|
|
2671
2589
|
if (literal.at(0) === '`' && literal.at(-1) === '`') {
|
|
2672
2590
|
if (!this.hasEval('function')) {
|
|
2673
|
-
errors =
|
|
2591
|
+
errors = errorMessage('eval', "Unsupported access", 'function');
|
|
2674
2592
|
continue;
|
|
2675
2593
|
}
|
|
2676
2594
|
try {
|
|
2677
2595
|
let unsafe = new Function('return ' + literal + ';').call(row);
|
|
2678
2596
|
if (!segment.startsWith('`')) {
|
|
2679
|
-
unsafe = segment.
|
|
2597
|
+
unsafe = segment.slice(0, segment.indexOf('`')) + unsafe;
|
|
2680
2598
|
}
|
|
2681
2599
|
if (!segment.endsWith('`')) {
|
|
2682
|
-
unsafe += segment.
|
|
2600
|
+
unsafe += segment.slice(segment.lastIndexOf('`') + 1);
|
|
2683
2601
|
}
|
|
2684
2602
|
segment = unsafe;
|
|
2685
2603
|
}
|
|
2686
2604
|
catch (err) {
|
|
2687
|
-
errors = err
|
|
2605
|
+
errors = isError(err) ? err : true;
|
|
2688
2606
|
continue;
|
|
2689
2607
|
}
|
|
2690
2608
|
}
|
|
2691
2609
|
else {
|
|
2692
2610
|
const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
|
|
2693
2611
|
while (match = pattern.exec(segment)) {
|
|
2694
|
-
segment = replaceMatch(match, segment, match[1] === "__index__" && !
|
|
2612
|
+
segment = replaceMatch(match, segment, match[1] === "__index__" && !isObject(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
|
|
2695
2613
|
}
|
|
2696
2614
|
}
|
|
2697
2615
|
value += trimTemplate(segment);
|
|
@@ -2707,7 +2625,7 @@ class ChromeDocument extends Document {
|
|
|
2707
2625
|
if (trailingText) {
|
|
2708
2626
|
value += trailingText;
|
|
2709
2627
|
}
|
|
2710
|
-
domElement.innerXml = domBase.initOpts.normalize ?
|
|
2628
|
+
domElement.innerXml = domBase.initOpts.normalize ? DomWriter.normalize(value, { newline: domBase.newline, escapeEntities: domBase.initOpts.escapeEntities }) : value;
|
|
2711
2629
|
}
|
|
2712
2630
|
else {
|
|
2713
2631
|
errors = true;
|
|
@@ -2716,12 +2634,12 @@ class ChromeDocument extends Document {
|
|
|
2716
2634
|
}
|
|
2717
2635
|
case 'attribute': {
|
|
2718
2636
|
const map = item.value;
|
|
2719
|
-
if (
|
|
2637
|
+
if (isPlainObject(map)) {
|
|
2720
2638
|
for (const attr in map) {
|
|
2721
2639
|
value = '';
|
|
2722
2640
|
let segment = map[attr], valid = false;
|
|
2723
2641
|
if (item.viewEngine) {
|
|
2724
|
-
if (!
|
|
2642
|
+
if (!isString(segment)) {
|
|
2725
2643
|
errors = true;
|
|
2726
2644
|
continue;
|
|
2727
2645
|
}
|
|
@@ -2734,10 +2652,10 @@ class ChromeDocument extends Document {
|
|
|
2734
2652
|
valid = true;
|
|
2735
2653
|
}
|
|
2736
2654
|
else {
|
|
2737
|
-
if (
|
|
2655
|
+
if (isString(segment)) {
|
|
2738
2656
|
segment = [segment];
|
|
2739
2657
|
}
|
|
2740
|
-
else if (!
|
|
2658
|
+
else if (!isArray(segment)) {
|
|
2741
2659
|
errors = true;
|
|
2742
2660
|
continue;
|
|
2743
2661
|
}
|
|
@@ -2796,10 +2714,10 @@ class ChromeDocument extends Document {
|
|
|
2796
2714
|
if (template) {
|
|
2797
2715
|
if (item.viewEngine) {
|
|
2798
2716
|
errors = true;
|
|
2799
|
-
if (
|
|
2717
|
+
if (isString(template)) {
|
|
2800
2718
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2801
2719
|
if (content !== null) {
|
|
2802
|
-
if (
|
|
2720
|
+
if (isString(content) && content.trim() === '') {
|
|
2803
2721
|
domElement.remove = true;
|
|
2804
2722
|
}
|
|
2805
2723
|
errors = false;
|
|
@@ -2807,10 +2725,10 @@ class ChromeDocument extends Document {
|
|
|
2807
2725
|
}
|
|
2808
2726
|
}
|
|
2809
2727
|
else {
|
|
2810
|
-
if (
|
|
2728
|
+
if (isString(template)) {
|
|
2811
2729
|
template = [template];
|
|
2812
2730
|
}
|
|
2813
|
-
else if (!
|
|
2731
|
+
else if (!isArray(template)) {
|
|
2814
2732
|
errors = true;
|
|
2815
2733
|
continue;
|
|
2816
2734
|
}
|
|
@@ -2850,7 +2768,7 @@ class ChromeDocument extends Document {
|
|
|
2850
2768
|
}
|
|
2851
2769
|
const sign = seg[0];
|
|
2852
2770
|
if (sign === '+' || sign === '-') {
|
|
2853
|
-
seg = seg.
|
|
2771
|
+
seg = seg.slice(1);
|
|
2854
2772
|
}
|
|
2855
2773
|
const data = getObjectValue(row, seg);
|
|
2856
2774
|
let keep = true;
|
|
@@ -2899,7 +2817,7 @@ class ChromeDocument extends Document {
|
|
|
2899
2817
|
break;
|
|
2900
2818
|
}
|
|
2901
2819
|
default:
|
|
2902
|
-
removeElement(
|
|
2820
|
+
removeElement(item, domElement);
|
|
2903
2821
|
if (length === 1) {
|
|
2904
2822
|
reject(errorDataSource('Invalid action', item.type || "Unknown"));
|
|
2905
2823
|
return;
|
|
@@ -2907,7 +2825,7 @@ class ChromeDocument extends Document {
|
|
|
2907
2825
|
break invalid;
|
|
2908
2826
|
}
|
|
2909
2827
|
if (!domBase.write(domElement) || errors) {
|
|
2910
|
-
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
|
|
2828
|
+
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 });
|
|
2911
2829
|
}
|
|
2912
2830
|
}
|
|
2913
2831
|
}
|
|
@@ -2915,7 +2833,7 @@ class ChromeDocument extends Document {
|
|
|
2915
2833
|
if (!empty && item.type !== 'display' || item.transactionFail) {
|
|
2916
2834
|
const emptyResponse = (value, service = item.source) => {
|
|
2917
2835
|
value ||= "Unknown";
|
|
2918
|
-
return errorDataSource(errors
|
|
2836
|
+
return errorDataSource(isError(errors) ? errors.message : service + ': Empty', value);
|
|
2919
2837
|
};
|
|
2920
2838
|
switch (item.source) {
|
|
2921
2839
|
case 'cloud': {
|
|
@@ -2925,12 +2843,12 @@ class ChromeDocument extends Document {
|
|
|
2925
2843
|
break;
|
|
2926
2844
|
}
|
|
2927
2845
|
case 'uri': {
|
|
2928
|
-
const { uri, format = uri &&
|
|
2846
|
+
const { uri, format = uri && asExt(uri) } = item;
|
|
2929
2847
|
this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri));
|
|
2930
2848
|
break;
|
|
2931
2849
|
}
|
|
2932
2850
|
case 'local': {
|
|
2933
|
-
const { pathname, format = pathname &&
|
|
2851
|
+
const { pathname, format = pathname && asExt(pathname) } = item;
|
|
2934
2852
|
this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname));
|
|
2935
2853
|
break;
|
|
2936
2854
|
}
|
|
@@ -2945,7 +2863,7 @@ class ChromeDocument extends Document {
|
|
|
2945
2863
|
}
|
|
2946
2864
|
}
|
|
2947
2865
|
}
|
|
2948
|
-
removeElement(
|
|
2866
|
+
removeElement(item);
|
|
2949
2867
|
}
|
|
2950
2868
|
}
|
|
2951
2869
|
resolve();
|
|
@@ -2959,13 +2877,51 @@ class ChromeDocument extends Document {
|
|
|
2959
2877
|
await setElements(displayItems);
|
|
2960
2878
|
}
|
|
2961
2879
|
}
|
|
2962
|
-
|
|
2880
|
+
async transformJs(processing, file, source) {
|
|
2881
|
+
const options = { file };
|
|
2882
|
+
let modified = false;
|
|
2883
|
+
for (const method of this.extensionsOf('js')) {
|
|
2884
|
+
try {
|
|
2885
|
+
const output = await method.call(this, source, options);
|
|
2886
|
+
if (isString(output)) {
|
|
2887
|
+
source = output;
|
|
2888
|
+
modified = true;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
catch (err) {
|
|
2892
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
if (modified) {
|
|
2896
|
+
return source;
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
async transformCss(processing, file, source) {
|
|
2900
|
+
const options = { file, config: this.config };
|
|
2901
|
+
let modified = false;
|
|
2902
|
+
for (const method of this.extensionsOf('css')) {
|
|
2903
|
+
try {
|
|
2904
|
+
const output = await method.call(this, source, options);
|
|
2905
|
+
if (isString(output)) {
|
|
2906
|
+
source = output;
|
|
2907
|
+
modified = true;
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
catch (err) {
|
|
2911
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
if (modified) {
|
|
2915
|
+
return source;
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
setProductionAttributes(processing) {
|
|
2963
2919
|
for (const item of this.assets) {
|
|
2964
2920
|
if (isIgnored(item, true)) {
|
|
2965
2921
|
continue;
|
|
2966
2922
|
}
|
|
2967
|
-
if (item.hash && !hashed.has(item)) {
|
|
2968
|
-
createHash(
|
|
2923
|
+
if (item.hash && !processing.hashed.has(item)) {
|
|
2924
|
+
this.createHash(processing, item, item.hash);
|
|
2969
2925
|
}
|
|
2970
2926
|
switch (item.element?.tagName.toLowerCase()) {
|
|
2971
2927
|
case 'style':
|
|
@@ -2976,23 +2932,23 @@ class ChromeDocument extends Document {
|
|
|
2976
2932
|
case 'script': {
|
|
2977
2933
|
const attributes = item.attributes;
|
|
2978
2934
|
if (attributes) {
|
|
2979
|
-
const algorithm =
|
|
2935
|
+
const algorithm = isString(attributes.integrity) ? attributes.integrity.toLowerCase() : '';
|
|
2980
2936
|
switch (algorithm) {
|
|
2981
2937
|
case 'sha256':
|
|
2982
2938
|
case 'sha384':
|
|
2983
2939
|
case 'sha512':
|
|
2984
2940
|
try {
|
|
2985
|
-
const data = getBuffer(item);
|
|
2986
|
-
|
|
2987
|
-
if (
|
|
2941
|
+
const data = processing.getBuffer(item);
|
|
2942
|
+
const value = data && Document.asHash(data, { algorithm, digestEncoding: 'base64', encoding: item.encoding });
|
|
2943
|
+
if (value) {
|
|
2988
2944
|
attributes.integrity = algorithm + '-' + value;
|
|
2989
2945
|
attributes.crossorigin ||= 'anonymous';
|
|
2990
2946
|
break;
|
|
2991
2947
|
}
|
|
2992
|
-
throw
|
|
2948
|
+
throw errorMessage('hash', 'Source not found', item.filename);
|
|
2993
2949
|
}
|
|
2994
2950
|
catch (err) {
|
|
2995
|
-
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime });
|
|
2951
|
+
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime: processing.startTime });
|
|
2996
2952
|
}
|
|
2997
2953
|
default:
|
|
2998
2954
|
if (algorithm) {
|
|
@@ -3006,391 +2962,26 @@ class ChromeDocument extends Document {
|
|
|
3006
2962
|
}
|
|
3007
2963
|
}
|
|
3008
2964
|
}
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
const revised = value.replace(useUnsafeCssReplace ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
|
|
3021
|
-
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) + '`';
|
|
3022
|
-
});
|
|
3023
|
-
let selector = '';
|
|
3024
|
-
for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
|
|
3025
|
-
let ch = revised[i], space = 0;
|
|
3026
|
-
switch (ch) {
|
|
3027
|
-
case '.':
|
|
3028
|
-
case '#':
|
|
3029
|
-
if (!attr) {
|
|
3030
|
-
casing = true;
|
|
3031
|
-
}
|
|
3032
|
-
break;
|
|
3033
|
-
case '[':
|
|
3034
|
-
if (!quote) {
|
|
3035
|
-
attr = true;
|
|
3036
|
-
casing = false;
|
|
3037
|
-
space = 2;
|
|
3038
|
-
}
|
|
3039
|
-
break;
|
|
3040
|
-
case ']':
|
|
3041
|
-
if (!quote || attr && revised[i - 1] === '"' && revised[i - 2] === '\\') {
|
|
3042
|
-
if (quote) {
|
|
3043
|
-
selector = selector.substring(0, selector.length - 1) + '`%%%`';
|
|
3044
|
-
quote = false;
|
|
3045
|
-
}
|
|
3046
|
-
attr = false;
|
|
3047
|
-
casing = false;
|
|
3048
|
-
space = 1;
|
|
3049
|
-
}
|
|
3050
|
-
break;
|
|
3051
|
-
case '=':
|
|
3052
|
-
if (attr && !quote) {
|
|
3053
|
-
casing = true;
|
|
3054
|
-
space = 3;
|
|
3055
|
-
}
|
|
3056
|
-
break;
|
|
3057
|
-
case '\\':
|
|
3058
|
-
ch = '`%%%%`';
|
|
3059
|
-
break;
|
|
3060
|
-
case '"':
|
|
3061
|
-
if (attr) {
|
|
3062
|
-
if (!quote) {
|
|
3063
|
-
ch = '`%%%`';
|
|
3064
|
-
quote = true;
|
|
3065
|
-
}
|
|
3066
|
-
else if (revised[i - 1] !== '\\') {
|
|
3067
|
-
ch = '`%%%`';
|
|
3068
|
-
quote = false;
|
|
3069
|
-
casing = false;
|
|
3070
|
-
}
|
|
3071
|
-
}
|
|
3072
|
-
break;
|
|
3073
|
-
case '~':
|
|
3074
|
-
case '^':
|
|
3075
|
-
case '$':
|
|
3076
|
-
case '*':
|
|
3077
|
-
case '|':
|
|
3078
|
-
if (attr && !quote) {
|
|
3079
|
-
space = 1;
|
|
3080
|
-
}
|
|
3081
|
-
break;
|
|
3082
|
-
case ' ':
|
|
3083
|
-
if (attr && !quote) {
|
|
3084
|
-
ch = '`%%`';
|
|
3085
|
-
break;
|
|
3086
|
-
}
|
|
3087
|
-
case ':':
|
|
3088
|
-
case ',':
|
|
3089
|
-
if (!attr) {
|
|
3090
|
-
casing = false;
|
|
3091
|
-
}
|
|
3092
|
-
break;
|
|
3093
|
-
}
|
|
3094
|
-
selector += (space & 1 ? '`%%`' : '') + (!casing && ch >= 'a' && ch <= 'z' ? '`' + ch + ch.toUpperCase() + '`' : ch) + (space & 2 ? '`%%`' : '');
|
|
3095
|
-
}
|
|
3096
|
-
selector = (0, types_1.escapePattern)(selector)
|
|
3097
|
-
.replace(/\s*(>|~(?!=)|\\\+|\\\*(?!=)])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3098
|
-
.replace(/`([a-z][A-Z]|%{2,4})`/g, (...capture) => {
|
|
3099
|
-
switch (capture[1]) {
|
|
3100
|
-
case '%%':
|
|
3101
|
-
return stringSome;
|
|
3102
|
-
case '%%%':
|
|
3103
|
-
return `(?:["']|${stringSome})`;
|
|
3104
|
-
case '%%%%':
|
|
3105
|
-
return '\\\\{0,}';
|
|
3106
|
-
default:
|
|
3107
|
-
return `[${capture[1]}]`;
|
|
3108
|
-
}
|
|
3109
|
-
});
|
|
3110
|
-
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
3111
|
-
selector = selector.replace('`%' + i + '`', items[i]);
|
|
3112
|
-
}
|
|
3113
|
-
return selector.replace(/ +/g, stringMany) + stringSome;
|
|
3114
|
-
};
|
|
3115
|
-
const replaceUnunsed = (name, items, nesting, increment = 1) => {
|
|
3116
|
-
for (let i = 0; i < items.length; i += increment) {
|
|
3117
|
-
const value = items[i].trim();
|
|
3118
|
-
let valueTo;
|
|
3119
|
-
const key = name + '_' + value + (increment === 2 && (valueTo = items[i + 1].trim()) ? '_' + valueTo : '') + (useUnsafeCssReplace ? '_1' : '');
|
|
3120
|
-
let pattern = queryMap.get(key), rule;
|
|
3121
|
-
if (!pattern) {
|
|
3122
|
-
let flags = 'gi', selector = '', revised = false;
|
|
3123
|
-
if (name === 'container') {
|
|
3124
|
-
for (let j = 0, length = value.length, casing = true; j < length; j++) {
|
|
3125
|
-
let ch = value[j];
|
|
3126
|
-
if (!casing) {
|
|
3127
|
-
ch = ch.toLowerCase();
|
|
3128
|
-
}
|
|
3129
|
-
else if (ch === '(') {
|
|
3130
|
-
casing = false;
|
|
3131
|
-
}
|
|
3132
|
-
if (casing || ch < 'a' || ch > 'z') {
|
|
3133
|
-
selector += value[j];
|
|
3134
|
-
if (selector.endsWith(' not ')) {
|
|
3135
|
-
selector = selector.replace(/ not $/, ' `nN``oO``tT` ');
|
|
3136
|
-
}
|
|
3137
|
-
}
|
|
3138
|
-
else {
|
|
3139
|
-
selector += '`' + ch + ch.toUpperCase() + '`';
|
|
3140
|
-
}
|
|
3141
|
-
}
|
|
3142
|
-
flags = 'g';
|
|
3143
|
-
}
|
|
3144
|
-
else if (name === 'scope') {
|
|
3145
|
-
selector = `\\(${stringSome + parseSelector(value)}\\)`;
|
|
3146
|
-
if (valueTo) {
|
|
3147
|
-
selector += `${stringMany}[tT][oO]${stringMany}\\(${stringSome + parseSelector(valueTo)}\\)`;
|
|
3148
|
-
}
|
|
3149
|
-
flags = 'g';
|
|
3150
|
-
revised = true;
|
|
3151
|
-
}
|
|
3152
|
-
else if (name === 'supports' && /^selector\(/i.test(value)) {
|
|
3153
|
-
const startIndex = value.indexOf('(');
|
|
3154
|
-
const endIndex = value.lastIndexOf(')');
|
|
3155
|
-
if (startIndex !== -1 && endIndex !== -1) {
|
|
3156
|
-
selector = '[sS][eE][lL][eE][cC][tT][oO][rR]\\(' + stringSome + parseSelector(value.substring(startIndex + 1, endIndex)) + '\\)';
|
|
3157
|
-
flags = 'g';
|
|
3158
|
-
revised = true;
|
|
3159
|
-
}
|
|
3160
|
-
}
|
|
3161
|
-
if (!revised) {
|
|
3162
|
-
selector = (0, types_1.escapePattern)(selector || value)
|
|
3163
|
-
.replace(/\s*(\\[()])\s*/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3164
|
-
.replace(/:\s+/g, stringSome + ':' + stringSome)
|
|
3165
|
-
.replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => stringSome + capture[1] + stringSome)
|
|
3166
|
-
.replace(/ +/g, stringMany);
|
|
3167
|
-
if (flags === 'g') {
|
|
3168
|
-
selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + stringMany + selector + stringSome + '{', flags);
|
|
3172
|
-
queryMap.set(key, pattern);
|
|
3173
|
-
}
|
|
3174
|
-
else {
|
|
3175
|
-
pattern.lastIndex = 0;
|
|
3176
|
-
}
|
|
3177
|
-
while (rule = pattern.exec(current)) {
|
|
3178
|
-
if (!nesting) {
|
|
3179
|
-
const block = Array.from(current.substring(0, rule.index).matchAll(/[{}]/g));
|
|
3180
|
-
if (block.filter(open => open[0] === '{').length !== block.filter(close => close[0] === '}').length) {
|
|
3181
|
-
continue;
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3184
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
|
|
3185
|
-
if (endIndex !== -1) {
|
|
3186
|
-
current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
|
|
3187
|
-
(checkEmpty ||= {})[name] = true;
|
|
3188
|
-
modified = true;
|
|
3189
|
-
}
|
|
3190
|
-
}
|
|
3191
|
-
}
|
|
3192
|
-
};
|
|
3193
|
-
if (!useUnsafeCssReplace) {
|
|
3194
|
-
const replaceBracket = (pattern) => {
|
|
3195
|
-
let bracket;
|
|
3196
|
-
while (bracket = pattern.exec(current)) {
|
|
3197
|
-
const segment = bracket[0];
|
|
3198
|
-
if (/[{}]/.test(segment)) {
|
|
3199
|
-
const placeholder = '`' + (0, node_crypto_1.randomUUID)().substring(0, 18) + '`';
|
|
3200
|
-
replaceMap.push([placeholder, segment]);
|
|
3201
|
-
current = replaceMatch(bracket, current, placeholder, pattern);
|
|
3202
|
-
}
|
|
3203
|
-
}
|
|
3204
|
-
pattern.lastIndex = 0;
|
|
3205
|
-
};
|
|
3206
|
-
replaceBracket(REGEXP_COMMENT);
|
|
3207
|
-
replaceBracket(REGEXP_QUOTEDVALUE);
|
|
3208
|
-
const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
|
|
3209
|
-
for (let i = 0, length = values.length; i < length; ++i) {
|
|
3210
|
-
const seg = values[i];
|
|
3211
|
-
if (/^url\([^{}]*[{}].*\)$/is.test(seg)) {
|
|
3212
|
-
replaceMap.push([values[i] = (0, node_crypto_1.randomUUID)().substring(0, 18), seg]);
|
|
3213
|
-
}
|
|
3214
|
-
}
|
|
3215
|
-
if (replaceMap.length > 0) {
|
|
3216
|
-
current = values.join('');
|
|
3217
|
-
}
|
|
3218
|
-
}
|
|
3219
|
-
if (unusedMedia) {
|
|
3220
|
-
replaceUnunsed('media', unusedMedia, true);
|
|
3221
|
-
}
|
|
3222
|
-
if (unusedSupports) {
|
|
3223
|
-
replaceUnunsed('supports', unusedSupports, true);
|
|
3224
|
-
}
|
|
3225
|
-
if (unusedContainer) {
|
|
3226
|
-
replaceUnunsed('container', unusedContainer, false);
|
|
3227
|
-
}
|
|
3228
|
-
if (unusedScope) {
|
|
3229
|
-
replaceUnunsed('scope', unusedScope.map(item => [item.start || '', item.end || '']).flat(), false, 2);
|
|
3230
|
-
}
|
|
3231
|
-
if (unusedStyles) {
|
|
3232
|
-
current = (function recurse(target, child) {
|
|
3233
|
-
let output = '', index = 0, pendingStart = 0, pendingEnd = 0, found = -1;
|
|
3234
|
-
while ((found = target.indexOf('{', index)) !== -1) {
|
|
3235
|
-
++found;
|
|
3236
|
-
const closing = findClosingIndex(target, found, '{')[0];
|
|
3237
|
-
if (closing === -1) {
|
|
3238
|
-
break;
|
|
3239
|
-
}
|
|
3240
|
-
let header = target.substring(index, found), invalid = 0, content;
|
|
3241
|
-
for (const value of unusedStyles) {
|
|
3242
|
-
const key = value + (child ? '_1' : '') + (useUnsafeCssReplace ? '_2' : '');
|
|
3243
|
-
const pattern = selectorMap.get(key);
|
|
3244
|
-
let single, group;
|
|
3245
|
-
if (!pattern) {
|
|
3246
|
-
const selector = parseSelector(value) + (child ? `(?:${stringSome}&${stringSome})*` : '');
|
|
3247
|
-
single = new RegExp(`(^|;)(${stringSome})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
|
|
3248
|
-
group = new RegExp(`((?:^|;)[^{]*?${stringSome}(,${stringSome}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
|
|
3249
|
-
selectorMap.set(key, [single, group]);
|
|
3250
|
-
}
|
|
3251
|
-
else {
|
|
3252
|
-
[single, group] = pattern;
|
|
3253
|
-
}
|
|
3254
|
-
if (match = single.exec(header)) {
|
|
3255
|
-
content = match[1] === ';' ? header.substring(0, match.index + 1) + match[2].replace(/[^\n]+$/, '') : undefined;
|
|
3256
|
-
invalid = 1;
|
|
3257
|
-
break;
|
|
3258
|
-
}
|
|
3259
|
-
let leading = -1, first = true;
|
|
3260
|
-
while (match = group.exec(header)) {
|
|
3261
|
-
const start = match.index + match[1].length;
|
|
3262
|
-
if (!child && first) {
|
|
3263
|
-
if (match[1].trimEnd().endsWith(';')) {
|
|
3264
|
-
leading = start;
|
|
3265
|
-
}
|
|
3266
|
-
first = false;
|
|
3267
|
-
}
|
|
3268
|
-
const sibling = match[2].startsWith(',');
|
|
3269
|
-
const trailing = match[4];
|
|
3270
|
-
const offset = trailing && !sibling ? /^,\s*/.exec(trailing)[0].length : 1;
|
|
3271
|
-
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));
|
|
3272
|
-
group.lastIndex = match.index;
|
|
3273
|
-
invalid = 2;
|
|
3274
|
-
}
|
|
3275
|
-
if (invalid) {
|
|
3276
|
-
group.lastIndex = 0;
|
|
3277
|
-
const empty = /(.)\s*{$/.exec(header);
|
|
3278
|
-
if (empty) {
|
|
3279
|
-
if (header.trim() === '{') {
|
|
3280
|
-
content = undefined;
|
|
3281
|
-
invalid = 1;
|
|
3282
|
-
break;
|
|
3283
|
-
}
|
|
3284
|
-
if (leading !== -1 && empty[1] === ';') {
|
|
3285
|
-
content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
|
|
3286
|
-
invalid = 1;
|
|
3287
|
-
break;
|
|
3288
|
-
}
|
|
3289
|
-
}
|
|
3290
|
-
}
|
|
3291
|
-
}
|
|
3292
|
-
if (invalid === 0 || invalid === 2) {
|
|
3293
|
-
const trailing = target.substring(found, closing);
|
|
3294
|
-
if (content = recurse(trailing, true)) {
|
|
3295
|
-
content = header + content;
|
|
3296
|
-
}
|
|
3297
|
-
else if (invalid === 2) {
|
|
3298
|
-
content = header + trailing;
|
|
3299
|
-
}
|
|
3300
|
-
}
|
|
3301
|
-
if (content) {
|
|
3302
|
-
if (pendingEnd) {
|
|
3303
|
-
output = target.substring(pendingStart, pendingEnd) + content;
|
|
3304
|
-
pendingEnd = 0;
|
|
3305
|
-
}
|
|
3306
|
-
else {
|
|
3307
|
-
output += content;
|
|
3308
|
-
}
|
|
3309
|
-
}
|
|
3310
|
-
else if (!invalid) {
|
|
3311
|
-
if (output) {
|
|
3312
|
-
output += target.substring(index, closing);
|
|
3313
|
-
}
|
|
3314
|
-
else {
|
|
3315
|
-
pendingEnd = closing;
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
else if (pendingEnd) {
|
|
3319
|
-
output = target.substring(pendingStart, pendingEnd);
|
|
3320
|
-
pendingEnd = 0;
|
|
3321
|
-
}
|
|
3322
|
-
else {
|
|
3323
|
-
pendingStart = closing;
|
|
3324
|
-
}
|
|
3325
|
-
index = closing;
|
|
3326
|
-
}
|
|
3327
|
-
if (output) {
|
|
3328
|
-
modified = true;
|
|
3329
|
-
return output + target.substring(index);
|
|
3330
|
-
}
|
|
3331
|
-
return child ? '' : target;
|
|
3332
|
-
})(current, false);
|
|
3333
|
-
}
|
|
3334
|
-
if (usedVariables) {
|
|
3335
|
-
let pattern = useUnsafeCssReplace ? REGEXP_VARIABLES_UNSAFE : REGEXP_VARIABLES;
|
|
3336
|
-
while (match = pattern.exec(current)) {
|
|
3337
|
-
if (!usedVariables.includes(match[2])) {
|
|
3338
|
-
current = replaceMatch(match, current, match[3] === ';' ? getNewlineString(match[1], match[4]) : '', pattern);
|
|
3339
|
-
modified = true;
|
|
3340
|
-
}
|
|
3341
|
-
}
|
|
3342
|
-
pattern.lastIndex = 0;
|
|
3343
|
-
pattern = useUnsafeCssReplace ? REGEXP_PROPERTY_UNSAFE : REGEXP_PROPERTY;
|
|
3344
|
-
while (match = pattern.exec(current)) {
|
|
3345
|
-
if (!usedVariables.includes(match[2])) {
|
|
3346
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3347
|
-
if (endIndex !== -1) {
|
|
3348
|
-
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3349
|
-
modified = true;
|
|
3350
|
-
}
|
|
3351
|
-
}
|
|
3352
|
-
}
|
|
3353
|
-
pattern.lastIndex = 0;
|
|
3354
|
-
}
|
|
3355
|
-
if (usedFontFace) {
|
|
3356
|
-
const pattern = useUnsafeCssReplace ? REGEXP_FONTFACE_UNSAFE : REGEXP_FONTFACE;
|
|
3357
|
-
const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
|
|
3358
|
-
while (match = pattern.exec(current)) {
|
|
3359
|
-
const font = fontFamily.exec(match[0]);
|
|
3360
|
-
if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])(.+)\1$/s, (...content) => content[2]))) {
|
|
3361
|
-
current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
|
|
3362
|
-
modified = true;
|
|
3363
|
-
}
|
|
3364
|
-
}
|
|
3365
|
-
pattern.lastIndex = 0;
|
|
3366
|
-
}
|
|
3367
|
-
if (usedKeyframes) {
|
|
3368
|
-
const pattern = useUnsafeCssReplace ? REGEXP_KEYFRAMES_UNSAFE : REGEXP_KEYFRAMES;
|
|
3369
|
-
while (match = pattern.exec(current)) {
|
|
3370
|
-
if (!usedKeyframes.includes(match[2].trim())) {
|
|
3371
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3372
|
-
if (endIndex !== -1) {
|
|
3373
|
-
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3374
|
-
modified = true;
|
|
2965
|
+
createHash(processing, file, hash) {
|
|
2966
|
+
const { host, bufferMap } = processing;
|
|
2967
|
+
const { filename, localUri } = file;
|
|
2968
|
+
try {
|
|
2969
|
+
const buffer = localUri && bufferMap[localUri] || processing.getBuffer(file, localUri);
|
|
2970
|
+
if (buffer) {
|
|
2971
|
+
const [algorithm, length] = getHashData(hash);
|
|
2972
|
+
const value = algorithm ? Document.asHash(buffer, algorithm, { encoding: file.encoding }) : '';
|
|
2973
|
+
if (value) {
|
|
2974
|
+
if (localUri) {
|
|
2975
|
+
bufferMap[localUri] = buffer;
|
|
3375
2976
|
}
|
|
2977
|
+
host.rename(file, appendSuffix(filename, length > 0 ? value.slice(0, length) : value));
|
|
2978
|
+
return file.filename;
|
|
3376
2979
|
}
|
|
3377
2980
|
}
|
|
3378
|
-
|
|
2981
|
+
throw errorMessage('hash', 'Source not found', filename);
|
|
3379
2982
|
}
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
const pattern = CACHE_ATRULES[name + (useUnsafeCssReplace ? '_1' : '')] ||= new RegExp(`(\\s*)@${name}[^{]*{${stringSome}}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
3383
|
-
while (match = pattern.exec(current)) {
|
|
3384
|
-
current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[2]);
|
|
3385
|
-
}
|
|
3386
|
-
pattern.lastIndex = 0;
|
|
3387
|
-
}
|
|
3388
|
-
if (replaceMap.length > 0) {
|
|
3389
|
-
for (const [placeholder, content] of replaceMap.reverse()) {
|
|
3390
|
-
current = current.replace(placeholder, content);
|
|
3391
|
-
}
|
|
3392
|
-
}
|
|
3393
|
-
return current;
|
|
2983
|
+
catch (err) {
|
|
2984
|
+
host.writeFail(["Unable to read file", filename], err, 32);
|
|
3394
2985
|
}
|
|
3395
2986
|
}
|
|
3396
2987
|
getSrcUrl(parent, file) {
|
|
@@ -3435,13 +3026,13 @@ class ChromeDocument extends Document {
|
|
|
3435
3026
|
file.inlineBase64 ||
|
|
3436
3027
|
this.replaced.includes(file) ||
|
|
3437
3028
|
initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) ||
|
|
3438
|
-
format && (
|
|
3029
|
+
format && (hasValue(format, 'base64') || hasValue(format, 'woff') || hasValue(format, 'woff2')) ? true : false);
|
|
3439
3030
|
}
|
|
3440
3031
|
async processData(item, result, method, validate) {
|
|
3441
3032
|
let callback;
|
|
3442
3033
|
if (typeof method === 'string') {
|
|
3443
3034
|
const template = this.findDataValue(method) || method;
|
|
3444
|
-
callback = this.hasEval('userconfig') ? Document.parseFunction(template, this.hasEval('absolute')) :
|
|
3035
|
+
callback = this.hasEval('userconfig') ? Document.parseFunction(template, { absolute: this.hasEval('absolute'), default: true }) : asFunction(template);
|
|
3445
3036
|
}
|
|
3446
3037
|
else {
|
|
3447
3038
|
callback = method;
|
|
@@ -3450,7 +3041,7 @@ class ChromeDocument extends Document {
|
|
|
3450
3041
|
if (typeof callback === 'function') {
|
|
3451
3042
|
try {
|
|
3452
3043
|
let output;
|
|
3453
|
-
if (
|
|
3044
|
+
if (isFunction(callback, true)) {
|
|
3454
3045
|
output = await callback(result, item);
|
|
3455
3046
|
}
|
|
3456
3047
|
else {
|
|
@@ -3471,14 +3062,8 @@ class ChromeDocument extends Document {
|
|
|
3471
3062
|
}
|
|
3472
3063
|
}
|
|
3473
3064
|
processJs(host, file, output) {
|
|
3474
|
-
const writeSourceMap = (uri, data, hash) => {
|
|
3475
|
-
const value = Document.writeSourceMap(uri, data, { hash, emptySources: !!this.productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
3476
|
-
if (value) {
|
|
3477
|
-
host.add(value, file, types_1.FILE_TYPE.SOURCEMAP);
|
|
3478
|
-
}
|
|
3479
|
-
};
|
|
3480
3065
|
if (output.map) {
|
|
3481
|
-
writeSourceMap(file
|
|
3066
|
+
this.writeSourceMap(host, file, output);
|
|
3482
3067
|
}
|
|
3483
3068
|
if (output.chunks) {
|
|
3484
3069
|
const elements = this.elements;
|
|
@@ -3490,7 +3075,7 @@ class ChromeDocument extends Document {
|
|
|
3490
3075
|
if (element) {
|
|
3491
3076
|
for (const item of elements) {
|
|
3492
3077
|
const append = item.append;
|
|
3493
|
-
if (append && !append.prepend &&
|
|
3078
|
+
if (append && !append.prepend && DomWriter.isEqual(item, element, host.moduleName, true)) {
|
|
3494
3079
|
(appending ||= []).push(append);
|
|
3495
3080
|
}
|
|
3496
3081
|
}
|
|
@@ -3503,7 +3088,7 @@ class ChromeDocument extends Document {
|
|
|
3503
3088
|
}
|
|
3504
3089
|
const chunkUri = path.join(localDir, chunkName);
|
|
3505
3090
|
if (chunk.map) {
|
|
3506
|
-
writeSourceMap(
|
|
3091
|
+
this.writeSourceMap(host, file, chunk, chunkUri);
|
|
3507
3092
|
}
|
|
3508
3093
|
try {
|
|
3509
3094
|
fs.writeFileSync(chunkUri, chunk.code);
|
|
@@ -3517,11 +3102,11 @@ class ChromeDocument extends Document {
|
|
|
3517
3102
|
elements.push({
|
|
3518
3103
|
...element,
|
|
3519
3104
|
attributes,
|
|
3520
|
-
append: { tagName: 'script', tagCount: element.tagCount, nextSibling:
|
|
3105
|
+
append: { tagName: 'script', tagCount: element.tagCount, nextSibling: DomWriter.isIndex(element.index) ? element.index + 1 : undefined, order: ++order }
|
|
3521
3106
|
});
|
|
3522
3107
|
}
|
|
3523
3108
|
else {
|
|
3524
|
-
this.writeFail(['Unable to create entry point', path.basename(chunkUri)],
|
|
3109
|
+
this.writeFail(['Unable to create entry point', path.basename(chunkUri)], errorMessage('js', 'Element not found', chunkUri), 4);
|
|
3525
3110
|
}
|
|
3526
3111
|
}
|
|
3527
3112
|
}
|
|
@@ -3533,7 +3118,7 @@ class ChromeDocument extends Document {
|
|
|
3533
3118
|
item.order += order;
|
|
3534
3119
|
});
|
|
3535
3120
|
}
|
|
3536
|
-
if (
|
|
3121
|
+
if (isArray(output.sourceFiles)) {
|
|
3537
3122
|
file.sourceFiles = output.sourceFiles;
|
|
3538
3123
|
}
|
|
3539
3124
|
file.modified = true;
|
|
@@ -3544,7 +3129,7 @@ class ChromeDocument extends Document {
|
|
|
3544
3129
|
const baseHref = collectBaseUrl(importFile || file, this.baseUrl);
|
|
3545
3130
|
const isHtml = type === 'html';
|
|
3546
3131
|
const isJs = type === 'js';
|
|
3547
|
-
const imageSet =
|
|
3132
|
+
const imageSet = /(?:\b(?<!-)|(?<!-)-webkit-)image-set\(/gi;
|
|
3548
3133
|
const pattern = isJs ? /\b(?<!-)import\(/g : type === 'svg' ? /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi : /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi;
|
|
3549
3134
|
let length = source.length, modified = false, match;
|
|
3550
3135
|
while (match = imageSet.exec(source)) {
|
|
@@ -3552,15 +3137,15 @@ class ChromeDocument extends Document {
|
|
|
3552
3137
|
const endIndex = findClosingIndex(source, startIndex, '(');
|
|
3553
3138
|
if (endIndex !== -1) {
|
|
3554
3139
|
REGEXP_IMAGESET_URL.lastIndex = 0;
|
|
3555
|
-
let content = source.
|
|
3140
|
+
let content = source.slice(startIndex, endIndex), url;
|
|
3556
3141
|
while (url = REGEXP_IMAGESET_URL.exec(content)) {
|
|
3557
3142
|
const quote = url[2] ? '"' : "'";
|
|
3558
3143
|
const [a, b] = url.indices[1];
|
|
3559
|
-
content =
|
|
3144
|
+
content = spliceString(content, a, b, `url(${quote + (url[2] || url[3]).trim() + quote})`, REGEXP_IMAGESET_URL);
|
|
3560
3145
|
modified = true;
|
|
3561
3146
|
}
|
|
3562
3147
|
if (modified) {
|
|
3563
|
-
source =
|
|
3148
|
+
source = spliceString(source, startIndex, endIndex, content, imageSet);
|
|
3564
3149
|
modified = false;
|
|
3565
3150
|
}
|
|
3566
3151
|
}
|
|
@@ -3615,7 +3200,8 @@ class ChromeDocument extends Document {
|
|
|
3615
3200
|
i = closed;
|
|
3616
3201
|
}
|
|
3617
3202
|
else {
|
|
3618
|
-
|
|
3203
|
+
i = j;
|
|
3204
|
+
content = content.slice(0, i);
|
|
3619
3205
|
}
|
|
3620
3206
|
break;
|
|
3621
3207
|
}
|
|
@@ -3630,12 +3216,12 @@ class ChromeDocument extends Document {
|
|
|
3630
3216
|
if (asset) {
|
|
3631
3217
|
if (!asset.inlineBase64) {
|
|
3632
3218
|
if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
|
|
3633
|
-
const inlineUrlCloud = asset.inlineUrlCloud ||=
|
|
3219
|
+
const inlineUrlCloud = asset.inlineUrlCloud ||= randomUUID();
|
|
3634
3220
|
(file.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
|
|
3635
3221
|
value = inlineUrlCloud;
|
|
3636
3222
|
}
|
|
3637
3223
|
else if (asset.hash && this.productionRelease) {
|
|
3638
|
-
const inlineUrl = asset.inlineUrl ||=
|
|
3224
|
+
const inlineUrl = asset.inlineUrl ||= randomUUID();
|
|
3639
3225
|
(file.inlineUrlMap ||= {})[inlineUrl] = value;
|
|
3640
3226
|
value = inlineUrl;
|
|
3641
3227
|
}
|
|
@@ -3646,7 +3232,7 @@ class ChromeDocument extends Document {
|
|
|
3646
3232
|
for (let k = i + 1; k < length; ++k) {
|
|
3647
3233
|
switch (source[k]) {
|
|
3648
3234
|
case ')': {
|
|
3649
|
-
const component = source.
|
|
3235
|
+
const component = source.slice(i + 1, k + 1);
|
|
3650
3236
|
const format = /\s+format\([^)]+\)$/i.exec(component);
|
|
3651
3237
|
if (format) {
|
|
3652
3238
|
trailing = component.replace(format[0], ` format("${font}")`);
|
|
@@ -3680,14 +3266,14 @@ class ChromeDocument extends Document {
|
|
|
3680
3266
|
if (isUrl) {
|
|
3681
3267
|
const index = value.indexOf('#');
|
|
3682
3268
|
if (index !== -1) {
|
|
3683
|
-
value = value.
|
|
3269
|
+
value = value.slice(0, index);
|
|
3684
3270
|
}
|
|
3685
3271
|
}
|
|
3686
3272
|
if (quote) {
|
|
3687
3273
|
value = quote + value + quote;
|
|
3688
3274
|
}
|
|
3689
3275
|
const revised = isJs ? `import(${value + trailing})` : isHref ? 'href=' + value : (isText ? '@import ' + value : `url(${value})`) + trailing;
|
|
3690
|
-
source =
|
|
3276
|
+
source = spliceString(source, startIndex, i + 1, revised, pattern);
|
|
3691
3277
|
length = source.length;
|
|
3692
3278
|
modified = true;
|
|
3693
3279
|
};
|
|
@@ -3702,11 +3288,11 @@ class ChromeDocument extends Document {
|
|
|
3702
3288
|
trailing = target[2].trim();
|
|
3703
3289
|
}
|
|
3704
3290
|
else {
|
|
3705
|
-
url =
|
|
3291
|
+
url = trimQuote(content);
|
|
3706
3292
|
}
|
|
3707
3293
|
}
|
|
3708
3294
|
else {
|
|
3709
|
-
url =
|
|
3295
|
+
url = trimQuote(content);
|
|
3710
3296
|
}
|
|
3711
3297
|
if (url.startsWith('data:')) {
|
|
3712
3298
|
const base64 = url.split(',')[1]?.trim();
|
|
@@ -3732,34 +3318,35 @@ class ChromeDocument extends Document {
|
|
|
3732
3318
|
}
|
|
3733
3319
|
}
|
|
3734
3320
|
if (asset && asset !== importFile) {
|
|
3735
|
-
if (!
|
|
3321
|
+
if (!hasValue(asset.format, 'base64')) {
|
|
3736
3322
|
if (asset.bundleReplace) {
|
|
3737
3323
|
let k = 0, valid = true;
|
|
3738
3324
|
if (!isText) {
|
|
3739
3325
|
let j = startIndex;
|
|
3740
3326
|
while (isSpace(source[--j])) { }
|
|
3741
|
-
|
|
3327
|
+
k = j - 6;
|
|
3328
|
+
valid = source.slice(k, j + 1).toLowerCase() === '@import';
|
|
3742
3329
|
}
|
|
3743
3330
|
else {
|
|
3744
3331
|
k = startIndex;
|
|
3745
3332
|
}
|
|
3746
3333
|
if (valid) {
|
|
3747
|
-
let l = i, revised =
|
|
3334
|
+
let l = i, revised = SourceMap.removeSourceMappingURL(host.getUTF8String(asset))[0];
|
|
3748
3335
|
for (let ch; l < length; ++l) {
|
|
3749
3336
|
if ((ch = source[l]) === ';' || ch === '\n') {
|
|
3750
3337
|
break;
|
|
3751
3338
|
}
|
|
3752
3339
|
}
|
|
3753
|
-
const layer = this.replaceContent(revised, source.
|
|
3340
|
+
const layer = this.replaceContent(revised, source.slice(k, l + 1), "text/css");
|
|
3754
3341
|
if (layer) {
|
|
3755
3342
|
revised = layer;
|
|
3756
3343
|
}
|
|
3757
3344
|
revised = this.processUrl(host, file, this.removeServerRoot(revised), type, asset) || revised;
|
|
3758
|
-
source =
|
|
3345
|
+
source = spliceString(source, k, l + 1, revised, pattern);
|
|
3759
3346
|
length = source.length;
|
|
3760
3347
|
if (file.watch) {
|
|
3761
3348
|
related.push(asset);
|
|
3762
|
-
if (!
|
|
3349
|
+
if (!existsFlag(asset.flags)) {
|
|
3763
3350
|
asset.flags |= 8;
|
|
3764
3351
|
}
|
|
3765
3352
|
}
|
|
@@ -3785,7 +3372,7 @@ class ChromeDocument extends Document {
|
|
|
3785
3372
|
}
|
|
3786
3373
|
}
|
|
3787
3374
|
else if (!asset.invalid) {
|
|
3788
|
-
fullUrl = asset.inlineBase64 ||=
|
|
3375
|
+
fullUrl = asset.inlineBase64 ||= randomUUID();
|
|
3789
3376
|
}
|
|
3790
3377
|
if (url !== fullUrl) {
|
|
3791
3378
|
setOutputURL(fullUrl, asset);
|
|
@@ -3818,7 +3405,7 @@ class ChromeDocument extends Document {
|
|
|
3818
3405
|
if (value) {
|
|
3819
3406
|
const index = value.indexOf(ChromeDocument.INTERNAL_ASSIGNUUID);
|
|
3820
3407
|
if (index !== -1) {
|
|
3821
|
-
target[attr] =
|
|
3408
|
+
target[attr] = spliceString(value, index, index + ChromeDocument.INTERNAL_ASSIGNUUID.length, this.formatLocation(attr, nameExt));
|
|
3822
3409
|
modified.push(attr);
|
|
3823
3410
|
return true;
|
|
3824
3411
|
}
|
|
@@ -3829,15 +3416,27 @@ class ChromeDocument extends Document {
|
|
|
3829
3416
|
checkAttribute('pathname');
|
|
3830
3417
|
return modified;
|
|
3831
3418
|
}
|
|
3419
|
+
writeSourceMap(host, file, data, uri, hash) {
|
|
3420
|
+
if (!uri && (uri = file.localUri)) {
|
|
3421
|
+
hash ||= file.hash;
|
|
3422
|
+
}
|
|
3423
|
+
else {
|
|
3424
|
+
return;
|
|
3425
|
+
}
|
|
3426
|
+
const value = Document.writeSourceMap(uri, data, { hash, emptySources: !!this.productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
3427
|
+
if (value) {
|
|
3428
|
+
host.add(value, file, FILE_TYPE.SOURCEMAP);
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3832
3431
|
formatLocation(attr, nameExt) {
|
|
3833
3432
|
const format = this.formatMap || this.module.format;
|
|
3834
|
-
if (
|
|
3433
|
+
if (format) {
|
|
3835
3434
|
const pattern = nameExt && nameExt in format ? format[nameExt] : format.uuid;
|
|
3836
|
-
if (
|
|
3837
|
-
return
|
|
3435
|
+
if (isString(pattern?.[attr])) {
|
|
3436
|
+
return randomString(pattern[attr], pattern.dictionary);
|
|
3838
3437
|
}
|
|
3839
3438
|
}
|
|
3840
|
-
return
|
|
3439
|
+
return randomUUID();
|
|
3841
3440
|
}
|
|
3842
3441
|
createTransformOptions(host, file, mimeType, source = {}) {
|
|
3843
3442
|
if (typeof source === 'string') {
|
|
@@ -3850,7 +3449,7 @@ class ChromeDocument extends Document {
|
|
|
3850
3449
|
case "text/css":
|
|
3851
3450
|
Object.assign(metadata, this.config);
|
|
3852
3451
|
default:
|
|
3853
|
-
if ((
|
|
3452
|
+
if (isPlainObject(file.metadata)) {
|
|
3854
3453
|
Object.assign(metadata, file.metadata);
|
|
3855
3454
|
}
|
|
3856
3455
|
break;
|
|
@@ -3870,17 +3469,17 @@ class ChromeDocument extends Document {
|
|
|
3870
3469
|
options.getSourceFiles = this.locateSourceFiles(file, source.code, source.contentFiles || (localUri ? host.contentToAppend.get(localUri) : undefined));
|
|
3871
3470
|
}
|
|
3872
3471
|
}
|
|
3873
|
-
if ((!this.productionRelease || this.productionIncremental) && !
|
|
3472
|
+
if ((!this.productionRelease || this.productionIncremental) && !modifiedFlag(file.flags)) {
|
|
3874
3473
|
options.cacheData = { uri: !file.exported ? uri : undefined, etag: !file.modified ? file.etag : undefined, encoding: file.encoding };
|
|
3875
3474
|
}
|
|
3876
3475
|
return options;
|
|
3877
3476
|
}
|
|
3878
3477
|
addSessionData(item, key, data, { timeout = 0, template = false } = {}) {
|
|
3879
|
-
if (
|
|
3478
|
+
if (isObject(data) || template && data != null) {
|
|
3880
3479
|
if (timeout === 0) {
|
|
3881
3480
|
const cache = this.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
|
|
3882
3481
|
if (cache) {
|
|
3883
|
-
timeout =
|
|
3482
|
+
timeout = ClientDb.getTimeout(cache);
|
|
3884
3483
|
}
|
|
3885
3484
|
}
|
|
3886
3485
|
if (timeout > 0) {
|
|
@@ -3891,6 +3490,32 @@ class ChromeDocument extends Document {
|
|
|
3891
3490
|
}
|
|
3892
3491
|
}
|
|
3893
3492
|
}
|
|
3493
|
+
#replaceCss(file) {
|
|
3494
|
+
const sanitizeCss = (map) => {
|
|
3495
|
+
for (const id in map) {
|
|
3496
|
+
map[id] = this.removeServerRoot(map[id]);
|
|
3497
|
+
}
|
|
3498
|
+
};
|
|
3499
|
+
if (file.inlineUrlMap) {
|
|
3500
|
+
sanitizeCss(file.inlineUrlMap);
|
|
3501
|
+
}
|
|
3502
|
+
if (file.inlineUrlCloudMap) {
|
|
3503
|
+
sanitizeCss(file.inlineUrlCloudMap);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
#replaceHtml(source, { productionRelease, contentMap }, cssMap) {
|
|
3507
|
+
const finalizeHtml = (value, data) => {
|
|
3508
|
+
for (const id in data) {
|
|
3509
|
+
value = value.replace(new RegExp(escapePattern(id), 'g'), data[id]);
|
|
3510
|
+
}
|
|
3511
|
+
return value;
|
|
3512
|
+
};
|
|
3513
|
+
if (cssMap) {
|
|
3514
|
+
source = finalizeHtml(source, cssMap);
|
|
3515
|
+
}
|
|
3516
|
+
source = finalizeHtml(source, contentMap);
|
|
3517
|
+
return productionRelease ? this.removeServerRoot(source) : source;
|
|
3518
|
+
}
|
|
3894
3519
|
get elements() {
|
|
3895
3520
|
if (this._elements) {
|
|
3896
3521
|
return this._elements;
|
|
@@ -3902,13 +3527,13 @@ class ChromeDocument extends Document {
|
|
|
3902
3527
|
for (const item of this.assets) {
|
|
3903
3528
|
const { element, id, flags } = item;
|
|
3904
3529
|
if (element) {
|
|
3905
|
-
if (restartable && id && !
|
|
3530
|
+
if (restartable && id && !cloneFlag(flags)) {
|
|
3906
3531
|
const backup = idMap[id];
|
|
3907
3532
|
if (backup) {
|
|
3908
|
-
elements.add(item.element =
|
|
3533
|
+
elements.add(item.element = cloneObject(backup, true));
|
|
3909
3534
|
continue;
|
|
3910
3535
|
}
|
|
3911
|
-
idMap[id] =
|
|
3536
|
+
idMap[id] = cloneObject(element, true);
|
|
3912
3537
|
}
|
|
3913
3538
|
elements.add(element);
|
|
3914
3539
|
}
|
|
@@ -3933,15 +3558,16 @@ class ChromeDocument extends Document {
|
|
|
3933
3558
|
const host = this.host;
|
|
3934
3559
|
if (host) {
|
|
3935
3560
|
const items = host.getDataSourceItems(this);
|
|
3936
|
-
return this._dataSource = host.restartable || this.watching ? items.map(item =>
|
|
3561
|
+
return this._dataSource = host.restartable || this.watching ? items.map(item => cloneObject(item, true)) : items;
|
|
3937
3562
|
}
|
|
3938
3563
|
return [];
|
|
3939
3564
|
}
|
|
3940
3565
|
get sessionKey() {
|
|
3941
|
-
return this._sessionKey ||=
|
|
3566
|
+
return this._sessionKey ||= randomUUID();
|
|
3942
3567
|
}
|
|
3943
3568
|
get settings() {
|
|
3944
3569
|
return this.module.settings ||= {};
|
|
3945
3570
|
}
|
|
3946
3571
|
}
|
|
3572
|
+
|
|
3947
3573
|
module.exports = ChromeDocument;
|