lexgui 8.2.4 → 8.2.5

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.
@@ -12,7 +12,7 @@ const g$2 = globalThis;
12
12
  let LX = g$2.LX;
13
13
  if (!LX) {
14
14
  LX = {
15
- version: '8.2.4',
15
+ version: '8.2.5',
16
16
  ready: false,
17
17
  extensions: [], // Store extensions used
18
18
  extraCommandbarEntries: [], // User specific entries for command bar
@@ -4982,6 +4982,7 @@ class NodeTree {
4982
4982
  item.id = LX.getSupportedDOMName(node.id);
4983
4983
  item.tabIndex = '0';
4984
4984
  item.treeData = node;
4985
+ node.treeEl = item;
4985
4986
  // Select hierarchy icon
4986
4987
  let icon = (this.options.skipDefaultIcon ?? true) ? null : 'Dot'; // Default: no childs
4987
4988
  if (isParent) {
@@ -5464,21 +5465,45 @@ class NodeTree {
5464
5465
  el.focus();
5465
5466
  }
5466
5467
  }
5467
- select(id) {
5468
+ /* 'path' here helps to identity the correct item based on its parent path, for same 'id' issues */
5469
+ select(id, path) {
5468
5470
  const nodeFilter = this.domEl.querySelector('.lexnodetreefilter');
5469
5471
  if (nodeFilter) {
5470
5472
  nodeFilter.value = '';
5471
5473
  }
5472
5474
  this.refresh(null, id);
5473
5475
  this.domEl.querySelectorAll('.selected').forEach((i) => i.classList.remove('selected'));
5474
- // Unselect
5475
- if (!id) {
5476
- this.selected.length = 0;
5477
- return;
5476
+ if (id === undefined) {
5477
+ // if no id, try with the path
5478
+ if (path !== undefined) {
5479
+ id = path.at(-1);
5480
+ }
5481
+ else {
5482
+ // Unselect
5483
+ this.selected.length = 0;
5484
+ return;
5485
+ }
5486
+ }
5487
+ let el = null;
5488
+ if (path !== undefined) {
5489
+ let sourceData = this.data;
5490
+ for (const p of path) {
5491
+ const pItem = sourceData.children.find((item) => item.id === p);
5492
+ if (!pItem)
5493
+ break;
5494
+ sourceData = pItem;
5495
+ }
5496
+ el = sourceData.treeEl;
5497
+ console.assert(el, 'NodeTree: No domEl in item ' + id);
5498
+ }
5499
+ else if (id !== undefined) {
5500
+ // Element should exist, since tree was refreshed to show it
5501
+ el = this.domEl.querySelector('#' + LX.getSupportedDOMName(id));
5502
+ console.assert(el, "NodeTree: Can't select node " + id);
5503
+ }
5504
+ if (!el) {
5505
+ console.assert(el, "NodeTree: Can't select node " + id);
5478
5506
  }
5479
- // Element should exist, since tree was refreshed to show it
5480
- const el = this.domEl.querySelector('#' + LX.getSupportedDOMName(id));
5481
- console.assert(el, "NodeTree: Can't select node " + id);
5482
5507
  el.classList.add('selected');
5483
5508
  this.selected = [el.treeData];
5484
5509
  el.focus();
@@ -14037,7 +14062,7 @@ class AssetView {
14037
14062
  rootItem;
14038
14063
  path = [];
14039
14064
  rootPath = '';
14040
- selectedItem = undefined;
14065
+ selectedItems = [];
14041
14066
  allowedTypes;
14042
14067
  searchValue = '';
14043
14068
  filter = 'None';
@@ -14049,7 +14074,8 @@ class AssetView {
14049
14074
  skipPreview = false;
14050
14075
  useNativeTitle = false;
14051
14076
  onlyFolders = true;
14052
- allowMultipleSelection = false;
14077
+ allowMultipleSelection = true;
14078
+ allowItemCheck = false;
14053
14079
  previewActions = [];
14054
14080
  contextMenu = [];
14055
14081
  itemContextMenuOptions = null;
@@ -14089,6 +14115,7 @@ class AssetView {
14089
14115
  this.useNativeTitle = options.useNativeTitle ?? this.useNativeTitle;
14090
14116
  this.onlyFolders = options.onlyFolders ?? this.onlyFolders;
14091
14117
  this.allowMultipleSelection = options.allowMultipleSelection ?? this.allowMultipleSelection;
14118
+ this.allowItemCheck = options.allowItemCheck ?? this.allowItemCheck;
14092
14119
  this.previewActions = options.previewActions ?? [];
14093
14120
  this.itemContextMenuOptions = options.itemContextMenuOptions;
14094
14121
  this.gridScale = options.gridScale ?? this.gridScale;
@@ -14185,9 +14212,9 @@ class AssetView {
14185
14212
  if (!this.useNativeTitle) {
14186
14213
  let desc = document.createElement('span');
14187
14214
  desc.className = 'lexitemdesc';
14188
- desc.id = `floatingTitle_${metadata.uid}`;
14215
+ desc.id = LX.getSupportedDOMName(`floatingTitle_${metadata.uid}`);
14189
14216
  desc.innerHTML = `File: ${item.id}<br>Type: ${type}`;
14190
- LX.insertChildAtIndex(this.content, desc, childIndex ? childIndex + 1 : undefined);
14217
+ LX.insertChildAtIndex(this.content, desc, childIndex !== undefined ? childIndex + 1 : undefined);
14191
14218
  itemEl.addEventListener('mousemove', (e) => {
14192
14219
  if (!isGridLayout) {
14193
14220
  return;
@@ -14213,7 +14240,7 @@ class AssetView {
14213
14240
  else {
14214
14241
  itemEl.title = type + ': ' + item.id;
14215
14242
  }
14216
- if (this.allowMultipleSelection) {
14243
+ if (this.allowItemCheck) {
14217
14244
  let checkbox = document.createElement('input');
14218
14245
  checkbox.type = 'checkbox';
14219
14246
  checkbox.className = 'lexcheckbox';
@@ -14302,11 +14329,12 @@ class AssetView {
14302
14329
  e.stopPropagation();
14303
14330
  const isDoubleClick = e.detail == LX.MOUSE_DOUBLE_CLICK;
14304
14331
  if (!isDoubleClick) {
14305
- if (!e.shiftKey) {
14332
+ if (!e.shiftKey || !that.allowMultipleSelection) {
14306
14333
  that.content.querySelectorAll('.lexassetitem').forEach((i) => i.classList.remove('selected'));
14334
+ that.selectedItems.length = 0;
14307
14335
  }
14308
14336
  this.classList.add('selected');
14309
- that.selectedItem = item;
14337
+ that.selectedItems.push(item);
14310
14338
  if (!that.skipPreview) {
14311
14339
  that._previewAsset(item);
14312
14340
  }
@@ -14338,35 +14366,44 @@ class AssetView {
14338
14366
  e.preventDefault();
14339
14367
  e.stopImmediatePropagation();
14340
14368
  e.stopPropagation();
14341
- const multiple = that.content.querySelectorAll('.selected').length;
14369
+ const multipleSelection = that.selectedItems.length > 1;
14342
14370
  const options = [
14343
14371
  {
14344
- name: (multiple > 1) ? (multiple + ' selected') : item.id,
14372
+ name: multipleSelection ? (`${that.selectedItems.length} selected`) : item.id,
14345
14373
  icon: LX.makeIcon('CircleSmall', { svgClass: `fill-current text-${typeColor}` }),
14346
14374
  className: 'text-sm',
14347
14375
  disabled: true
14348
14376
  },
14349
14377
  null
14350
14378
  ];
14351
- if (multiple <= 1) {
14379
+ // By now, allow with none/single selected items
14380
+ if (!multipleSelection) {
14352
14381
  options.push({ name: 'Rename', icon: 'TextCursor', callback: that._renameItemPopover.bind(that, item) });
14353
14382
  }
14354
- if (!isFolder) {
14383
+ // By now, allow with none/single selected items
14384
+ if (!isFolder && !multipleSelection) {
14355
14385
  options.push({ name: 'Clone', icon: 'Copy', callback: that._requestCloneItem.bind(that, item) });
14356
14386
  }
14357
- options.push({ name: 'Move', icon: 'FolderInput', callback: () => that._moveItem(item) });
14358
- if (type == 'Script' && LX.has('CodeEditor')) {
14387
+ // By now, allow with none/single selected items
14388
+ if (!multipleSelection) {
14389
+ options.push({ name: 'Move', icon: 'FolderInput', callback: () => that._moveItem(item) });
14390
+ }
14391
+ // By now, allow with none/single selected items
14392
+ if (!multipleSelection && type == 'Script' && LX.has('CodeEditor')) {
14359
14393
  options.push({ name: 'Open in Editor', icon: 'Code', callback: that._openScriptInEditor.bind(that, item) });
14360
14394
  }
14361
14395
  if (that.itemContextMenuOptions) {
14362
- options.push(null);
14396
+ if (options.length > 2)
14397
+ options.push(null);
14363
14398
  for (let o of that.itemContextMenuOptions) {
14364
14399
  if (!o.name || !o.callback)
14365
14400
  continue;
14366
- options.push({ name: o.name, icon: o.icon, callback: o.callback?.bind(that, item) });
14401
+ options.push({ name: o.name, icon: o.icon,
14402
+ callback: o.callback?.bind(that, multipleSelection ? that.selectedItems : [item]) });
14367
14403
  }
14368
14404
  }
14369
- options.push(null, { name: 'Delete', icon: 'Trash2', className: 'destructive', callback: that._requestDeleteItem.bind(that, item) });
14405
+ options.push(null, { name: 'Delete', icon: 'Trash2', className: 'destructive',
14406
+ callback: that._requestDeleteItem.bind(that, multipleSelection ? that.selectedItems : [item]) });
14370
14407
  LX.addClass(that.contentPanel.root, 'pointer-events-none');
14371
14408
  LX.addDropdownMenu(e.target, options, { side: 'right', align: 'start', event: e, onBlur: () => {
14372
14409
  LX.removeClass(that.contentPanel.root, 'pointer-events-none');
@@ -14397,7 +14434,8 @@ class AssetView {
14397
14434
  e.dataTransfer.setDragImage(img, 0, 0);
14398
14435
  e.dataTransfer.effectAllowed = 'move';
14399
14436
  }
14400
- const desc = that.content.querySelector(`#floatingTitle_${metadata.uid}`);
14437
+ const domName = LX.getSupportedDOMName(`floatingTitle_${metadata.uid}`);
14438
+ const desc = that.content.querySelector(`#${domName}`);
14401
14439
  if (desc)
14402
14440
  desc.style.display = 'none';
14403
14441
  }, false);
@@ -14432,7 +14470,8 @@ class AssetView {
14432
14470
  });
14433
14471
  itemEl.addEventListener('mouseenter', (e) => {
14434
14472
  if (!that.useNativeTitle && isGridLayout) {
14435
- const desc = that.content.querySelector(`#floatingTitle_${metadata.uid}`);
14473
+ const domName = LX.getSupportedDOMName(`floatingTitle_${metadata.uid}`);
14474
+ const desc = that.content.querySelector(`#${domName}`);
14436
14475
  if (desc)
14437
14476
  desc.style.display = 'unset';
14438
14477
  }
@@ -14446,7 +14485,8 @@ class AssetView {
14446
14485
  itemEl.addEventListener('mouseleave', (e) => {
14447
14486
  if (!that.useNativeTitle && isGridLayout) {
14448
14487
  setTimeout(() => {
14449
- const desc = that.content.querySelector(`#floatingTitle_${metadata.uid}`);
14488
+ const domName = LX.getSupportedDOMName(`floatingTitle_${metadata.uid}`);
14489
+ const desc = that.content.querySelector(`#${domName}`);
14450
14490
  if (desc)
14451
14491
  desc.style.display = 'none';
14452
14492
  }, 100);
@@ -14575,7 +14615,7 @@ class AssetView {
14575
14615
  const dom = node.domEl;
14576
14616
  dom?.classList.add('selected');
14577
14617
  }
14578
- this.selectedItem = node;
14618
+ this.selectedItems = [node];
14579
14619
  }
14580
14620
  });
14581
14621
  tree.on('beforeMove', (event, resolve) => {
@@ -14726,6 +14766,7 @@ class AssetView {
14726
14766
  });
14727
14767
  this.content.addEventListener('click', function () {
14728
14768
  this.querySelectorAll('.lexassetitem').forEach((i) => i.classList.remove('selected'));
14769
+ that.selectedItems.length = 0;
14729
14770
  });
14730
14771
  this.content.addEventListener('contextmenu', function (e) {
14731
14772
  e.preventDefault();
@@ -14944,7 +14985,7 @@ class AssetView {
14944
14985
  return;
14945
14986
  }
14946
14987
  const child = this.currentData[0];
14947
- const sameFolder = child?.parent?.id === folderItem.id;
14988
+ const sameFolder = child?.parent?.metadata?.uid === folderItem.metadata?.uid;
14948
14989
  if (storeCurrent) {
14949
14990
  this.prevData.push(this.currentFolder ?? {
14950
14991
  id: '/',
@@ -14970,7 +15011,15 @@ class AssetView {
14970
15011
  if (mustRefresh) {
14971
15012
  this._processData(this.data);
14972
15013
  this._refreshContent();
14973
- this.tree?.select(this.currentFolder.id);
15014
+ // Get path to avoid same id issues
15015
+ let path = `${this.currentFolder.id}/`;
15016
+ let parent = this.currentFolder.parent;
15017
+ while (parent && parent.id !== '/') {
15018
+ path += `${parent.id}/`;
15019
+ parent = parent.parent;
15020
+ }
15021
+ const parentsPath = path.split('/').filter(Boolean).reverse();
15022
+ this.tree?.select(undefined, parentsPath);
14974
15023
  }
14975
15024
  this._updatePath();
14976
15025
  }
@@ -14995,14 +15044,14 @@ class AssetView {
14995
15044
  }
14996
15045
  return true;
14997
15046
  }
14998
- _requestDeleteItem(item) {
15047
+ _requestDeleteItem(items) {
14999
15048
  const onBeforeDelete = this._callbacks['beforeDelete'];
15000
15049
  const onDelete = this._callbacks['delete'];
15001
15050
  const resolve = (...args) => {
15002
- this._deleteItem(item);
15051
+ items.forEach((item) => this._deleteItem(item));
15003
15052
  const event = {
15004
15053
  type: 'delete',
15005
- items: [item],
15054
+ items,
15006
15055
  userInitiated: true
15007
15056
  };
15008
15057
  if (onDelete)
@@ -15011,7 +15060,7 @@ class AssetView {
15011
15060
  if (onBeforeDelete) {
15012
15061
  const event = {
15013
15062
  type: 'delete',
15014
- items: [item],
15063
+ items,
15015
15064
  userInitiated: true
15016
15065
  };
15017
15066
  onBeforeDelete(event, resolve);
@@ -15120,7 +15169,7 @@ class AssetView {
15120
15169
  }
15121
15170
  bcContainer.innerHTML = '';
15122
15171
  bcContainer.appendChild(LX.makeBreadcrumb(path.reverse().map((p) => {
15123
- return { title: p };
15172
+ return { name: p };
15124
15173
  }), {
15125
15174
  maxItems: 4,
15126
15175
  separatorIcon: 'ChevronRight'
@@ -15290,16 +15339,21 @@ class AssetView {
15290
15339
  // It could be a Tree event, so maybe the elements is not created yet
15291
15340
  if (item.domEl) {
15292
15341
  const wasSelected = LX.hasClass(item.domEl, 'selected');
15293
- const hoverTitle = this.content.querySelector(`#floatingTitle_${item.id.replace(/\s/g, '_').replaceAll('.', '_')}`);
15342
+ const hoverTitleDomName = LX.getSupportedDOMName(`floatingTitle_${item.metadata.uid}`);
15343
+ const hoverTitle = this.content.querySelector(`#${hoverTitleDomName}`);
15294
15344
  if (hoverTitle)
15295
15345
  hoverTitle.remove();
15296
15346
  item.domEl?.remove();
15347
+ // Update new name
15348
+ item.id = newName;
15297
15349
  item.domEl = this.addItem(item, idx * 2);
15298
15350
  if (wasSelected) {
15299
15351
  this._previewAsset(item);
15300
15352
  }
15301
15353
  }
15302
- item.id = newName;
15354
+ else {
15355
+ item.id = newName;
15356
+ }
15303
15357
  this.tree?.refresh();
15304
15358
  this._processData(this.data);
15305
15359
  }
@@ -15578,7 +15632,7 @@ function swapArrayElements(array, id0, id1) {
15578
15632
  [array[id0], array[id1]] = [array[id1], array[id0]];
15579
15633
  }
15580
15634
  function sliceChars(str, idx, n = 1) {
15581
- return str.substr(0, idx) + str.substr(idx + n);
15635
+ return str.substring(0, idx) + str.substring(idx + n);
15582
15636
  }
15583
15637
  function firstNonspaceIndex(str) {
15584
15638
  const index = str.search(/\S|$/);
@@ -15823,7 +15877,7 @@ const HighlightRules = {
15823
15877
  common: [
15824
15878
  { test: (ctx) => ctx.inBlockComment, className: 'cm-com' },
15825
15879
  { test: (ctx) => ctx.inString, action: (ctx, editor) => editor._appendStringToken(ctx.token), discard: true },
15826
- { test: (ctx) => ctx.token.substr(0, ctx.singleLineCommentToken.length) == ctx.singleLineCommentToken, className: 'cm-com' },
15880
+ { test: (ctx) => ctx.token.substring(0, ctx.singleLineCommentToken.length) == ctx.singleLineCommentToken, className: 'cm-com' },
15827
15881
  { test: (ctx, editor) => editor._isKeyword(ctx), className: 'cm-kwd' },
15828
15882
  {
15829
15883
  test: (ctx, editor) => editor._mustHightlightWord(ctx.token, CE.builtIn, ctx.lang) && (ctx.lang.tags ?? false
@@ -16589,8 +16643,8 @@ class CodeEditor {
16589
16643
  var _c0 = this.getCharAtPos(cursor, -1);
16590
16644
  var _c1 = this.getCharAtPos(cursor);
16591
16645
  this.code.lines.splice(cursor.line + 1, 0, '');
16592
- this.code.lines[cursor.line + 1] = this.code.lines[ln].substr(cursor.position); // new line (below)
16593
- this.code.lines[ln] = this.code.lines[ln].substr(0, cursor.position); // line above
16646
+ this.code.lines[cursor.line + 1] = this.code.lines[ln].substring(cursor.position); // new line (below)
16647
+ this.code.lines[ln] = this.code.lines[ln].substring(0, cursor.position); // line above
16594
16648
  this.lineDown(cursor, true);
16595
16649
  // Check indentation
16596
16650
  var spaces = firstNonspaceIndex(this.code.lines[ln]);
@@ -16682,7 +16736,7 @@ class CodeEditor {
16682
16736
  e.keepSelection = kS;
16683
16737
  }
16684
16738
  var diff = Math.max(cursor.position - from, 1);
16685
- var substr = word.substr(0, diff);
16739
+ var substr = word.substring(0, diff);
16686
16740
  // Selections...
16687
16741
  if (e.shiftKey) {
16688
16742
  if (!cursor.selection) {
@@ -16752,7 +16806,7 @@ class CodeEditor {
16752
16806
  if (!word.length)
16753
16807
  this.lineDown(cursor, true);
16754
16808
  var diff = cursor.position - from;
16755
- var substr = word.substr(diff);
16809
+ var substr = word.substring(diff);
16756
16810
  // Selections...
16757
16811
  if (e.shiftKey) {
16758
16812
  if (!cursor.selection) {
@@ -17136,6 +17190,7 @@ class CodeEditor {
17136
17190
  this._addRedoStep(cursor);
17137
17191
  // Extract info from the last code state
17138
17192
  const step = this.code.undoSteps.pop();
17193
+ debugger;
17139
17194
  // Set old state lines
17140
17195
  this.code.lines = step.lines;
17141
17196
  this.processLines();
@@ -17751,9 +17806,9 @@ class CodeEditor {
17751
17806
  index += i == cursor.selection.fromY ? cursor.selection.fromX : this.code.lines[i].length;
17752
17807
  }
17753
17808
  index += cursor.selection.fromY * separator.length;
17754
- const num_chars = cursor.selection.chars
17809
+ const numChars = cursor.selection.chars
17755
17810
  + (cursor.selection.toY - cursor.selection.fromY) * separator.length;
17756
- const text = code.substr(index, num_chars);
17811
+ const text = code.substring(index, index + numChars);
17757
17812
  content = text.split(separator).join('\n');
17758
17813
  }
17759
17814
  const options = this.onContextMenu(this, content, e);
@@ -17898,7 +17953,7 @@ class CodeEditor {
17898
17953
  : this.code.lines[i].substring(toX, fromX);
17899
17954
  }
17900
17955
  else
17901
- string = this.code.lines[i].substr(fromX);
17956
+ string = this.code.lines[i].substring(fromX);
17902
17957
  const pixels = (reverse && deltaY == 0 ? toX : fromX) * this.charWidth;
17903
17958
  if (isVisible)
17904
17959
  domEl.style.left = `calc(${pixels}px + ${this.xPadding})`;
@@ -17938,7 +17993,7 @@ class CodeEditor {
17938
17993
  // Compute new width and selection margins
17939
17994
  let string;
17940
17995
  if (sId == 0) {
17941
- string = this.code.lines[i].substr(toX);
17996
+ string = this.code.lines[i].substring(toX);
17942
17997
  const pixels = toX * this.charWidth;
17943
17998
  if (isVisible)
17944
17999
  domEl.style.left = 'calc(' + pixels + 'px + ' + this.xPadding + ')';
@@ -18265,9 +18320,9 @@ class CodeEditor {
18265
18320
  index += i == cursor.selection.fromY ? cursor.selection.fromX : this.code.lines[i].length;
18266
18321
  }
18267
18322
  index += cursor.selection.fromY * separator.length;
18268
- const num_chars = cursor.selection.chars
18323
+ const numChars = cursor.selection.chars
18269
18324
  + (cursor.selection.toY - cursor.selection.fromY) * separator.length;
18270
- const text = code.substr(index, num_chars);
18325
+ const text = code.substring(index, index + numChars);
18271
18326
  const lines = text.split(separator);
18272
18327
  textToCopy = lines.join('\n');
18273
18328
  }
@@ -18301,7 +18356,7 @@ class CodeEditor {
18301
18356
  index += cursor.selection.fromY * separator.length;
18302
18357
  const numChars = cursor.selection.chars
18303
18358
  + (cursor.selection.toY - cursor.selection.fromY) * separator.length;
18304
- const text = code.substr(index, numChars);
18359
+ const text = code.substring(index, index + numChars);
18305
18360
  const lines = text.split(separator);
18306
18361
  textToCut = lines.join('\n');
18307
18362
  this.deleteSelection(cursor);
@@ -18582,7 +18637,7 @@ class CodeEditor {
18582
18637
  tokens: tokensToEvaluate
18583
18638
  });
18584
18639
  if (blockComments && this._buildingBlockComment != undefined
18585
- && token.substr(0, blockCommentsTokens[1].length) == blockCommentsTokens[1]) {
18640
+ && token.substring(0, blockCommentsTokens[1].length) == blockCommentsTokens[1]) {
18586
18641
  const [commentLineNumber, tokenPos] = this._buildingBlockComment;
18587
18642
  this._blockCommentCache.push([new LX.vec2(commentLineNumber, lineNumber), new LX.vec2(tokenPos, tokenStartIndex)]);
18588
18643
  delete this._buildingBlockComment;
@@ -18605,10 +18660,10 @@ class CodeEditor {
18605
18660
  const openIdx = kLineString.lastIndexOf('{');
18606
18661
  const closeIdx = kLineString.lastIndexOf('}');
18607
18662
  if (openIdx > -1) {
18608
- kLineString = kLineString.substr(openIdx);
18663
+ kLineString = kLineString.substring(openIdx);
18609
18664
  }
18610
18665
  else if (closeIdx > -1) {
18611
- kLineString = kLineString.substr(closeIdx);
18666
+ kLineString = kLineString.substring(closeIdx);
18612
18667
  }
18613
18668
  contextTokens = [...this._getTokensFromLine(kLineString), ...contextTokens];
18614
18669
  if (kLineString.length !== this.code.lines[lineNumber - k]) {
@@ -18671,7 +18726,7 @@ class CodeEditor {
18671
18726
  until reaching new delimiters
18672
18727
  */
18673
18728
  if (lineOpensBlock) {
18674
- const r = tokens.filter((t) => t.substr(0, blockCommentsTokens[0].length) == blockCommentsTokens[0]);
18729
+ const r = tokens.filter((t) => t.substring(0, blockCommentsTokens[0].length) == blockCommentsTokens[0]);
18675
18730
  if (!r.length) {
18676
18731
  this._buildingBlockComment = [lineNumber - 1, 0];
18677
18732
  this.mustProcessPreviousLine = (tokens) => {
@@ -18693,7 +18748,7 @@ class CodeEditor {
18693
18748
  }
18694
18749
  }
18695
18750
  else if (lineClosesBlock) {
18696
- const r = tokens.filter((t) => t.substr(0, blockCommentsTokens[1].length) == blockCommentsTokens[1]);
18751
+ const r = tokens.filter((t) => t.substring(0, blockCommentsTokens[1].length) == blockCommentsTokens[1]);
18697
18752
  if (!r.length) {
18698
18753
  this._buildingBlockComment = [section[0].x, section[1].x];
18699
18754
  this.mustProcessNextLine = (tokens) => {
@@ -19468,9 +19523,9 @@ class CodeEditor {
19468
19523
  index += i == selection.fromY ? selection.fromX : this.code.lines[i].length;
19469
19524
  }
19470
19525
  index += selection.fromY * separator.length;
19471
- const num_chars = selection.chars + (selection.toY - selection.fromY) * separator.length;
19526
+ const numChars = selection.chars + (selection.toY - selection.fromY) * separator.length;
19472
19527
  const pre = code.slice(0, index);
19473
- const post = code.slice(index + num_chars);
19528
+ const post = code.slice(index + numChars);
19474
19529
  this.code.lines = (pre + post).split(separator);
19475
19530
  this.cursorToLine(cursor, selection.fromY, true);
19476
19531
  this.cursorToPosition(cursor, selection.fromX);
@@ -20116,7 +20171,7 @@ class CodeEditor {
20116
20171
  preWord.innerHTML = currSuggestion.substring(0, index);
20117
20172
  pre.appendChild(preWord);
20118
20173
  var actualWord = document.createElement('span');
20119
- actualWord.innerHTML = currSuggestion.substr(index, word.length);
20174
+ actualWord.innerHTML = currSuggestion.substring(index, index + word.length);
20120
20175
  actualWord.classList.add('word-highlight');
20121
20176
  pre.appendChild(actualWord);
20122
20177
  var postWord = document.createElement('span');
@@ -20257,13 +20312,13 @@ class CodeEditor {
20257
20312
  const getIndex = (l) => {
20258
20313
  var string = this.code.lines[l];
20259
20314
  if (reverse) {
20260
- string = string.substr(0, l == cursorData.y ? cursorData.x : string.length);
20315
+ string = string.substring(0, l == cursorData.y ? cursorData.x : string.length);
20261
20316
  var reversed = strReverse(string);
20262
20317
  var reversedIdx = reversed.indexOf(strReverse(text));
20263
20318
  return reversedIdx == -1 ? -1 : string.length - reversedIdx - text.length;
20264
20319
  }
20265
20320
  else {
20266
- return string.substr(l == cursorData.y ? cursorData.x : 0).indexOf(text);
20321
+ return string.substring(l == cursorData.y ? cursorData.x : 0).indexOf(text);
20267
20322
  }
20268
20323
  };
20269
20324
  if (reverse) {
@@ -20646,11 +20701,17 @@ if (!LX) {
20646
20701
  throw ('Missing LX namespace!');
20647
20702
  }
20648
20703
  LX.extensions.push('DocMaker');
20704
+ const CLASS_WORDS = ['uint32_t', 'uint64_t', 'uint8_t'];
20649
20705
  const CPP_KEY_WORDS = ['int', 'float', 'double', 'bool', 'char', 'wchar_t', 'const', 'static_cast', 'dynamic_cast', 'new', 'delete', 'void', 'true',
20650
20706
  'false', 'auto', 'struct', 'typedef', 'nullptr', 'NULL', 'unsigned', 'namespace', 'auto'];
20651
- const CLASS_WORDS = ['uint32_t', 'uint64_t', 'uint8_t'];
20652
- const STATEMENT_WORDS = ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'import', 'from', 'await'];
20653
20707
  const JS_KEY_WORDS = ['var', 'let', 'const', 'static', 'function', 'null', 'undefined', 'new', 'delete', 'true', 'false', 'NaN', 'this'];
20708
+ const WGSL_KEY_WORDS = ['var', 'let', 'const', 'override', 'fn', 'struct', 'alias', 'true', 'false', 'bool', 'f16', 'f32', 'i32', 'u32', 'vec2',
20709
+ 'vec3', 'vec4', 'mat2x2', 'mat2x3', 'mat2x4', 'mat3x2', 'mat3x3', 'mat3x4', 'mat4x2', 'mat4x3', 'mat4x4' // 'atomic', 'array', 'ptr', 'sampler', 'sampler_comparison', 'texture_1d', 'texture_2d', 'texture_2d_array', 'texture_3d', 'texture_cube', 'texture_cube_array',
20710
+ // 'texture_multisampled_2d', 'texture_external', 'texture_storage_1d', 'texture_storage_2d', 'texture_storage_2d_array', 'texture_storage_3d', 'texture_depth_2d',
20711
+ // 'texture_depth_2d_array', 'texture_depth_cube', 'texture_depth_cube_array', 'texture_depth_multisampled_2d', 'function', 'private', 'workgroup', 'uniform',
20712
+ // 'storage', 'read', 'write', 'read_write', 'binding', 'builtin', 'group', 'id', 'interpolate', 'invariant', 'location', 'size', 'align', 'stride', 'vertex', 'fragment', 'compute', 'workgroup_size',
20713
+ ];
20714
+ const STATEMENT_WORDS = ['for', 'if', 'else', 'return', 'continue', 'break', 'case', 'switch', 'while', 'import', 'from', 'await'];
20654
20715
  const HTML_ATTRIBUTES = ['html', 'charset', 'rel', 'src', 'href', 'crossorigin', 'type', 'lang'];
20655
20716
  const HTML_TAGS = ['DOCTYPE', 'html', 'head', 'body', 'title', 'base', 'link', 'meta', 'style', 'main', 'section', 'nav', 'article', 'aside',
20656
20717
  'header', 'footer', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure',
@@ -20759,6 +20820,9 @@ class DocMaker {
20759
20820
  else if (language == 'js' && JS_KEY_WORDS.includes(content)) {
20760
20821
  highlight = 'kwd';
20761
20822
  }
20823
+ else if (language == 'wgsl' && WGSL_KEY_WORDS.includes(content)) {
20824
+ highlight = 'kwd';
20825
+ }
20762
20826
  else if (CLASS_WORDS.includes(content)) {
20763
20827
  highlight = 'cls';
20764
20828
  }
@@ -20780,8 +20844,8 @@ class DocMaker {
20780
20844
  highlight = 'dec';
20781
20845
  }
20782
20846
  else {
20783
- console.error('ERROR[Code Parsing]: Unknown highlight type: ' + content);
20784
- return;
20847
+ highlight = '';
20848
+ console.error('WARNING[Code Parsing]: Unknown highlight type: ' + content);
20785
20849
  }
20786
20850
  html = getHTML(highlight, content);
20787
20851
  text = text.replace(`@${content}@`, html);