@pi-r/chrome 0.11.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extensions/css/remove-unused/index.js +423 -0
- package/index.d.ts +1 -1
- package/index.js +418 -797
- package/package.json +5 -5
- package/types/index.d.ts +40 -11
- package/types/squared.d.ts +2 -1
- package/util.d.ts +20 -0
- package/util.js +49 -0
package/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const { randomUUID } = require('node:crypto');
|
|
6
|
+
const { imageSize } = require('image-size');
|
|
7
|
+
const Cloud = require('@e-mc/cloud');
|
|
8
|
+
const { ClientDb } = require('@e-mc/core');
|
|
9
|
+
const { DomWriter, HtmlElement, IGNORE_FLAG } = require('@e-mc/document/parse/dom');
|
|
10
|
+
const { ERR_CODE, FILE_TYPE, WATCH_EVENT, asExt, asFunction, cascadeObject, cloneFlag, cloneObject, coerceObject, createAbortError, errorMessage, errorValue, escapePattern, existsFlag, getEncoding, ignoreFlag, isArray, isEmpty, isError, isErrorCode, isFunction, isObject, isPlainObject, isString, modifiedFlag, processFlag, randomString, renameExt, requireESM, watchFlag } = require('@e-mc/types');
|
|
11
|
+
const { isEqual, setInitialValue } = require('@e-mc/document/asset');
|
|
12
|
+
const { appendSuffix, getHashData, getModuleName, getNewline, hasValue, spliceString, trimQuote } = require('@e-mc/document/util');
|
|
13
|
+
const { SourceMap } = require('@e-mc/document/transform');
|
|
14
|
+
const { PATTERN_PARENTHESIS, findClosingIndex, getNewlineString, isSpace, replaceMatch } = require('@pi-r/chrome/util');
|
|
13
15
|
const Document = require('@e-mc/document');
|
|
14
16
|
const kChrome = Symbol.for('chrome:constructor');
|
|
15
17
|
const CACHE_DBRESULT = new Map();
|
|
@@ -19,62 +21,40 @@ const CACHE_SELECTOR = new Map();
|
|
|
19
21
|
const CACHE_ETAG = new Map();
|
|
20
22
|
const CACHE_CONTENT = new Map();
|
|
21
23
|
const CACHE_FORMAT = new Map();
|
|
22
|
-
const CACHE_DATASET =
|
|
23
|
-
const CACHE_ATRULES = {};
|
|
24
|
-
const PATTERN_STRING_SOME = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}`)*';
|
|
25
|
-
const PATTERN_STRING_MANY = PATTERN_STRING_SOME.slice(0, -1) + '+';
|
|
26
|
-
const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE, REGEXP_REPLACECSS] = (function () {
|
|
27
|
-
const parenthesis = '(?:,[^()]+(?=\\))|[^()]|\\([^()]*\\(+|\\([^()]*\\)|(?:\\)[^()]+)?\\)*?)+';
|
|
28
|
-
return [
|
|
29
|
-
new RegExp(`\\(${PATTERN_STRING_SOME}([+-])?(?:(\\d*)[nN]|(0))?${PATTERN_STRING_SOME}([+-])?${PATTERN_STRING_SOME}(\\d*)(?:${PATTERN_STRING_MANY}[oO][fF]${PATTERN_STRING_MANY}(${parenthesis})${PATTERN_STRING_SOME}\\)|${PATTERN_STRING_SOME}\\))`, 'g'),
|
|
30
|
-
new RegExp(`\\(\\s*([+-])?(?:(\\d*)[nN]|(0))?\\s*([+-])?\\s*(\\d*)(?:\\s+[oO][fF]\\s+(${parenthesis})\\s*\\)|\\s*\\))`, 'g'),
|
|
31
|
-
new RegExp(`^@import\\s+(?:url\\((?:[^)]|(?<=\\\\)\\))+\\)|"(?:[^"]|(?<=\\\\)")+"|'(?:[^']|(?<=\\\\)')+')(\\s*layer(\\([^)]*\\))?)?(?:\\s*supports\\((${parenthesis})\\))?(.*)$`, '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 {
|
|
@@ -2449,8 +2362,8 @@ class ChromeDocument extends Document {
|
|
|
2449
2362
|
case 'redis':
|
|
2450
2363
|
for (let j = 0; j < length; ++j) {
|
|
2451
2364
|
const cmd = batch[j];
|
|
2452
|
-
const
|
|
2453
|
-
if (
|
|
2365
|
+
const search = cmd.search;
|
|
2366
|
+
if (isObject(search) && typeof search.schema === 'string') {
|
|
2454
2367
|
const pathname = this.resolveDir('schema', search.schema);
|
|
2455
2368
|
if (pathname) {
|
|
2456
2369
|
if (!cmd.ignoreCache && CACHE_LOCALFILE.has(pathname)) {
|
|
@@ -2462,11 +2375,11 @@ class ChromeDocument extends Document {
|
|
|
2462
2375
|
}
|
|
2463
2376
|
if (!(search.schema = this._sessionData[pathname])) {
|
|
2464
2377
|
try {
|
|
2465
|
-
search.schema = loadLocalFile(
|
|
2378
|
+
search.schema = loadLocalFile(pathname, cmd.encoding);
|
|
2466
2379
|
this.addSessionData(current, pathname, search.schema, { template: true });
|
|
2467
2380
|
}
|
|
2468
2381
|
catch (err) {
|
|
2469
|
-
this.writeFail(['Unable to parse document', path.basename(pathname)], err
|
|
2382
|
+
this.writeFail(['Unable to parse document', path.basename(pathname)], isError(err) ? errors = err : err, 32);
|
|
2470
2383
|
search.schema = undefined;
|
|
2471
2384
|
}
|
|
2472
2385
|
}
|
|
@@ -2476,8 +2389,8 @@ class ChromeDocument extends Document {
|
|
|
2476
2389
|
search.schema = undefined;
|
|
2477
2390
|
}
|
|
2478
2391
|
}
|
|
2479
|
-
if (key) {
|
|
2480
|
-
cmd.cacheObjectKey = (
|
|
2392
|
+
if (cmd.key) {
|
|
2393
|
+
cmd.cacheObjectKey = (cmd.cascade ? cmd.cascade : '') + '_' + (cmd.query ? Document.asString(cmd.query, true) : '');
|
|
2481
2394
|
}
|
|
2482
2395
|
}
|
|
2483
2396
|
break;
|
|
@@ -2500,7 +2413,7 @@ class ChromeDocument extends Document {
|
|
|
2500
2413
|
if (!(cmd.query = this._sessionData[pathname])) {
|
|
2501
2414
|
const out = { content: '' };
|
|
2502
2415
|
try {
|
|
2503
|
-
cmd.query = loadLocalFile(
|
|
2416
|
+
cmd.query = loadLocalFile(pathname, cmd.encoding, out);
|
|
2504
2417
|
}
|
|
2505
2418
|
catch {
|
|
2506
2419
|
cmd.query = out.content;
|
|
@@ -2510,7 +2423,7 @@ class ChromeDocument extends Document {
|
|
|
2510
2423
|
}
|
|
2511
2424
|
}
|
|
2512
2425
|
else {
|
|
2513
|
-
throw
|
|
2426
|
+
throw errorMessage(type, "File not found", query);
|
|
2514
2427
|
}
|
|
2515
2428
|
}
|
|
2516
2429
|
catch (err) {
|
|
@@ -2534,7 +2447,7 @@ class ChromeDocument extends Document {
|
|
|
2534
2447
|
aborting = commandType !== db.commandType.UPDATE;
|
|
2535
2448
|
message = Document.asString(data.search || data.key);
|
|
2536
2449
|
}
|
|
2537
|
-
else if (
|
|
2450
|
+
else if (isObject(data.credential)) {
|
|
2538
2451
|
message = data.credential.database;
|
|
2539
2452
|
}
|
|
2540
2453
|
if (data.willAbort) {
|
|
@@ -2544,7 +2457,7 @@ class ChromeDocument extends Document {
|
|
|
2544
2457
|
this.abort(type, err);
|
|
2545
2458
|
}
|
|
2546
2459
|
if (err) {
|
|
2547
|
-
this.writeFail(["Unable to execute query", message || "Unknown"], err
|
|
2460
|
+
this.writeFail(["Unable to execute query", message || "Unknown"], isError(err) ? errors = err : err, { type: 65536, startTime });
|
|
2548
2461
|
}
|
|
2549
2462
|
return this.aborted;
|
|
2550
2463
|
};
|
|
@@ -2593,7 +2506,7 @@ class ChromeDocument extends Document {
|
|
|
2593
2506
|
}
|
|
2594
2507
|
if (items.length > 0 && !item.transactionFail) {
|
|
2595
2508
|
const element = item.element;
|
|
2596
|
-
const domElement = new
|
|
2509
|
+
const domElement = new HtmlElement(this.moduleName, element);
|
|
2597
2510
|
let value = '';
|
|
2598
2511
|
const checkValue = async (name) => {
|
|
2599
2512
|
const data = await this.processData(item, value, name, row => typeof row === 'string');
|
|
@@ -2636,7 +2549,7 @@ class ChromeDocument extends Document {
|
|
|
2636
2549
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2637
2550
|
if (content === null) {
|
|
2638
2551
|
++domBase.failCount;
|
|
2639
|
-
removeElement(
|
|
2552
|
+
removeElement(item, domElement);
|
|
2640
2553
|
if (length === 1) {
|
|
2641
2554
|
resolve();
|
|
2642
2555
|
return;
|
|
@@ -2648,7 +2561,7 @@ class ChromeDocument extends Document {
|
|
|
2648
2561
|
else {
|
|
2649
2562
|
for (let j = 0, match; j < items.length; ++j) {
|
|
2650
2563
|
const row = items[j];
|
|
2651
|
-
if (
|
|
2564
|
+
if (isPlainObject(row)) {
|
|
2652
2565
|
row.__index__ ??= j + 1;
|
|
2653
2566
|
}
|
|
2654
2567
|
let segment = template;
|
|
@@ -2670,28 +2583,28 @@ class ChromeDocument extends Document {
|
|
|
2670
2583
|
const literal = segment.trim();
|
|
2671
2584
|
if (literal.at(0) === '`' && literal.at(-1) === '`') {
|
|
2672
2585
|
if (!this.hasEval('function')) {
|
|
2673
|
-
errors =
|
|
2586
|
+
errors = errorMessage('eval', "Unsupported access", 'function');
|
|
2674
2587
|
continue;
|
|
2675
2588
|
}
|
|
2676
2589
|
try {
|
|
2677
2590
|
let unsafe = new Function('return ' + literal + ';').call(row);
|
|
2678
2591
|
if (!segment.startsWith('`')) {
|
|
2679
|
-
unsafe = segment.
|
|
2592
|
+
unsafe = segment.slice(0, segment.indexOf('`')) + unsafe;
|
|
2680
2593
|
}
|
|
2681
2594
|
if (!segment.endsWith('`')) {
|
|
2682
|
-
unsafe += segment.
|
|
2595
|
+
unsafe += segment.slice(segment.lastIndexOf('`') + 1);
|
|
2683
2596
|
}
|
|
2684
2597
|
segment = unsafe;
|
|
2685
2598
|
}
|
|
2686
2599
|
catch (err) {
|
|
2687
|
-
errors = err
|
|
2600
|
+
errors = isError(err) ? err : true;
|
|
2688
2601
|
continue;
|
|
2689
2602
|
}
|
|
2690
2603
|
}
|
|
2691
2604
|
else {
|
|
2692
2605
|
const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
|
|
2693
2606
|
while (match = pattern.exec(segment)) {
|
|
2694
|
-
segment = replaceMatch(match, segment, match[1] === "__index__" && !
|
|
2607
|
+
segment = replaceMatch(match, segment, match[1] === "__index__" && !isObject(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
|
|
2695
2608
|
}
|
|
2696
2609
|
}
|
|
2697
2610
|
value += trimTemplate(segment);
|
|
@@ -2707,7 +2620,7 @@ class ChromeDocument extends Document {
|
|
|
2707
2620
|
if (trailingText) {
|
|
2708
2621
|
value += trailingText;
|
|
2709
2622
|
}
|
|
2710
|
-
domElement.innerXml = domBase.initOpts.normalize ?
|
|
2623
|
+
domElement.innerXml = domBase.initOpts.normalize ? DomWriter.normalize(value, { newline: domBase.newline, escapeEntities: domBase.initOpts.escapeEntities }) : value;
|
|
2711
2624
|
}
|
|
2712
2625
|
else {
|
|
2713
2626
|
errors = true;
|
|
@@ -2716,12 +2629,12 @@ class ChromeDocument extends Document {
|
|
|
2716
2629
|
}
|
|
2717
2630
|
case 'attribute': {
|
|
2718
2631
|
const map = item.value;
|
|
2719
|
-
if (
|
|
2632
|
+
if (isPlainObject(map)) {
|
|
2720
2633
|
for (const attr in map) {
|
|
2721
2634
|
value = '';
|
|
2722
2635
|
let segment = map[attr], valid = false;
|
|
2723
2636
|
if (item.viewEngine) {
|
|
2724
|
-
if (!
|
|
2637
|
+
if (!isString(segment)) {
|
|
2725
2638
|
errors = true;
|
|
2726
2639
|
continue;
|
|
2727
2640
|
}
|
|
@@ -2734,10 +2647,10 @@ class ChromeDocument extends Document {
|
|
|
2734
2647
|
valid = true;
|
|
2735
2648
|
}
|
|
2736
2649
|
else {
|
|
2737
|
-
if (
|
|
2650
|
+
if (isString(segment)) {
|
|
2738
2651
|
segment = [segment];
|
|
2739
2652
|
}
|
|
2740
|
-
else if (!
|
|
2653
|
+
else if (!isArray(segment)) {
|
|
2741
2654
|
errors = true;
|
|
2742
2655
|
continue;
|
|
2743
2656
|
}
|
|
@@ -2796,10 +2709,10 @@ class ChromeDocument extends Document {
|
|
|
2796
2709
|
if (template) {
|
|
2797
2710
|
if (item.viewEngine) {
|
|
2798
2711
|
errors = true;
|
|
2799
|
-
if (
|
|
2712
|
+
if (isString(template)) {
|
|
2800
2713
|
const content = await this.parseTemplate(item.viewEngine, template, items);
|
|
2801
2714
|
if (content !== null) {
|
|
2802
|
-
if (
|
|
2715
|
+
if (isString(content) && content.trim() === '') {
|
|
2803
2716
|
domElement.remove = true;
|
|
2804
2717
|
}
|
|
2805
2718
|
errors = false;
|
|
@@ -2807,10 +2720,10 @@ class ChromeDocument extends Document {
|
|
|
2807
2720
|
}
|
|
2808
2721
|
}
|
|
2809
2722
|
else {
|
|
2810
|
-
if (
|
|
2723
|
+
if (isString(template)) {
|
|
2811
2724
|
template = [template];
|
|
2812
2725
|
}
|
|
2813
|
-
else if (!
|
|
2726
|
+
else if (!isArray(template)) {
|
|
2814
2727
|
errors = true;
|
|
2815
2728
|
continue;
|
|
2816
2729
|
}
|
|
@@ -2850,7 +2763,7 @@ class ChromeDocument extends Document {
|
|
|
2850
2763
|
}
|
|
2851
2764
|
const sign = seg[0];
|
|
2852
2765
|
if (sign === '+' || sign === '-') {
|
|
2853
|
-
seg = seg.
|
|
2766
|
+
seg = seg.slice(1);
|
|
2854
2767
|
}
|
|
2855
2768
|
const data = getObjectValue(row, seg);
|
|
2856
2769
|
let keep = true;
|
|
@@ -2899,7 +2812,7 @@ class ChromeDocument extends Document {
|
|
|
2899
2812
|
break;
|
|
2900
2813
|
}
|
|
2901
2814
|
default:
|
|
2902
|
-
removeElement(
|
|
2815
|
+
removeElement(item, domElement);
|
|
2903
2816
|
if (length === 1) {
|
|
2904
2817
|
reject(errorDataSource('Invalid action', item.type || "Unknown"));
|
|
2905
2818
|
return;
|
|
@@ -2907,7 +2820,7 @@ class ChromeDocument extends Document {
|
|
|
2907
2820
|
break invalid;
|
|
2908
2821
|
}
|
|
2909
2822
|
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
|
|
2823
|
+
this.writeFail(item.type === 'display' ? domElement.remove && errors !== 1 ? errors ? 'Element was removed with errors' : 'Unable to remove element' : 'Unable to determine display conditional' : 'Unable to replace ' + item.type, isError(errors) ? errors : errorHtml(element), { type: 4, startTime });
|
|
2911
2824
|
}
|
|
2912
2825
|
}
|
|
2913
2826
|
}
|
|
@@ -2915,7 +2828,7 @@ class ChromeDocument extends Document {
|
|
|
2915
2828
|
if (!empty && item.type !== 'display' || item.transactionFail) {
|
|
2916
2829
|
const emptyResponse = (value, service = item.source) => {
|
|
2917
2830
|
value ||= "Unknown";
|
|
2918
|
-
return errorDataSource(errors
|
|
2831
|
+
return errorDataSource(isError(errors) ? errors.message : service + ': Empty', value);
|
|
2919
2832
|
};
|
|
2920
2833
|
switch (item.source) {
|
|
2921
2834
|
case 'cloud': {
|
|
@@ -2925,12 +2838,12 @@ class ChromeDocument extends Document {
|
|
|
2925
2838
|
break;
|
|
2926
2839
|
}
|
|
2927
2840
|
case 'uri': {
|
|
2928
|
-
const { uri, format = uri &&
|
|
2841
|
+
const { uri, format = uri && asExt(uri) } = item;
|
|
2929
2842
|
this.formatFail(4, format || 'URI', ['No records were found', uri], emptyResponse(uri));
|
|
2930
2843
|
break;
|
|
2931
2844
|
}
|
|
2932
2845
|
case 'local': {
|
|
2933
|
-
const { pathname, format = pathname &&
|
|
2846
|
+
const { pathname, format = pathname && asExt(pathname) } = item;
|
|
2934
2847
|
this.formatFail(4, format || 'LOCAL', ['No records were found', pathname], emptyResponse(pathname));
|
|
2935
2848
|
break;
|
|
2936
2849
|
}
|
|
@@ -2945,7 +2858,7 @@ class ChromeDocument extends Document {
|
|
|
2945
2858
|
}
|
|
2946
2859
|
}
|
|
2947
2860
|
}
|
|
2948
|
-
removeElement(
|
|
2861
|
+
removeElement(item);
|
|
2949
2862
|
}
|
|
2950
2863
|
}
|
|
2951
2864
|
resolve();
|
|
@@ -2959,13 +2872,51 @@ class ChromeDocument extends Document {
|
|
|
2959
2872
|
await setElements(displayItems);
|
|
2960
2873
|
}
|
|
2961
2874
|
}
|
|
2962
|
-
|
|
2875
|
+
async transformJs(processing, file, source) {
|
|
2876
|
+
const options = { file };
|
|
2877
|
+
let modified = false;
|
|
2878
|
+
for (const method of this.extensionsOf('js')) {
|
|
2879
|
+
try {
|
|
2880
|
+
const output = await method.call(this, source, options);
|
|
2881
|
+
if (isString(output)) {
|
|
2882
|
+
source = output;
|
|
2883
|
+
modified = true;
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
catch (err) {
|
|
2887
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
if (modified) {
|
|
2891
|
+
return source;
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
async transformCss(processing, file, source) {
|
|
2895
|
+
const options = { file, config: this.config };
|
|
2896
|
+
let modified = false;
|
|
2897
|
+
for (const method of this.extensionsOf('css')) {
|
|
2898
|
+
try {
|
|
2899
|
+
const output = await method.call(this, source, options);
|
|
2900
|
+
if (isString(output)) {
|
|
2901
|
+
source = output;
|
|
2902
|
+
modified = true;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
catch (err) {
|
|
2906
|
+
this.writeFail(["Unable to transform document", file.filename], err, { type: 4, startTime: processing.startTime, fatal: false });
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
if (modified) {
|
|
2910
|
+
return source;
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
setProductionAttributes(processing) {
|
|
2963
2914
|
for (const item of this.assets) {
|
|
2964
2915
|
if (isIgnored(item, true)) {
|
|
2965
2916
|
continue;
|
|
2966
2917
|
}
|
|
2967
|
-
if (item.hash && !hashed.has(item)) {
|
|
2968
|
-
createHash(
|
|
2918
|
+
if (item.hash && !processing.hashed.has(item)) {
|
|
2919
|
+
this.createHash(processing, item, item.hash);
|
|
2969
2920
|
}
|
|
2970
2921
|
switch (item.element?.tagName.toLowerCase()) {
|
|
2971
2922
|
case 'style':
|
|
@@ -2976,23 +2927,23 @@ class ChromeDocument extends Document {
|
|
|
2976
2927
|
case 'script': {
|
|
2977
2928
|
const attributes = item.attributes;
|
|
2978
2929
|
if (attributes) {
|
|
2979
|
-
const algorithm =
|
|
2930
|
+
const algorithm = isString(attributes.integrity) ? attributes.integrity.toLowerCase() : '';
|
|
2980
2931
|
switch (algorithm) {
|
|
2981
2932
|
case 'sha256':
|
|
2982
2933
|
case 'sha384':
|
|
2983
2934
|
case 'sha512':
|
|
2984
2935
|
try {
|
|
2985
|
-
const data = getBuffer(item);
|
|
2986
|
-
|
|
2987
|
-
if (
|
|
2936
|
+
const data = processing.getBuffer(item);
|
|
2937
|
+
const value = data && Document.asHash(data, { algorithm, digestEncoding: 'base64', encoding: item.encoding });
|
|
2938
|
+
if (value) {
|
|
2988
2939
|
attributes.integrity = algorithm + '-' + value;
|
|
2989
2940
|
attributes.crossorigin ||= 'anonymous';
|
|
2990
2941
|
break;
|
|
2991
2942
|
}
|
|
2992
|
-
throw
|
|
2943
|
+
throw errorMessage('hash', 'Source not found', item.filename);
|
|
2993
2944
|
}
|
|
2994
2945
|
catch (err) {
|
|
2995
|
-
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime });
|
|
2946
|
+
this.writeFail(["Unable to read file", item.filename], err, { type: 32, startTime: processing.startTime });
|
|
2996
2947
|
}
|
|
2997
2948
|
default:
|
|
2998
2949
|
if (algorithm) {
|
|
@@ -3006,391 +2957,26 @@ class ChromeDocument extends Document {
|
|
|
3006
2957
|
}
|
|
3007
2958
|
}
|
|
3008
2959
|
}
|
|
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;
|
|
2960
|
+
createHash(processing, file, hash) {
|
|
2961
|
+
const { host, bufferMap } = processing;
|
|
2962
|
+
const { filename, localUri } = file;
|
|
2963
|
+
try {
|
|
2964
|
+
const buffer = localUri && bufferMap[localUri] || processing.getBuffer(file, localUri);
|
|
2965
|
+
if (buffer) {
|
|
2966
|
+
const [algorithm, length] = getHashData(hash);
|
|
2967
|
+
const value = algorithm ? Document.asHash(buffer, algorithm, { encoding: file.encoding }) : '';
|
|
2968
|
+
if (value) {
|
|
2969
|
+
if (localUri) {
|
|
2970
|
+
bufferMap[localUri] = buffer;
|
|
3375
2971
|
}
|
|
2972
|
+
host.rename(file, appendSuffix(filename, length > 0 ? value.slice(0, length) : value));
|
|
2973
|
+
return file.filename;
|
|
3376
2974
|
}
|
|
3377
2975
|
}
|
|
3378
|
-
|
|
2976
|
+
throw errorMessage('hash', 'Source not found', filename);
|
|
3379
2977
|
}
|
|
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;
|
|
2978
|
+
catch (err) {
|
|
2979
|
+
host.writeFail(["Unable to read file", filename], err, 32);
|
|
3394
2980
|
}
|
|
3395
2981
|
}
|
|
3396
2982
|
getSrcUrl(parent, file) {
|
|
@@ -3435,13 +3021,13 @@ class ChromeDocument extends Document {
|
|
|
3435
3021
|
file.inlineBase64 ||
|
|
3436
3022
|
this.replaced.includes(file) ||
|
|
3437
3023
|
initialValue && (file.inlineFilename !== initialValue.inlineFilename || file.pathname !== initialValue.pathname || initialValue.cacheable === false) ||
|
|
3438
|
-
format && (
|
|
3024
|
+
format && (hasValue(format, 'base64') || hasValue(format, 'woff') || hasValue(format, 'woff2')) ? true : false);
|
|
3439
3025
|
}
|
|
3440
3026
|
async processData(item, result, method, validate) {
|
|
3441
3027
|
let callback;
|
|
3442
3028
|
if (typeof method === 'string') {
|
|
3443
3029
|
const template = this.findDataValue(method) || method;
|
|
3444
|
-
callback = this.hasEval('userconfig') ? Document.parseFunction(template, this.hasEval('absolute')) :
|
|
3030
|
+
callback = this.hasEval('userconfig') ? Document.parseFunction(template, { absolute: this.hasEval('absolute'), default: true }) : asFunction(template);
|
|
3445
3031
|
}
|
|
3446
3032
|
else {
|
|
3447
3033
|
callback = method;
|
|
@@ -3450,7 +3036,7 @@ class ChromeDocument extends Document {
|
|
|
3450
3036
|
if (typeof callback === 'function') {
|
|
3451
3037
|
try {
|
|
3452
3038
|
let output;
|
|
3453
|
-
if (
|
|
3039
|
+
if (isFunction(callback, true)) {
|
|
3454
3040
|
output = await callback(result, item);
|
|
3455
3041
|
}
|
|
3456
3042
|
else {
|
|
@@ -3471,14 +3057,8 @@ class ChromeDocument extends Document {
|
|
|
3471
3057
|
}
|
|
3472
3058
|
}
|
|
3473
3059
|
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
3060
|
if (output.map) {
|
|
3481
|
-
writeSourceMap(file
|
|
3061
|
+
this.writeSourceMap(host, file, output);
|
|
3482
3062
|
}
|
|
3483
3063
|
if (output.chunks) {
|
|
3484
3064
|
const elements = this.elements;
|
|
@@ -3490,7 +3070,7 @@ class ChromeDocument extends Document {
|
|
|
3490
3070
|
if (element) {
|
|
3491
3071
|
for (const item of elements) {
|
|
3492
3072
|
const append = item.append;
|
|
3493
|
-
if (append && !append.prepend &&
|
|
3073
|
+
if (append && !append.prepend && DomWriter.isEqual(item, element, host.moduleName, true)) {
|
|
3494
3074
|
(appending ||= []).push(append);
|
|
3495
3075
|
}
|
|
3496
3076
|
}
|
|
@@ -3503,7 +3083,7 @@ class ChromeDocument extends Document {
|
|
|
3503
3083
|
}
|
|
3504
3084
|
const chunkUri = path.join(localDir, chunkName);
|
|
3505
3085
|
if (chunk.map) {
|
|
3506
|
-
writeSourceMap(
|
|
3086
|
+
this.writeSourceMap(host, file, chunk, chunkUri);
|
|
3507
3087
|
}
|
|
3508
3088
|
try {
|
|
3509
3089
|
fs.writeFileSync(chunkUri, chunk.code);
|
|
@@ -3517,11 +3097,11 @@ class ChromeDocument extends Document {
|
|
|
3517
3097
|
elements.push({
|
|
3518
3098
|
...element,
|
|
3519
3099
|
attributes,
|
|
3520
|
-
append: { tagName: 'script', tagCount: element.tagCount, nextSibling:
|
|
3100
|
+
append: { tagName: 'script', tagCount: element.tagCount, nextSibling: DomWriter.isIndex(element.index) ? element.index + 1 : undefined, order: ++order }
|
|
3521
3101
|
});
|
|
3522
3102
|
}
|
|
3523
3103
|
else {
|
|
3524
|
-
this.writeFail(['Unable to create entry point', path.basename(chunkUri)],
|
|
3104
|
+
this.writeFail(['Unable to create entry point', path.basename(chunkUri)], errorMessage('js', 'Element not found', chunkUri), 4);
|
|
3525
3105
|
}
|
|
3526
3106
|
}
|
|
3527
3107
|
}
|
|
@@ -3533,7 +3113,7 @@ class ChromeDocument extends Document {
|
|
|
3533
3113
|
item.order += order;
|
|
3534
3114
|
});
|
|
3535
3115
|
}
|
|
3536
|
-
if (
|
|
3116
|
+
if (isArray(output.sourceFiles)) {
|
|
3537
3117
|
file.sourceFiles = output.sourceFiles;
|
|
3538
3118
|
}
|
|
3539
3119
|
file.modified = true;
|
|
@@ -3544,7 +3124,7 @@ class ChromeDocument extends Document {
|
|
|
3544
3124
|
const baseHref = collectBaseUrl(importFile || file, this.baseUrl);
|
|
3545
3125
|
const isHtml = type === 'html';
|
|
3546
3126
|
const isJs = type === 'js';
|
|
3547
|
-
const imageSet =
|
|
3127
|
+
const imageSet = /(?:\b(?<!-)|(?<!-)-webkit-)image-set\(/gi;
|
|
3548
3128
|
const pattern = isJs ? /\b(?<!-)import\(/g : type === 'svg' ? /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi : /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi;
|
|
3549
3129
|
let length = source.length, modified = false, match;
|
|
3550
3130
|
while (match = imageSet.exec(source)) {
|
|
@@ -3552,15 +3132,15 @@ class ChromeDocument extends Document {
|
|
|
3552
3132
|
const endIndex = findClosingIndex(source, startIndex, '(');
|
|
3553
3133
|
if (endIndex !== -1) {
|
|
3554
3134
|
REGEXP_IMAGESET_URL.lastIndex = 0;
|
|
3555
|
-
let content = source.
|
|
3135
|
+
let content = source.slice(startIndex, endIndex), url;
|
|
3556
3136
|
while (url = REGEXP_IMAGESET_URL.exec(content)) {
|
|
3557
3137
|
const quote = url[2] ? '"' : "'";
|
|
3558
3138
|
const [a, b] = url.indices[1];
|
|
3559
|
-
content =
|
|
3139
|
+
content = spliceString(content, a, b, `url(${quote + (url[2] || url[3]).trim() + quote})`, REGEXP_IMAGESET_URL);
|
|
3560
3140
|
modified = true;
|
|
3561
3141
|
}
|
|
3562
3142
|
if (modified) {
|
|
3563
|
-
source =
|
|
3143
|
+
source = spliceString(source, startIndex, endIndex, content, imageSet);
|
|
3564
3144
|
modified = false;
|
|
3565
3145
|
}
|
|
3566
3146
|
}
|
|
@@ -3615,7 +3195,8 @@ class ChromeDocument extends Document {
|
|
|
3615
3195
|
i = closed;
|
|
3616
3196
|
}
|
|
3617
3197
|
else {
|
|
3618
|
-
|
|
3198
|
+
i = j;
|
|
3199
|
+
content = content.slice(0, i);
|
|
3619
3200
|
}
|
|
3620
3201
|
break;
|
|
3621
3202
|
}
|
|
@@ -3630,12 +3211,12 @@ class ChromeDocument extends Document {
|
|
|
3630
3211
|
if (asset) {
|
|
3631
3212
|
if (!asset.inlineBase64) {
|
|
3632
3213
|
if (host.Cloud?.getStorage('upload', asset.cloudStorage)) {
|
|
3633
|
-
const inlineUrlCloud = asset.inlineUrlCloud ||=
|
|
3214
|
+
const inlineUrlCloud = asset.inlineUrlCloud ||= randomUUID();
|
|
3634
3215
|
(file.inlineUrlCloudMap ||= {})[inlineUrlCloud] = value;
|
|
3635
3216
|
value = inlineUrlCloud;
|
|
3636
3217
|
}
|
|
3637
3218
|
else if (asset.hash && this.productionRelease) {
|
|
3638
|
-
const inlineUrl = asset.inlineUrl ||=
|
|
3219
|
+
const inlineUrl = asset.inlineUrl ||= randomUUID();
|
|
3639
3220
|
(file.inlineUrlMap ||= {})[inlineUrl] = value;
|
|
3640
3221
|
value = inlineUrl;
|
|
3641
3222
|
}
|
|
@@ -3646,7 +3227,7 @@ class ChromeDocument extends Document {
|
|
|
3646
3227
|
for (let k = i + 1; k < length; ++k) {
|
|
3647
3228
|
switch (source[k]) {
|
|
3648
3229
|
case ')': {
|
|
3649
|
-
const component = source.
|
|
3230
|
+
const component = source.slice(i + 1, k + 1);
|
|
3650
3231
|
const format = /\s+format\([^)]+\)$/i.exec(component);
|
|
3651
3232
|
if (format) {
|
|
3652
3233
|
trailing = component.replace(format[0], ` format("${font}")`);
|
|
@@ -3680,14 +3261,14 @@ class ChromeDocument extends Document {
|
|
|
3680
3261
|
if (isUrl) {
|
|
3681
3262
|
const index = value.indexOf('#');
|
|
3682
3263
|
if (index !== -1) {
|
|
3683
|
-
value = value.
|
|
3264
|
+
value = value.slice(0, index);
|
|
3684
3265
|
}
|
|
3685
3266
|
}
|
|
3686
3267
|
if (quote) {
|
|
3687
3268
|
value = quote + value + quote;
|
|
3688
3269
|
}
|
|
3689
3270
|
const revised = isJs ? `import(${value + trailing})` : isHref ? 'href=' + value : (isText ? '@import ' + value : `url(${value})`) + trailing;
|
|
3690
|
-
source =
|
|
3271
|
+
source = spliceString(source, startIndex, i + 1, revised, pattern);
|
|
3691
3272
|
length = source.length;
|
|
3692
3273
|
modified = true;
|
|
3693
3274
|
};
|
|
@@ -3702,11 +3283,11 @@ class ChromeDocument extends Document {
|
|
|
3702
3283
|
trailing = target[2].trim();
|
|
3703
3284
|
}
|
|
3704
3285
|
else {
|
|
3705
|
-
url =
|
|
3286
|
+
url = trimQuote(content);
|
|
3706
3287
|
}
|
|
3707
3288
|
}
|
|
3708
3289
|
else {
|
|
3709
|
-
url =
|
|
3290
|
+
url = trimQuote(content);
|
|
3710
3291
|
}
|
|
3711
3292
|
if (url.startsWith('data:')) {
|
|
3712
3293
|
const base64 = url.split(',')[1]?.trim();
|
|
@@ -3732,34 +3313,35 @@ class ChromeDocument extends Document {
|
|
|
3732
3313
|
}
|
|
3733
3314
|
}
|
|
3734
3315
|
if (asset && asset !== importFile) {
|
|
3735
|
-
if (!
|
|
3316
|
+
if (!hasValue(asset.format, 'base64')) {
|
|
3736
3317
|
if (asset.bundleReplace) {
|
|
3737
3318
|
let k = 0, valid = true;
|
|
3738
3319
|
if (!isText) {
|
|
3739
3320
|
let j = startIndex;
|
|
3740
3321
|
while (isSpace(source[--j])) { }
|
|
3741
|
-
|
|
3322
|
+
k = j - 6;
|
|
3323
|
+
valid = source.slice(k, j + 1).toLowerCase() === '@import';
|
|
3742
3324
|
}
|
|
3743
3325
|
else {
|
|
3744
3326
|
k = startIndex;
|
|
3745
3327
|
}
|
|
3746
3328
|
if (valid) {
|
|
3747
|
-
let l = i, revised =
|
|
3329
|
+
let l = i, revised = SourceMap.removeSourceMappingURL(host.getUTF8String(asset))[0];
|
|
3748
3330
|
for (let ch; l < length; ++l) {
|
|
3749
3331
|
if ((ch = source[l]) === ';' || ch === '\n') {
|
|
3750
3332
|
break;
|
|
3751
3333
|
}
|
|
3752
3334
|
}
|
|
3753
|
-
const layer = this.replaceContent(revised, source.
|
|
3335
|
+
const layer = this.replaceContent(revised, source.slice(k, l + 1), "text/css");
|
|
3754
3336
|
if (layer) {
|
|
3755
3337
|
revised = layer;
|
|
3756
3338
|
}
|
|
3757
3339
|
revised = this.processUrl(host, file, this.removeServerRoot(revised), type, asset) || revised;
|
|
3758
|
-
source =
|
|
3340
|
+
source = spliceString(source, k, l + 1, revised, pattern);
|
|
3759
3341
|
length = source.length;
|
|
3760
3342
|
if (file.watch) {
|
|
3761
3343
|
related.push(asset);
|
|
3762
|
-
if (!
|
|
3344
|
+
if (!existsFlag(asset.flags)) {
|
|
3763
3345
|
asset.flags |= 8;
|
|
3764
3346
|
}
|
|
3765
3347
|
}
|
|
@@ -3785,7 +3367,7 @@ class ChromeDocument extends Document {
|
|
|
3785
3367
|
}
|
|
3786
3368
|
}
|
|
3787
3369
|
else if (!asset.invalid) {
|
|
3788
|
-
fullUrl = asset.inlineBase64 ||=
|
|
3370
|
+
fullUrl = asset.inlineBase64 ||= randomUUID();
|
|
3789
3371
|
}
|
|
3790
3372
|
if (url !== fullUrl) {
|
|
3791
3373
|
setOutputURL(fullUrl, asset);
|
|
@@ -3818,7 +3400,7 @@ class ChromeDocument extends Document {
|
|
|
3818
3400
|
if (value) {
|
|
3819
3401
|
const index = value.indexOf(ChromeDocument.INTERNAL_ASSIGNUUID);
|
|
3820
3402
|
if (index !== -1) {
|
|
3821
|
-
target[attr] =
|
|
3403
|
+
target[attr] = spliceString(value, index, index + ChromeDocument.INTERNAL_ASSIGNUUID.length, this.formatLocation(attr, nameExt));
|
|
3822
3404
|
modified.push(attr);
|
|
3823
3405
|
return true;
|
|
3824
3406
|
}
|
|
@@ -3829,15 +3411,27 @@ class ChromeDocument extends Document {
|
|
|
3829
3411
|
checkAttribute('pathname');
|
|
3830
3412
|
return modified;
|
|
3831
3413
|
}
|
|
3414
|
+
writeSourceMap(host, file, data, uri, hash) {
|
|
3415
|
+
if (!uri && (uri = file.localUri)) {
|
|
3416
|
+
hash ||= file.hash;
|
|
3417
|
+
}
|
|
3418
|
+
else {
|
|
3419
|
+
return;
|
|
3420
|
+
}
|
|
3421
|
+
const value = Document.writeSourceMap(uri, data, { hash, emptySources: !!this.productionRelease, inlineMap: hasSourceMap(file.metadata, 'inline') });
|
|
3422
|
+
if (value) {
|
|
3423
|
+
host.add(value, file, FILE_TYPE.SOURCEMAP);
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3832
3426
|
formatLocation(attr, nameExt) {
|
|
3833
3427
|
const format = this.formatMap || this.module.format;
|
|
3834
|
-
if (
|
|
3428
|
+
if (format) {
|
|
3835
3429
|
const pattern = nameExt && nameExt in format ? format[nameExt] : format.uuid;
|
|
3836
|
-
if (
|
|
3837
|
-
return
|
|
3430
|
+
if (pattern && isString(pattern[attr])) {
|
|
3431
|
+
return randomString(pattern[attr], pattern.dictionary);
|
|
3838
3432
|
}
|
|
3839
3433
|
}
|
|
3840
|
-
return
|
|
3434
|
+
return randomUUID();
|
|
3841
3435
|
}
|
|
3842
3436
|
createTransformOptions(host, file, mimeType, source = {}) {
|
|
3843
3437
|
if (typeof source === 'string') {
|
|
@@ -3850,7 +3444,7 @@ class ChromeDocument extends Document {
|
|
|
3850
3444
|
case "text/css":
|
|
3851
3445
|
Object.assign(metadata, this.config);
|
|
3852
3446
|
default:
|
|
3853
|
-
if ((
|
|
3447
|
+
if (isPlainObject(file.metadata)) {
|
|
3854
3448
|
Object.assign(metadata, file.metadata);
|
|
3855
3449
|
}
|
|
3856
3450
|
break;
|
|
@@ -3870,17 +3464,17 @@ class ChromeDocument extends Document {
|
|
|
3870
3464
|
options.getSourceFiles = this.locateSourceFiles(file, source.code, source.contentFiles || (localUri ? host.contentToAppend.get(localUri) : undefined));
|
|
3871
3465
|
}
|
|
3872
3466
|
}
|
|
3873
|
-
if ((!this.productionRelease || this.productionIncremental) && !
|
|
3467
|
+
if ((!this.productionRelease || this.productionIncremental) && !modifiedFlag(file.flags)) {
|
|
3874
3468
|
options.cacheData = { uri: !file.exported ? uri : undefined, etag: !file.modified ? file.etag : undefined, encoding: file.encoding };
|
|
3875
3469
|
}
|
|
3876
3470
|
return options;
|
|
3877
3471
|
}
|
|
3878
3472
|
addSessionData(item, key, data, { timeout = 0, template = false } = {}) {
|
|
3879
|
-
if (
|
|
3473
|
+
if (isObject(data) || template && data != null) {
|
|
3880
3474
|
if (timeout === 0) {
|
|
3881
3475
|
const cache = this.settingsOf(item.source, template && item.source !== 'local' ? 'local_file' : 'cache');
|
|
3882
3476
|
if (cache) {
|
|
3883
|
-
timeout =
|
|
3477
|
+
timeout = ClientDb.getTimeout(cache);
|
|
3884
3478
|
}
|
|
3885
3479
|
}
|
|
3886
3480
|
if (timeout > 0) {
|
|
@@ -3891,6 +3485,32 @@ class ChromeDocument extends Document {
|
|
|
3891
3485
|
}
|
|
3892
3486
|
}
|
|
3893
3487
|
}
|
|
3488
|
+
#replaceCss(file) {
|
|
3489
|
+
const sanitizeCss = (map) => {
|
|
3490
|
+
for (const id in map) {
|
|
3491
|
+
map[id] = this.removeServerRoot(map[id]);
|
|
3492
|
+
}
|
|
3493
|
+
};
|
|
3494
|
+
if (file.inlineUrlMap) {
|
|
3495
|
+
sanitizeCss(file.inlineUrlMap);
|
|
3496
|
+
}
|
|
3497
|
+
if (file.inlineUrlCloudMap) {
|
|
3498
|
+
sanitizeCss(file.inlineUrlCloudMap);
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3501
|
+
#replaceHtml(source, { productionRelease, contentMap }, cssMap) {
|
|
3502
|
+
const finalizeHtml = (value, data) => {
|
|
3503
|
+
for (const id in data) {
|
|
3504
|
+
value = value.replace(new RegExp(escapePattern(id), 'g'), data[id]);
|
|
3505
|
+
}
|
|
3506
|
+
return value;
|
|
3507
|
+
};
|
|
3508
|
+
if (cssMap) {
|
|
3509
|
+
source = finalizeHtml(source, cssMap);
|
|
3510
|
+
}
|
|
3511
|
+
source = finalizeHtml(source, contentMap);
|
|
3512
|
+
return productionRelease ? this.removeServerRoot(source) : source;
|
|
3513
|
+
}
|
|
3894
3514
|
get elements() {
|
|
3895
3515
|
if (this._elements) {
|
|
3896
3516
|
return this._elements;
|
|
@@ -3902,13 +3522,13 @@ class ChromeDocument extends Document {
|
|
|
3902
3522
|
for (const item of this.assets) {
|
|
3903
3523
|
const { element, id, flags } = item;
|
|
3904
3524
|
if (element) {
|
|
3905
|
-
if (restartable && id && !
|
|
3525
|
+
if (restartable && id && !cloneFlag(flags)) {
|
|
3906
3526
|
const backup = idMap[id];
|
|
3907
3527
|
if (backup) {
|
|
3908
|
-
elements.add(item.element =
|
|
3528
|
+
elements.add(item.element = cloneObject(backup, true));
|
|
3909
3529
|
continue;
|
|
3910
3530
|
}
|
|
3911
|
-
idMap[id] =
|
|
3531
|
+
idMap[id] = cloneObject(element, true);
|
|
3912
3532
|
}
|
|
3913
3533
|
elements.add(element);
|
|
3914
3534
|
}
|
|
@@ -3933,15 +3553,16 @@ class ChromeDocument extends Document {
|
|
|
3933
3553
|
const host = this.host;
|
|
3934
3554
|
if (host) {
|
|
3935
3555
|
const items = host.getDataSourceItems(this);
|
|
3936
|
-
return this._dataSource = host.restartable || this.watching ? items.map(item =>
|
|
3556
|
+
return this._dataSource = host.restartable || this.watching ? items.map(item => cloneObject(item, true)) : items;
|
|
3937
3557
|
}
|
|
3938
3558
|
return [];
|
|
3939
3559
|
}
|
|
3940
3560
|
get sessionKey() {
|
|
3941
|
-
return this._sessionKey ||=
|
|
3561
|
+
return this._sessionKey ||= randomUUID();
|
|
3942
3562
|
}
|
|
3943
3563
|
get settings() {
|
|
3944
3564
|
return this.module.settings ||= {};
|
|
3945
3565
|
}
|
|
3946
3566
|
}
|
|
3567
|
+
|
|
3947
3568
|
module.exports = ChromeDocument;
|