@pi-r/chrome 0.11.1 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +97 -105
  2. package/package.json +5 -5
package/index.js CHANGED
@@ -28,7 +28,7 @@ const [REGEXP_NTHCHILD, REGEXP_NTHCHILD_UNSAFE, REGEXP_REPLACECSS] = (function (
28
28
  return [
29
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
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(?:\\(([^)]*)\\)|\\b))?(?:\\s*supports\\((${parenthesis})\\))?(.*?);?$`)
31
+ new RegExp(`^@import\\s+(?:url\\((?:[^)]|(?<=\\\\)\\))+\\)|"(?:[^"]|(?<=\\\\)")+"|'(?:[^']|(?<=\\\\)')+')(\\s*layer(\\([^)]*\\))?)?(?:\\s*supports\\((${parenthesis})\\))?(.*)$`, 'si')
32
32
  ];
33
33
  })();
34
34
  const REGEXP_SRCSETSIZE = /~\s*([\d.]+)\s*([wx])/i;
@@ -46,11 +46,11 @@ const REGEXP_FONTFACE = new RegExp(`(\\s*)@font-face${PATTERN_STRING_SOME}{([^}]
46
46
  const REGEXP_FONTFAMILY = new RegExp(`\\bfont-family${PATTERN_STRING_SOME}:([^;}]+)`, 'i');
47
47
  const REGEXP_KEYFRAMES = new RegExp(`(\\s*)@keyframes${PATTERN_STRING_MANY}([^{]+){`, 'gi');
48
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');
49
+ const REGEXP_VARIABLES_UNSAFE = new RegExp(`(?<!style\\()(\\s*)(--[^\\s:]+)\\s*:[^;}]*([;}])` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'g');
50
50
  const REGEXP_FONTFACE_UNSAFE = new RegExp(`(\\s*)@font-face\\s*{([^}]+)}` + dom_1.DomWriter.PATTERN_TRAILINGSPACE, 'gi');
51
51
  const REGEXP_FONTFAMILY_UNSAFE = /\bfont-family\s*:([^;}]+)/i;
52
52
  const REGEXP_KEYFRAMES_UNSAFE = /(\s*)@keyframes\s+([^{]+){/gi;
53
- const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--[^\s]+)\s*{/gi;
53
+ const REGEXP_PROPERTY_UNSAFE = /(\s*)@property\s+(--\S+)\s*{/gi;
54
54
  const REGEXP_IMAGESET_URL = /(?:^|[^(])\s*("(\s*[^)][^"]*)"|'(\s*[^)][^"]*)')\s*(?:,|$|[^)][^,]*,?)/gd;
55
55
  const REGEXP_SANITIZEALL = new RegExp(`(?:\\s+|\\b)data-(?:pathname|filename|intl-locales|(?:use|exclude)-[^=\\s]+)\\s*${dom_1.DomWriter.PATTERN_ATTRVALUE}(?=(?:[^"<]+"[^"]*"|[^'<]+'[^']*')*[^<>]*>)`, 'g');
56
56
  function removeNamespace(name, source, newline, comments) {
@@ -177,10 +177,6 @@ function parseArg(data, value) {
177
177
  if (!isNaN(n)) {
178
178
  return n;
179
179
  }
180
- const match = /^(["'])(.*)\1$/s.exec(value);
181
- if (match) {
182
- return match[2];
183
- }
184
180
  return getObjectValue(data, value);
185
181
  }
186
182
  function hasCondition(data, condition) {
@@ -197,7 +193,7 @@ function hasCondition(data, condition) {
197
193
  if (items.length > 0 && !isSpace(match[0][0])) {
198
194
  return false;
199
195
  }
200
- items.push([match[1], (0, util_1.trimQuote)(match[2]), (0, util_1.trimQuote)(match[3])]);
196
+ items.push([match[1], (0, util_1.trimQuote)(match[2]), match[3] ? (0, util_1.trimQuote)(match[3]) : '']);
201
197
  }
202
198
  REGEXP_TEMPLATECOMPARISON.lastIndex = 0;
203
199
  const length = items.length;
@@ -205,12 +201,10 @@ function hasCondition(data, condition) {
205
201
  return false;
206
202
  }
207
203
  for (let i = 0; i < length; ++i) {
208
- const item = items[i];
209
- const arg1 = item[1];
210
- const arg2 = item[2];
204
+ const [cmp, arg1, arg2] = items[i];
211
205
  let valid = false;
212
206
  if (arg2) {
213
- switch (item[0]) {
207
+ switch (cmp) {
214
208
  case 'eq':
215
209
  valid = parseArg(data, arg1) == parseArg(data, arg2);
216
210
  break;
@@ -233,7 +227,7 @@ function hasCondition(data, condition) {
233
227
  return false;
234
228
  }
235
229
  }
236
- else if (item[0]) {
230
+ else if (cmp) {
237
231
  return false;
238
232
  }
239
233
  else {
@@ -1091,7 +1085,7 @@ class ChromeDocument extends Document {
1091
1085
  }
1092
1086
  case "image/svg+xml": {
1093
1087
  const source = host.getUTF8String(file, localUri);
1094
- if (/\burl\(/i.test(source)) {
1088
+ if (/\b(?<!-)url\(/i.test(source)) {
1095
1089
  file.editing = true;
1096
1090
  this.editing.push(file);
1097
1091
  this.svgFiles.push(file);
@@ -1208,103 +1202,101 @@ class ChromeDocument extends Document {
1208
1202
  }
1209
1203
  resolveUri(file, source, trailing) {
1210
1204
  const host = this.host;
1211
- if (host) {
1212
- switch (file.mimeType) {
1213
- case "text/javascript":
1214
- case "application/javascript":
1215
- if (file.imports) {
1216
- [[file.uri, source], [this.baseUrl, trailing]].forEach(([uri, code], index) => {
1217
- let localFile;
1218
- if (uri && code && (localFile = this.findSourceRoot(uri))) {
1219
- const { exported, bundleId } = file;
1220
- const bundleMain = !(0, types_1.isEmpty)(bundleId) && this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
1221
- let output;
1222
- if ((index === 1 || exported) && Array.isArray(file.imports)) {
1223
- output = this.resolveImports(file, code, bundleMain || file);
1205
+ switch (file.mimeType) {
1206
+ case "text/javascript":
1207
+ case "application/javascript":
1208
+ if (file.imports) {
1209
+ [[file.uri, source], [this.baseUrl, trailing]].forEach(([uri, code], index) => {
1210
+ let localFile;
1211
+ if (uri && code && (localFile = this.findSourceRoot(uri))) {
1212
+ const { exported, bundleId } = file;
1213
+ const bundleMain = !(0, types_1.isEmpty)(bundleId) && this.assets.find(item => item.bundleId === bundleId && item.bundleIndex === 0);
1214
+ let output;
1215
+ if ((index === 1 || exported) && Array.isArray(file.imports)) {
1216
+ output = this.resolveImports(file, code, bundleMain || file);
1217
+ }
1218
+ else if (index === 0 && !exported) {
1219
+ if (!Document.isDir(localFile)) {
1220
+ localFile = path.dirname(localFile);
1224
1221
  }
1225
- else if (index === 0 && !exported) {
1226
- if (!Document.isDir(localFile)) {
1227
- localFile = path.dirname(localFile);
1228
- }
1229
- output = code;
1230
- let mainFile, pathname, match;
1231
- const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (Document.isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1232
- while (match = REGEXP_IMPORTMODULE.exec(output)) {
1233
- const type = match[3] || match[5];
1234
- const idx = match[1] ? 1 : match[2] ? 2 : 4;
1235
- const [a, b] = match.indices[idx];
1236
- const from = (0, util_1.trimQuote)(match[idx]);
1237
- const quote = output[a];
1238
- const relative = /^\.{0,2}\//.test(from);
1239
- if (type && /\btype\s*:\s*(["'`])(?:css|json)\1/.test(type)) {
1240
- try {
1241
- const asset = host.findAsset(relative ? new URL(from, uri) : from);
1242
- if (asset) {
1243
- const [relativeUrl, sameDir] = this.getSrcUrl(bundleMain || file, asset);
1244
- if (relativeUrl) {
1245
- output = (0, util_1.spliceString)(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
1246
- }
1222
+ output = code;
1223
+ let mainFile, pathname, match;
1224
+ const ignorePath = bundleMain && (mainFile = this.findSourceRoot(bundleMain.uri)) && (Document.isDir(mainFile) || (mainFile = path.dirname(mainFile))) && mainFile === localFile;
1225
+ while (match = REGEXP_IMPORTMODULE.exec(output)) {
1226
+ const type = match[3] || match[5];
1227
+ const idx = match[1] ? 1 : match[2] ? 2 : 4;
1228
+ const [a, b] = match.indices[idx];
1229
+ const from = (0, util_1.trimQuote)(match[idx]);
1230
+ const quote = output[a];
1231
+ const relative = /^\.{0,2}\//.test(from);
1232
+ if (type && /\btype\s*:\s*(["'`])(?:css|json)\1/.test(type)) {
1233
+ try {
1234
+ const asset = host.findAsset(relative ? new URL(from, uri) : from);
1235
+ if (asset) {
1236
+ const [relativeUrl, sameDir] = this.getSrcUrl(bundleMain || file, asset);
1237
+ if (relativeUrl) {
1238
+ output = (0, util_1.spliceString)(output, a, b, quote + (sameDir ? './' : '') + relativeUrl + quote, REGEXP_IMPORTMODULE);
1247
1239
  }
1248
1240
  }
1249
- catch {
1250
- }
1251
- continue;
1252
1241
  }
1253
- if (relative) {
1254
- if (ignorePath) {
1255
- continue;
1256
- }
1257
- pathname = path.join(localFile, from);
1258
- }
1259
- else if (!(pathname = this.findSourceRoot(from)) || !Document.isPath(pathname)) {
1260
- const asset = host.findAsset(from);
1261
- if (!asset || asset.invalid) {
1262
- continue;
1263
- }
1264
- pathname = asset.localUri;
1242
+ catch {
1265
1243
  }
1266
- if (pathname && Document.isPath(pathname)) {
1267
- output = (0, util_1.spliceString)(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
1244
+ continue;
1245
+ }
1246
+ if (relative) {
1247
+ if (ignorePath) {
1248
+ continue;
1268
1249
  }
1250
+ pathname = path.join(localFile, from);
1269
1251
  }
1270
- REGEXP_IMPORTMODULE.lastIndex = 0;
1271
- }
1272
- if (output && output !== code) {
1273
- if (index === 0) {
1274
- source = output;
1252
+ else if (!(pathname = this.findSourceRoot(from)) || !Document.isPath(pathname)) {
1253
+ const asset = host.findAsset(from);
1254
+ if (!asset || asset.invalid) {
1255
+ continue;
1256
+ }
1257
+ pathname = asset.localUri;
1275
1258
  }
1276
- else {
1277
- trailing = output;
1259
+ if (pathname && Document.isPath(pathname)) {
1260
+ output = (0, util_1.spliceString)(output, a, b, quote + pathname + quote, REGEXP_IMPORTMODULE);
1278
1261
  }
1279
1262
  }
1263
+ REGEXP_IMPORTMODULE.lastIndex = 0;
1280
1264
  }
1281
- });
1282
- }
1283
- break;
1284
- case "text/css":
1285
- if (file.editing) {
1286
- const bundleId = file.bundleId;
1287
- if (!(0, types_1.isEmpty)(bundleId)) {
1288
- for (const asset of this.assets) {
1289
- if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
1290
- const output = this.processUrl(host, file, source, 'css', asset);
1291
- if (output) {
1292
- source = output;
1293
- file.modified = true;
1294
- }
1295
- break;
1265
+ if (output && output !== code) {
1266
+ if (index === 0) {
1267
+ source = output;
1268
+ }
1269
+ else {
1270
+ trailing = output;
1296
1271
  }
1297
1272
  }
1298
1273
  }
1299
- if (trailing && this.htmlFile) {
1300
- const output = this.processUrl(host, file, trailing, 'css', this.htmlFile);
1301
- if (output) {
1302
- trailing = output;
1274
+ });
1275
+ }
1276
+ break;
1277
+ case "text/css":
1278
+ if (file.editing) {
1279
+ const bundleId = file.bundleId;
1280
+ if (!(0, types_1.isEmpty)(bundleId)) {
1281
+ for (const asset of this.assets) {
1282
+ if (asset.bundleIndex === 0 && asset.bundleId === bundleId) {
1283
+ const output = this.processUrl(host, file, source, 'css', asset);
1284
+ if (output) {
1285
+ source = output;
1286
+ file.modified = true;
1287
+ }
1288
+ break;
1303
1289
  }
1304
1290
  }
1305
1291
  }
1306
- break;
1307
- }
1292
+ if (trailing && this.htmlFile) {
1293
+ const output = this.processUrl(host, file, trailing, 'css', this.htmlFile);
1294
+ if (output) {
1295
+ trailing = output;
1296
+ }
1297
+ }
1298
+ }
1299
+ break;
1308
1300
  }
1309
1301
  return (trailing !== undefined ? [source, trailing] : source);
1310
1302
  }
@@ -1371,7 +1363,7 @@ class ChromeDocument extends Document {
1371
1363
  if (match) {
1372
1364
  const layer = match[1];
1373
1365
  const supports = match[3]?.trim();
1374
- const query = match[4].trim();
1366
+ const query = match[4].trim().replace(/;+$/, '');
1375
1367
  if (layer || supports || query) {
1376
1368
  const newline = (0, util_1.getNewline)(source);
1377
1369
  let result = supports ? `@supports (${supports}) {` + newline : '';
@@ -1379,8 +1371,8 @@ class ChromeDocument extends Document {
1379
1371
  result += `@media ${query} {` + newline;
1380
1372
  }
1381
1373
  if (layer) {
1382
- let name = match[2];
1383
- result += '@layer ' + (name && (name = name.trim()) ? name + ' ' : '') + `{${newline + source + newline}}` + (query ? newline + '}' : '');
1374
+ const name = match[2]?.replace(/\s+/g, '');
1375
+ result += '@layer ' + (name ? name.slice(1, -1) + ' ' : '') + `{${newline + source + newline}}` + (query ? newline + '}' : '');
1384
1376
  }
1385
1377
  else if (query) {
1386
1378
  result += source + newline + '}';
@@ -2676,20 +2668,20 @@ class ChromeDocument extends Document {
2676
2668
  segment = replaceMatch(match, segment, target[col] ? (!match[1] || target[col - 1].includes('\n') ? '' : match[1]) + target[col - 1] + target[col] : '', REGEXP_TEMPLATECONDITIONAL);
2677
2669
  }
2678
2670
  const literal = segment.trim();
2679
- if (literal.startsWith('`') && literal.endsWith('`')) {
2671
+ if (literal.at(0) === '`' && literal.at(-1) === '`') {
2680
2672
  if (!this.hasEval('function')) {
2681
2673
  errors = (0, types_1.errorMessage)('eval', "Unsupported access", 'function');
2682
2674
  continue;
2683
2675
  }
2684
2676
  try {
2685
- let content = new Function('return ' + literal + ';')(row);
2677
+ let unsafe = new Function('return ' + literal + ';').call(row);
2686
2678
  if (!segment.startsWith('`')) {
2687
- content = segment.substring(0, segment.indexOf('`')) + content;
2679
+ unsafe = segment.substring(0, segment.indexOf('`')) + unsafe;
2688
2680
  }
2689
2681
  if (!segment.endsWith('`')) {
2690
- content += segment.substring(segment.lastIndexOf('`') + 1);
2682
+ unsafe += segment.substring(segment.lastIndexOf('`') + 1);
2691
2683
  }
2692
- segment = content;
2684
+ segment = unsafe;
2693
2685
  }
2694
2686
  catch (err) {
2695
2687
  errors = err instanceof Error ? err : true;
@@ -2923,7 +2915,7 @@ class ChromeDocument extends Document {
2923
2915
  if (!empty && item.type !== 'display' || item.transactionFail) {
2924
2916
  const emptyResponse = (value, service = item.source) => {
2925
2917
  value ||= "Unknown";
2926
- return errorDataSource(service + ': ' + (errors instanceof Error ? errors.message : 'Empty'), value);
2918
+ return errorDataSource(errors instanceof Error ? errors.message : service + ': Empty', value);
2927
2919
  };
2928
2920
  switch (item.source) {
2929
2921
  case 'cloud': {
@@ -3553,7 +3545,7 @@ class ChromeDocument extends Document {
3553
3545
  const isHtml = type === 'html';
3554
3546
  const isJs = type === 'js';
3555
3547
  const imageSet = /\b(?:-webkit-)?image-set\(/gi;
3556
- const pattern = isJs ? /\bimport\(/g : type === 'svg' ? /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g : /(?:\b[Uu][Rr][Ll]\(|@import\s+(["'])|\b([Hh][Rr][Ee][Ff])\s*=)/g;
3548
+ const pattern = isJs ? /\b(?<!-)import\(/g : type === 'svg' ? /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi : /(?:\b(?<!-)url\(|@import\s+(["'])|\b(?<!-)(href)\s*=)/gi;
3557
3549
  let length = source.length, modified = false, match;
3558
3550
  while (match = imageSet.exec(source)) {
3559
3551
  const startIndex = match.index + match[0].length;
@@ -3746,7 +3738,7 @@ class ChromeDocument extends Document {
3746
3738
  if (!isText) {
3747
3739
  let j = startIndex;
3748
3740
  while (isSpace(source[--j])) { }
3749
- valid = source.substring(k = j - 6, j + 1) === '@import';
3741
+ valid = source.substring(k = j - 6, j + 1).toLowerCase() === '@import';
3750
3742
  }
3751
3743
  else {
3752
3744
  k = startIndex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/chrome",
3
- "version": "0.11.1",
3
+ "version": "0.11.3",
4
4
  "description": "Chrome document constructor for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -20,10 +20,10 @@
20
20
  "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
22
  "dependencies": {
23
- "@e-mc/cloud": "^0.13.5",
24
- "@e-mc/core": "^0.13.5",
25
- "@e-mc/document": "^0.13.5",
26
- "@e-mc/types": "^0.13.5",
23
+ "@e-mc/cloud": "^0.13.10",
24
+ "@e-mc/core": "^0.13.10",
25
+ "@e-mc/document": "^0.13.10",
26
+ "@e-mc/types": "^0.13.10",
27
27
  "image-size": "^2.0.2"
28
28
  }
29
29
  }