@pi-r/chrome 0.3.0 → 0.6.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/index.js +286 -164
- package/package.json +5 -5
- package/types/index.d.ts +7 -0
- package/types/squared.d.ts +1 -0
package/index.js
CHANGED
|
@@ -12,38 +12,53 @@ const transform_1 = require("@e-mc/document/transform");
|
|
|
12
12
|
const Document = require('@e-mc/document');
|
|
13
13
|
const CACHE_DBRESULT = new Map();
|
|
14
14
|
const CACHE_LOCALFILE = new Map();
|
|
15
|
+
const CACHE_QUERY = new Map();
|
|
16
|
+
const CACHE_SELECTOR = new Map();
|
|
15
17
|
const CACHE_DATASET = {};
|
|
16
18
|
const CACHE_ATRULES = {};
|
|
17
19
|
let CACHE_TOTAL = 0;
|
|
20
|
+
const [PATTERN_STRING_SOME, PATTERN_STRING_MANY] = (function () {
|
|
21
|
+
const grouping = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`)';
|
|
22
|
+
return [grouping + '*', grouping + '+'];
|
|
23
|
+
})();
|
|
24
|
+
const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE] = (function () {
|
|
25
|
+
const parenthesis = '(?:,[^()]+(?=\\))|[^()]|\\([^()]*\\(+|\\([^()]*\\)|(?:\\)[^()]+)?\\)*?)+';
|
|
26
|
+
return [
|
|
27
|
+
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'),
|
|
28
|
+
new RegExp(`\\(\\s*([+-])?(?:(\\d*)[nN]|(0))?\\s*([+-])?\\s*(\\d*)(?:\\s+[oO][fF]\\s+(${parenthesis})\\s*\\)|\\s*\\))`, 'g')
|
|
29
|
+
];
|
|
30
|
+
})();
|
|
18
31
|
const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
|
|
19
32
|
const REGEXP_TEMPLATECONDITIONAL = /(\n\s+)?\{\{if\s+((?:[^}]|}(?!}))+?)\}\}(\s*)([\S\s]*?)(?:\s*\{\{else(?:\s+if\s+((?:[^}]|}(?!}))+?))?\}\}(\s*)([\S\s]*?)\s*)?\s*\{\{end\}\}/g;
|
|
20
|
-
const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(
|
|
21
|
-
const REGEXP_TEMPLATEMATCH = new RegExp(`^(
|
|
22
|
-
const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]
|
|
33
|
+
const REGEXP_TEMPLATECOMPARISON = /\s*\(\s*(?:\b(eq|ne|lt|le|gt|ge)\s+)?("[^"]+"|'[^']+'|[^\s)]+)(?:\s+("[^"]+"|'[^']+'|[^\s)]+))?\s*\)/g;
|
|
34
|
+
const REGEXP_TEMPLATEMATCH = new RegExp(`^(?:\\b(and|or|not)\\s+)?((?:${REGEXP_TEMPLATECOMPARISON.source})+)|(!|not\\s+)?([^\\s][\\S\\s]*)$`);
|
|
35
|
+
const REGEXP_IMPORTMODULE = /(?:(?:^|[\n;]+)\s*import\s+(?:("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')|.+?from\s+("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(?:[ \t]+assert[ \t]+\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\})?)|\bimport\(\s*("(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')\s*(?:,\s*\{((?:"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+'|`(?:[^`]|(?<=\\)`)+`|{[^{]*{|{[^}]*}|}[^}]*}|[^"'`]+)+)\}\s*)?\))/g;
|
|
23
36
|
const REGEXP_BLOCKEXCLUDE = new RegExp(`(\\s*)<!--\\s*exclude\\s*:\\s*(?:start|end)\\s*-->` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
24
|
-
const [PATTERN_STRING_SOME, PATTERN_STRING_MANY] = (function () {
|
|
25
|
-
const pattern = '(?:\\s|' + dom_1.DomWriter.PATTERN_COMMENT + '|`[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`)';
|
|
26
|
-
return [pattern + '*', pattern + '+'];
|
|
27
|
-
})();
|
|
28
37
|
const REGEXP_COMMENT = new RegExp(dom_1.DomWriter.PATTERN_COMMENT, 'g');
|
|
29
|
-
const
|
|
38
|
+
const REGEXP_QUOTEDVALUE = new RegExp(`\\b(?:@import${PATTERN_STRING_MANY}|content${PATTERN_STRING_SOME}:${PATTERN_STRING_SOME})(?:"[^"]*"|'[^']*')`, 'gi');
|
|
30
39
|
const REGEXP_STYLE = new RegExp(`(<style${dom_1.DomWriter.PATTERN_TAGOPEN}*>)([\\S\\s]*?)(<\\/style\\s*>)`, 'gi');
|
|
31
|
-
const REGEXP_VARIABLES = new RegExp(`(\\s*)(--[^\\s:]*)${PATTERN_STRING_SOME}:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
40
|
+
const REGEXP_VARIABLES = new RegExp(`(?<!style\\()(\\s*)(--[^\\s:]*)${PATTERN_STRING_SOME}:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
32
41
|
const REGEXP_FONTFACE = new RegExp(`(\\s*)@font-face${PATTERN_STRING_SOME}{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
33
|
-
const REGEXP_FONTFAMILY = new RegExp(
|
|
42
|
+
const REGEXP_FONTFAMILY = new RegExp(`\\bfont-family${PATTERN_STRING_SOME}:([^;}]+)`, 'i');
|
|
34
43
|
const REGEXP_KEYFRAMES = new RegExp(`(\\s*)@keyframes${PATTERN_STRING_MANY}([^{]+){`, 'gi');
|
|
35
|
-
const
|
|
36
|
-
const REGEXP_VARIABLES_UNSAFE = new RegExp(`(\\s*)(--[^\\s:]*)\\s*:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
44
|
+
const REGEXP_PROPERTY = new RegExp(`(\\s*)@property${PATTERN_STRING_MANY}(--[^\\s]+)${PATTERN_STRING_SOME}{`, 'gi');
|
|
45
|
+
const REGEXP_VARIABLES_UNSAFE = new RegExp(`(?<!style\\()(\\s*)(--[^\\s:]*)\\s*:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
|
|
37
46
|
const REGEXP_FONTFACE_UNSAFE = new RegExp(`(\\s*)@font-face\\s*{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
|
|
38
|
-
const REGEXP_FONTFAMILY_UNSAFE =
|
|
47
|
+
const REGEXP_FONTFAMILY_UNSAFE = /\bfont-family\s*:([^;}]+)/i;
|
|
39
48
|
const REGEXP_KEYFRAMES_UNSAFE = /(\s*)@keyframes\s+([^{]+){/gi;
|
|
40
|
-
const
|
|
49
|
+
const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--[^\s]+)\s*{/gi;
|
|
41
50
|
const REGEXP_OBJECT_NAME = /([^[.\s]+)((?:\s*\[[^\]]+\]\s*)+)?\s*\.?\s*/g;
|
|
42
51
|
const REGEXP_OBJECT_SUBSCRIPT = /\[\s*(["'])?(.+?)\1\s*\]/g;
|
|
43
52
|
const REGEXP_TEMPLATE_LEADING = /\s*\{\{- \s*((?:[^}]|}(?!}))+?)\}\}/g;
|
|
44
53
|
const REGEXP_TEMPLATE_TRAILING = /\{\{((?:[^}]|}(?!}))+?)\s*? -\}\}\s*/g;
|
|
54
|
+
const REGEXP_URL = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
|
|
55
|
+
const REGEXP_URL_JS = /\bimport\(/g;
|
|
56
|
+
const REGEXP_URL_SVG = /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
|
|
57
|
+
const REGEXP_IMAGESET = /\b(?:-webkit-)?image-set\(/gi;
|
|
58
|
+
const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/g;
|
|
59
|
+
const REGEXP_REPLACECSS = /^@import\s+(?:url\((?:[^)]|(?<=\\)\))+\)|"(?:[^"]|(?<=\\)")+"|'(?:[^']|(?<=\\)')+')(\s*layer(?:\(([^)]*)\)|\b))?(?:\s*supports\(((?:\([^(]+\(|\([^)]+\)|\)[^)]+\)|(?:(?!\))[^(])+|(?:(?!\()[^)])+)+)\))?(.*?);?$/;
|
|
45
60
|
function removeNamespace(name, source, newline, comments) {
|
|
46
|
-
if (source.
|
|
61
|
+
if (source.includes('-' + name)) {
|
|
47
62
|
const [a, b, c, d, e] = CACHE_DATASET[name] || (CACHE_DATASET[name] = [
|
|
48
63
|
new RegExp(`(\\s*)<(script|style)(${dom_1.DomWriter.PATTERN_TAGOPEN}+)>[\\S\\s]*?<\\/\\2\\s*>` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi'),
|
|
49
64
|
new RegExp(`(\\s*)<link(${dom_1.DomWriter.PATTERN_TAGOPEN}+)>` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi'),
|
|
@@ -106,15 +121,18 @@ function trimQuote(value) {
|
|
|
106
121
|
const last = value[value.length - 1];
|
|
107
122
|
return first === last && (first === '"' || first === "'") ? value.substring(1, value.length - 1).trim() : value;
|
|
108
123
|
}
|
|
109
|
-
function findClosingIndex(source, lastIndex) {
|
|
110
|
-
const pattern = /[{}]/g;
|
|
124
|
+
function findClosingIndex(source, lastIndex, char) {
|
|
125
|
+
const pattern = char === '{' ? /[{}]/g : /[()]/g;
|
|
111
126
|
pattern.lastIndex = lastIndex;
|
|
112
127
|
let opened = 1, closed = 0, endIndex = -1, trailing = '', match;
|
|
113
128
|
while (match = pattern.exec(source)) {
|
|
114
|
-
if (match[0] ===
|
|
129
|
+
if (match[0] === char) {
|
|
115
130
|
++opened;
|
|
116
131
|
}
|
|
117
132
|
else if (++closed === opened) {
|
|
133
|
+
if (char === '(') {
|
|
134
|
+
return match.index;
|
|
135
|
+
}
|
|
118
136
|
endIndex = match.index + 1;
|
|
119
137
|
let ch;
|
|
120
138
|
while (isSpace(ch = source[endIndex])) {
|
|
@@ -261,27 +279,26 @@ function isTruthy(data, attr, falsey) {
|
|
|
261
279
|
}
|
|
262
280
|
function hasSameOrigin(value, ...other) {
|
|
263
281
|
for (let url of other) {
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
282
|
+
if (url) {
|
|
283
|
+
try {
|
|
284
|
+
if (typeof value === 'string') {
|
|
285
|
+
value = new URL(value);
|
|
286
|
+
}
|
|
287
|
+
if (typeof url === 'string') {
|
|
288
|
+
url = new URL(url);
|
|
289
|
+
}
|
|
290
|
+
if (value.origin === url.origin) {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
273
293
|
}
|
|
274
|
-
|
|
275
|
-
return true;
|
|
294
|
+
catch {
|
|
276
295
|
}
|
|
277
296
|
}
|
|
278
|
-
catch {
|
|
279
|
-
}
|
|
280
297
|
}
|
|
281
298
|
return false;
|
|
282
299
|
}
|
|
283
300
|
function restoreSearchParams(value, prefix = '__sqd') {
|
|
284
|
-
if (value?.
|
|
301
|
+
if (value?.includes(prefix)) {
|
|
285
302
|
const params = new URLSearchParams(value);
|
|
286
303
|
params.forEach((_, key) => key.startsWith(prefix) && params.delete(key));
|
|
287
304
|
if (value = params.toString()) {
|
|
@@ -316,14 +333,10 @@ function getBaseURLs(asset, baseUrl) {
|
|
|
316
333
|
}
|
|
317
334
|
return result;
|
|
318
335
|
}
|
|
319
|
-
function createHash(host, file, bufferMap) {
|
|
320
|
-
const hash = file.hash;
|
|
321
|
-
if (!hash) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
336
|
+
function createHash(host, file, hash, bufferMap) {
|
|
324
337
|
const { filename, localUri } = file;
|
|
325
338
|
try {
|
|
326
|
-
const buffer = localUri && bufferMap[localUri] || getBuffer(file);
|
|
339
|
+
const buffer = localUri && bufferMap[localUri] || getBuffer(file, localUri);
|
|
327
340
|
if (buffer) {
|
|
328
341
|
const [algorithm, length] = (0, util_1.getHashData)(hash);
|
|
329
342
|
let value;
|
|
@@ -377,8 +390,29 @@ function transformURL(host, parent, type, source, importFile) {
|
|
|
377
390
|
const baseHref = getBaseURLs(importFile || parent, this.baseUrl);
|
|
378
391
|
const isHtml = type === 'html';
|
|
379
392
|
const isJs = type === 'js';
|
|
380
|
-
const pattern = isJs ?
|
|
393
|
+
const pattern = isJs ? REGEXP_URL_JS : type === 'svg' ? REGEXP_URL_SVG : REGEXP_URL;
|
|
394
|
+
pattern.lastIndex = 0;
|
|
395
|
+
REGEXP_IMAGESET.lastIndex = 0;
|
|
381
396
|
let length = source.length, modified, match;
|
|
397
|
+
while (match = REGEXP_IMAGESET.exec(source)) {
|
|
398
|
+
const startIndex = match.index + match[0].length;
|
|
399
|
+
const endIndex = findClosingIndex(source, startIndex, '(');
|
|
400
|
+
if (endIndex === -1) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
REGEXP_IMAGESET_URL.lastIndex = 0;
|
|
404
|
+
const original = source.substring(startIndex, endIndex);
|
|
405
|
+
let content = original, url;
|
|
406
|
+
while (url = REGEXP_IMAGESET_URL.exec(original)) {
|
|
407
|
+
const quote = url[2] ? '"' : "'";
|
|
408
|
+
content = content.replace(url[1], `url(${quote + (url[2] || url[3]).trim() + quote})`);
|
|
409
|
+
modified = true;
|
|
410
|
+
}
|
|
411
|
+
if (modified) {
|
|
412
|
+
source = spliceString(source, startIndex, REGEXP_IMAGESET.lastIndex = endIndex, content);
|
|
413
|
+
modified = false;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
382
416
|
while (match = pattern.exec(source)) {
|
|
383
417
|
const isText = !!match[1];
|
|
384
418
|
const isHref = !!match[2];
|
|
@@ -484,10 +518,10 @@ function transformURL(host, parent, type, source, importFile) {
|
|
|
484
518
|
related.push(asset);
|
|
485
519
|
}
|
|
486
520
|
if (!quote && !isHtml && !isJs) {
|
|
487
|
-
if (value.
|
|
521
|
+
if (!value.includes('"')) {
|
|
488
522
|
quote = '"';
|
|
489
523
|
}
|
|
490
|
-
else if (value.
|
|
524
|
+
else if (!value.includes("'")) {
|
|
491
525
|
quote = "'";
|
|
492
526
|
}
|
|
493
527
|
}
|
|
@@ -735,7 +769,7 @@ function transformJs(host, file, output) {
|
|
|
735
769
|
});
|
|
736
770
|
}
|
|
737
771
|
else {
|
|
738
|
-
this.writeFail(['Unable to create
|
|
772
|
+
this.writeFail(['Unable to create script entry point', path.basename(chunkUri)], (0, types_1.errorMessage)('js', 'Element not found', chunkUri), 4 /* LOG_TYPE.PROCESS */);
|
|
739
773
|
}
|
|
740
774
|
}
|
|
741
775
|
}
|
|
@@ -766,11 +800,16 @@ function replaceCss(file) {
|
|
|
766
800
|
}
|
|
767
801
|
}
|
|
768
802
|
function replaceHtml(source, { productionRelease, contentMap }, cssMap) {
|
|
769
|
-
|
|
803
|
+
const finalize = (value, data) => {
|
|
770
804
|
for (const id in data) {
|
|
771
|
-
|
|
805
|
+
value = value.replace(new RegExp((0, types_1.escapePattern)(id), 'g'), data[id]);
|
|
772
806
|
}
|
|
807
|
+
return value;
|
|
808
|
+
};
|
|
809
|
+
if (cssMap) {
|
|
810
|
+
source = finalize(source, cssMap);
|
|
773
811
|
}
|
|
812
|
+
source = finalize(source, contentMap);
|
|
774
813
|
return productionRelease ? this.removeServerRoot(source) : source;
|
|
775
814
|
}
|
|
776
815
|
function isWatched(file) {
|
|
@@ -839,10 +878,6 @@ async function checkData(item, name, result, validate) {
|
|
|
839
878
|
}
|
|
840
879
|
}
|
|
841
880
|
}
|
|
842
|
-
function getBuffer(item) {
|
|
843
|
-
let localUri;
|
|
844
|
-
return item.sourceUTF8 || item.buffer || ((localUri = item.localUri) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
|
|
845
|
-
}
|
|
846
881
|
const getNewlineString = dom_1.DomWriter.getNewlineString.bind(dom_1.DomWriter);
|
|
847
882
|
const isSpace = dom_1.DomWriter.isSpace.bind(dom_1.DomWriter);
|
|
848
883
|
const replaceMatch = dom_1.DomWriter.replaceMatch.bind(dom_1.DomWriter);
|
|
@@ -853,6 +888,7 @@ const asString = Document.asString.bind(Document);
|
|
|
853
888
|
const resolvePath = Document.resolvePath.bind(Document);
|
|
854
889
|
const toPosix = Document.toPosix.bind(Document);
|
|
855
890
|
const isDir = Document.isDir.bind(Document);
|
|
891
|
+
const getBuffer = (item, localUri) => item.sourceUTF8 || item.buffer || ((localUri || (localUri = item.localUri)) && isPath(localUri) ? fs.readFileSync(localUri, item.encoding) : null);
|
|
856
892
|
const hasSourceMap = (metadata, value) => (0, types_1.isObject)(metadata) && metadata.__sourcemap__ === value;
|
|
857
893
|
const isBundled = (value, main) => typeof value === 'number' && (value > 0 || main && value === 0);
|
|
858
894
|
const isFont = (value) => value === 'truetype' || value === 'opentype' || value === 'woff' || value === 'woff2';
|
|
@@ -882,6 +918,7 @@ class ChromeDocument extends Document {
|
|
|
882
918
|
useOriginalHtmlPage: undefined,
|
|
883
919
|
useUnsafeHtmlReplace: undefined,
|
|
884
920
|
useUnsafeCssReplace: undefined,
|
|
921
|
+
useSessionCache: undefined,
|
|
885
922
|
stripCommentsAndCDATA: undefined,
|
|
886
923
|
normalizeHtmlOutput: undefined,
|
|
887
924
|
escapeReservedCharacters: undefined,
|
|
@@ -904,7 +941,8 @@ class ChromeDocument extends Document {
|
|
|
904
941
|
this._elements = null;
|
|
905
942
|
this._idMap = Object.create(null);
|
|
906
943
|
this._editing = [];
|
|
907
|
-
this.
|
|
944
|
+
this._queryMap = new Map();
|
|
945
|
+
this._selectorMap = new Map();
|
|
908
946
|
}
|
|
909
947
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
910
948
|
if (typeof limit === 'boolean') {
|
|
@@ -912,14 +950,14 @@ class ChromeDocument extends Document {
|
|
|
912
950
|
limit = 0;
|
|
913
951
|
}
|
|
914
952
|
let result = 0;
|
|
915
|
-
if (limit === 0 || CACHE_TOTAL >= limit) {
|
|
953
|
+
if ((limit === 0 || CACHE_TOTAL >= limit) && percent > 0) {
|
|
916
954
|
if (percent >= 1) {
|
|
917
955
|
result += CACHE_DBRESULT.size + CACHE_LOCALFILE.size;
|
|
918
956
|
CACHE_DBRESULT.clear();
|
|
919
957
|
CACHE_LOCALFILE.clear();
|
|
920
958
|
CACHE_TOTAL = 0;
|
|
921
959
|
}
|
|
922
|
-
else
|
|
960
|
+
else {
|
|
923
961
|
const stored = [];
|
|
924
962
|
for (const map of [CACHE_DBRESULT, CACHE_LOCALFILE]) {
|
|
925
963
|
for (const [key, value] of map) {
|
|
@@ -934,6 +972,8 @@ class ChromeDocument extends Document {
|
|
|
934
972
|
}
|
|
935
973
|
CACHE_TOTAL = stored.length - result;
|
|
936
974
|
}
|
|
975
|
+
CACHE_QUERY.clear();
|
|
976
|
+
CACHE_SELECTOR.clear();
|
|
937
977
|
}
|
|
938
978
|
return result + (parent && result > 0 ? await super.purgeMemory(typeof parent === 'number' && parent > 0 ? parent : percent, limit, true) : 0);
|
|
939
979
|
}
|
|
@@ -1027,16 +1067,15 @@ class ChromeDocument extends Document {
|
|
|
1027
1067
|
const items = new Set((asset.watch.assets || []));
|
|
1028
1068
|
(function recurse(children) {
|
|
1029
1069
|
for (const item of children) {
|
|
1030
|
-
if (items.has(item)) {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
item
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
recurse(next);
|
|
1070
|
+
if (!items.has(item)) {
|
|
1071
|
+
if (isWatched.call(instance, item)) {
|
|
1072
|
+
item.flags |= 8 /* ASSET_FLAG.WATCH */;
|
|
1073
|
+
}
|
|
1074
|
+
items.add(item);
|
|
1075
|
+
const next = related.get(item);
|
|
1076
|
+
if (next) {
|
|
1077
|
+
recurse(next);
|
|
1078
|
+
}
|
|
1040
1079
|
}
|
|
1041
1080
|
}
|
|
1042
1081
|
})(includes);
|
|
@@ -1052,20 +1091,18 @@ class ChromeDocument extends Document {
|
|
|
1052
1091
|
if (this.canWrite(productionRelease)) {
|
|
1053
1092
|
const serverRoot = ChromeDocument.INTERNAL_SERVERROOT;
|
|
1054
1093
|
const srcDir = path.join(this.baseDirectory, serverRoot);
|
|
1055
|
-
if (
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
else {
|
|
1068
|
-
instance.writeFail(["Unable to move file" /* ERR_MESSAGE.MOVE_FILE */, instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
|
|
1094
|
+
if (isDir(srcDir)) {
|
|
1095
|
+
const result = await Document.copyDir(srcDir, productionRelease, this.incremental !== 'staging');
|
|
1096
|
+
const failed = result.failed.map(value => this.removeCwd(value));
|
|
1097
|
+
for (const value of this.files) {
|
|
1098
|
+
if (value.startsWith(serverRoot)) {
|
|
1099
|
+
if (!failed.includes(value)) {
|
|
1100
|
+
this.delete(value);
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
instance.writeFail(["Unable to move file" /* ERR_MESSAGE.MOVE_FILE */, instance.moduleName], (0, types_1.errorMessage)('production', path.join(this.baseDirectory, value)), { fatal: true });
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1069
1106
|
}
|
|
1070
1107
|
}
|
|
1071
1108
|
}
|
|
@@ -1566,12 +1603,14 @@ class ChromeDocument extends Document {
|
|
|
1566
1603
|
}
|
|
1567
1604
|
for (const placeholder in importMap) {
|
|
1568
1605
|
const items = importMap[placeholder];
|
|
1606
|
+
let found;
|
|
1569
1607
|
for (let i = 0, length = items.length; i < length; ++i) {
|
|
1570
1608
|
const index = code.indexOf(placeholder);
|
|
1571
1609
|
if (index !== -1) {
|
|
1572
1610
|
const { uri, original, type, dynamic } = items[i];
|
|
1611
|
+
const hosted = type === 'css';
|
|
1573
1612
|
let value;
|
|
1574
|
-
if (
|
|
1613
|
+
if (hosted) {
|
|
1575
1614
|
const asset = this.host?.findAsset(uri);
|
|
1576
1615
|
if (asset) {
|
|
1577
1616
|
const [relativeUrl, sameDir] = getSrcURL.call(this, bundleMain || file, asset);
|
|
@@ -1583,11 +1622,12 @@ class ChromeDocument extends Document {
|
|
|
1583
1622
|
else if (!(dynamic && file.imported !== false)) {
|
|
1584
1623
|
value = this.findSourceRoot(uri);
|
|
1585
1624
|
}
|
|
1586
|
-
if (!value) {
|
|
1625
|
+
if (!value || !hosted && !Document.isPath(value)) {
|
|
1587
1626
|
if (i < length - 1) {
|
|
1627
|
+
found || (found = value);
|
|
1588
1628
|
continue;
|
|
1589
1629
|
}
|
|
1590
|
-
value = original;
|
|
1630
|
+
value = found || original;
|
|
1591
1631
|
}
|
|
1592
1632
|
code = spliceString(code, index, index + placeholder.length, value);
|
|
1593
1633
|
modified = true;
|
|
@@ -1602,7 +1642,7 @@ class ChromeDocument extends Document {
|
|
|
1602
1642
|
replaceContent(source, statement, mimeType) {
|
|
1603
1643
|
switch (mimeType) {
|
|
1604
1644
|
case 'text/css': {
|
|
1605
|
-
const match =
|
|
1645
|
+
const match = REGEXP_REPLACECSS.exec((typeof statement === 'string' ? statement : statement[0]).trim());
|
|
1606
1646
|
if (match) {
|
|
1607
1647
|
const layer = match[1];
|
|
1608
1648
|
const supports = match[3]?.trim();
|
|
@@ -1671,7 +1711,7 @@ class ChromeDocument extends Document {
|
|
|
1671
1711
|
}
|
|
1672
1712
|
return this.editing.includes(file);
|
|
1673
1713
|
}
|
|
1674
|
-
cloudUpload({ host }, file, url, active) {
|
|
1714
|
+
async cloudUpload({ host }, file, url, active) {
|
|
1675
1715
|
if (active) {
|
|
1676
1716
|
const endpoint = this._cloudEndpoint;
|
|
1677
1717
|
const inlineUrlCloud = file.inlineUrlCloud;
|
|
@@ -1683,7 +1723,7 @@ class ChromeDocument extends Document {
|
|
|
1683
1723
|
for (const item of this.editing) {
|
|
1684
1724
|
if (item.inlineUrlCloudMap?.[inlineUrlCloud]) {
|
|
1685
1725
|
const source = host.getUTF8String(item);
|
|
1686
|
-
const output = source.replace(pattern, endpoint && item !== htmlFile && cloudUrl.
|
|
1726
|
+
const output = source.replace(pattern, endpoint && item !== htmlFile && cloudUrl.includes('/') ? url : cloudUrl);
|
|
1687
1727
|
if (source !== output) {
|
|
1688
1728
|
item.sourceUTF8 = output;
|
|
1689
1729
|
item.modified = true;
|
|
@@ -1693,7 +1733,7 @@ class ChromeDocument extends Document {
|
|
|
1693
1733
|
this._cloudUploaded.add(inlineUrlCloud);
|
|
1694
1734
|
}
|
|
1695
1735
|
}
|
|
1696
|
-
return
|
|
1736
|
+
return false;
|
|
1697
1737
|
}
|
|
1698
1738
|
async cloudFinalize(state) {
|
|
1699
1739
|
if (this.aborted) {
|
|
@@ -1801,7 +1841,7 @@ class ChromeDocument extends Document {
|
|
|
1801
1841
|
}
|
|
1802
1842
|
else if (current = watch.assets.find(item => (0, asset_1.isEqual)(item, asset))) {
|
|
1803
1843
|
const { inlineUrlCloud: inlineUrlCloud, initialValue = {} } = current;
|
|
1804
|
-
if (inlineUrlCloud && inlineUrlCloudMap[inlineUrlCloud] || path.join(initialValue.pathname || asset.pathname, initialValue.filename || asset.filename).
|
|
1844
|
+
if (inlineUrlCloud && inlineUrlCloudMap[inlineUrlCloud] || path.join(initialValue.pathname || asset.pathname, initialValue.filename || asset.filename).includes(ChromeDocument.INTERNAL_ASSIGNUUID)) {
|
|
1805
1845
|
using.push(asset);
|
|
1806
1846
|
}
|
|
1807
1847
|
}
|
|
@@ -1890,7 +1930,7 @@ class ChromeDocument extends Document {
|
|
|
1890
1930
|
for (const url of items) {
|
|
1891
1931
|
const resolve = sameOrigin && !Document.isURL(url);
|
|
1892
1932
|
const pathname = url.split(/[\\/]/).map(seg => (0, types_1.escapePattern)(seg)).join('[\\\\/]');
|
|
1893
|
-
const pattern = new RegExp(`(,?\\s*)(${(resolve && url
|
|
1933
|
+
const pattern = new RegExp(`(,?\\s*)(${(resolve && !url.startsWith('.') ? `(?:\\.\\.[\\\\/])*\\.\\.${pathname}|` : '') + pathname})(` + (!url.includes('?') ? '(?:(?!,)(?:[^?]|$)[^,]*)|(?!\\?)[^,]*)' : '[^,]*)'), 'g');
|
|
1894
1934
|
while (match = pattern.exec(current)) {
|
|
1895
1935
|
const partial = match[2];
|
|
1896
1936
|
if (!resolve || baseHref.some(baseUri => uri === resolvePath(partial, baseUri))) {
|
|
@@ -1937,12 +1977,12 @@ class ChromeDocument extends Document {
|
|
|
1937
1977
|
}
|
|
1938
1978
|
}
|
|
1939
1979
|
if (productionRelease) {
|
|
1940
|
-
const {
|
|
1980
|
+
const { inlineUrl, inlineUrlCloud, imported, hash } = item;
|
|
1941
1981
|
if (inlineUrl || inlineUrlCloud) {
|
|
1942
|
-
const filename = createHash(host, item, bufferMap);
|
|
1982
|
+
const filename = hash && createHash(host, item, hash, bufferMap);
|
|
1943
1983
|
if (filename) {
|
|
1944
|
-
for (const
|
|
1945
|
-
const url = inlineUrl ?
|
|
1984
|
+
for (const asset of this.assets) {
|
|
1985
|
+
const url = inlineUrl ? asset.inlineUrlMap?.[inlineUrl] : asset.inlineUrlCloudMap?.[inlineUrlCloud];
|
|
1946
1986
|
if (url) {
|
|
1947
1987
|
const search = url.indexOf('?');
|
|
1948
1988
|
const index = (search !== -1 ? url.substring(0, search) : url).lastIndexOf('/');
|
|
@@ -1955,17 +1995,17 @@ class ChromeDocument extends Document {
|
|
|
1955
1995
|
result += url.substring(search);
|
|
1956
1996
|
}
|
|
1957
1997
|
if (inlineUrl) {
|
|
1958
|
-
|
|
1998
|
+
asset.inlineUrlMap[inlineUrl] = result;
|
|
1959
1999
|
}
|
|
1960
2000
|
else {
|
|
1961
|
-
|
|
2001
|
+
asset.inlineUrlCloudMap[inlineUrlCloud] = result;
|
|
1962
2002
|
}
|
|
1963
2003
|
}
|
|
1964
2004
|
}
|
|
1965
2005
|
}
|
|
1966
2006
|
hashed.add(item);
|
|
1967
2007
|
}
|
|
1968
|
-
else if ((!item.editing || imported) && createHash(host, item, bufferMap)) {
|
|
2008
|
+
else if (hash && (!item.editing || imported) && createHash(host, item, hash, bufferMap)) {
|
|
1969
2009
|
hashed.add(item);
|
|
1970
2010
|
}
|
|
1971
2011
|
}
|
|
@@ -2021,7 +2061,7 @@ class ChromeDocument extends Document {
|
|
|
2021
2061
|
}
|
|
2022
2062
|
}
|
|
2023
2063
|
item.sourceUTF8 = source;
|
|
2024
|
-
if (productionRelease && !hashed.has(item) && createHash(host, item, bufferMap)) {
|
|
2064
|
+
if (productionRelease && item.hash && !hashed.has(item) && createHash(host, item, item.hash, bufferMap)) {
|
|
2025
2065
|
hashed.add(item);
|
|
2026
2066
|
}
|
|
2027
2067
|
}
|
|
@@ -2347,7 +2387,7 @@ class ChromeDocument extends Document {
|
|
|
2347
2387
|
}
|
|
2348
2388
|
if (data) {
|
|
2349
2389
|
if ((0, types_1.isString)(query) && item.source !== 'mongodb') {
|
|
2350
|
-
const pkg = query
|
|
2390
|
+
const pkg = query.startsWith('$') ? 'jsonpath' : 'jmespath';
|
|
2351
2391
|
try {
|
|
2352
2392
|
if (pkg === 'jsonpath') {
|
|
2353
2393
|
data = require(pkg).query(data, query);
|
|
@@ -2422,7 +2462,7 @@ class ChromeDocument extends Document {
|
|
|
2422
2462
|
for (const key in batchMap) {
|
|
2423
2463
|
batchGroup.push(batchMap[key]);
|
|
2424
2464
|
}
|
|
2425
|
-
return this.allSettled(batchGroup.map(batch => {
|
|
2465
|
+
return this.allSettled(batchGroup.map(async (batch) => {
|
|
2426
2466
|
return new Promise(async (resolve, reject) => {
|
|
2427
2467
|
const errorRemove = (item, reason) => {
|
|
2428
2468
|
removeElement(item);
|
|
@@ -2438,13 +2478,13 @@ class ChromeDocument extends Document {
|
|
|
2438
2478
|
const length = batch.length;
|
|
2439
2479
|
const current = batch[0];
|
|
2440
2480
|
const type = current.source;
|
|
2441
|
-
let result = new Array(length);
|
|
2481
|
+
let result = new Array(length), errors;
|
|
2442
2482
|
switch (type) {
|
|
2443
2483
|
case 'cloud':
|
|
2444
2484
|
result = await cloud.getDatabaseBatchRows(batch, true, sessionKey).catch(err => {
|
|
2445
2485
|
this.abort(type);
|
|
2446
2486
|
if (err instanceof Error) {
|
|
2447
|
-
cloud.addLog(this.aborted ? types_1.STATUS_TYPE.ERROR : types_1.STATUS_TYPE.WARN, err);
|
|
2487
|
+
cloud.addLog(this.aborted ? types_1.STATUS_TYPE.ERROR : types_1.STATUS_TYPE.WARN, errors = err);
|
|
2448
2488
|
}
|
|
2449
2489
|
return [];
|
|
2450
2490
|
});
|
|
@@ -2610,9 +2650,7 @@ class ChromeDocument extends Document {
|
|
|
2610
2650
|
}
|
|
2611
2651
|
if (!getData) {
|
|
2612
2652
|
const { settings, encoding, persist = true } = current;
|
|
2613
|
-
|
|
2614
|
-
target = settings && this.settings.export?.[settings] || pathname;
|
|
2615
|
-
}
|
|
2653
|
+
target || (target = settings && this.settings.export?.[settings] || pathname);
|
|
2616
2654
|
if (typeof target === 'function') {
|
|
2617
2655
|
getData = target;
|
|
2618
2656
|
hint = target.name;
|
|
@@ -2700,7 +2738,7 @@ class ChromeDocument extends Document {
|
|
|
2700
2738
|
search.schema = loadLocalFile.call(this, current, pathname, cacheData, cmd.encoding);
|
|
2701
2739
|
}
|
|
2702
2740
|
catch (err) {
|
|
2703
|
-
this.writeFail(['Unable to parse document', path.basename(pathname)], err, { startTime });
|
|
2741
|
+
this.writeFail(['Unable to parse document', path.basename(pathname)], err instanceof Error ? errors = err : err, { startTime });
|
|
2704
2742
|
search.schema = undefined;
|
|
2705
2743
|
}
|
|
2706
2744
|
}
|
|
@@ -2780,13 +2818,13 @@ class ChromeDocument extends Document {
|
|
|
2780
2818
|
}
|
|
2781
2819
|
}
|
|
2782
2820
|
if (data.willAbort) {
|
|
2783
|
-
this.abort();
|
|
2821
|
+
this.abort(undefined, err);
|
|
2784
2822
|
}
|
|
2785
2823
|
else if (aborting) {
|
|
2786
|
-
this.abort(type);
|
|
2824
|
+
this.abort(type, err);
|
|
2787
2825
|
}
|
|
2788
2826
|
if (err) {
|
|
2789
|
-
this.writeFail(["Unable to execute query" /* ERR_DB.EXEC_QUERY */, message || "Unknown" /* ERR_MESSAGE.UNKNOWN */], err, { type: 65536 /* LOG_TYPE.DB */, startTime });
|
|
2827
|
+
this.writeFail(["Unable to execute query" /* ERR_DB.EXEC_QUERY */, message || "Unknown" /* ERR_MESSAGE.UNKNOWN */], err instanceof Error ? errors = err : err, { type: 65536 /* LOG_TYPE.DB */, startTime });
|
|
2790
2828
|
}
|
|
2791
2829
|
return this.aborted;
|
|
2792
2830
|
};
|
|
@@ -2839,7 +2877,7 @@ class ChromeDocument extends Document {
|
|
|
2839
2877
|
if (items.length && !item.transactionFail) {
|
|
2840
2878
|
const { element, preRender } = item;
|
|
2841
2879
|
const domElement = new dom_1.HtmlElement(moduleName, element);
|
|
2842
|
-
let
|
|
2880
|
+
let value = '';
|
|
2843
2881
|
const checkValue = async (name) => {
|
|
2844
2882
|
const data = await checkData.call(this, item, name, value, row => typeof row === 'string');
|
|
2845
2883
|
if (data) {
|
|
@@ -2901,21 +2939,21 @@ class ChromeDocument extends Document {
|
|
|
2901
2939
|
let segment = template;
|
|
2902
2940
|
while (match = REGEXP_TEMPLATECONDITIONAL.exec(segment)) {
|
|
2903
2941
|
const col = hasCondition(row, match[2]) ? 4 : hasCondition(row, match[5]) ? 7 : -1;
|
|
2904
|
-
segment = replaceMatch(match, segment, match[col] ? (!match[1] || match[col - 1].
|
|
2942
|
+
segment = replaceMatch(match, segment, match[col] ? (!match[1] || match[col - 1].includes('\n') ? '' : match[1]) + match[col - 1] + match[col] : '', REGEXP_TEMPLATECONDITIONAL);
|
|
2905
2943
|
}
|
|
2906
2944
|
REGEXP_TEMPLATECONDITIONAL.lastIndex = 0;
|
|
2907
2945
|
const literal = segment.trim();
|
|
2908
|
-
if (literal
|
|
2946
|
+
if (literal.startsWith('`') && literal.endsWith('`')) {
|
|
2909
2947
|
if (!this.hasEval('function')) {
|
|
2910
2948
|
errors = (0, types_1.errorMessage)('eval', "Unsupported access" /* ERR_MESSAGE.UNSUPPORTED_ACCESS */, 'function');
|
|
2911
2949
|
continue;
|
|
2912
2950
|
}
|
|
2913
2951
|
try {
|
|
2914
2952
|
let content = new Function('return ' + literal + ';').call(row);
|
|
2915
|
-
if (segment
|
|
2953
|
+
if (!segment.startsWith('`')) {
|
|
2916
2954
|
content = segment.substring(0, segment.indexOf('`')) + content;
|
|
2917
2955
|
}
|
|
2918
|
-
if (segment
|
|
2956
|
+
if (!segment.endsWith('`')) {
|
|
2919
2957
|
content += segment.substring(segment.lastIndexOf('`') + 1);
|
|
2920
2958
|
}
|
|
2921
2959
|
segment = content;
|
|
@@ -2928,7 +2966,7 @@ class ChromeDocument extends Document {
|
|
|
2928
2966
|
else {
|
|
2929
2967
|
const pattern = /\$\{\s*([^\s}]+)\s*\}/g;
|
|
2930
2968
|
while (match = pattern.exec(segment)) {
|
|
2931
|
-
segment = replaceMatch(match, segment, match[1] ===
|
|
2969
|
+
segment = replaceMatch(match, segment, match[1] === "__index__" /* PROPERTIES.INDEX */ && !(0, types_1.isObject)(row) ? (j + 1).toString() : valueAsString(getObjectValue(row, match[1]), ', '), pattern);
|
|
2932
2970
|
}
|
|
2933
2971
|
}
|
|
2934
2972
|
value += trimTemplate(segment);
|
|
@@ -2975,7 +3013,7 @@ class ChromeDocument extends Document {
|
|
|
2975
3013
|
for (const row of items) {
|
|
2976
3014
|
for (let seg of segment) {
|
|
2977
3015
|
seg = seg.trim();
|
|
2978
|
-
if (seg
|
|
3016
|
+
if (seg.startsWith(':') && (match = /^:join\(([\S\s]*)\)$/i.exec(seg))) {
|
|
2979
3017
|
joinString = match[1];
|
|
2980
3018
|
continue;
|
|
2981
3019
|
}
|
|
@@ -3135,7 +3173,10 @@ class ChromeDocument extends Document {
|
|
|
3135
3173
|
}
|
|
3136
3174
|
else {
|
|
3137
3175
|
if (!empty && item.type !== 'display' || item.transactionFail) {
|
|
3138
|
-
const emptyResponse = (value, service = item.source) =>
|
|
3176
|
+
const emptyResponse = (value, service = item.source) => {
|
|
3177
|
+
value || (value = "Unknown" /* ERR_MESSAGE.UNKNOWN */);
|
|
3178
|
+
return errors instanceof Error ? (0, types_1.errorMessage)(service, value, errors.message) : errorDataSource(service + ' -> Empty', value);
|
|
3179
|
+
};
|
|
3139
3180
|
switch (item.source) {
|
|
3140
3181
|
case 'cloud': {
|
|
3141
3182
|
const { service, table, id, query } = item;
|
|
@@ -3183,8 +3224,8 @@ class ChromeDocument extends Document {
|
|
|
3183
3224
|
if (isIgnored(item, true)) {
|
|
3184
3225
|
continue;
|
|
3185
3226
|
}
|
|
3186
|
-
if (!hashed.has(item)) {
|
|
3187
|
-
createHash(host, item, bufferMap);
|
|
3227
|
+
if (item.hash && !hashed.has(item)) {
|
|
3228
|
+
createHash(host, item, item.hash, bufferMap);
|
|
3188
3229
|
}
|
|
3189
3230
|
switch (item.element?.tagName.toLowerCase()) {
|
|
3190
3231
|
case 'style':
|
|
@@ -3225,12 +3266,13 @@ class ChromeDocument extends Document {
|
|
|
3225
3266
|
}
|
|
3226
3267
|
}
|
|
3227
3268
|
}
|
|
3228
|
-
removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedContainer, unusedSupports } = this.config) {
|
|
3269
|
+
removeUnusedStyles(source, { useUnsafeCssReplace, usedVariables, usedFontFace, usedKeyframes, unusedStyles, unusedMedia, unusedContainer, unusedSupports, useSessionCache } = this.config) {
|
|
3229
3270
|
var _a;
|
|
3230
3271
|
if (!usedVariables && !usedFontFace && !usedKeyframes && !unusedStyles && !unusedMedia && !unusedContainer && !unusedSupports) {
|
|
3231
3272
|
return;
|
|
3232
3273
|
}
|
|
3233
|
-
const
|
|
3274
|
+
const queryMap = useSessionCache ? CACHE_QUERY : this._queryMap;
|
|
3275
|
+
const selectorMap = useSessionCache ? CACHE_SELECTOR : this._selectorMap;
|
|
3234
3276
|
const replaceMap = [];
|
|
3235
3277
|
const getStringSome = () => useUnsafeCssReplace ? '\\s*' : PATTERN_STRING_SOME;
|
|
3236
3278
|
const getStringMany = () => useUnsafeCssReplace ? '\\s+' : PATTERN_STRING_MANY;
|
|
@@ -3238,7 +3280,7 @@ class ChromeDocument extends Document {
|
|
|
3238
3280
|
const parseSelector = (value) => {
|
|
3239
3281
|
const items = [];
|
|
3240
3282
|
const revised = value.replace(useUnsafeCssReplace ? REGEXP_NTHCHILD_UNSAFE : REGEXP_NTHCHILD, (...capture) => {
|
|
3241
|
-
return '`%' + (items.push('\\(' + getStringSome() + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + getStringSome() + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + getStringSome() + capture[5] : `(?:[+-]${getStringSome()}0)?`) + getStringSome() + '\\)') - 1) + '`';
|
|
3283
|
+
return '`%' + (items.push('\\(' + getStringSome() + (capture[1] === '-' ? '\\x2d' : '\\x2b?') + (capture[2] || '[01]?') + (capture[3] === '0' ? !capture[1] && !capture[2] && !capture[4] && !capture[5] ? '[+-]?0[nN]?' : '0' : '[nN]') + getStringSome() + (capture[5] ? (capture[4] === '-' ? '\\x2d' : '\\x2b') + getStringSome() + capture[5] : `(?:[+-]${getStringSome()}0)?`) + (capture[6] ? getStringMany() + '[oO][fF]' + getStringMany() + capture[6].trim() : '') + getStringSome() + '\\)') - 1) + '`';
|
|
3242
3284
|
});
|
|
3243
3285
|
let selector = '';
|
|
3244
3286
|
for (let i = 0, length = revised.length, casing = false, attr = false, quote = false; i < length; i++) {
|
|
@@ -3327,17 +3369,17 @@ class ChromeDocument extends Document {
|
|
|
3327
3369
|
return `[${capture[1]}]`;
|
|
3328
3370
|
}
|
|
3329
3371
|
});
|
|
3330
|
-
for (let i = 0; i <
|
|
3372
|
+
for (let i = 0, length = revised.length; i < length; ++i) {
|
|
3331
3373
|
selector = selector.replace('`%' + i + '`', items[i]);
|
|
3332
3374
|
}
|
|
3333
|
-
return selector.replace(/
|
|
3375
|
+
return selector.replace(/ +/g, getStringMany()) + getStringSome();
|
|
3334
3376
|
};
|
|
3335
3377
|
const replaceUnunsed = (name, items) => {
|
|
3336
3378
|
for (let value of items) {
|
|
3337
3379
|
const key = name + '_' + (value = value.trim()) + (useUnsafeCssReplace ? '_1' : '');
|
|
3338
|
-
let
|
|
3380
|
+
let pattern = queryMap.get(key), rule;
|
|
3339
3381
|
if (!pattern) {
|
|
3340
|
-
let flags = 'gi', revised;
|
|
3382
|
+
let flags = 'gi', selector = '', revised;
|
|
3341
3383
|
if (name === 'container') {
|
|
3342
3384
|
for (let i = 0, length = value.length, casing = true; i < length; i++) {
|
|
3343
3385
|
let ch = value[i];
|
|
@@ -3373,27 +3415,25 @@ class ChromeDocument extends Document {
|
|
|
3373
3415
|
.replace(/\s*(\\[()])\s*/g, (...capture) => getStringSome() + capture[1] + getStringSome())
|
|
3374
3416
|
.replace(/:\s+/g, getStringSome() + ':' + getStringSome())
|
|
3375
3417
|
.replace(/\s+([<>/]|<=|>=|\\\*)\s+/g, (...capture) => getStringSome() + capture[1] + getStringSome())
|
|
3376
|
-
.replace(/
|
|
3418
|
+
.replace(/ +/g, getStringMany());
|
|
3377
3419
|
if (flags === 'g') {
|
|
3378
3420
|
selector = selector.replace(/`([a-z][A-Z])`/g, (...capture) => `[${capture[1]}]`);
|
|
3379
3421
|
}
|
|
3380
3422
|
}
|
|
3381
3423
|
pattern = new RegExp('(\\s*)@' + (flags === 'g' ? name.split('').map(ch => `[${ch + ch.toUpperCase()}]`).join('') : name) + getStringMany() + selector + getStringSome() + '{', flags);
|
|
3424
|
+
queryMap.set(key, pattern);
|
|
3382
3425
|
}
|
|
3383
3426
|
else {
|
|
3384
3427
|
pattern.lastIndex = 0;
|
|
3385
3428
|
}
|
|
3386
3429
|
while (rule = pattern.exec(current)) {
|
|
3387
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule));
|
|
3430
|
+
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(rule), '{');
|
|
3388
3431
|
if (endIndex !== -1) {
|
|
3389
3432
|
current = spliceSource(current, rule.index, endIndex, pattern, rule[1], trailing);
|
|
3390
3433
|
(checkEmpty || (checkEmpty = {}))[name] = true;
|
|
3391
3434
|
modified = true;
|
|
3392
3435
|
}
|
|
3393
3436
|
}
|
|
3394
|
-
if (selector) {
|
|
3395
|
-
selectorMap[key] = [pattern];
|
|
3396
|
-
}
|
|
3397
3437
|
}
|
|
3398
3438
|
};
|
|
3399
3439
|
if (!useUnsafeCssReplace) {
|
|
@@ -3410,7 +3450,7 @@ class ChromeDocument extends Document {
|
|
|
3410
3450
|
pattern.lastIndex = 0;
|
|
3411
3451
|
};
|
|
3412
3452
|
replaceBracket(REGEXP_COMMENT);
|
|
3413
|
-
replaceBracket(
|
|
3453
|
+
replaceBracket(REGEXP_QUOTEDVALUE);
|
|
3414
3454
|
const values = (0, util_1.splitEnclosing)(current, /\burl/gi);
|
|
3415
3455
|
for (let i = 0, length = values.length; i < length; ++i) {
|
|
3416
3456
|
const seg = values[i];
|
|
@@ -3432,41 +3472,110 @@ class ChromeDocument extends Document {
|
|
|
3432
3472
|
replaceUnunsed('container', unusedContainer);
|
|
3433
3473
|
}
|
|
3434
3474
|
if (unusedStyles) {
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3475
|
+
current = (function recurse(target, child) {
|
|
3476
|
+
let output = '', index = 0, pendingStart = 0, pendingEnd = 0, found = -1;
|
|
3477
|
+
while ((found = target.indexOf('{', index)) !== -1) {
|
|
3478
|
+
++found;
|
|
3479
|
+
const closing = findClosingIndex(target, found, '{')[0];
|
|
3480
|
+
if (closing === -1) {
|
|
3481
|
+
break;
|
|
3482
|
+
}
|
|
3483
|
+
let header = target.substring(index, found), invalid = 0, content;
|
|
3484
|
+
for (const value of unusedStyles) {
|
|
3485
|
+
const key = value + (child ? '_1' : '') + (useUnsafeCssReplace ? '_2' : '');
|
|
3486
|
+
const pattern = selectorMap.get(key);
|
|
3487
|
+
let single, group;
|
|
3488
|
+
if (!pattern) {
|
|
3489
|
+
const selector = parseSelector(value) + (child ? `(?:${getStringSome()}&${getStringSome()})*` : '');
|
|
3490
|
+
single = new RegExp(`(^|;)(${getStringSome()})(?<!${child ? '&|' : ''}@[^};]*)${selector}\\{$`);
|
|
3491
|
+
group = new RegExp(`((?:^|;)[^{]*?${getStringSome()}(,${getStringSome()}|(?<!@[^};]*)))(${(child ? '(?:&\\s+|(?<!&))' : '') + selector})(,[^{]*)?\\{$`, 'g');
|
|
3492
|
+
selectorMap.set(key, [single, group]);
|
|
3493
|
+
}
|
|
3494
|
+
else {
|
|
3495
|
+
[single, group] = pattern;
|
|
3496
|
+
}
|
|
3497
|
+
if (match = single.exec(header)) {
|
|
3498
|
+
content = match[1] === ';' ? header.substring(0, match.index + 1) + match[2].replace(/[^\n]+$/, '') : undefined;
|
|
3499
|
+
invalid = 1;
|
|
3500
|
+
break;
|
|
3501
|
+
}
|
|
3502
|
+
let leading = -1, first = true;
|
|
3503
|
+
while (match = group.exec(header)) {
|
|
3504
|
+
const start = match.index + match[1].length;
|
|
3505
|
+
if (!child && first) {
|
|
3506
|
+
if (match[1].trimEnd().endsWith(';')) {
|
|
3507
|
+
leading = start;
|
|
3508
|
+
}
|
|
3509
|
+
first = false;
|
|
3510
|
+
}
|
|
3511
|
+
const sibling = match[2].startsWith(',');
|
|
3512
|
+
const trailing = match[4];
|
|
3513
|
+
const offset = trailing && !sibling ? /^,\s*/.exec(trailing)[0].length : 1;
|
|
3514
|
+
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));
|
|
3515
|
+
group.lastIndex = match.index;
|
|
3516
|
+
invalid = 2;
|
|
3517
|
+
}
|
|
3518
|
+
if (invalid) {
|
|
3519
|
+
group.lastIndex = 0;
|
|
3520
|
+
const empty = /(.)\s*{$/.exec(header);
|
|
3521
|
+
if (empty) {
|
|
3522
|
+
if (header.trim() === '{') {
|
|
3523
|
+
content = undefined;
|
|
3524
|
+
invalid = 1;
|
|
3525
|
+
break;
|
|
3526
|
+
}
|
|
3527
|
+
else if (leading !== -1 && empty[1] === ';') {
|
|
3528
|
+
content = target.substring(index, found).substring(0, leading).replace(/[^\n;]+$/, '');
|
|
3529
|
+
invalid = 1;
|
|
3530
|
+
break;
|
|
3531
|
+
}
|
|
3532
|
+
}
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
if (invalid === 0 || invalid === 2) {
|
|
3536
|
+
const trailing = target.substring(found, closing);
|
|
3537
|
+
if (content = recurse(trailing, true)) {
|
|
3538
|
+
content = header + content;
|
|
3539
|
+
}
|
|
3540
|
+
else if (invalid === 2) {
|
|
3541
|
+
content = header + trailing;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
if (content) {
|
|
3545
|
+
if (pendingEnd) {
|
|
3546
|
+
output = target.substring(pendingStart, pendingEnd) + content;
|
|
3547
|
+
pendingEnd = 0;
|
|
3548
|
+
}
|
|
3549
|
+
else {
|
|
3550
|
+
output += content;
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
else if (!invalid) {
|
|
3554
|
+
if (output) {
|
|
3555
|
+
output += target.substring(index, closing);
|
|
3556
|
+
}
|
|
3557
|
+
else {
|
|
3558
|
+
pendingEnd = closing;
|
|
3559
|
+
}
|
|
3560
|
+
}
|
|
3561
|
+
else if (pendingEnd) {
|
|
3562
|
+
output = target.substring(pendingStart, pendingEnd);
|
|
3563
|
+
pendingEnd = 0;
|
|
3564
|
+
}
|
|
3565
|
+
else {
|
|
3566
|
+
pendingStart = closing;
|
|
3461
3567
|
}
|
|
3568
|
+
index = closing;
|
|
3462
3569
|
}
|
|
3463
|
-
if (
|
|
3464
|
-
|
|
3570
|
+
if (output) {
|
|
3571
|
+
modified = true;
|
|
3572
|
+
return output + target.substring(index);
|
|
3465
3573
|
}
|
|
3466
|
-
|
|
3574
|
+
return !child ? target : '';
|
|
3575
|
+
})(current, false);
|
|
3467
3576
|
}
|
|
3468
3577
|
if (usedVariables) {
|
|
3469
|
-
|
|
3578
|
+
let pattern = useUnsafeCssReplace ? REGEXP_VARIABLES_UNSAFE : REGEXP_VARIABLES;
|
|
3470
3579
|
while (match = pattern.exec(current)) {
|
|
3471
3580
|
if (!usedVariables.includes(match[2])) {
|
|
3472
3581
|
current = replaceMatch(match, current, match[3] === ';' ? getNewlineString(match[1], match[4]) : '', pattern);
|
|
@@ -3474,24 +3583,35 @@ class ChromeDocument extends Document {
|
|
|
3474
3583
|
}
|
|
3475
3584
|
}
|
|
3476
3585
|
pattern.lastIndex = 0;
|
|
3586
|
+
pattern = useUnsafeCssReplace ? REGEXP_PROPERTY_UNSAFE : REGEXP_PROPERTY;
|
|
3587
|
+
while (match = pattern.exec(current)) {
|
|
3588
|
+
if (!usedVariables.includes(match[2])) {
|
|
3589
|
+
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3590
|
+
if (endIndex !== -1) {
|
|
3591
|
+
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3592
|
+
modified = true;
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
pattern.lastIndex = 0;
|
|
3477
3597
|
}
|
|
3478
3598
|
if (usedFontFace) {
|
|
3479
|
-
const
|
|
3599
|
+
const pattern = useUnsafeCssReplace ? REGEXP_FONTFACE_UNSAFE : REGEXP_FONTFACE;
|
|
3480
3600
|
const fontFamily = useUnsafeCssReplace ? REGEXP_FONTFAMILY_UNSAFE : REGEXP_FONTFAMILY;
|
|
3481
|
-
while (match =
|
|
3601
|
+
while (match = pattern.exec(current)) {
|
|
3482
3602
|
const font = fontFamily.exec(match[0]);
|
|
3483
3603
|
if (font && !usedFontFace.includes(font[1].trim().replace(/^(["'])([\S\s]+)\1$/, (...content) => content[2]))) {
|
|
3484
|
-
current = spliceSource(current, match.index, getEndIndex(match),
|
|
3604
|
+
current = spliceSource(current, match.index, getEndIndex(match), pattern, match[1], match[3]);
|
|
3485
3605
|
modified = true;
|
|
3486
3606
|
}
|
|
3487
3607
|
}
|
|
3488
|
-
|
|
3608
|
+
pattern.lastIndex = 0;
|
|
3489
3609
|
}
|
|
3490
3610
|
if (usedKeyframes) {
|
|
3491
3611
|
const pattern = useUnsafeCssReplace ? REGEXP_KEYFRAMES_UNSAFE : REGEXP_KEYFRAMES;
|
|
3492
3612
|
while (match = pattern.exec(current)) {
|
|
3493
3613
|
if (!usedKeyframes.includes(match[2].trim())) {
|
|
3494
|
-
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match));
|
|
3614
|
+
const [endIndex, trailing] = findClosingIndex(current, getEndIndex(match), '{');
|
|
3495
3615
|
if (endIndex !== -1) {
|
|
3496
3616
|
current = spliceSource(current, match.index, endIndex, pattern, match[1], trailing);
|
|
3497
3617
|
modified = true;
|
|
@@ -3546,7 +3666,9 @@ class ChromeDocument extends Document {
|
|
|
3546
3666
|
return this._editing;
|
|
3547
3667
|
}
|
|
3548
3668
|
set dataSource(value) {
|
|
3549
|
-
|
|
3669
|
+
if (Array.isArray(value)) {
|
|
3670
|
+
this._dataSource = value;
|
|
3671
|
+
}
|
|
3550
3672
|
}
|
|
3551
3673
|
get dataSource() {
|
|
3552
3674
|
const result = this._dataSource;
|
|
@@ -3569,7 +3691,7 @@ class ChromeDocument extends Document {
|
|
|
3569
3691
|
return (_a = this.module).settings || (_a.settings = {});
|
|
3570
3692
|
}
|
|
3571
3693
|
}
|
|
3572
|
-
ChromeDocument.INTERNAL_ASSIGNUUID =
|
|
3573
|
-
ChromeDocument.INTERNAL_SERVERROOT =
|
|
3694
|
+
ChromeDocument.INTERNAL_ASSIGNUUID = "__assign__" /* PROPERTIES.ASSIGN */;
|
|
3695
|
+
ChromeDocument.INTERNAL_SERVERROOT = "__serverroot__" /* PROPERTIES.SERVERROOT */;
|
|
3574
3696
|
|
|
3575
3697
|
module.exports = ChromeDocument;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/chrome",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Chrome document constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/cloud": "^0.
|
|
24
|
-
"@e-mc/core": "^0.
|
|
25
|
-
"@e-mc/document": "^0.
|
|
26
|
-
"@e-mc/types": "^0.
|
|
23
|
+
"@e-mc/cloud": "^0.8.0",
|
|
24
|
+
"@e-mc/core": "^0.8.0",
|
|
25
|
+
"@e-mc/document": "^0.8.0",
|
|
26
|
+
"@e-mc/types": "^0.8.0"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -10,6 +10,13 @@ import type { IDomWriter, IXmlElement } from '@e-mc/document/parse/types';
|
|
|
10
10
|
|
|
11
11
|
import type { ChromeAsset, CssRuleData, DataSource, DocumentOutput } from './squared';
|
|
12
12
|
|
|
13
|
+
export const enum PROPERTIES {
|
|
14
|
+
INDEX = '__index__',
|
|
15
|
+
FROM_HTML = '__fromhtml__',
|
|
16
|
+
ASSIGN = '__assign__',
|
|
17
|
+
SERVERROOT = '__serverroot__'
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
interface DocumentDirectory extends IDocumentDirectory {
|
|
14
21
|
template?: string;
|
|
15
22
|
data?: string;
|
package/types/squared.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface DocumentOutput {
|
|
|
29
29
|
productionIncremental?: boolean;
|
|
30
30
|
useOriginalHtmlPage?: boolean | string;
|
|
31
31
|
useUnsafeReplace?: ArrayOf<"html" | "css"> | boolean;
|
|
32
|
+
useSessionCache?: boolean;
|
|
32
33
|
stripCommentsAndCDATA?: boolean | string;
|
|
33
34
|
normalizeHtmlOutput?: boolean | string;
|
|
34
35
|
escapeReservedCharacters?: boolean;
|