lexgui 0.7.7 → 0.7.9

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.
@@ -1,7 +1,8 @@
1
1
  import { LX } from 'lexgui';
2
2
 
3
- if(!LX) {
4
- throw("lexgui.js missing!");
3
+ if( !LX )
4
+ {
5
+ throw( "lexgui.js missing!" );
5
6
  }
6
7
 
7
8
  LX.extensions.push( 'CodeEditor' );
@@ -14,8 +15,8 @@ function strReverse( str ) { return str.split( "" ).reverse().join( "" ); }
14
15
  function isLetter( c ){ return /[a-zA-Z]/.test( c ); };
15
16
  function isSymbol( c ){ return /[^\w\s]/.test( c ); };
16
17
 
17
- function indexOfFrom( str, reg, from, reverse ) {
18
-
18
+ function indexOfFrom( str, reg, from, reverse )
19
+ {
19
20
  from = from ?? 0;
20
21
 
21
22
  if( reverse )
@@ -33,7 +34,8 @@ function indexOfFrom( str, reg, from, reverse ) {
33
34
  }
34
35
  }
35
36
 
36
- function codeScopesEqual( a, b ) {
37
+ function codeScopesEqual( a, b )
38
+ {
37
39
  if( a.length !== b.length ) return false;
38
40
  for( let i = 0; i < a.length; i++ )
39
41
  {
@@ -42,10 +44,10 @@ function codeScopesEqual( a, b ) {
42
44
  return true;
43
45
  }
44
46
 
45
- class CodeSelection {
46
-
47
- constructor( editor, cursor, className = "lexcodeselection" ) {
48
-
47
+ class CodeSelection
48
+ {
49
+ constructor( editor, cursor, className = "lexcodeselection" )
50
+ {
49
51
  this.editor = editor;
50
52
  this.cursor = cursor;
51
53
  this.className = className;
@@ -57,20 +59,23 @@ class CodeSelection {
57
59
  this.toY = cursor.line;
58
60
  }
59
61
 
60
- sameLine() {
62
+ sameLine()
63
+ {
61
64
  return this.fromY === this.toY;
62
65
  }
63
66
 
64
- samePosition() {
67
+ samePosition()
68
+ {
65
69
  return this.fromX === this.toX;
66
70
  }
67
71
 
68
- isEmpty() {
72
+ isEmpty()
73
+ {
69
74
  return this.sameLine() && this.samePosition();
70
75
  }
71
76
 
72
- invertIfNecessary() {
73
- // if( this.fromX > this.toX )
77
+ invertIfNecessary()
78
+ {
74
79
  if( this.fromY > this.toY )
75
80
  {
76
81
  swapElements( this, 'fromX', 'toX' );
@@ -82,8 +87,8 @@ class CodeSelection {
82
87
  }
83
88
  }
84
89
 
85
- selectInline( cursor, x, y, width, isSearchResult ) {
86
-
90
+ selectInline( cursor, x, y, width, isSearchResult )
91
+ {
87
92
  this.chars = width / this.editor.charWidth;
88
93
  this.fromX = x;
89
94
  this.toX = x + this.chars;
@@ -110,8 +115,8 @@ class CodeSelection {
110
115
  this.editor._hideActiveLine();
111
116
  }
112
117
 
113
- save() {
114
-
118
+ save()
119
+ {
115
120
  return {
116
121
  fromX: this.fromX,
117
122
  fromY: this.fromY,
@@ -120,16 +125,16 @@ class CodeSelection {
120
125
  }
121
126
  }
122
127
 
123
- load( data ) {
124
-
128
+ load( data )
129
+ {
125
130
  this.fromX = data.fromX;
126
131
  this.fromY = data.fromY;
127
132
  this.toX = data.toX;
128
133
  this.toY = data.toY;
129
134
  }
130
135
 
131
- getText() {
132
-
136
+ getText()
137
+ {
133
138
  if( !this.editor.code || !this.sameLine() )
134
139
  return null;
135
140
 
@@ -137,16 +142,16 @@ class CodeSelection {
137
142
  }
138
143
  };
139
144
 
140
- class ScrollBar {
141
-
145
+ class ScrollBar
146
+ {
142
147
  static SCROLLBAR_VERTICAL = 1;
143
148
  static SCROLLBAR_HORIZONTAL = 2;
144
149
 
145
150
  static SCROLLBAR_VERTICAL_WIDTH = 10;
146
151
  static SCROLLBAR_HORIZONTAL_HEIGHT = 10;
147
152
 
148
- constructor( editor, type ) {
149
-
153
+ constructor( editor, type )
154
+ {
150
155
  this.editor = editor;
151
156
  this.type = type;
152
157
 
@@ -199,7 +204,6 @@ class ScrollBar {
199
204
  doc.removeEventListener( "mouseup", inner_mouseup );
200
205
  }
201
206
  }
202
-
203
207
  }
204
208
 
205
209
  /* Highlight rules
@@ -210,8 +214,8 @@ class ScrollBar {
210
214
  to "ctx.discardToken" and no class is applied
211
215
  */
212
216
 
213
- const HighlightRules = {
214
-
217
+ const HighlightRules =
218
+ {
215
219
  common: [
216
220
  { test: ctx => ctx.inBlockComment, className: "cm-com" },
217
221
  { test: ctx => ctx.inString, action: (ctx, editor) => editor._appendStringToken( ctx.token ), discard: true },
@@ -280,9 +284,9 @@ const HighlightRules = {
280
284
  * @class CodeEditor
281
285
  */
282
286
 
283
- class CodeEditor {
284
-
285
- static __instances = [];
287
+ class CodeEditor
288
+ {
289
+ static __instances = [];
286
290
 
287
291
  static CURSOR_LEFT = 1;
288
292
  static CURSOR_TOP = 2;
@@ -295,17 +299,17 @@ class CodeEditor {
295
299
  static KEEP_VISIBLE_LINES = 1;
296
300
  static UPDATE_VISIBLE_LINES = 2;
297
301
 
298
- static WORD_TYPE_METHOD = 0;
299
- static WORD_TYPE_CLASS = 1;
302
+ static WORD_TYPE_METHOD = 0;
303
+ static WORD_TYPE_CLASS = 1;
300
304
 
301
- static CODE_MIN_FONT_SIZE = 9;
302
- static CODE_MAX_FONT_SIZE = 22;
305
+ static CODE_MIN_FONT_SIZE = 9;
306
+ static CODE_MAX_FONT_SIZE = 22;
303
307
 
304
- static LINE_GUTTER_WIDTH = 48;
305
- static LINE_GUTTER_WIDTH = 48;
308
+ static LINE_GUTTER_WIDTH = 48;
309
+ static LINE_GUTTER_WIDTH = 48;
306
310
 
307
- static RESIZE_SCROLLBAR_H = 1;
308
- static RESIZE_SCROLLBAR_V = 2;
311
+ static RESIZE_SCROLLBAR_H = 1;
312
+ static RESIZE_SCROLLBAR_V = 2;
309
313
  static RESIZE_SCROLLBAR_H_V = CodeEditor.RESIZE_SCROLLBAR_H | CodeEditor.RESIZE_SCROLLBAR_V;
310
314
 
311
315
  /**
@@ -317,8 +321,8 @@ class CodeEditor {
317
321
  * disableEdition:
318
322
  */
319
323
 
320
- constructor( area, options = {} ) {
321
-
324
+ constructor( area, options = {} )
325
+ {
322
326
  if( options.filesAsync )
323
327
  {
324
328
  options.files = [ ...options.filesAsync ];
@@ -336,8 +340,8 @@ class CodeEditor {
336
340
  }
337
341
  }
338
342
 
339
- async _init( area, options ) {
340
-
343
+ async _init( area, options )
344
+ {
341
345
  window.editor = this;
342
346
 
343
347
  CodeEditor.__instances.push( this );
@@ -360,6 +364,7 @@ class CodeEditor {
360
364
  this.onCreateStatusPanel = options.onCreateStatusPanel;
361
365
  this.onContextMenu = options.onContextMenu;
362
366
  this.onNewTab = options.onNewTab;
367
+ this.onSelectTab = options.onSelectTab;
363
368
 
364
369
  // File explorer
365
370
  if( this.useFileExplorer )
@@ -671,16 +676,18 @@ class CodeEditor {
671
676
 
672
677
  // Add search LINE box
673
678
  {
674
- var box = document.createElement( 'div' );
675
- box.className = "searchbox gotoline";
679
+ const box = document.createElement( 'div' );
680
+ box.className = "searchbox";
676
681
 
677
- var searchPanel = new LX.Panel();
682
+ const searchPanel = new LX.Panel();
678
683
  box.appendChild( searchPanel.root );
679
684
 
685
+ searchPanel.sameLine( 2 );
680
686
  searchPanel.addText( null, "", ( value, event ) => {
681
687
  input.value = ":" + value.replaceAll( ':', '' );
682
688
  this.goToLine( input.value.slice( 1 ) );
683
689
  }, { placeholder: "Go to line", trigger: "input" } );
690
+ searchPanel.addButton( null, "x", this.hideSearchLineBox.bind( this ), { icon: "X", title: "Close", tooltip: true } );
684
691
 
685
692
  let input = box.querySelector( 'input' );
686
693
  input.addEventListener( 'keyup', e => {
@@ -1194,8 +1201,8 @@ class CodeEditor {
1194
1201
  else // Next char
1195
1202
  {
1196
1203
  var letter = this.getCharAtPos( cursor );
1197
- if( letter ) {
1198
-
1204
+ if( letter )
1205
+ {
1199
1206
  // Selecting chars
1200
1207
  if( e.shiftKey )
1201
1208
  {
@@ -1207,7 +1214,8 @@ class CodeEditor {
1207
1214
  }
1208
1215
  else
1209
1216
  {
1210
- if( !cursor.selection ) {
1217
+ if( !cursor.selection )
1218
+ {
1211
1219
  this.cursorToRight( letter, cursor );
1212
1220
  if( this.useAutoComplete && this.isAutoCompleteActive )
1213
1221
  this.showAutoCompleteBox( 'foo', cursor );
@@ -1218,16 +1226,20 @@ class CodeEditor {
1218
1226
  this.resetCursorPos( CodeEditor.CURSOR_LEFT_TOP, cursor );
1219
1227
  this.cursorToLine( cursor, cursor.selection.toY );
1220
1228
  this.cursorToPosition( cursor, cursor.selection.toX );
1221
- this.endSelection();
1229
+ this.endSelection( cursor );
1222
1230
  }
1223
1231
  }
1224
1232
  }
1225
- else if( this.code.lines[ cursor.line + 1 ] !== undefined ) {
1226
-
1227
- if( e.shiftKey ) {
1233
+ else if( this.code.lines[ cursor.line + 1 ] !== undefined )
1234
+ {
1235
+ if( e.shiftKey )
1236
+ {
1228
1237
  if( !cursor.selection ) this.startSelection( cursor );
1229
1238
  }
1230
- else this.endSelection();
1239
+ else
1240
+ {
1241
+ this.endSelection();
1242
+ }
1231
1243
 
1232
1244
  this.lineDown( cursor, true );
1233
1245
 
@@ -1334,14 +1346,22 @@ class CodeEditor {
1334
1346
  }
1335
1347
  }
1336
1348
 
1349
+ // Clear signals
1350
+ clear()
1351
+ {
1352
+ console.assert( this.rightStatusPanel && this.leftStatusPanel, "No panels to clear." );
1353
+ this.rightStatusPanel.clear();
1354
+ this.leftStatusPanel.clear();
1355
+ }
1356
+
1337
1357
  static getInstances()
1338
1358
  {
1339
1359
  return CodeEditor.__instances;
1340
1360
  }
1341
1361
 
1342
1362
  // This received key inputs from the entire document...
1343
- onKeyPressed( e ) {
1344
-
1363
+ onKeyPressed( e )
1364
+ {
1345
1365
  // Toggle visibility of the file explorer
1346
1366
  if( e.key == 'b' && e.ctrlKey && this.useFileExplorer )
1347
1367
  {
@@ -1359,13 +1379,14 @@ class CodeEditor {
1359
1379
  }
1360
1380
  }
1361
1381
 
1362
- getText( min ) {
1382
+ getText( min )
1383
+ {
1363
1384
  return this.code.lines.join( min ? ' ' : '\n' );
1364
1385
  }
1365
1386
 
1366
1387
  // This can be used to empty all text...
1367
- setText( text = "", lang ) {
1368
-
1388
+ setText( text = "", lang )
1389
+ {
1369
1390
  let newLines = text.split( '\n' );
1370
1391
  this.code.lines = [].concat( newLines );
1371
1392
 
@@ -1387,8 +1408,8 @@ class CodeEditor {
1387
1408
  this._processLinesIfNecessary();
1388
1409
  }
1389
1410
 
1390
- appendText( text, cursor ) {
1391
-
1411
+ appendText( text, cursor )
1412
+ {
1392
1413
  let lidx = cursor.line;
1393
1414
 
1394
1415
  if( cursor.selection )
@@ -1458,8 +1479,18 @@ class CodeEditor {
1458
1479
  } );
1459
1480
  }
1460
1481
 
1461
- async loadFile( file, options = {} ) {
1482
+ setCustomSuggestions( suggestions )
1483
+ {
1484
+ if( !suggestions || suggestions.constructor !== Array )
1485
+ {
1486
+ return;
1487
+ }
1462
1488
 
1489
+ this.customSuggestions = suggestions;
1490
+ }
1491
+
1492
+ async loadFile( file, options = {} )
1493
+ {
1463
1494
  const _innerAddTab = ( text, name, title ) => {
1464
1495
 
1465
1496
  // Remove Carriage Return in some cases and sub tabs using spaces
@@ -1530,8 +1561,8 @@ class CodeEditor {
1530
1561
  }
1531
1562
  }
1532
1563
 
1533
- _addUndoStep( cursor, force, deleteRedo = true ) {
1534
-
1564
+ _addUndoStep( cursor, force, deleteRedo = true )
1565
+ {
1535
1566
  // Only the mainc cursor stores undo steps
1536
1567
  if( !cursor.isMain )
1537
1568
  return;
@@ -1572,10 +1603,12 @@ class CodeEditor {
1572
1603
  } );
1573
1604
  }
1574
1605
 
1575
- _doUndo( cursor ) {
1576
-
1606
+ _doUndo( cursor )
1607
+ {
1577
1608
  if( !this.code.undoSteps.length )
1609
+ {
1578
1610
  return;
1611
+ }
1579
1612
 
1580
1613
  this._addRedoStep( cursor );
1581
1614
 
@@ -1602,8 +1635,8 @@ class CodeEditor {
1602
1635
  this._hideActiveLine();
1603
1636
  }
1604
1637
 
1605
- _addRedoStep( cursor ) {
1606
-
1638
+ _addRedoStep( cursor )
1639
+ {
1607
1640
  // Only the mainc cursor stores redo steps
1608
1641
  if( !cursor.isMain )
1609
1642
  {
@@ -1616,10 +1649,12 @@ class CodeEditor {
1616
1649
  } );
1617
1650
  }
1618
1651
 
1619
- _doRedo( cursor ) {
1620
-
1652
+ _doRedo( cursor )
1653
+ {
1621
1654
  if( !this.code.redoSteps.length )
1655
+ {
1622
1656
  return;
1657
+ }
1623
1658
 
1624
1659
  this._addUndoStep( cursor, true, false);
1625
1660
 
@@ -1646,8 +1681,8 @@ class CodeEditor {
1646
1681
  }
1647
1682
  }
1648
1683
 
1649
- _changeLanguage( lang, langExtension, override = false ) {
1650
-
1684
+ _changeLanguage( lang, langExtension, override = false )
1685
+ {
1651
1686
  this.code.language = lang;
1652
1687
  this.highlight = lang;
1653
1688
 
@@ -1692,8 +1727,8 @@ class CodeEditor {
1692
1727
  }
1693
1728
  }
1694
1729
 
1695
- _changeLanguageFromExtension( ext ) {
1696
-
1730
+ _changeLanguageFromExtension( ext )
1731
+ {
1697
1732
  if( !ext )
1698
1733
  {
1699
1734
  return this._changeLanguage( this.code.language );
@@ -1723,8 +1758,8 @@ class CodeEditor {
1723
1758
  this._changeLanguage( 'Plain Text' );
1724
1759
  }
1725
1760
 
1726
- _createStatusPanel( options ) {
1727
-
1761
+ _createStatusPanel( options )
1762
+ {
1728
1763
  if( this.skipInfo )
1729
1764
  {
1730
1765
  return;
@@ -1737,7 +1772,7 @@ class CodeEditor {
1737
1772
  this.onCreateStatusPanel( panel, this );
1738
1773
  }
1739
1774
 
1740
- let leftStatusPanel = new LX.Panel( { id: "FontSizeZoomStatusComponent", height: "auto" } );
1775
+ let leftStatusPanel = this.leftStatusPanel = new LX.Panel( { id: "FontSizeZoomStatusComponent", height: "auto" } );
1741
1776
  leftStatusPanel.sameLine();
1742
1777
 
1743
1778
  if( this.skipTabs )
@@ -1751,7 +1786,7 @@ class CodeEditor {
1751
1786
  leftStatusPanel.endLine( "justify-start" );
1752
1787
  panel.attach( leftStatusPanel.root );
1753
1788
 
1754
- let rightStatusPanel = new LX.Panel( { height: "auto" } );
1789
+ let rightStatusPanel = this.rightStatusPanel = new LX.Panel( { height: "auto" } );
1755
1790
  rightStatusPanel.sameLine();
1756
1791
  rightStatusPanel.addLabel( this.code?.title ?? "", { id: "EditorFilenameStatusComponent", fit: true, signal: "@tab-name" });
1757
1792
  rightStatusPanel.addButton( null, "Ln 1, Col 1", this.showSearchLineBox.bind( this ), { id: "EditorSelectionStatusComponent", fit: true, signal: "@cursor-data" });
@@ -1823,8 +1858,8 @@ class CodeEditor {
1823
1858
  return panel;
1824
1859
  }
1825
1860
 
1826
- _getFileIcon( name, extension, lang ) {
1827
-
1861
+ _getFileIcon( name, extension, lang )
1862
+ {
1828
1863
  const isNewTabButton = name ? ( name === '+' ) : false;
1829
1864
  if( isNewTabButton )
1830
1865
  {
@@ -1878,8 +1913,8 @@ class CodeEditor {
1878
1913
  return "AlignLeft gray";
1879
1914
  }
1880
1915
 
1881
- _onNewTab( e ) {
1882
-
1916
+ _onNewTab( e )
1917
+ {
1883
1918
  this.processFocus( false );
1884
1919
 
1885
1920
  if( this.onNewTab )
@@ -1896,8 +1931,8 @@ class CodeEditor {
1896
1931
  new LX.DropdownMenu( e.target, dmOptions, { side: "bottom", align: "start" });
1897
1932
  }
1898
1933
 
1899
- _onCreateNewFile() {
1900
-
1934
+ _onCreateNewFile()
1935
+ {
1901
1936
  let options = {};
1902
1937
 
1903
1938
  if( this.onCreateFile )
@@ -1913,8 +1948,8 @@ class CodeEditor {
1913
1948
  this.addTab( name, true, name, { indexOffset: options.indexOffset, language: options.language ?? "JavaScript" } );
1914
1949
  }
1915
1950
 
1916
- _onSelectTab( isNewTabButton, event, name ) {
1917
-
1951
+ _onSelectTab( isNewTabButton, event, name )
1952
+ {
1918
1953
  if( this.disableEdition )
1919
1954
  {
1920
1955
  return;
@@ -1928,9 +1963,16 @@ class CodeEditor {
1928
1963
 
1929
1964
  this._removeSecondaryCursors();
1930
1965
 
1931
- var cursor = this.getCurrentCursor( true );
1932
- this.saveCursor( cursor, this.code.cursorState );
1966
+ const cursor = this.getCurrentCursor( true );
1967
+ const lastCode = this.code;
1968
+
1969
+ if( lastCode )
1970
+ {
1971
+ this.saveCursor( cursor, lastCode.cursorState );
1972
+ }
1973
+
1933
1974
  this.code = this.loadedTabs[ name ];
1975
+
1934
1976
  this.restoreCursor( cursor, this.code.cursorState );
1935
1977
 
1936
1978
  this.endSelection();
@@ -1949,10 +1991,15 @@ class CodeEditor {
1949
1991
  }
1950
1992
 
1951
1993
  this.processLines();
1952
- }
1953
1994
 
1954
- _onContextMenuTab( isNewTabButton, event, name, ) {
1995
+ if( !isNewTabButton && this.onSelectTab )
1996
+ {
1997
+ this.onSelectTab( name, this );
1998
+ }
1999
+ }
1955
2000
 
2001
+ _onContextMenuTab( isNewTabButton, event, name, )
2002
+ {
1956
2003
  if( isNewTabButton )
1957
2004
  {
1958
2005
  return;
@@ -1981,8 +2028,8 @@ class CodeEditor {
1981
2028
  ], { side: "bottom", align: "start", event });
1982
2029
  }
1983
2030
 
1984
- addTab( name, selected, title, options = {} ) {
1985
-
2031
+ addTab( name, selected, title, options = {} )
2032
+ {
1986
2033
  // If already loaded, set new name...
1987
2034
  const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
1988
2035
  const noRepeatName = key.replace( /[_\d+]/g, '');
@@ -2036,6 +2083,10 @@ class CodeEditor {
2036
2083
  this.loadedTabs[ name ] = code;
2037
2084
  this.openedTabs[ name ] = code;
2038
2085
 
2086
+ const lastCode = this.code;
2087
+
2088
+ this.code = code;
2089
+
2039
2090
  const tabIcon = this._getFileIcon( name );
2040
2091
 
2041
2092
  if( this.useFileExplorer && !isNewTabButton )
@@ -2063,13 +2114,6 @@ class CodeEditor {
2063
2114
 
2064
2115
  this.endSelection();
2065
2116
 
2066
- if( selected )
2067
- {
2068
- this.code = code;
2069
- this.resetCursorPos( CodeEditor.CURSOR_LEFT_TOP );
2070
- this.mustProcessLines = true;
2071
- }
2072
-
2073
2117
  if( options.language )
2074
2118
  {
2075
2119
  code.languageOverride = options.language;
@@ -2083,6 +2127,16 @@ class CodeEditor {
2083
2127
  this.mustProcessLines = true;
2084
2128
  }
2085
2129
 
2130
+ if( selected )
2131
+ {
2132
+ this.resetCursorPos( CodeEditor.CURSOR_LEFT_TOP );
2133
+ this.mustProcessLines = true;
2134
+ }
2135
+ else
2136
+ {
2137
+ this.code = lastCode;
2138
+ }
2139
+
2086
2140
  this._processLinesIfNecessary();
2087
2141
 
2088
2142
  this._updateDataInfoPanel( "@tab-name", name );
@@ -2091,8 +2145,8 @@ class CodeEditor {
2091
2145
  return name;
2092
2146
  }
2093
2147
 
2094
- loadCode( name ) {
2095
-
2148
+ loadCode( name )
2149
+ {
2096
2150
  // Hide all others
2097
2151
  this.codeSizer.querySelectorAll( ".code" ).forEach( c => c.classList.add( "hidden" ) );
2098
2152
 
@@ -2150,8 +2204,8 @@ class CodeEditor {
2150
2204
  this._updateDataInfoPanel( "@tab-name", code.tabName );
2151
2205
  }
2152
2206
 
2153
- loadTab( name ) {
2154
-
2207
+ loadTab( name )
2208
+ {
2155
2209
  // Already open...
2156
2210
  if( this.openedTabs[ name ] )
2157
2211
  {
@@ -2216,8 +2270,8 @@ class CodeEditor {
2216
2270
  this._updateDataInfoPanel( "@tab-name", code.tabName );
2217
2271
  }
2218
2272
 
2219
- closeTab( name, eraseAll ) {
2220
-
2273
+ closeTab( name, eraseAll )
2274
+ {
2221
2275
  if( !this.allowClosingTabs )
2222
2276
  {
2223
2277
  return;
@@ -2233,12 +2287,13 @@ class CodeEditor {
2233
2287
  }
2234
2288
  }
2235
2289
 
2236
- getSelectedTabName() {
2290
+ getSelectedTabName()
2291
+ {
2237
2292
  return this.tabs.selected;
2238
2293
  }
2239
2294
 
2240
- loadTabFromFile() {
2241
-
2295
+ loadTabFromFile()
2296
+ {
2242
2297
  const input = document.createElement( 'input' );
2243
2298
  input.type = 'file';
2244
2299
  document.body.appendChild( input );
@@ -2252,8 +2307,8 @@ class CodeEditor {
2252
2307
  });
2253
2308
  }
2254
2309
 
2255
- processFocus( active ) {
2256
-
2310
+ processFocus( active )
2311
+ {
2257
2312
  if( active )
2258
2313
  {
2259
2314
  this.restartBlink();
@@ -2265,8 +2320,8 @@ class CodeEditor {
2265
2320
  }
2266
2321
  }
2267
2322
 
2268
- processMouse( e ) {
2269
-
2323
+ processMouse( e )
2324
+ {
2270
2325
  if( !e.target.classList.contains('code') && !e.target.classList.contains('lexcodearea') ) return;
2271
2326
  if( !this.code ) return;
2272
2327
 
@@ -2406,8 +2461,8 @@ class CodeEditor {
2406
2461
  }
2407
2462
  }
2408
2463
 
2409
- _onMouseUp( e ) {
2410
-
2464
+ _onMouseUp( e )
2465
+ {
2411
2466
  if( ( LX.getTime() - this.lastMouseDown ) < 120 )
2412
2467
  {
2413
2468
  this.state.selectingText = false;
@@ -2424,8 +2479,8 @@ class CodeEditor {
2424
2479
  delete this._lastSelectionKeyDir;
2425
2480
  }
2426
2481
 
2427
- processClick( e ) {
2428
-
2482
+ processClick( e )
2483
+ {
2429
2484
  var cursor = this.getCurrentCursor();
2430
2485
  var code_rect = this.codeScroller.getBoundingClientRect();
2431
2486
  var position = [( e.clientX - code_rect.x ) + this.getScrollLeft(), (e.clientY - code_rect.y) + this.getScrollTop()];
@@ -2456,8 +2511,8 @@ class CodeEditor {
2456
2511
  this.hideAutoCompleteBox();
2457
2512
  }
2458
2513
 
2459
- updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y ) {
2460
-
2514
+ updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
2515
+ {
2461
2516
  for( let cursor of this.cursors.children )
2462
2517
  {
2463
2518
  if( !cursor.selection )
@@ -2469,16 +2524,16 @@ class CodeEditor {
2469
2524
  }
2470
2525
  }
2471
2526
 
2472
- processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y ) {
2473
-
2527
+ processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
2528
+ {
2474
2529
  for( let cursor of this.cursors.children )
2475
2530
  {
2476
2531
  this._processSelection( cursor, e, keepRange, flags );
2477
2532
  }
2478
2533
  }
2479
2534
 
2480
- _processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y ) {
2481
-
2535
+ _processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y )
2536
+ {
2482
2537
  const isMouseEvent = e && ( e.constructor == MouseEvent );
2483
2538
 
2484
2539
  if( isMouseEvent )
@@ -2639,8 +2694,8 @@ class CodeEditor {
2639
2694
  }
2640
2695
  }
2641
2696
 
2642
- async processKey( e ) {
2643
-
2697
+ async processKey( e )
2698
+ {
2644
2699
  const numCursors = this.cursors.childElementCount;
2645
2700
 
2646
2701
  if( !this.code || e.srcElement.constructor != HTMLDivElement )
@@ -2708,8 +2763,8 @@ class CodeEditor {
2708
2763
  delete this._lastProcessedCursorIndex;
2709
2764
  }
2710
2765
 
2711
- async processKeyAtTargetCursor( e, key, targetIdx ) {
2712
-
2766
+ async processKeyAtTargetCursor( e, key, targetIdx )
2767
+ {
2713
2768
  let cursor = this.cursors.children[ targetIdx ];
2714
2769
 
2715
2770
  // We could delete secondary cursor while iterating..
@@ -2720,13 +2775,14 @@ class CodeEditor {
2720
2775
  this._processGlobalKeys( e, key );
2721
2776
  }
2722
2777
 
2723
- _processGlobalKeys( e, key ) {
2724
-
2778
+ _processGlobalKeys( e, key )
2779
+ {
2725
2780
  let cursor = this.getCurrentCursor();
2726
2781
 
2727
2782
  if( e.ctrlKey || e.metaKey )
2728
2783
  {
2729
- switch( key.toLowerCase() ) {
2784
+ switch( key.toLowerCase() )
2785
+ {
2730
2786
  case 'a': // select all
2731
2787
  e.preventDefault();
2732
2788
  this.selectAll();
@@ -2802,8 +2858,8 @@ class CodeEditor {
2802
2858
  return false;
2803
2859
  }
2804
2860
 
2805
- async _processKeyAtCursor( e, key, cursor ) {
2806
-
2861
+ async _processKeyAtCursor( e, key, cursor )
2862
+ {
2807
2863
  const skipUndo = e.detail.skipUndo ?? false;
2808
2864
 
2809
2865
  // keys with length > 1 are probably special keys
@@ -2965,8 +3021,8 @@ class CodeEditor {
2965
3021
  }
2966
3022
  }
2967
3023
 
2968
- async _pasteContent( cursor ) {
2969
-
3024
+ async _pasteContent( cursor )
3025
+ {
2970
3026
  const mustDetectLanguage = ( !this.getText().length );
2971
3027
 
2972
3028
  let text = await navigator.clipboard.readText();
@@ -2996,8 +3052,8 @@ class CodeEditor {
2996
3052
  }
2997
3053
  }
2998
3054
 
2999
- async _copyContent( cursor ) {
3000
-
3055
+ async _copyContent( cursor )
3056
+ {
3001
3057
  let textToCopy = "";
3002
3058
 
3003
3059
  if( !cursor.selection )
@@ -3031,8 +3087,8 @@ class CodeEditor {
3031
3087
  // .then(() => console.log("Successfully copied"), (err) => console.error("Error"));
3032
3088
  }
3033
3089
 
3034
- async _cutContent( cursor ) {
3035
-
3090
+ async _cutContent( cursor )
3091
+ {
3036
3092
  let lidx = cursor.line;
3037
3093
  let textToCut = "";
3038
3094
 
@@ -3078,8 +3134,8 @@ class CodeEditor {
3078
3134
  // .then(() => console.log("Successfully cut"), (err) => console.error("Error"));
3079
3135
  }
3080
3136
 
3081
- _duplicateLine( lidx, cursor ) {
3082
-
3137
+ _duplicateLine( lidx, cursor )
3138
+ {
3083
3139
  this.endSelection();
3084
3140
  this._addUndoStep( cursor, true );
3085
3141
  this.code.lines.splice( lidx, 0, this.code.lines[ lidx ] );
@@ -3088,8 +3144,8 @@ class CodeEditor {
3088
3144
  this.hideAutoCompleteBox();
3089
3145
  }
3090
3146
 
3091
- _commentLines( cursor, useCommentBlock ) {
3092
-
3147
+ _commentLines( cursor, useCommentBlock )
3148
+ {
3093
3149
  const lang = CodeEditor.languages[ this.highlight ];
3094
3150
 
3095
3151
  this.state.keyChain = null;
@@ -3166,8 +3222,8 @@ class CodeEditor {
3166
3222
  this._hideActiveLine();
3167
3223
  }
3168
3224
 
3169
- _commentLine( cursor, line, minNonspaceIdx, updateCursor = true ) {
3170
-
3225
+ _commentLine( cursor, line, minNonspaceIdx, updateCursor = true )
3226
+ {
3171
3227
  const lang = CodeEditor.languages[ this.highlight ];
3172
3228
  if( !( lang.singleLineComments ?? true ) )
3173
3229
  return;
@@ -3196,8 +3252,8 @@ class CodeEditor {
3196
3252
  }
3197
3253
  }
3198
3254
 
3199
- _uncommentLines( cursor ) {
3200
-
3255
+ _uncommentLines( cursor )
3256
+ {
3201
3257
  this.state.keyChain = null;
3202
3258
 
3203
3259
  if( cursor.selection )
@@ -3223,8 +3279,8 @@ class CodeEditor {
3223
3279
  this._hideActiveLine();
3224
3280
  }
3225
3281
 
3226
- _uncommentLine( cursor, line ) {
3227
-
3282
+ _uncommentLine( cursor, line )
3283
+ {
3228
3284
  const lang = CodeEditor.languages[ this.highlight ];
3229
3285
 
3230
3286
  if( !( lang.singleLineComments ?? true ))
@@ -3245,8 +3301,8 @@ class CodeEditor {
3245
3301
  }
3246
3302
  }
3247
3303
 
3248
- action( key, deleteSelection, fn, eventSkipDelete ) {
3249
-
3304
+ action( key, deleteSelection, fn, eventSkipDelete )
3305
+ {
3250
3306
  this.actions[ key ] = {
3251
3307
  "key": key,
3252
3308
  "callback": fn,
@@ -3255,13 +3311,14 @@ class CodeEditor {
3255
3311
  };
3256
3312
  }
3257
3313
 
3258
- _actionMustDelete( cursor, action, e ) {
3314
+ _actionMustDelete( cursor, action, e )
3315
+ {
3259
3316
  return cursor.selection && action.deleteSelection &&
3260
3317
  ( action.eventSkipDelete ? !e[ action.eventSkipDelete ] : true );
3261
3318
  }
3262
3319
 
3263
- scanWordSuggestions() {
3264
-
3320
+ scanWordSuggestions()
3321
+ {
3265
3322
  this.code.tokens = {};
3266
3323
 
3267
3324
  for( let i = 0; i < this.code.lines.length; ++i )
@@ -3272,16 +3329,19 @@ class CodeEditor {
3272
3329
  }
3273
3330
  }
3274
3331
 
3275
- toLocalLine( line ) {
3332
+ toLocalLine( line )
3333
+ {
3276
3334
  const d = Math.max( this.firstLineInViewport - this.lineScrollMargin.x, 0 );
3277
3335
  return Math.min( Math.max( line - d, 0 ), this.code.lines.length - 1 );
3278
3336
  }
3279
3337
 
3280
- getMaxLineLength() {
3338
+ getMaxLineLength()
3339
+ {
3281
3340
  return Math.max(...this.code.lines.map( v => v.length ));
3282
3341
  }
3283
3342
 
3284
- _processLinesIfNecessary() {
3343
+ _processLinesIfNecessary()
3344
+ {
3285
3345
  if( this.mustProcessLines )
3286
3346
  {
3287
3347
  this.mustProcessLines = false;
@@ -3289,8 +3349,8 @@ class CodeEditor {
3289
3349
  }
3290
3350
  }
3291
3351
 
3292
- processLines( mode ) {
3293
-
3352
+ processLines( mode )
3353
+ {
3294
3354
  if( !this.code )
3295
3355
  {
3296
3356
  return;
@@ -3344,8 +3404,8 @@ class CodeEditor {
3344
3404
  this.resize();
3345
3405
  }
3346
3406
 
3347
- processLine( lineNumber, force, skipPropagation ) {
3348
-
3407
+ processLine( lineNumber, force, skipPropagation )
3408
+ {
3349
3409
  if( this._scopeStack )
3350
3410
  {
3351
3411
  this.code.lineScopes[ lineNumber ] = [ ...this._scopeStack ];
@@ -3567,14 +3627,15 @@ class CodeEditor {
3567
3627
  return this._updateLine( force, lineNumber, lineInnerHtml, skipPropagation, symbols, tokensToEvaluate );
3568
3628
  }
3569
3629
 
3570
- _getLineSignatureFromTokens( tokens ) {
3630
+ _getLineSignatureFromTokens( tokens )
3631
+ {
3571
3632
  const structuralChars = new Set( [ '{', '}'] );
3572
3633
  const sign = tokens.filter( t => structuralChars.has( t ) );
3573
3634
  return sign.join( "_" );
3574
3635
  }
3575
3636
 
3576
- _updateBlockComments( section, lineNumber, tokens ) {
3577
-
3637
+ _updateBlockComments( section, lineNumber, tokens )
3638
+ {
3578
3639
  const lang = CodeEditor.languages[ this.highlight ];
3579
3640
  const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
3580
3641
  const lineOpensBlock = ( section[ 0 ].x === lineNumber );
@@ -3653,8 +3714,8 @@ class CodeEditor {
3653
3714
  }
3654
3715
  }
3655
3716
 
3656
- _processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation ) {
3657
-
3717
+ _processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation )
3718
+ {
3658
3719
  if( !this._scopeStack )
3659
3720
  {
3660
3721
  console.warn( "CodeEditor: No scope available" );
@@ -3721,8 +3782,8 @@ class CodeEditor {
3721
3782
  }
3722
3783
  }
3723
3784
 
3724
- _updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] ) {
3725
-
3785
+ _updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] )
3786
+ {
3726
3787
  const gutterLineHtml = `<span class='line-gutter'>${ lineNumber + 1 }</span>`;
3727
3788
  const oldSymbols = this._updateLineSymbols( lineNumber, symbols );
3728
3789
  const lineScope = CodeEditor.debugScopes && this.code.lineScopes[ lineNumber ] ? this.code.lineScopes[ lineNumber ].map( s => `${ s.type }` ).join( ", " ) : "";
@@ -3780,8 +3841,8 @@ class CodeEditor {
3780
3841
  /**
3781
3842
  * Parses a single line of code and extract declared symbols
3782
3843
  */
3783
- _parseLineForSymbols( lineNumber, lineString, tokens, pushedScope ) {
3784
-
3844
+ _parseLineForSymbols( lineNumber, lineString, tokens, pushedScope )
3845
+ {
3785
3846
  const scope = this._scopeStack.at( pushedScope ? -2 : -1 );
3786
3847
 
3787
3848
  if( !scope || this._inBlockCommentSection( lineNumber ) )
@@ -3917,8 +3978,8 @@ class CodeEditor {
3917
3978
  * - Removes old symbols from that line
3918
3979
  * - Inserts the new symbols
3919
3980
  */
3920
- _updateLineSymbols( lineNumber, newSymbols ) {
3921
-
3981
+ _updateLineSymbols( lineNumber, newSymbols )
3982
+ {
3922
3983
  this.code.lineSymbols[ lineNumber ] = this.code.lineSymbols[ lineNumber ] ?? [];
3923
3984
  const oldSymbols = LX.deepCopy( this.code.lineSymbols[ lineNumber ] );
3924
3985
 
@@ -3957,8 +4018,8 @@ class CodeEditor {
3957
4018
  return oldSymbols;
3958
4019
  }
3959
4020
 
3960
- _lineHasComment( lineString ) {
3961
-
4021
+ _lineHasComment( lineString )
4022
+ {
3962
4023
  const lang = CodeEditor.languages[ this.highlight ];
3963
4024
 
3964
4025
  if( !(lang.singleLineComments ?? true) )
@@ -3983,8 +4044,8 @@ class CodeEditor {
3983
4044
  }
3984
4045
  }
3985
4046
 
3986
- _getTokensFromLine( lineString, skipNonWords ) {
3987
-
4047
+ _getTokensFromLine( lineString, skipNonWords )
4048
+ {
3988
4049
  if( !lineString || !lineString.length )
3989
4050
  {
3990
4051
  return [];
@@ -4043,8 +4104,8 @@ class CodeEditor {
4043
4104
  return this._processTokens( tokensToEvaluate );
4044
4105
  }
4045
4106
 
4046
- _processTokens( tokens, offset = 0 ) {
4047
-
4107
+ _processTokens( tokens, offset = 0 )
4108
+ {
4048
4109
  if( this.highlight == 'C++' || this.highlight == 'CSS' )
4049
4110
  {
4050
4111
  var idx = tokens.slice( offset ).findIndex( ( value, index ) => this._isNumber( value ) );
@@ -4113,8 +4174,8 @@ class CodeEditor {
4113
4174
  return tokens;
4114
4175
  }
4115
4176
 
4116
- _mustHightlightWord( token, wordCategory, lang ) {
4117
-
4177
+ _mustHightlightWord( token, wordCategory, lang )
4178
+ {
4118
4179
  if( !lang )
4119
4180
  {
4120
4181
  lang = CodeEditor.languages[ this.highlight ];
@@ -4130,8 +4191,8 @@ class CodeEditor {
4130
4191
  return wordCategory[ this.highlight ] && wordCategory[ this.highlight ].has( t );
4131
4192
  }
4132
4193
 
4133
- _getTokenHighlighting( ctx, highlight ) {
4134
-
4194
+ _getTokenHighlighting( ctx, highlight )
4195
+ {
4135
4196
  const rules = [ ...HighlightRules.common, ...( HighlightRules[ highlight ] || [] ), ...HighlightRules.post_common ];
4136
4197
 
4137
4198
  for( const rule of rules )
@@ -4149,8 +4210,8 @@ class CodeEditor {
4149
4210
  return null;
4150
4211
  }
4151
4212
 
4152
- _evaluateToken( ctxData ) {
4153
-
4213
+ _evaluateToken( ctxData )
4214
+ {
4154
4215
  let { token, prev, next, tokenIndex, isFirstToken, isLastToken } = ctxData;
4155
4216
 
4156
4217
  const lang = CodeEditor.languages[ this.highlight ];
@@ -4158,7 +4219,7 @@ class CodeEditor {
4158
4219
  const customStringKeys = Object.assign( {}, this.stringKeys );
4159
4220
  const lineNumber = this._currentLineNumber;
4160
4221
  const tokenStartIndex = this._currentTokenPositions[ tokenIndex ];
4161
- const inBlockComment = ( this._buildingBlockComment ?? this._inBlockCommentSection( lineNumber, tokenStartIndex, token.length ) !== undefined )
4222
+ const inBlockComment = ( this._buildingBlockComment ?? this._inBlockCommentSection( lineNumber, tokenStartIndex, token.length ) ) !== undefined;
4162
4223
 
4163
4224
  var usePreviousTokenToCheckString = false;
4164
4225
 
@@ -4247,8 +4308,8 @@ class CodeEditor {
4247
4308
  return `<span class="${ highlight } ${ tokenClass }">${ token }</span>`;
4248
4309
  }
4249
4310
 
4250
- _appendStringToken( token ) {
4251
-
4311
+ _appendStringToken( token )
4312
+ {
4252
4313
  if( !this._pendingString )
4253
4314
  {
4254
4315
  this._pendingString = "";
@@ -4259,14 +4320,15 @@ class CodeEditor {
4259
4320
  return true;
4260
4321
  }
4261
4322
 
4262
- _getCurrentString() {
4323
+ _getCurrentString()
4324
+ {
4263
4325
  const chars = this._pendingString;
4264
4326
  delete this._pendingString;
4265
4327
  return chars;
4266
4328
  }
4267
4329
 
4268
- _enclosedByTokens( token, tokenIndex, tagStart, tagEnd ) {
4269
-
4330
+ _enclosedByTokens( token, tokenIndex, tagStart, tagEnd )
4331
+ {
4270
4332
  const tokenStartIndex = this._currentTokenPositions[ tokenIndex ];
4271
4333
  const tagStartIndex = indexOfFrom( this._currentLineString, tagStart, tokenStartIndex, true );
4272
4334
  if( tagStartIndex < 0 ) // Not found..
@@ -4284,8 +4346,8 @@ class CodeEditor {
4284
4346
  }
4285
4347
  }
4286
4348
 
4287
- _inBlockCommentSection( lineNumber, tokenPosition, tokenLength ) {
4288
-
4349
+ _inBlockCommentSection( lineNumber, tokenPosition, tokenLength )
4350
+ {
4289
4351
  const lang = CodeEditor.languages[ this.highlight ];
4290
4352
  const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
4291
4353
 
@@ -4312,8 +4374,8 @@ class CodeEditor {
4312
4374
  }
4313
4375
  }
4314
4376
 
4315
- _isKeyword( ctxData ) {
4316
-
4377
+ _isKeyword( ctxData )
4378
+ {
4317
4379
  const { token, tokenIndex, tokens, lang } = ctxData;
4318
4380
 
4319
4381
  let isKwd = this._mustHightlightWord( token, CodeEditor.keywords ) || this.highlight == 'XML';
@@ -4344,8 +4406,8 @@ class CodeEditor {
4344
4406
  return isKwd;
4345
4407
  }
4346
4408
 
4347
- _isNumber( token ) {
4348
-
4409
+ _isNumber( token )
4410
+ {
4349
4411
  const lang = CodeEditor.languages[ this.highlight ];
4350
4412
  if( !( lang.numbers ?? true ) )
4351
4413
  {
@@ -4383,8 +4445,8 @@ class CodeEditor {
4383
4445
  return token.length && token != ' ' && !Number.isNaN( +token );
4384
4446
  }
4385
4447
 
4386
- _encloseSelectedWordWithKey( key, lidx, cursor ) {
4387
-
4448
+ _encloseSelectedWordWithKey( key, lidx, cursor )
4449
+ {
4388
4450
  if( !cursor.selection || ( cursor.selection.fromY != cursor.selection.toY ) )
4389
4451
  {
4390
4452
  return false;
@@ -4431,8 +4493,8 @@ class CodeEditor {
4431
4493
  return true;
4432
4494
  }
4433
4495
 
4434
- _detectLanguage( text ) {
4435
-
4496
+ _detectLanguage( text )
4497
+ {
4436
4498
  const tokenSet = new Set( this._getTokensFromLine( text, true ) );
4437
4499
  const scores = {};
4438
4500
 
@@ -4471,8 +4533,8 @@ class CodeEditor {
4471
4533
  return sorted[0][1] > 0 ? sorted[0][0] : undefined;
4472
4534
  }
4473
4535
 
4474
- lineUp( cursor, resetLeft ) {
4475
-
4536
+ lineUp( cursor, resetLeft )
4537
+ {
4476
4538
  if( this.code.lines[ cursor.line - 1 ] == undefined )
4477
4539
  return false;
4478
4540
 
@@ -4483,8 +4545,8 @@ class CodeEditor {
4483
4545
  return true;
4484
4546
  }
4485
4547
 
4486
- lineDown( cursor, resetLeft ) {
4487
-
4548
+ lineDown( cursor, resetLeft )
4549
+ {
4488
4550
  if( this.code.lines[ cursor.line + 1 ] == undefined )
4489
4551
  return false;
4490
4552
 
@@ -4495,8 +4557,8 @@ class CodeEditor {
4495
4557
  return true;
4496
4558
  }
4497
4559
 
4498
- restartBlink() {
4499
-
4560
+ restartBlink()
4561
+ {
4500
4562
  if( !this.code ) return;
4501
4563
 
4502
4564
  clearInterval( this.blinker );
@@ -4510,8 +4572,8 @@ class CodeEditor {
4510
4572
  this.cursors.classList.remove( 'show' );
4511
4573
  }
4512
4574
 
4513
- startSelection( cursor ) {
4514
-
4575
+ startSelection( cursor )
4576
+ {
4515
4577
  // Show elements
4516
4578
  let selectionContainer = document.createElement( 'div' );
4517
4579
  selectionContainer.className = 'selections';
@@ -4524,8 +4586,8 @@ class CodeEditor {
4524
4586
  cursor.selection = new CodeSelection( this, cursor );
4525
4587
  }
4526
4588
 
4527
- deleteSelection( cursor ) {
4528
-
4589
+ deleteSelection( cursor )
4590
+ {
4529
4591
  // I think it's not necessary but...
4530
4592
  if( this.disableEdition )
4531
4593
  {
@@ -4557,8 +4619,8 @@ class CodeEditor {
4557
4619
  this.processLines();
4558
4620
  }
4559
4621
 
4560
- endSelection( cursor ) {
4561
-
4622
+ endSelection( cursor )
4623
+ {
4562
4624
  delete this._tripleClickSelection;
4563
4625
  delete this._lastSelectionKeyDir;
4564
4626
  delete this._currentOcurrences;
@@ -4581,7 +4643,9 @@ class CodeEditor {
4581
4643
  }
4582
4644
  }
4583
4645
 
4584
- selectAll() {
4646
+ selectAll()
4647
+ {
4648
+ this.endSelection();
4585
4649
 
4586
4650
  // Use main cursor
4587
4651
  this._removeSecondaryCursors();
@@ -4603,8 +4667,8 @@ class CodeEditor {
4603
4667
  this.hideAutoCompleteBox();
4604
4668
  }
4605
4669
 
4606
- cursorToRight( key, cursor ) {
4607
-
4670
+ cursorToRight( key, cursor )
4671
+ {
4608
4672
  if( !key ) return;
4609
4673
 
4610
4674
  cursor._left += this.charWidth;
@@ -4622,8 +4686,8 @@ class CodeEditor {
4622
4686
  }
4623
4687
  }
4624
4688
 
4625
- cursorToLeft( key, cursor ) {
4626
-
4689
+ cursorToLeft( key, cursor )
4690
+ {
4627
4691
  if( !key ) return;
4628
4692
 
4629
4693
  cursor._left -= this.charWidth;
@@ -4643,8 +4707,8 @@ class CodeEditor {
4643
4707
  }
4644
4708
  }
4645
4709
 
4646
- cursorToTop( cursor, resetLeft = false ) {
4647
-
4710
+ cursorToTop( cursor, resetLeft = false )
4711
+ {
4648
4712
  cursor._top -= this.lineHeight;
4649
4713
  cursor._top = Math.max( cursor._top, 0 );
4650
4714
  cursor.style.top = `calc(${ cursor._top }px)`;
@@ -4663,8 +4727,8 @@ class CodeEditor {
4663
4727
  }
4664
4728
  }
4665
4729
 
4666
- cursorToBottom( cursor, resetLeft = false ) {
4667
-
4730
+ cursorToBottom( cursor, resetLeft = false )
4731
+ {
4668
4732
  cursor._top += this.lineHeight;
4669
4733
  cursor.style.top = `calc(${ cursor._top }px)`;
4670
4734
 
@@ -4684,8 +4748,8 @@ class CodeEditor {
4684
4748
  }
4685
4749
  }
4686
4750
 
4687
- cursorToString( cursor, text, reverse ) {
4688
-
4751
+ cursorToString( cursor, text, reverse )
4752
+ {
4689
4753
  if( !text.length )
4690
4754
  {
4691
4755
  return;
@@ -4697,23 +4761,23 @@ class CodeEditor {
4697
4761
  }
4698
4762
  }
4699
4763
 
4700
- cursorToPosition( cursor, position ) {
4701
-
4764
+ cursorToPosition( cursor, position )
4765
+ {
4702
4766
  cursor.position = position;
4703
4767
  cursor._left = position * this.charWidth;
4704
4768
  cursor.style.left = `calc( ${ cursor._left }px + ${ this.xPadding } )`;
4705
4769
  }
4706
4770
 
4707
- cursorToLine( cursor, line, resetLeft = false ) {
4708
-
4771
+ cursorToLine( cursor, line, resetLeft = false )
4772
+ {
4709
4773
  cursor.line = line;
4710
4774
  cursor._top = this.lineHeight * line;
4711
4775
  cursor.style.top = cursor._top + "px";
4712
4776
  if( resetLeft ) this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
4713
4777
  }
4714
4778
 
4715
- saveCursor( cursor, state = {} ) {
4716
-
4779
+ saveCursor( cursor, state = {} )
4780
+ {
4717
4781
  state.position = cursor.position;
4718
4782
  state.line = cursor.line;
4719
4783
  state.selection = cursor.selection ? cursor.selection.save() : undefined;
@@ -4721,8 +4785,8 @@ class CodeEditor {
4721
4785
  return state;
4722
4786
  }
4723
4787
 
4724
- saveCursors() {
4725
-
4788
+ saveCursors()
4789
+ {
4726
4790
  var cursors = [];
4727
4791
 
4728
4792
  for( let cursor of this.cursors.children )
@@ -4733,8 +4797,8 @@ class CodeEditor {
4733
4797
  return cursors;
4734
4798
  }
4735
4799
 
4736
- getCurrentCursor( removeOthers ) {
4737
-
4800
+ getCurrentCursor( removeOthers )
4801
+ {
4738
4802
  if( removeOthers )
4739
4803
  {
4740
4804
  this._removeSecondaryCursors();
@@ -4743,8 +4807,8 @@ class CodeEditor {
4743
4807
  return this.cursors.children[ 0 ];
4744
4808
  }
4745
4809
 
4746
- relocateCursors() {
4747
-
4810
+ relocateCursors()
4811
+ {
4748
4812
  for( let cursor of this.cursors.children )
4749
4813
  {
4750
4814
  cursor._left = cursor.position * this.charWidth;
@@ -4754,8 +4818,8 @@ class CodeEditor {
4754
4818
  }
4755
4819
  }
4756
4820
 
4757
- mergeCursors( line ) {
4758
-
4821
+ mergeCursors( line )
4822
+ {
4759
4823
  console.assert( line >= 0 );
4760
4824
  const cursorsInLine = Array.from( this.cursors.children ).filter( v => v.line == line );
4761
4825
 
@@ -4763,8 +4827,8 @@ class CodeEditor {
4763
4827
  this.removeCursor( cursorsInLine.pop() );
4764
4828
  }
4765
4829
 
4766
- restoreCursor( cursor, state ) {
4767
-
4830
+ restoreCursor( cursor, state )
4831
+ {
4768
4832
  cursor.position = state.position ?? 0;
4769
4833
  cursor.line = state.line ?? 0;
4770
4834
 
@@ -4785,15 +4849,15 @@ class CodeEditor {
4785
4849
  }
4786
4850
  }
4787
4851
 
4788
- removeCursor( cursor ) {
4789
-
4852
+ removeCursor( cursor )
4853
+ {
4790
4854
  LX.deleteElement( this.selections[ cursor.name ] );
4791
4855
  delete this.selections[ cursor.name ];
4792
4856
  LX.deleteElement( cursor );
4793
4857
  }
4794
4858
 
4795
- resetCursorPos( flag, cursor ) {
4796
-
4859
+ resetCursorPos( flag, cursor )
4860
+ {
4797
4861
  cursor = cursor ?? this.getCurrentCursor();
4798
4862
 
4799
4863
  if( flag & CodeEditor.CURSOR_LEFT )
@@ -4811,8 +4875,8 @@ class CodeEditor {
4811
4875
  }
4812
4876
  }
4813
4877
 
4814
- _addCursor( line = 0, position = 0, force, isMain = false ) {
4815
-
4878
+ _addCursor( line = 0, position = 0, force, isMain = false )
4879
+ {
4816
4880
  // If cursor in that position exists, remove it instead..
4817
4881
  const exists = Array.from( this.cursors.children ).find( v => v.position == position && v.line == line );
4818
4882
  if( exists && !force )
@@ -4862,30 +4926,42 @@ class CodeEditor {
4862
4926
  return cursor;
4863
4927
  }
4864
4928
 
4865
- _removeSecondaryCursors() {
4866
-
4929
+ _removeSecondaryCursors()
4930
+ {
4867
4931
  while( this.cursors.childElementCount > 1 )
4932
+ {
4868
4933
  this.cursors.lastChild.remove();
4934
+ }
4869
4935
  }
4870
4936
 
4871
- _logCursors() {
4937
+ _getLastCursor()
4938
+ {
4939
+ return this.cursors.lastChild;
4940
+ }
4941
+
4942
+ _isLastCursor( cursor )
4943
+ {
4944
+ return cursor === this._getLastCursor();
4945
+ }
4872
4946
 
4947
+ _logCursors()
4948
+ {
4873
4949
  for( let cursor of this.cursors.children )
4874
4950
  {
4875
4951
  cursor.print();
4876
4952
  }
4877
4953
  }
4878
4954
 
4879
- _addSpaceTabs( cursor, n ) {
4880
-
4955
+ _addSpaceTabs( cursor, n )
4956
+ {
4881
4957
  for( var i = 0; i < n; ++i )
4882
4958
  {
4883
4959
  this.actions[ 'Tab' ].callback( cursor.line, cursor, null );
4884
4960
  }
4885
4961
  }
4886
4962
 
4887
- _addSpaces( n ) {
4888
-
4963
+ _addSpaces( n )
4964
+ {
4889
4965
  for( var i = 0; i < n; ++i )
4890
4966
  {
4891
4967
  this.root.dispatchEvent( new CustomEvent( 'keydown', { 'detail': {
@@ -4896,8 +4972,8 @@ class CodeEditor {
4896
4972
  }
4897
4973
  }
4898
4974
 
4899
- _removeSpaces( cursor ) {
4900
-
4975
+ _removeSpaces( cursor )
4976
+ {
4901
4977
  const lidx = cursor.line;
4902
4978
 
4903
4979
  // Remove indentation
@@ -4936,17 +5012,20 @@ class CodeEditor {
4936
5012
  }
4937
5013
  }
4938
5014
 
4939
- getScrollLeft() {
5015
+ getScrollLeft()
5016
+ {
4940
5017
  if( !this.codeScroller ) return 0;
4941
5018
  return this.codeScroller.scrollLeft;
4942
5019
  }
4943
5020
 
4944
- getScrollTop() {
5021
+ getScrollTop()
5022
+ {
4945
5023
  if( !this.codeScroller ) return 0;
4946
5024
  return this.codeScroller.scrollTop;
4947
5025
  }
4948
5026
 
4949
- setScrollLeft( value ) {
5027
+ setScrollLeft( value )
5028
+ {
4950
5029
  if( !this.codeScroller ) return;
4951
5030
  LX.doAsync( () => {
4952
5031
  this.codeScroller.scrollLeft = value;
@@ -4954,7 +5033,8 @@ class CodeEditor {
4954
5033
  }, 20 );
4955
5034
  }
4956
5035
 
4957
- setScrollTop( value ) {
5036
+ setScrollTop( value )
5037
+ {
4958
5038
  if( !this.codeScroller ) return;
4959
5039
  LX.doAsync( () => {
4960
5040
  this.codeScroller.scrollTop = value;
@@ -4962,8 +5042,8 @@ class CodeEditor {
4962
5042
  }, 20 );
4963
5043
  }
4964
5044
 
4965
- resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize ) {
4966
-
5045
+ resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize )
5046
+ {
4967
5047
  setTimeout( () => {
4968
5048
 
4969
5049
  let scrollWidth, scrollHeight;
@@ -4993,8 +5073,8 @@ class CodeEditor {
4993
5073
  }, 10 );
4994
5074
  }
4995
5075
 
4996
- resizeIfNecessary( cursor, force ) {
4997
-
5076
+ resizeIfNecessary( cursor, force )
5077
+ {
4998
5078
  const maxLineLength = this.getMaxLineLength();
4999
5079
  const numViewportChars = Math.floor( ( this.codeScroller.clientWidth - CodeEditor.LINE_GUTTER_WIDTH ) / this.charWidth );
5000
5080
  if( force || ( maxLineLength >= numViewportChars && maxLineLength != this._lastMaxLineLength ) )
@@ -5008,8 +5088,8 @@ class CodeEditor {
5008
5088
  }
5009
5089
  }
5010
5090
 
5011
- resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V ) {
5012
-
5091
+ resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V )
5092
+ {
5013
5093
  if( flag & CodeEditor.RESIZE_SCROLLBAR_V )
5014
5094
  {
5015
5095
  const totalLinesInViewport = (( this.codeScroller.offsetHeight ) / this.lineHeight)|0;
@@ -5042,8 +5122,8 @@ class CodeEditor {
5042
5122
  }
5043
5123
  }
5044
5124
 
5045
- setScrollBarValue( type = 'vertical', value ) {
5046
-
5125
+ setScrollBarValue( type = 'vertical', value )
5126
+ {
5047
5127
  if( type == 'vertical' )
5048
5128
  {
5049
5129
  const scrollBarHeight = this.vScrollbar.thumb.parentElement.offsetHeight;
@@ -5073,8 +5153,8 @@ class CodeEditor {
5073
5153
  }
5074
5154
  }
5075
5155
 
5076
- updateHorizontalScrollFromScrollBar( value ) {
5077
-
5156
+ updateHorizontalScrollFromScrollBar( value )
5157
+ {
5078
5158
  value = this.hScrollbar.thumb._left - value;
5079
5159
 
5080
5160
  // Move scrollbar thumb
@@ -5095,8 +5175,8 @@ class CodeEditor {
5095
5175
  this._discardScroll = true;
5096
5176
  }
5097
5177
 
5098
- updateVerticalScrollFromScrollBar( value ) {
5099
-
5178
+ updateVerticalScrollFromScrollBar( value )
5179
+ {
5100
5180
  value = this.vScrollbar.thumb._top - value;
5101
5181
 
5102
5182
  // Move scrollbar thumb
@@ -5114,12 +5194,13 @@ class CodeEditor {
5114
5194
  this.codeScroller.scrollTop = currentScroll;
5115
5195
  }
5116
5196
 
5117
- getCharAtPos( cursor, offset = 0 ) {
5197
+ getCharAtPos( cursor, offset = 0 )
5198
+ {
5118
5199
  return this.code.lines[ cursor.line ][ cursor.position + offset ];
5119
5200
  }
5120
5201
 
5121
- getWordAtPos( cursor, offset = 0 ) {
5122
-
5202
+ getWordAtPos( cursor, offset = 0 )
5203
+ {
5123
5204
  const col = cursor.line;
5124
5205
  const words = this.code.lines[ col ];
5125
5206
 
@@ -5168,7 +5249,8 @@ class CodeEditor {
5168
5249
  return [ word, from, to ];
5169
5250
  }
5170
5251
 
5171
- _measureChar( char = "a", useFloating = false, getBB = false ) {
5252
+ _measureChar( char = "a", useFloating = false, getBB = false )
5253
+ {
5172
5254
  const parentContainer = LX.makeContainer( null, "lexcodeeditor", "", document.body );
5173
5255
  const container = LX.makeContainer( null, "code", "", parentContainer );
5174
5256
  const line = document.createElement( "pre" );
@@ -5182,12 +5264,13 @@ class CodeEditor {
5182
5264
  return getBB ? bb : bb[ 0 ];
5183
5265
  }
5184
5266
 
5185
- measureString( str ) {
5267
+ measureString( str )
5268
+ {
5186
5269
  return str.length * this.charWidth;
5187
5270
  }
5188
5271
 
5189
- runScript( code ) {
5190
-
5272
+ runScript( code )
5273
+ {
5191
5274
  const script = document.createElement( 'script' );
5192
5275
  script.type = 'module';
5193
5276
  script.innerHTML = code;
@@ -5197,8 +5280,8 @@ class CodeEditor {
5197
5280
  document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
5198
5281
  }
5199
5282
 
5200
- toJSONFormat( text ) {
5201
-
5283
+ toJSONFormat( text )
5284
+ {
5202
5285
  let params = text.split( ':' );
5203
5286
 
5204
5287
  for(let i = 0; i < params.length; i++) {
@@ -5232,8 +5315,8 @@ class CodeEditor {
5232
5315
  }
5233
5316
  }
5234
5317
 
5235
- showAutoCompleteBox( key, cursor ) {
5236
-
5318
+ showAutoCompleteBox( key, cursor )
5319
+ {
5237
5320
  if( !cursor.isMain )
5238
5321
  {
5239
5322
  return;
@@ -5326,7 +5409,6 @@ class CodeEditor {
5326
5409
  }
5327
5410
 
5328
5411
  pre.appendChild( LX.makeIcon( iconName, { iconClass: "mr-1", svgClass: "sm " + iconClass } ) );
5329
- s
5330
5412
  pre.addEventListener( 'click', () => {
5331
5413
  this.autoCompleteWord( s );
5332
5414
  } );
@@ -5366,8 +5448,8 @@ s
5366
5448
  this.isAutoCompleteActive = true;
5367
5449
  }
5368
5450
 
5369
- hideAutoCompleteBox() {
5370
-
5451
+ hideAutoCompleteBox()
5452
+ {
5371
5453
  if( !this.autocomplete )
5372
5454
  {
5373
5455
  return;
@@ -5381,8 +5463,8 @@ s
5381
5463
  return isActive != this.isAutoCompleteActive;
5382
5464
  }
5383
5465
 
5384
- autoCompleteWord( suggestion ) {
5385
-
5466
+ autoCompleteWord( suggestion )
5467
+ {
5386
5468
  if( !this.isAutoCompleteActive )
5387
5469
  return;
5388
5470
 
@@ -5408,8 +5490,8 @@ s
5408
5490
  this.hideAutoCompleteBox();
5409
5491
  }
5410
5492
 
5411
- _getSelectedAutoComplete() {
5412
-
5493
+ _getSelectedAutoComplete()
5494
+ {
5413
5495
  if( !this.isAutoCompleteActive )
5414
5496
  {
5415
5497
  return;
@@ -5435,18 +5517,21 @@ s
5435
5517
  }
5436
5518
  }
5437
5519
 
5438
- _moveArrowSelectedAutoComplete( dir ) {
5439
-
5520
+ _moveArrowSelectedAutoComplete( dir )
5521
+ {
5440
5522
  if( !this.isAutoCompleteActive )
5441
- return;
5523
+ return;
5442
5524
 
5443
- const [word, idx] = this._getSelectedAutoComplete();
5525
+ const [ word, idx ] = this._getSelectedAutoComplete();
5444
5526
  const offset = dir == 'down' ? 1 : -1;
5445
5527
 
5446
- if( dir == 'down' ) {
5447
- if( (idx + offset) >= this.autocomplete.childElementCount ) return;
5448
- } else if( dir == 'up') {
5449
- if( (idx + offset) < 0 ) return;
5528
+ if( dir == 'down' )
5529
+ {
5530
+ if( ( idx + offset ) >= this.autocomplete.childElementCount ) return;
5531
+ }
5532
+ else if( dir == 'up')
5533
+ {
5534
+ if( ( idx + offset ) < 0 ) return;
5450
5535
  }
5451
5536
 
5452
5537
  this.autocomplete.scrollTop += offset * 20;
@@ -5456,8 +5541,8 @@ s
5456
5541
  this.autocomplete.childNodes[ idx + offset ].classList.add('selected');
5457
5542
  }
5458
5543
 
5459
- showSearchBox( clear ) {
5460
-
5544
+ showSearchBox( clear )
5545
+ {
5461
5546
  this.hideSearchLineBox();
5462
5547
 
5463
5548
  this.searchbox.classList.add( 'opened' );
@@ -5485,8 +5570,8 @@ s
5485
5570
  input.focus();
5486
5571
  }
5487
5572
 
5488
- hideSearchBox() {
5489
-
5573
+ hideSearchBox()
5574
+ {
5490
5575
  const active = this.searchboxActive;
5491
5576
 
5492
5577
  if( this.searchboxActive )
@@ -5503,11 +5588,11 @@ s
5503
5588
 
5504
5589
  this.searchResultSelections.classList.remove( 'show' );
5505
5590
 
5506
- return active != this.searchboxActive;
5591
+ return ( active != this.searchboxActive );
5507
5592
  }
5508
5593
 
5509
- search( text, reverse, callback, skipAlert ) {
5510
-
5594
+ search( text, reverse, callback, skipAlert, forceFocus = true )
5595
+ {
5511
5596
  text = text ?? this._lastTextFound;
5512
5597
 
5513
5598
  if( !text )
@@ -5629,12 +5714,15 @@ s
5629
5714
  };
5630
5715
 
5631
5716
  // Force focus back to search box
5632
- const input = this.searchbox.querySelector( 'input' );
5633
- input.focus();
5717
+ if( forceFocus )
5718
+ {
5719
+ const input = this.searchbox.querySelector( 'input' );
5720
+ input.focus();
5721
+ }
5634
5722
  }
5635
5723
 
5636
- showSearchLineBox() {
5637
-
5724
+ showSearchLineBox()
5725
+ {
5638
5726
  this.hideSearchBox();
5639
5727
 
5640
5728
  this.searchlinebox.classList.add( 'opened' );
@@ -5645,8 +5733,8 @@ s
5645
5733
  input.focus();
5646
5734
  }
5647
5735
 
5648
- hideSearchLineBox() {
5649
-
5736
+ hideSearchLineBox()
5737
+ {
5650
5738
  if( this.searchlineboxActive )
5651
5739
  {
5652
5740
  this.searchlinebox.classList.remove( 'opened' );
@@ -5654,8 +5742,8 @@ s
5654
5742
  }
5655
5743
  }
5656
5744
 
5657
- goToLine( line ) {
5658
-
5745
+ goToLine( line )
5746
+ {
5659
5747
  if( !this._isNumber( line ) )
5660
5748
  return;
5661
5749
 
@@ -5666,8 +5754,8 @@ s
5666
5754
  this.cursorToLine( cursor, line - 1, true );
5667
5755
  }
5668
5756
 
5669
- selectNextOcurrence( cursor ) {
5670
-
5757
+ selectNextOcurrence( cursor )
5758
+ {
5671
5759
  if( !cursor.selection )
5672
5760
  return;
5673
5761
 
@@ -5682,11 +5770,12 @@ s
5682
5770
  this._currentOcurrences[ currentKey ] = true;
5683
5771
  }
5684
5772
 
5685
- this.search( text, false, (col, ln) => {
5773
+ this.search( text, false, ( col, ln ) => {
5686
5774
 
5687
5775
  const key = [ col, ln ].join( '_' );
5688
5776
 
5689
- if( this._currentOcurrences[ key ] ) {
5777
+ if( this._currentOcurrences[ key ] )
5778
+ {
5690
5779
  return;
5691
5780
  }
5692
5781
 
@@ -5697,11 +5786,11 @@ s
5697
5786
 
5698
5787
  this._currentOcurrences[ key ] = true;
5699
5788
 
5700
- }, true );
5789
+ }, true, false );
5701
5790
  }
5702
5791
 
5703
- _updateDataInfoPanel( signal, value ) {
5704
-
5792
+ _updateDataInfoPanel( signal, value )
5793
+ {
5705
5794
  if( !this.skipInfo )
5706
5795
  {
5707
5796
  if( this.cursors.childElementCount > 1 )
@@ -5713,8 +5802,8 @@ s
5713
5802
  }
5714
5803
  }
5715
5804
 
5716
- _setActiveLine( number ) {
5717
-
5805
+ _setActiveLine( number )
5806
+ {
5718
5807
  number = number ?? this.state.activeLine;
5719
5808
 
5720
5809
  const cursor = this.getCurrentCursor();
@@ -5740,11 +5829,13 @@ s
5740
5829
  }
5741
5830
  }
5742
5831
 
5743
- _hideActiveLine() {
5832
+ _hideActiveLine()
5833
+ {
5744
5834
  this.code.querySelectorAll( '.active-line' ).forEach( e => e.classList.remove( 'active-line' ) );
5745
5835
  }
5746
5836
 
5747
- _setFontSize( size ) {
5837
+ _setFontSize( size )
5838
+ {
5748
5839
  // Change font size
5749
5840
  this.fontSize = size;
5750
5841
  const r = document.querySelector( ':root' );
@@ -5768,20 +5859,24 @@ s
5768
5859
  LX.emit( "@font-size", this.fontSize );
5769
5860
  }
5770
5861
 
5771
- _applyFontSizeOffset( offset = 0 ) {
5862
+ _applyFontSizeOffset( offset = 0 )
5863
+ {
5772
5864
  const newFontSize = LX.clamp( this.fontSize + offset, CodeEditor.CODE_MIN_FONT_SIZE, CodeEditor.CODE_MAX_FONT_SIZE );
5773
5865
  this._setFontSize( newFontSize );
5774
5866
  }
5775
5867
 
5776
- _increaseFontSize() {
5868
+ _increaseFontSize()
5869
+ {
5777
5870
  this._applyFontSizeOffset( 1 );
5778
5871
  }
5779
5872
 
5780
- _decreaseFontSize() {
5873
+ _decreaseFontSize()
5874
+ {
5781
5875
  this._applyFontSizeOffset( -1 );
5782
5876
  }
5783
5877
 
5784
- _clearTmpVariables() {
5878
+ _clearTmpVariables()
5879
+ {
5785
5880
  delete this._currentLineString;
5786
5881
  delete this._currentLineNumber;
5787
5882
  delete this._buildingString;
@@ -5792,7 +5887,8 @@ s
5792
5887
  delete this._scopeStack;
5793
5888
  }
5794
5889
 
5795
- async _requestFileAsync( url, dataType, nocache ) {
5890
+ async _requestFileAsync( url, dataType, nocache )
5891
+ {
5796
5892
  return new Promise( (resolve, reject) => {
5797
5893
  dataType = dataType ?? "arraybuffer";
5798
5894
  const mimeType = dataType === "arraybuffer" ? "application/octet-stream" : undefined;
@@ -5823,7 +5919,8 @@ s
5823
5919
  }
5824
5920
  }
5825
5921
 
5826
- CodeEditor.languages = {
5922
+ CodeEditor.languages =
5923
+ {
5827
5924
  'Plain Text': { ext: "txt", blockComments: false, singleLineComments: false, numbers: false, icon: "AlignLeft gray" },
5828
5925
  'JavaScript': { ext: "js", icon: "Js goldenrod" },
5829
5926
  'TypeScript': { ext: "ts", icon: "Ts pipelineblue" },
@@ -5843,17 +5940,20 @@ CodeEditor.languages = {
5843
5940
  'PHP': { ext: "php", icon: "Php blueviolet" },
5844
5941
  };
5845
5942
 
5846
- CodeEditor.nativeTypes = {
5943
+ CodeEditor.nativeTypes =
5944
+ {
5847
5945
  'C++': ['int', 'float', 'double', 'bool', 'long', 'short', 'char', 'wchar_t', 'void'],
5848
5946
  'WGSL': ['bool', 'u32', 'i32', 'f16', 'f32', 'vec2', 'vec3', 'vec4', 'vec2f', 'vec3f', 'vec4f', 'mat2x2f', 'mat3x3f', 'mat4x4f', 'array', 'vec2u', 'vec3u', 'vec4u', 'ptr', 'sampler']
5849
5947
  };
5850
5948
 
5851
- CodeEditor.declarationKeywords = {
5949
+ CodeEditor.declarationKeywords =
5950
+ {
5852
5951
  'JavaScript': ['var', 'let', 'const', 'this', 'static', 'class'],
5853
5952
  'C++': [...CodeEditor.nativeTypes["C++"], 'const', 'auto', 'class', 'struct', 'namespace', 'enum', 'extern']
5854
5953
  };
5855
5954
 
5856
- CodeEditor.keywords = {
5955
+ CodeEditor.keywords =
5956
+ {
5857
5957
  'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null', 'typeof', 'debugger', 'abstract',
5858
5958
  'arguments', 'extends', 'instanceof', 'Infinity'],
5859
5959
  'TypeScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'class', 'extends', 'instanceof', 'Infinity', 'private', 'public', 'protected', 'interface',
@@ -5882,7 +5982,9 @@ CodeEditor.keywords = {
5882
5982
  'enum'],
5883
5983
  };
5884
5984
 
5885
- CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to autocomplete only...
5985
+ // These ones don't have hightlight, used as suggestions to autocomplete only...
5986
+ CodeEditor.utils =
5987
+ {
5886
5988
  'JavaScript': ['querySelector', 'body', 'addEventListener', 'removeEventListener', 'remove', 'sort', 'keys', 'filter', 'isNaN', 'parseFloat', 'parseInt', 'EPSILON', 'isFinite',
5887
5989
  'bind', 'prototype', 'length', 'assign', 'entries', 'values', 'concat', 'substring', 'substr', 'splice', 'slice', 'buffer', 'appendChild', 'createElement', 'prompt',
5888
5990
  'alert'],
@@ -5900,7 +6002,8 @@ CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to
5900
6002
  'lime', 'teal', 'navy', 'transparent', 'currentcolor', 'inherit', 'initial', 'unset', 'revert', 'none', 'auto', 'fit-content', 'min-content', 'max-content']
5901
6003
  };
5902
6004
 
5903
- CodeEditor.types = {
6005
+ CodeEditor.types =
6006
+ {
5904
6007
  'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent',
5905
6008
  'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
5906
6009
  'TypeScript': ['arguments', 'constructor', 'null', 'typeof', 'debugger', 'abstract', 'Object', 'string', 'String', 'Function', 'Boolean', 'boolean', 'Error', 'Number', 'number', 'TextEncoder',
@@ -5914,7 +6017,8 @@ CodeEditor.types = {
5914
6017
  'PHP': ['Exception', 'DateTime', 'JsonSerializable'],
5915
6018
  };
5916
6019
 
5917
- CodeEditor.builtIn = {
6020
+ CodeEditor.builtIn =
6021
+ {
5918
6022
  'JavaScript': ['document', 'console', 'window', 'navigator', 'performance'],
5919
6023
  'CSS': ['*', '!important'],
5920
6024
  'C++': ['vector', 'list', 'map'],
@@ -5924,7 +6028,8 @@ CodeEditor.builtIn = {
5924
6028
  'PHP': ['echo', 'print'],
5925
6029
  };
5926
6030
 
5927
- CodeEditor.statements = {
6031
+ CodeEditor.statements =
6032
+ {
5928
6033
  'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await'],
5929
6034
  'TypeScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await', 'as'],
5930
6035
  'CSS': ['@', 'import'],
@@ -5940,7 +6045,8 @@ CodeEditor.statements = {
5940
6045
  'try', 'catch', 'die', 'do', 'exit', 'finally'],
5941
6046
  };
5942
6047
 
5943
- CodeEditor.symbols = {
6048
+ CodeEditor.symbols =
6049
+ {
5944
6050
  'JavaScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
5945
6051
  'TypeScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
5946
6052
  'C': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '*', '-', '+'],