lexgui 0.7.8 → 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.
- package/build/extensions/codeeditor.js +398 -321
- package/build/extensions/videoeditor.js +50 -10
- package/build/lexgui.js +24 -10
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +24 -10
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +16 -1
- package/package.json +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LX } from 'lexgui';
|
|
2
2
|
|
|
3
|
-
if(!LX)
|
|
4
|
-
|
|
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
|
-
|
|
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
|
|
299
|
-
static WORD_TYPE_CLASS
|
|
302
|
+
static WORD_TYPE_METHOD = 0;
|
|
303
|
+
static WORD_TYPE_CLASS = 1;
|
|
300
304
|
|
|
301
|
-
static CODE_MIN_FONT_SIZE
|
|
302
|
-
static CODE_MAX_FONT_SIZE
|
|
305
|
+
static CODE_MIN_FONT_SIZE = 9;
|
|
306
|
+
static CODE_MAX_FONT_SIZE = 22;
|
|
303
307
|
|
|
304
|
-
static LINE_GUTTER_WIDTH
|
|
305
|
-
static LINE_GUTTER_WIDTH
|
|
308
|
+
static LINE_GUTTER_WIDTH = 48;
|
|
309
|
+
static LINE_GUTTER_WIDTH = 48;
|
|
306
310
|
|
|
307
|
-
static RESIZE_SCROLLBAR_H
|
|
308
|
-
static RESIZE_SCROLLBAR_V
|
|
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 );
|
|
@@ -1197,8 +1201,8 @@ class CodeEditor {
|
|
|
1197
1201
|
else // Next char
|
|
1198
1202
|
{
|
|
1199
1203
|
var letter = this.getCharAtPos( cursor );
|
|
1200
|
-
if( letter )
|
|
1201
|
-
|
|
1204
|
+
if( letter )
|
|
1205
|
+
{
|
|
1202
1206
|
// Selecting chars
|
|
1203
1207
|
if( e.shiftKey )
|
|
1204
1208
|
{
|
|
@@ -1210,7 +1214,8 @@ class CodeEditor {
|
|
|
1210
1214
|
}
|
|
1211
1215
|
else
|
|
1212
1216
|
{
|
|
1213
|
-
if( !cursor.selection )
|
|
1217
|
+
if( !cursor.selection )
|
|
1218
|
+
{
|
|
1214
1219
|
this.cursorToRight( letter, cursor );
|
|
1215
1220
|
if( this.useAutoComplete && this.isAutoCompleteActive )
|
|
1216
1221
|
this.showAutoCompleteBox( 'foo', cursor );
|
|
@@ -1221,16 +1226,20 @@ class CodeEditor {
|
|
|
1221
1226
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT_TOP, cursor );
|
|
1222
1227
|
this.cursorToLine( cursor, cursor.selection.toY );
|
|
1223
1228
|
this.cursorToPosition( cursor, cursor.selection.toX );
|
|
1224
|
-
this.endSelection();
|
|
1229
|
+
this.endSelection( cursor );
|
|
1225
1230
|
}
|
|
1226
1231
|
}
|
|
1227
1232
|
}
|
|
1228
|
-
else if( this.code.lines[ cursor.line + 1 ] !== undefined )
|
|
1229
|
-
|
|
1230
|
-
if( e.shiftKey )
|
|
1233
|
+
else if( this.code.lines[ cursor.line + 1 ] !== undefined )
|
|
1234
|
+
{
|
|
1235
|
+
if( e.shiftKey )
|
|
1236
|
+
{
|
|
1231
1237
|
if( !cursor.selection ) this.startSelection( cursor );
|
|
1232
1238
|
}
|
|
1233
|
-
else
|
|
1239
|
+
else
|
|
1240
|
+
{
|
|
1241
|
+
this.endSelection();
|
|
1242
|
+
}
|
|
1234
1243
|
|
|
1235
1244
|
this.lineDown( cursor, true );
|
|
1236
1245
|
|
|
@@ -1338,7 +1347,8 @@ class CodeEditor {
|
|
|
1338
1347
|
}
|
|
1339
1348
|
|
|
1340
1349
|
// Clear signals
|
|
1341
|
-
clear()
|
|
1350
|
+
clear()
|
|
1351
|
+
{
|
|
1342
1352
|
console.assert( this.rightStatusPanel && this.leftStatusPanel, "No panels to clear." );
|
|
1343
1353
|
this.rightStatusPanel.clear();
|
|
1344
1354
|
this.leftStatusPanel.clear();
|
|
@@ -1350,8 +1360,8 @@ class CodeEditor {
|
|
|
1350
1360
|
}
|
|
1351
1361
|
|
|
1352
1362
|
// This received key inputs from the entire document...
|
|
1353
|
-
onKeyPressed( e )
|
|
1354
|
-
|
|
1363
|
+
onKeyPressed( e )
|
|
1364
|
+
{
|
|
1355
1365
|
// Toggle visibility of the file explorer
|
|
1356
1366
|
if( e.key == 'b' && e.ctrlKey && this.useFileExplorer )
|
|
1357
1367
|
{
|
|
@@ -1369,13 +1379,14 @@ class CodeEditor {
|
|
|
1369
1379
|
}
|
|
1370
1380
|
}
|
|
1371
1381
|
|
|
1372
|
-
getText( min )
|
|
1382
|
+
getText( min )
|
|
1383
|
+
{
|
|
1373
1384
|
return this.code.lines.join( min ? ' ' : '\n' );
|
|
1374
1385
|
}
|
|
1375
1386
|
|
|
1376
1387
|
// This can be used to empty all text...
|
|
1377
|
-
setText( text = "", lang )
|
|
1378
|
-
|
|
1388
|
+
setText( text = "", lang )
|
|
1389
|
+
{
|
|
1379
1390
|
let newLines = text.split( '\n' );
|
|
1380
1391
|
this.code.lines = [].concat( newLines );
|
|
1381
1392
|
|
|
@@ -1397,8 +1408,8 @@ class CodeEditor {
|
|
|
1397
1408
|
this._processLinesIfNecessary();
|
|
1398
1409
|
}
|
|
1399
1410
|
|
|
1400
|
-
appendText( text, cursor )
|
|
1401
|
-
|
|
1411
|
+
appendText( text, cursor )
|
|
1412
|
+
{
|
|
1402
1413
|
let lidx = cursor.line;
|
|
1403
1414
|
|
|
1404
1415
|
if( cursor.selection )
|
|
@@ -1468,8 +1479,18 @@ class CodeEditor {
|
|
|
1468
1479
|
} );
|
|
1469
1480
|
}
|
|
1470
1481
|
|
|
1471
|
-
|
|
1482
|
+
setCustomSuggestions( suggestions )
|
|
1483
|
+
{
|
|
1484
|
+
if( !suggestions || suggestions.constructor !== Array )
|
|
1485
|
+
{
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
this.customSuggestions = suggestions;
|
|
1490
|
+
}
|
|
1472
1491
|
|
|
1492
|
+
async loadFile( file, options = {} )
|
|
1493
|
+
{
|
|
1473
1494
|
const _innerAddTab = ( text, name, title ) => {
|
|
1474
1495
|
|
|
1475
1496
|
// Remove Carriage Return in some cases and sub tabs using spaces
|
|
@@ -1540,8 +1561,8 @@ class CodeEditor {
|
|
|
1540
1561
|
}
|
|
1541
1562
|
}
|
|
1542
1563
|
|
|
1543
|
-
_addUndoStep( cursor, force, deleteRedo = true )
|
|
1544
|
-
|
|
1564
|
+
_addUndoStep( cursor, force, deleteRedo = true )
|
|
1565
|
+
{
|
|
1545
1566
|
// Only the mainc cursor stores undo steps
|
|
1546
1567
|
if( !cursor.isMain )
|
|
1547
1568
|
return;
|
|
@@ -1582,10 +1603,12 @@ class CodeEditor {
|
|
|
1582
1603
|
} );
|
|
1583
1604
|
}
|
|
1584
1605
|
|
|
1585
|
-
_doUndo( cursor )
|
|
1586
|
-
|
|
1606
|
+
_doUndo( cursor )
|
|
1607
|
+
{
|
|
1587
1608
|
if( !this.code.undoSteps.length )
|
|
1609
|
+
{
|
|
1588
1610
|
return;
|
|
1611
|
+
}
|
|
1589
1612
|
|
|
1590
1613
|
this._addRedoStep( cursor );
|
|
1591
1614
|
|
|
@@ -1612,8 +1635,8 @@ class CodeEditor {
|
|
|
1612
1635
|
this._hideActiveLine();
|
|
1613
1636
|
}
|
|
1614
1637
|
|
|
1615
|
-
_addRedoStep( cursor )
|
|
1616
|
-
|
|
1638
|
+
_addRedoStep( cursor )
|
|
1639
|
+
{
|
|
1617
1640
|
// Only the mainc cursor stores redo steps
|
|
1618
1641
|
if( !cursor.isMain )
|
|
1619
1642
|
{
|
|
@@ -1626,10 +1649,12 @@ class CodeEditor {
|
|
|
1626
1649
|
} );
|
|
1627
1650
|
}
|
|
1628
1651
|
|
|
1629
|
-
_doRedo( cursor )
|
|
1630
|
-
|
|
1652
|
+
_doRedo( cursor )
|
|
1653
|
+
{
|
|
1631
1654
|
if( !this.code.redoSteps.length )
|
|
1655
|
+
{
|
|
1632
1656
|
return;
|
|
1657
|
+
}
|
|
1633
1658
|
|
|
1634
1659
|
this._addUndoStep( cursor, true, false);
|
|
1635
1660
|
|
|
@@ -1656,8 +1681,8 @@ class CodeEditor {
|
|
|
1656
1681
|
}
|
|
1657
1682
|
}
|
|
1658
1683
|
|
|
1659
|
-
_changeLanguage( lang, langExtension, override = false )
|
|
1660
|
-
|
|
1684
|
+
_changeLanguage( lang, langExtension, override = false )
|
|
1685
|
+
{
|
|
1661
1686
|
this.code.language = lang;
|
|
1662
1687
|
this.highlight = lang;
|
|
1663
1688
|
|
|
@@ -1702,8 +1727,8 @@ class CodeEditor {
|
|
|
1702
1727
|
}
|
|
1703
1728
|
}
|
|
1704
1729
|
|
|
1705
|
-
_changeLanguageFromExtension( ext )
|
|
1706
|
-
|
|
1730
|
+
_changeLanguageFromExtension( ext )
|
|
1731
|
+
{
|
|
1707
1732
|
if( !ext )
|
|
1708
1733
|
{
|
|
1709
1734
|
return this._changeLanguage( this.code.language );
|
|
@@ -1733,8 +1758,8 @@ class CodeEditor {
|
|
|
1733
1758
|
this._changeLanguage( 'Plain Text' );
|
|
1734
1759
|
}
|
|
1735
1760
|
|
|
1736
|
-
_createStatusPanel( options )
|
|
1737
|
-
|
|
1761
|
+
_createStatusPanel( options )
|
|
1762
|
+
{
|
|
1738
1763
|
if( this.skipInfo )
|
|
1739
1764
|
{
|
|
1740
1765
|
return;
|
|
@@ -1833,8 +1858,8 @@ class CodeEditor {
|
|
|
1833
1858
|
return panel;
|
|
1834
1859
|
}
|
|
1835
1860
|
|
|
1836
|
-
_getFileIcon( name, extension, lang )
|
|
1837
|
-
|
|
1861
|
+
_getFileIcon( name, extension, lang )
|
|
1862
|
+
{
|
|
1838
1863
|
const isNewTabButton = name ? ( name === '+' ) : false;
|
|
1839
1864
|
if( isNewTabButton )
|
|
1840
1865
|
{
|
|
@@ -1888,8 +1913,8 @@ class CodeEditor {
|
|
|
1888
1913
|
return "AlignLeft gray";
|
|
1889
1914
|
}
|
|
1890
1915
|
|
|
1891
|
-
_onNewTab( e )
|
|
1892
|
-
|
|
1916
|
+
_onNewTab( e )
|
|
1917
|
+
{
|
|
1893
1918
|
this.processFocus( false );
|
|
1894
1919
|
|
|
1895
1920
|
if( this.onNewTab )
|
|
@@ -1906,8 +1931,8 @@ class CodeEditor {
|
|
|
1906
1931
|
new LX.DropdownMenu( e.target, dmOptions, { side: "bottom", align: "start" });
|
|
1907
1932
|
}
|
|
1908
1933
|
|
|
1909
|
-
_onCreateNewFile()
|
|
1910
|
-
|
|
1934
|
+
_onCreateNewFile()
|
|
1935
|
+
{
|
|
1911
1936
|
let options = {};
|
|
1912
1937
|
|
|
1913
1938
|
if( this.onCreateFile )
|
|
@@ -1923,8 +1948,8 @@ class CodeEditor {
|
|
|
1923
1948
|
this.addTab( name, true, name, { indexOffset: options.indexOffset, language: options.language ?? "JavaScript" } );
|
|
1924
1949
|
}
|
|
1925
1950
|
|
|
1926
|
-
_onSelectTab( isNewTabButton, event, name )
|
|
1927
|
-
|
|
1951
|
+
_onSelectTab( isNewTabButton, event, name )
|
|
1952
|
+
{
|
|
1928
1953
|
if( this.disableEdition )
|
|
1929
1954
|
{
|
|
1930
1955
|
return;
|
|
@@ -1973,8 +1998,8 @@ class CodeEditor {
|
|
|
1973
1998
|
}
|
|
1974
1999
|
}
|
|
1975
2000
|
|
|
1976
|
-
_onContextMenuTab( isNewTabButton, event, name, )
|
|
1977
|
-
|
|
2001
|
+
_onContextMenuTab( isNewTabButton, event, name, )
|
|
2002
|
+
{
|
|
1978
2003
|
if( isNewTabButton )
|
|
1979
2004
|
{
|
|
1980
2005
|
return;
|
|
@@ -2003,8 +2028,8 @@ class CodeEditor {
|
|
|
2003
2028
|
], { side: "bottom", align: "start", event });
|
|
2004
2029
|
}
|
|
2005
2030
|
|
|
2006
|
-
addTab( name, selected, title, options = {} )
|
|
2007
|
-
|
|
2031
|
+
addTab( name, selected, title, options = {} )
|
|
2032
|
+
{
|
|
2008
2033
|
// If already loaded, set new name...
|
|
2009
2034
|
const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
|
|
2010
2035
|
const noRepeatName = key.replace( /[_\d+]/g, '');
|
|
@@ -2120,8 +2145,8 @@ class CodeEditor {
|
|
|
2120
2145
|
return name;
|
|
2121
2146
|
}
|
|
2122
2147
|
|
|
2123
|
-
loadCode( name )
|
|
2124
|
-
|
|
2148
|
+
loadCode( name )
|
|
2149
|
+
{
|
|
2125
2150
|
// Hide all others
|
|
2126
2151
|
this.codeSizer.querySelectorAll( ".code" ).forEach( c => c.classList.add( "hidden" ) );
|
|
2127
2152
|
|
|
@@ -2179,8 +2204,8 @@ class CodeEditor {
|
|
|
2179
2204
|
this._updateDataInfoPanel( "@tab-name", code.tabName );
|
|
2180
2205
|
}
|
|
2181
2206
|
|
|
2182
|
-
loadTab( name )
|
|
2183
|
-
|
|
2207
|
+
loadTab( name )
|
|
2208
|
+
{
|
|
2184
2209
|
// Already open...
|
|
2185
2210
|
if( this.openedTabs[ name ] )
|
|
2186
2211
|
{
|
|
@@ -2245,8 +2270,8 @@ class CodeEditor {
|
|
|
2245
2270
|
this._updateDataInfoPanel( "@tab-name", code.tabName );
|
|
2246
2271
|
}
|
|
2247
2272
|
|
|
2248
|
-
closeTab( name, eraseAll )
|
|
2249
|
-
|
|
2273
|
+
closeTab( name, eraseAll )
|
|
2274
|
+
{
|
|
2250
2275
|
if( !this.allowClosingTabs )
|
|
2251
2276
|
{
|
|
2252
2277
|
return;
|
|
@@ -2262,12 +2287,13 @@ class CodeEditor {
|
|
|
2262
2287
|
}
|
|
2263
2288
|
}
|
|
2264
2289
|
|
|
2265
|
-
getSelectedTabName()
|
|
2290
|
+
getSelectedTabName()
|
|
2291
|
+
{
|
|
2266
2292
|
return this.tabs.selected;
|
|
2267
2293
|
}
|
|
2268
2294
|
|
|
2269
|
-
loadTabFromFile()
|
|
2270
|
-
|
|
2295
|
+
loadTabFromFile()
|
|
2296
|
+
{
|
|
2271
2297
|
const input = document.createElement( 'input' );
|
|
2272
2298
|
input.type = 'file';
|
|
2273
2299
|
document.body.appendChild( input );
|
|
@@ -2281,8 +2307,8 @@ class CodeEditor {
|
|
|
2281
2307
|
});
|
|
2282
2308
|
}
|
|
2283
2309
|
|
|
2284
|
-
processFocus( active )
|
|
2285
|
-
|
|
2310
|
+
processFocus( active )
|
|
2311
|
+
{
|
|
2286
2312
|
if( active )
|
|
2287
2313
|
{
|
|
2288
2314
|
this.restartBlink();
|
|
@@ -2294,8 +2320,8 @@ class CodeEditor {
|
|
|
2294
2320
|
}
|
|
2295
2321
|
}
|
|
2296
2322
|
|
|
2297
|
-
processMouse( e )
|
|
2298
|
-
|
|
2323
|
+
processMouse( e )
|
|
2324
|
+
{
|
|
2299
2325
|
if( !e.target.classList.contains('code') && !e.target.classList.contains('lexcodearea') ) return;
|
|
2300
2326
|
if( !this.code ) return;
|
|
2301
2327
|
|
|
@@ -2435,8 +2461,8 @@ class CodeEditor {
|
|
|
2435
2461
|
}
|
|
2436
2462
|
}
|
|
2437
2463
|
|
|
2438
|
-
_onMouseUp( e )
|
|
2439
|
-
|
|
2464
|
+
_onMouseUp( e )
|
|
2465
|
+
{
|
|
2440
2466
|
if( ( LX.getTime() - this.lastMouseDown ) < 120 )
|
|
2441
2467
|
{
|
|
2442
2468
|
this.state.selectingText = false;
|
|
@@ -2453,8 +2479,8 @@ class CodeEditor {
|
|
|
2453
2479
|
delete this._lastSelectionKeyDir;
|
|
2454
2480
|
}
|
|
2455
2481
|
|
|
2456
|
-
processClick( e )
|
|
2457
|
-
|
|
2482
|
+
processClick( e )
|
|
2483
|
+
{
|
|
2458
2484
|
var cursor = this.getCurrentCursor();
|
|
2459
2485
|
var code_rect = this.codeScroller.getBoundingClientRect();
|
|
2460
2486
|
var position = [( e.clientX - code_rect.x ) + this.getScrollLeft(), (e.clientY - code_rect.y) + this.getScrollTop()];
|
|
@@ -2485,8 +2511,8 @@ class CodeEditor {
|
|
|
2485
2511
|
this.hideAutoCompleteBox();
|
|
2486
2512
|
}
|
|
2487
2513
|
|
|
2488
|
-
updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2489
|
-
|
|
2514
|
+
updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2515
|
+
{
|
|
2490
2516
|
for( let cursor of this.cursors.children )
|
|
2491
2517
|
{
|
|
2492
2518
|
if( !cursor.selection )
|
|
@@ -2498,16 +2524,16 @@ class CodeEditor {
|
|
|
2498
2524
|
}
|
|
2499
2525
|
}
|
|
2500
2526
|
|
|
2501
|
-
processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2502
|
-
|
|
2527
|
+
processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2528
|
+
{
|
|
2503
2529
|
for( let cursor of this.cursors.children )
|
|
2504
2530
|
{
|
|
2505
2531
|
this._processSelection( cursor, e, keepRange, flags );
|
|
2506
2532
|
}
|
|
2507
2533
|
}
|
|
2508
2534
|
|
|
2509
|
-
_processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2510
|
-
|
|
2535
|
+
_processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2536
|
+
{
|
|
2511
2537
|
const isMouseEvent = e && ( e.constructor == MouseEvent );
|
|
2512
2538
|
|
|
2513
2539
|
if( isMouseEvent )
|
|
@@ -2668,8 +2694,8 @@ class CodeEditor {
|
|
|
2668
2694
|
}
|
|
2669
2695
|
}
|
|
2670
2696
|
|
|
2671
|
-
async processKey( e )
|
|
2672
|
-
|
|
2697
|
+
async processKey( e )
|
|
2698
|
+
{
|
|
2673
2699
|
const numCursors = this.cursors.childElementCount;
|
|
2674
2700
|
|
|
2675
2701
|
if( !this.code || e.srcElement.constructor != HTMLDivElement )
|
|
@@ -2737,8 +2763,8 @@ class CodeEditor {
|
|
|
2737
2763
|
delete this._lastProcessedCursorIndex;
|
|
2738
2764
|
}
|
|
2739
2765
|
|
|
2740
|
-
async processKeyAtTargetCursor( e, key, targetIdx )
|
|
2741
|
-
|
|
2766
|
+
async processKeyAtTargetCursor( e, key, targetIdx )
|
|
2767
|
+
{
|
|
2742
2768
|
let cursor = this.cursors.children[ targetIdx ];
|
|
2743
2769
|
|
|
2744
2770
|
// We could delete secondary cursor while iterating..
|
|
@@ -2749,13 +2775,14 @@ class CodeEditor {
|
|
|
2749
2775
|
this._processGlobalKeys( e, key );
|
|
2750
2776
|
}
|
|
2751
2777
|
|
|
2752
|
-
_processGlobalKeys( e, key )
|
|
2753
|
-
|
|
2778
|
+
_processGlobalKeys( e, key )
|
|
2779
|
+
{
|
|
2754
2780
|
let cursor = this.getCurrentCursor();
|
|
2755
2781
|
|
|
2756
2782
|
if( e.ctrlKey || e.metaKey )
|
|
2757
2783
|
{
|
|
2758
|
-
switch( key.toLowerCase() )
|
|
2784
|
+
switch( key.toLowerCase() )
|
|
2785
|
+
{
|
|
2759
2786
|
case 'a': // select all
|
|
2760
2787
|
e.preventDefault();
|
|
2761
2788
|
this.selectAll();
|
|
@@ -2831,8 +2858,8 @@ class CodeEditor {
|
|
|
2831
2858
|
return false;
|
|
2832
2859
|
}
|
|
2833
2860
|
|
|
2834
|
-
async _processKeyAtCursor( e, key, cursor )
|
|
2835
|
-
|
|
2861
|
+
async _processKeyAtCursor( e, key, cursor )
|
|
2862
|
+
{
|
|
2836
2863
|
const skipUndo = e.detail.skipUndo ?? false;
|
|
2837
2864
|
|
|
2838
2865
|
// keys with length > 1 are probably special keys
|
|
@@ -2994,8 +3021,8 @@ class CodeEditor {
|
|
|
2994
3021
|
}
|
|
2995
3022
|
}
|
|
2996
3023
|
|
|
2997
|
-
async _pasteContent( cursor )
|
|
2998
|
-
|
|
3024
|
+
async _pasteContent( cursor )
|
|
3025
|
+
{
|
|
2999
3026
|
const mustDetectLanguage = ( !this.getText().length );
|
|
3000
3027
|
|
|
3001
3028
|
let text = await navigator.clipboard.readText();
|
|
@@ -3025,8 +3052,8 @@ class CodeEditor {
|
|
|
3025
3052
|
}
|
|
3026
3053
|
}
|
|
3027
3054
|
|
|
3028
|
-
async _copyContent( cursor )
|
|
3029
|
-
|
|
3055
|
+
async _copyContent( cursor )
|
|
3056
|
+
{
|
|
3030
3057
|
let textToCopy = "";
|
|
3031
3058
|
|
|
3032
3059
|
if( !cursor.selection )
|
|
@@ -3060,8 +3087,8 @@ class CodeEditor {
|
|
|
3060
3087
|
// .then(() => console.log("Successfully copied"), (err) => console.error("Error"));
|
|
3061
3088
|
}
|
|
3062
3089
|
|
|
3063
|
-
async _cutContent( cursor )
|
|
3064
|
-
|
|
3090
|
+
async _cutContent( cursor )
|
|
3091
|
+
{
|
|
3065
3092
|
let lidx = cursor.line;
|
|
3066
3093
|
let textToCut = "";
|
|
3067
3094
|
|
|
@@ -3107,8 +3134,8 @@ class CodeEditor {
|
|
|
3107
3134
|
// .then(() => console.log("Successfully cut"), (err) => console.error("Error"));
|
|
3108
3135
|
}
|
|
3109
3136
|
|
|
3110
|
-
_duplicateLine( lidx, cursor )
|
|
3111
|
-
|
|
3137
|
+
_duplicateLine( lidx, cursor )
|
|
3138
|
+
{
|
|
3112
3139
|
this.endSelection();
|
|
3113
3140
|
this._addUndoStep( cursor, true );
|
|
3114
3141
|
this.code.lines.splice( lidx, 0, this.code.lines[ lidx ] );
|
|
@@ -3117,8 +3144,8 @@ class CodeEditor {
|
|
|
3117
3144
|
this.hideAutoCompleteBox();
|
|
3118
3145
|
}
|
|
3119
3146
|
|
|
3120
|
-
_commentLines( cursor, useCommentBlock )
|
|
3121
|
-
|
|
3147
|
+
_commentLines( cursor, useCommentBlock )
|
|
3148
|
+
{
|
|
3122
3149
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3123
3150
|
|
|
3124
3151
|
this.state.keyChain = null;
|
|
@@ -3195,8 +3222,8 @@ class CodeEditor {
|
|
|
3195
3222
|
this._hideActiveLine();
|
|
3196
3223
|
}
|
|
3197
3224
|
|
|
3198
|
-
_commentLine( cursor, line, minNonspaceIdx, updateCursor = true )
|
|
3199
|
-
|
|
3225
|
+
_commentLine( cursor, line, minNonspaceIdx, updateCursor = true )
|
|
3226
|
+
{
|
|
3200
3227
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3201
3228
|
if( !( lang.singleLineComments ?? true ) )
|
|
3202
3229
|
return;
|
|
@@ -3225,8 +3252,8 @@ class CodeEditor {
|
|
|
3225
3252
|
}
|
|
3226
3253
|
}
|
|
3227
3254
|
|
|
3228
|
-
_uncommentLines( cursor )
|
|
3229
|
-
|
|
3255
|
+
_uncommentLines( cursor )
|
|
3256
|
+
{
|
|
3230
3257
|
this.state.keyChain = null;
|
|
3231
3258
|
|
|
3232
3259
|
if( cursor.selection )
|
|
@@ -3252,8 +3279,8 @@ class CodeEditor {
|
|
|
3252
3279
|
this._hideActiveLine();
|
|
3253
3280
|
}
|
|
3254
3281
|
|
|
3255
|
-
_uncommentLine( cursor, line )
|
|
3256
|
-
|
|
3282
|
+
_uncommentLine( cursor, line )
|
|
3283
|
+
{
|
|
3257
3284
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3258
3285
|
|
|
3259
3286
|
if( !( lang.singleLineComments ?? true ))
|
|
@@ -3274,8 +3301,8 @@ class CodeEditor {
|
|
|
3274
3301
|
}
|
|
3275
3302
|
}
|
|
3276
3303
|
|
|
3277
|
-
action( key, deleteSelection, fn, eventSkipDelete )
|
|
3278
|
-
|
|
3304
|
+
action( key, deleteSelection, fn, eventSkipDelete )
|
|
3305
|
+
{
|
|
3279
3306
|
this.actions[ key ] = {
|
|
3280
3307
|
"key": key,
|
|
3281
3308
|
"callback": fn,
|
|
@@ -3284,13 +3311,14 @@ class CodeEditor {
|
|
|
3284
3311
|
};
|
|
3285
3312
|
}
|
|
3286
3313
|
|
|
3287
|
-
_actionMustDelete( cursor, action, e )
|
|
3314
|
+
_actionMustDelete( cursor, action, e )
|
|
3315
|
+
{
|
|
3288
3316
|
return cursor.selection && action.deleteSelection &&
|
|
3289
3317
|
( action.eventSkipDelete ? !e[ action.eventSkipDelete ] : true );
|
|
3290
3318
|
}
|
|
3291
3319
|
|
|
3292
|
-
scanWordSuggestions()
|
|
3293
|
-
|
|
3320
|
+
scanWordSuggestions()
|
|
3321
|
+
{
|
|
3294
3322
|
this.code.tokens = {};
|
|
3295
3323
|
|
|
3296
3324
|
for( let i = 0; i < this.code.lines.length; ++i )
|
|
@@ -3301,16 +3329,19 @@ class CodeEditor {
|
|
|
3301
3329
|
}
|
|
3302
3330
|
}
|
|
3303
3331
|
|
|
3304
|
-
toLocalLine( line )
|
|
3332
|
+
toLocalLine( line )
|
|
3333
|
+
{
|
|
3305
3334
|
const d = Math.max( this.firstLineInViewport - this.lineScrollMargin.x, 0 );
|
|
3306
3335
|
return Math.min( Math.max( line - d, 0 ), this.code.lines.length - 1 );
|
|
3307
3336
|
}
|
|
3308
3337
|
|
|
3309
|
-
getMaxLineLength()
|
|
3338
|
+
getMaxLineLength()
|
|
3339
|
+
{
|
|
3310
3340
|
return Math.max(...this.code.lines.map( v => v.length ));
|
|
3311
3341
|
}
|
|
3312
3342
|
|
|
3313
|
-
_processLinesIfNecessary()
|
|
3343
|
+
_processLinesIfNecessary()
|
|
3344
|
+
{
|
|
3314
3345
|
if( this.mustProcessLines )
|
|
3315
3346
|
{
|
|
3316
3347
|
this.mustProcessLines = false;
|
|
@@ -3318,8 +3349,8 @@ class CodeEditor {
|
|
|
3318
3349
|
}
|
|
3319
3350
|
}
|
|
3320
3351
|
|
|
3321
|
-
processLines( mode )
|
|
3322
|
-
|
|
3352
|
+
processLines( mode )
|
|
3353
|
+
{
|
|
3323
3354
|
if( !this.code )
|
|
3324
3355
|
{
|
|
3325
3356
|
return;
|
|
@@ -3373,8 +3404,8 @@ class CodeEditor {
|
|
|
3373
3404
|
this.resize();
|
|
3374
3405
|
}
|
|
3375
3406
|
|
|
3376
|
-
processLine( lineNumber, force, skipPropagation )
|
|
3377
|
-
|
|
3407
|
+
processLine( lineNumber, force, skipPropagation )
|
|
3408
|
+
{
|
|
3378
3409
|
if( this._scopeStack )
|
|
3379
3410
|
{
|
|
3380
3411
|
this.code.lineScopes[ lineNumber ] = [ ...this._scopeStack ];
|
|
@@ -3596,14 +3627,15 @@ class CodeEditor {
|
|
|
3596
3627
|
return this._updateLine( force, lineNumber, lineInnerHtml, skipPropagation, symbols, tokensToEvaluate );
|
|
3597
3628
|
}
|
|
3598
3629
|
|
|
3599
|
-
_getLineSignatureFromTokens( tokens )
|
|
3630
|
+
_getLineSignatureFromTokens( tokens )
|
|
3631
|
+
{
|
|
3600
3632
|
const structuralChars = new Set( [ '{', '}'] );
|
|
3601
3633
|
const sign = tokens.filter( t => structuralChars.has( t ) );
|
|
3602
3634
|
return sign.join( "_" );
|
|
3603
3635
|
}
|
|
3604
3636
|
|
|
3605
|
-
_updateBlockComments( section, lineNumber, tokens )
|
|
3606
|
-
|
|
3637
|
+
_updateBlockComments( section, lineNumber, tokens )
|
|
3638
|
+
{
|
|
3607
3639
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3608
3640
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
3609
3641
|
const lineOpensBlock = ( section[ 0 ].x === lineNumber );
|
|
@@ -3682,8 +3714,8 @@ class CodeEditor {
|
|
|
3682
3714
|
}
|
|
3683
3715
|
}
|
|
3684
3716
|
|
|
3685
|
-
_processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation )
|
|
3686
|
-
|
|
3717
|
+
_processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation )
|
|
3718
|
+
{
|
|
3687
3719
|
if( !this._scopeStack )
|
|
3688
3720
|
{
|
|
3689
3721
|
console.warn( "CodeEditor: No scope available" );
|
|
@@ -3750,8 +3782,8 @@ class CodeEditor {
|
|
|
3750
3782
|
}
|
|
3751
3783
|
}
|
|
3752
3784
|
|
|
3753
|
-
_updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] )
|
|
3754
|
-
|
|
3785
|
+
_updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] )
|
|
3786
|
+
{
|
|
3755
3787
|
const gutterLineHtml = `<span class='line-gutter'>${ lineNumber + 1 }</span>`;
|
|
3756
3788
|
const oldSymbols = this._updateLineSymbols( lineNumber, symbols );
|
|
3757
3789
|
const lineScope = CodeEditor.debugScopes && this.code.lineScopes[ lineNumber ] ? this.code.lineScopes[ lineNumber ].map( s => `${ s.type }` ).join( ", " ) : "";
|
|
@@ -3809,8 +3841,8 @@ class CodeEditor {
|
|
|
3809
3841
|
/**
|
|
3810
3842
|
* Parses a single line of code and extract declared symbols
|
|
3811
3843
|
*/
|
|
3812
|
-
_parseLineForSymbols( lineNumber, lineString, tokens, pushedScope )
|
|
3813
|
-
|
|
3844
|
+
_parseLineForSymbols( lineNumber, lineString, tokens, pushedScope )
|
|
3845
|
+
{
|
|
3814
3846
|
const scope = this._scopeStack.at( pushedScope ? -2 : -1 );
|
|
3815
3847
|
|
|
3816
3848
|
if( !scope || this._inBlockCommentSection( lineNumber ) )
|
|
@@ -3946,8 +3978,8 @@ class CodeEditor {
|
|
|
3946
3978
|
* - Removes old symbols from that line
|
|
3947
3979
|
* - Inserts the new symbols
|
|
3948
3980
|
*/
|
|
3949
|
-
_updateLineSymbols( lineNumber, newSymbols )
|
|
3950
|
-
|
|
3981
|
+
_updateLineSymbols( lineNumber, newSymbols )
|
|
3982
|
+
{
|
|
3951
3983
|
this.code.lineSymbols[ lineNumber ] = this.code.lineSymbols[ lineNumber ] ?? [];
|
|
3952
3984
|
const oldSymbols = LX.deepCopy( this.code.lineSymbols[ lineNumber ] );
|
|
3953
3985
|
|
|
@@ -3986,8 +4018,8 @@ class CodeEditor {
|
|
|
3986
4018
|
return oldSymbols;
|
|
3987
4019
|
}
|
|
3988
4020
|
|
|
3989
|
-
_lineHasComment( lineString )
|
|
3990
|
-
|
|
4021
|
+
_lineHasComment( lineString )
|
|
4022
|
+
{
|
|
3991
4023
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3992
4024
|
|
|
3993
4025
|
if( !(lang.singleLineComments ?? true) )
|
|
@@ -4012,8 +4044,8 @@ class CodeEditor {
|
|
|
4012
4044
|
}
|
|
4013
4045
|
}
|
|
4014
4046
|
|
|
4015
|
-
_getTokensFromLine( lineString, skipNonWords )
|
|
4016
|
-
|
|
4047
|
+
_getTokensFromLine( lineString, skipNonWords )
|
|
4048
|
+
{
|
|
4017
4049
|
if( !lineString || !lineString.length )
|
|
4018
4050
|
{
|
|
4019
4051
|
return [];
|
|
@@ -4072,8 +4104,8 @@ class CodeEditor {
|
|
|
4072
4104
|
return this._processTokens( tokensToEvaluate );
|
|
4073
4105
|
}
|
|
4074
4106
|
|
|
4075
|
-
_processTokens( tokens, offset = 0 )
|
|
4076
|
-
|
|
4107
|
+
_processTokens( tokens, offset = 0 )
|
|
4108
|
+
{
|
|
4077
4109
|
if( this.highlight == 'C++' || this.highlight == 'CSS' )
|
|
4078
4110
|
{
|
|
4079
4111
|
var idx = tokens.slice( offset ).findIndex( ( value, index ) => this._isNumber( value ) );
|
|
@@ -4142,8 +4174,8 @@ class CodeEditor {
|
|
|
4142
4174
|
return tokens;
|
|
4143
4175
|
}
|
|
4144
4176
|
|
|
4145
|
-
_mustHightlightWord( token, wordCategory, lang )
|
|
4146
|
-
|
|
4177
|
+
_mustHightlightWord( token, wordCategory, lang )
|
|
4178
|
+
{
|
|
4147
4179
|
if( !lang )
|
|
4148
4180
|
{
|
|
4149
4181
|
lang = CodeEditor.languages[ this.highlight ];
|
|
@@ -4159,8 +4191,8 @@ class CodeEditor {
|
|
|
4159
4191
|
return wordCategory[ this.highlight ] && wordCategory[ this.highlight ].has( t );
|
|
4160
4192
|
}
|
|
4161
4193
|
|
|
4162
|
-
_getTokenHighlighting( ctx, highlight )
|
|
4163
|
-
|
|
4194
|
+
_getTokenHighlighting( ctx, highlight )
|
|
4195
|
+
{
|
|
4164
4196
|
const rules = [ ...HighlightRules.common, ...( HighlightRules[ highlight ] || [] ), ...HighlightRules.post_common ];
|
|
4165
4197
|
|
|
4166
4198
|
for( const rule of rules )
|
|
@@ -4178,8 +4210,8 @@ class CodeEditor {
|
|
|
4178
4210
|
return null;
|
|
4179
4211
|
}
|
|
4180
4212
|
|
|
4181
|
-
_evaluateToken( ctxData )
|
|
4182
|
-
|
|
4213
|
+
_evaluateToken( ctxData )
|
|
4214
|
+
{
|
|
4183
4215
|
let { token, prev, next, tokenIndex, isFirstToken, isLastToken } = ctxData;
|
|
4184
4216
|
|
|
4185
4217
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
@@ -4276,8 +4308,8 @@ class CodeEditor {
|
|
|
4276
4308
|
return `<span class="${ highlight } ${ tokenClass }">${ token }</span>`;
|
|
4277
4309
|
}
|
|
4278
4310
|
|
|
4279
|
-
_appendStringToken( token )
|
|
4280
|
-
|
|
4311
|
+
_appendStringToken( token )
|
|
4312
|
+
{
|
|
4281
4313
|
if( !this._pendingString )
|
|
4282
4314
|
{
|
|
4283
4315
|
this._pendingString = "";
|
|
@@ -4288,14 +4320,15 @@ class CodeEditor {
|
|
|
4288
4320
|
return true;
|
|
4289
4321
|
}
|
|
4290
4322
|
|
|
4291
|
-
_getCurrentString()
|
|
4323
|
+
_getCurrentString()
|
|
4324
|
+
{
|
|
4292
4325
|
const chars = this._pendingString;
|
|
4293
4326
|
delete this._pendingString;
|
|
4294
4327
|
return chars;
|
|
4295
4328
|
}
|
|
4296
4329
|
|
|
4297
|
-
_enclosedByTokens( token, tokenIndex, tagStart, tagEnd )
|
|
4298
|
-
|
|
4330
|
+
_enclosedByTokens( token, tokenIndex, tagStart, tagEnd )
|
|
4331
|
+
{
|
|
4299
4332
|
const tokenStartIndex = this._currentTokenPositions[ tokenIndex ];
|
|
4300
4333
|
const tagStartIndex = indexOfFrom( this._currentLineString, tagStart, tokenStartIndex, true );
|
|
4301
4334
|
if( tagStartIndex < 0 ) // Not found..
|
|
@@ -4313,8 +4346,8 @@ class CodeEditor {
|
|
|
4313
4346
|
}
|
|
4314
4347
|
}
|
|
4315
4348
|
|
|
4316
|
-
_inBlockCommentSection( lineNumber, tokenPosition, tokenLength )
|
|
4317
|
-
|
|
4349
|
+
_inBlockCommentSection( lineNumber, tokenPosition, tokenLength )
|
|
4350
|
+
{
|
|
4318
4351
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
4319
4352
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
4320
4353
|
|
|
@@ -4341,8 +4374,8 @@ class CodeEditor {
|
|
|
4341
4374
|
}
|
|
4342
4375
|
}
|
|
4343
4376
|
|
|
4344
|
-
_isKeyword( ctxData )
|
|
4345
|
-
|
|
4377
|
+
_isKeyword( ctxData )
|
|
4378
|
+
{
|
|
4346
4379
|
const { token, tokenIndex, tokens, lang } = ctxData;
|
|
4347
4380
|
|
|
4348
4381
|
let isKwd = this._mustHightlightWord( token, CodeEditor.keywords ) || this.highlight == 'XML';
|
|
@@ -4373,8 +4406,8 @@ class CodeEditor {
|
|
|
4373
4406
|
return isKwd;
|
|
4374
4407
|
}
|
|
4375
4408
|
|
|
4376
|
-
_isNumber( token )
|
|
4377
|
-
|
|
4409
|
+
_isNumber( token )
|
|
4410
|
+
{
|
|
4378
4411
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
4379
4412
|
if( !( lang.numbers ?? true ) )
|
|
4380
4413
|
{
|
|
@@ -4412,8 +4445,8 @@ class CodeEditor {
|
|
|
4412
4445
|
return token.length && token != ' ' && !Number.isNaN( +token );
|
|
4413
4446
|
}
|
|
4414
4447
|
|
|
4415
|
-
_encloseSelectedWordWithKey( key, lidx, cursor )
|
|
4416
|
-
|
|
4448
|
+
_encloseSelectedWordWithKey( key, lidx, cursor )
|
|
4449
|
+
{
|
|
4417
4450
|
if( !cursor.selection || ( cursor.selection.fromY != cursor.selection.toY ) )
|
|
4418
4451
|
{
|
|
4419
4452
|
return false;
|
|
@@ -4460,8 +4493,8 @@ class CodeEditor {
|
|
|
4460
4493
|
return true;
|
|
4461
4494
|
}
|
|
4462
4495
|
|
|
4463
|
-
_detectLanguage( text )
|
|
4464
|
-
|
|
4496
|
+
_detectLanguage( text )
|
|
4497
|
+
{
|
|
4465
4498
|
const tokenSet = new Set( this._getTokensFromLine( text, true ) );
|
|
4466
4499
|
const scores = {};
|
|
4467
4500
|
|
|
@@ -4500,8 +4533,8 @@ class CodeEditor {
|
|
|
4500
4533
|
return sorted[0][1] > 0 ? sorted[0][0] : undefined;
|
|
4501
4534
|
}
|
|
4502
4535
|
|
|
4503
|
-
lineUp( cursor, resetLeft )
|
|
4504
|
-
|
|
4536
|
+
lineUp( cursor, resetLeft )
|
|
4537
|
+
{
|
|
4505
4538
|
if( this.code.lines[ cursor.line - 1 ] == undefined )
|
|
4506
4539
|
return false;
|
|
4507
4540
|
|
|
@@ -4512,8 +4545,8 @@ class CodeEditor {
|
|
|
4512
4545
|
return true;
|
|
4513
4546
|
}
|
|
4514
4547
|
|
|
4515
|
-
lineDown( cursor, resetLeft )
|
|
4516
|
-
|
|
4548
|
+
lineDown( cursor, resetLeft )
|
|
4549
|
+
{
|
|
4517
4550
|
if( this.code.lines[ cursor.line + 1 ] == undefined )
|
|
4518
4551
|
return false;
|
|
4519
4552
|
|
|
@@ -4524,8 +4557,8 @@ class CodeEditor {
|
|
|
4524
4557
|
return true;
|
|
4525
4558
|
}
|
|
4526
4559
|
|
|
4527
|
-
restartBlink()
|
|
4528
|
-
|
|
4560
|
+
restartBlink()
|
|
4561
|
+
{
|
|
4529
4562
|
if( !this.code ) return;
|
|
4530
4563
|
|
|
4531
4564
|
clearInterval( this.blinker );
|
|
@@ -4539,8 +4572,8 @@ class CodeEditor {
|
|
|
4539
4572
|
this.cursors.classList.remove( 'show' );
|
|
4540
4573
|
}
|
|
4541
4574
|
|
|
4542
|
-
startSelection( cursor )
|
|
4543
|
-
|
|
4575
|
+
startSelection( cursor )
|
|
4576
|
+
{
|
|
4544
4577
|
// Show elements
|
|
4545
4578
|
let selectionContainer = document.createElement( 'div' );
|
|
4546
4579
|
selectionContainer.className = 'selections';
|
|
@@ -4553,8 +4586,8 @@ class CodeEditor {
|
|
|
4553
4586
|
cursor.selection = new CodeSelection( this, cursor );
|
|
4554
4587
|
}
|
|
4555
4588
|
|
|
4556
|
-
deleteSelection( cursor )
|
|
4557
|
-
|
|
4589
|
+
deleteSelection( cursor )
|
|
4590
|
+
{
|
|
4558
4591
|
// I think it's not necessary but...
|
|
4559
4592
|
if( this.disableEdition )
|
|
4560
4593
|
{
|
|
@@ -4586,8 +4619,8 @@ class CodeEditor {
|
|
|
4586
4619
|
this.processLines();
|
|
4587
4620
|
}
|
|
4588
4621
|
|
|
4589
|
-
endSelection( cursor )
|
|
4590
|
-
|
|
4622
|
+
endSelection( cursor )
|
|
4623
|
+
{
|
|
4591
4624
|
delete this._tripleClickSelection;
|
|
4592
4625
|
delete this._lastSelectionKeyDir;
|
|
4593
4626
|
delete this._currentOcurrences;
|
|
@@ -4610,7 +4643,9 @@ class CodeEditor {
|
|
|
4610
4643
|
}
|
|
4611
4644
|
}
|
|
4612
4645
|
|
|
4613
|
-
selectAll()
|
|
4646
|
+
selectAll()
|
|
4647
|
+
{
|
|
4648
|
+
this.endSelection();
|
|
4614
4649
|
|
|
4615
4650
|
// Use main cursor
|
|
4616
4651
|
this._removeSecondaryCursors();
|
|
@@ -4632,8 +4667,8 @@ class CodeEditor {
|
|
|
4632
4667
|
this.hideAutoCompleteBox();
|
|
4633
4668
|
}
|
|
4634
4669
|
|
|
4635
|
-
cursorToRight( key, cursor )
|
|
4636
|
-
|
|
4670
|
+
cursorToRight( key, cursor )
|
|
4671
|
+
{
|
|
4637
4672
|
if( !key ) return;
|
|
4638
4673
|
|
|
4639
4674
|
cursor._left += this.charWidth;
|
|
@@ -4651,8 +4686,8 @@ class CodeEditor {
|
|
|
4651
4686
|
}
|
|
4652
4687
|
}
|
|
4653
4688
|
|
|
4654
|
-
cursorToLeft( key, cursor )
|
|
4655
|
-
|
|
4689
|
+
cursorToLeft( key, cursor )
|
|
4690
|
+
{
|
|
4656
4691
|
if( !key ) return;
|
|
4657
4692
|
|
|
4658
4693
|
cursor._left -= this.charWidth;
|
|
@@ -4672,8 +4707,8 @@ class CodeEditor {
|
|
|
4672
4707
|
}
|
|
4673
4708
|
}
|
|
4674
4709
|
|
|
4675
|
-
cursorToTop( cursor, resetLeft = false )
|
|
4676
|
-
|
|
4710
|
+
cursorToTop( cursor, resetLeft = false )
|
|
4711
|
+
{
|
|
4677
4712
|
cursor._top -= this.lineHeight;
|
|
4678
4713
|
cursor._top = Math.max( cursor._top, 0 );
|
|
4679
4714
|
cursor.style.top = `calc(${ cursor._top }px)`;
|
|
@@ -4692,8 +4727,8 @@ class CodeEditor {
|
|
|
4692
4727
|
}
|
|
4693
4728
|
}
|
|
4694
4729
|
|
|
4695
|
-
cursorToBottom( cursor, resetLeft = false )
|
|
4696
|
-
|
|
4730
|
+
cursorToBottom( cursor, resetLeft = false )
|
|
4731
|
+
{
|
|
4697
4732
|
cursor._top += this.lineHeight;
|
|
4698
4733
|
cursor.style.top = `calc(${ cursor._top }px)`;
|
|
4699
4734
|
|
|
@@ -4713,8 +4748,8 @@ class CodeEditor {
|
|
|
4713
4748
|
}
|
|
4714
4749
|
}
|
|
4715
4750
|
|
|
4716
|
-
cursorToString( cursor, text, reverse )
|
|
4717
|
-
|
|
4751
|
+
cursorToString( cursor, text, reverse )
|
|
4752
|
+
{
|
|
4718
4753
|
if( !text.length )
|
|
4719
4754
|
{
|
|
4720
4755
|
return;
|
|
@@ -4726,23 +4761,23 @@ class CodeEditor {
|
|
|
4726
4761
|
}
|
|
4727
4762
|
}
|
|
4728
4763
|
|
|
4729
|
-
cursorToPosition( cursor, position )
|
|
4730
|
-
|
|
4764
|
+
cursorToPosition( cursor, position )
|
|
4765
|
+
{
|
|
4731
4766
|
cursor.position = position;
|
|
4732
4767
|
cursor._left = position * this.charWidth;
|
|
4733
4768
|
cursor.style.left = `calc( ${ cursor._left }px + ${ this.xPadding } )`;
|
|
4734
4769
|
}
|
|
4735
4770
|
|
|
4736
|
-
cursorToLine( cursor, line, resetLeft = false )
|
|
4737
|
-
|
|
4771
|
+
cursorToLine( cursor, line, resetLeft = false )
|
|
4772
|
+
{
|
|
4738
4773
|
cursor.line = line;
|
|
4739
4774
|
cursor._top = this.lineHeight * line;
|
|
4740
4775
|
cursor.style.top = cursor._top + "px";
|
|
4741
4776
|
if( resetLeft ) this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
|
|
4742
4777
|
}
|
|
4743
4778
|
|
|
4744
|
-
saveCursor( cursor, state = {} )
|
|
4745
|
-
|
|
4779
|
+
saveCursor( cursor, state = {} )
|
|
4780
|
+
{
|
|
4746
4781
|
state.position = cursor.position;
|
|
4747
4782
|
state.line = cursor.line;
|
|
4748
4783
|
state.selection = cursor.selection ? cursor.selection.save() : undefined;
|
|
@@ -4750,8 +4785,8 @@ class CodeEditor {
|
|
|
4750
4785
|
return state;
|
|
4751
4786
|
}
|
|
4752
4787
|
|
|
4753
|
-
saveCursors()
|
|
4754
|
-
|
|
4788
|
+
saveCursors()
|
|
4789
|
+
{
|
|
4755
4790
|
var cursors = [];
|
|
4756
4791
|
|
|
4757
4792
|
for( let cursor of this.cursors.children )
|
|
@@ -4762,8 +4797,8 @@ class CodeEditor {
|
|
|
4762
4797
|
return cursors;
|
|
4763
4798
|
}
|
|
4764
4799
|
|
|
4765
|
-
getCurrentCursor( removeOthers )
|
|
4766
|
-
|
|
4800
|
+
getCurrentCursor( removeOthers )
|
|
4801
|
+
{
|
|
4767
4802
|
if( removeOthers )
|
|
4768
4803
|
{
|
|
4769
4804
|
this._removeSecondaryCursors();
|
|
@@ -4772,8 +4807,8 @@ class CodeEditor {
|
|
|
4772
4807
|
return this.cursors.children[ 0 ];
|
|
4773
4808
|
}
|
|
4774
4809
|
|
|
4775
|
-
relocateCursors()
|
|
4776
|
-
|
|
4810
|
+
relocateCursors()
|
|
4811
|
+
{
|
|
4777
4812
|
for( let cursor of this.cursors.children )
|
|
4778
4813
|
{
|
|
4779
4814
|
cursor._left = cursor.position * this.charWidth;
|
|
@@ -4783,8 +4818,8 @@ class CodeEditor {
|
|
|
4783
4818
|
}
|
|
4784
4819
|
}
|
|
4785
4820
|
|
|
4786
|
-
mergeCursors( line )
|
|
4787
|
-
|
|
4821
|
+
mergeCursors( line )
|
|
4822
|
+
{
|
|
4788
4823
|
console.assert( line >= 0 );
|
|
4789
4824
|
const cursorsInLine = Array.from( this.cursors.children ).filter( v => v.line == line );
|
|
4790
4825
|
|
|
@@ -4792,8 +4827,8 @@ class CodeEditor {
|
|
|
4792
4827
|
this.removeCursor( cursorsInLine.pop() );
|
|
4793
4828
|
}
|
|
4794
4829
|
|
|
4795
|
-
restoreCursor( cursor, state )
|
|
4796
|
-
|
|
4830
|
+
restoreCursor( cursor, state )
|
|
4831
|
+
{
|
|
4797
4832
|
cursor.position = state.position ?? 0;
|
|
4798
4833
|
cursor.line = state.line ?? 0;
|
|
4799
4834
|
|
|
@@ -4814,15 +4849,15 @@ class CodeEditor {
|
|
|
4814
4849
|
}
|
|
4815
4850
|
}
|
|
4816
4851
|
|
|
4817
|
-
removeCursor( cursor )
|
|
4818
|
-
|
|
4852
|
+
removeCursor( cursor )
|
|
4853
|
+
{
|
|
4819
4854
|
LX.deleteElement( this.selections[ cursor.name ] );
|
|
4820
4855
|
delete this.selections[ cursor.name ];
|
|
4821
4856
|
LX.deleteElement( cursor );
|
|
4822
4857
|
}
|
|
4823
4858
|
|
|
4824
|
-
resetCursorPos( flag, cursor )
|
|
4825
|
-
|
|
4859
|
+
resetCursorPos( flag, cursor )
|
|
4860
|
+
{
|
|
4826
4861
|
cursor = cursor ?? this.getCurrentCursor();
|
|
4827
4862
|
|
|
4828
4863
|
if( flag & CodeEditor.CURSOR_LEFT )
|
|
@@ -4840,8 +4875,8 @@ class CodeEditor {
|
|
|
4840
4875
|
}
|
|
4841
4876
|
}
|
|
4842
4877
|
|
|
4843
|
-
_addCursor( line = 0, position = 0, force, isMain = false )
|
|
4844
|
-
|
|
4878
|
+
_addCursor( line = 0, position = 0, force, isMain = false )
|
|
4879
|
+
{
|
|
4845
4880
|
// If cursor in that position exists, remove it instead..
|
|
4846
4881
|
const exists = Array.from( this.cursors.children ).find( v => v.position == position && v.line == line );
|
|
4847
4882
|
if( exists && !force )
|
|
@@ -4891,30 +4926,42 @@ class CodeEditor {
|
|
|
4891
4926
|
return cursor;
|
|
4892
4927
|
}
|
|
4893
4928
|
|
|
4894
|
-
_removeSecondaryCursors()
|
|
4895
|
-
|
|
4929
|
+
_removeSecondaryCursors()
|
|
4930
|
+
{
|
|
4896
4931
|
while( this.cursors.childElementCount > 1 )
|
|
4932
|
+
{
|
|
4897
4933
|
this.cursors.lastChild.remove();
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
|
|
4937
|
+
_getLastCursor()
|
|
4938
|
+
{
|
|
4939
|
+
return this.cursors.lastChild;
|
|
4898
4940
|
}
|
|
4899
4941
|
|
|
4900
|
-
|
|
4942
|
+
_isLastCursor( cursor )
|
|
4943
|
+
{
|
|
4944
|
+
return cursor === this._getLastCursor();
|
|
4945
|
+
}
|
|
4901
4946
|
|
|
4947
|
+
_logCursors()
|
|
4948
|
+
{
|
|
4902
4949
|
for( let cursor of this.cursors.children )
|
|
4903
4950
|
{
|
|
4904
4951
|
cursor.print();
|
|
4905
4952
|
}
|
|
4906
4953
|
}
|
|
4907
4954
|
|
|
4908
|
-
_addSpaceTabs( cursor, n )
|
|
4909
|
-
|
|
4955
|
+
_addSpaceTabs( cursor, n )
|
|
4956
|
+
{
|
|
4910
4957
|
for( var i = 0; i < n; ++i )
|
|
4911
4958
|
{
|
|
4912
4959
|
this.actions[ 'Tab' ].callback( cursor.line, cursor, null );
|
|
4913
4960
|
}
|
|
4914
4961
|
}
|
|
4915
4962
|
|
|
4916
|
-
_addSpaces( n )
|
|
4917
|
-
|
|
4963
|
+
_addSpaces( n )
|
|
4964
|
+
{
|
|
4918
4965
|
for( var i = 0; i < n; ++i )
|
|
4919
4966
|
{
|
|
4920
4967
|
this.root.dispatchEvent( new CustomEvent( 'keydown', { 'detail': {
|
|
@@ -4925,8 +4972,8 @@ class CodeEditor {
|
|
|
4925
4972
|
}
|
|
4926
4973
|
}
|
|
4927
4974
|
|
|
4928
|
-
_removeSpaces( cursor )
|
|
4929
|
-
|
|
4975
|
+
_removeSpaces( cursor )
|
|
4976
|
+
{
|
|
4930
4977
|
const lidx = cursor.line;
|
|
4931
4978
|
|
|
4932
4979
|
// Remove indentation
|
|
@@ -4965,17 +5012,20 @@ class CodeEditor {
|
|
|
4965
5012
|
}
|
|
4966
5013
|
}
|
|
4967
5014
|
|
|
4968
|
-
getScrollLeft()
|
|
5015
|
+
getScrollLeft()
|
|
5016
|
+
{
|
|
4969
5017
|
if( !this.codeScroller ) return 0;
|
|
4970
5018
|
return this.codeScroller.scrollLeft;
|
|
4971
5019
|
}
|
|
4972
5020
|
|
|
4973
|
-
getScrollTop()
|
|
5021
|
+
getScrollTop()
|
|
5022
|
+
{
|
|
4974
5023
|
if( !this.codeScroller ) return 0;
|
|
4975
5024
|
return this.codeScroller.scrollTop;
|
|
4976
5025
|
}
|
|
4977
5026
|
|
|
4978
|
-
setScrollLeft( value )
|
|
5027
|
+
setScrollLeft( value )
|
|
5028
|
+
{
|
|
4979
5029
|
if( !this.codeScroller ) return;
|
|
4980
5030
|
LX.doAsync( () => {
|
|
4981
5031
|
this.codeScroller.scrollLeft = value;
|
|
@@ -4983,7 +5033,8 @@ class CodeEditor {
|
|
|
4983
5033
|
}, 20 );
|
|
4984
5034
|
}
|
|
4985
5035
|
|
|
4986
|
-
setScrollTop( value )
|
|
5036
|
+
setScrollTop( value )
|
|
5037
|
+
{
|
|
4987
5038
|
if( !this.codeScroller ) return;
|
|
4988
5039
|
LX.doAsync( () => {
|
|
4989
5040
|
this.codeScroller.scrollTop = value;
|
|
@@ -4991,8 +5042,8 @@ class CodeEditor {
|
|
|
4991
5042
|
}, 20 );
|
|
4992
5043
|
}
|
|
4993
5044
|
|
|
4994
|
-
resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize )
|
|
4995
|
-
|
|
5045
|
+
resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize )
|
|
5046
|
+
{
|
|
4996
5047
|
setTimeout( () => {
|
|
4997
5048
|
|
|
4998
5049
|
let scrollWidth, scrollHeight;
|
|
@@ -5022,8 +5073,8 @@ class CodeEditor {
|
|
|
5022
5073
|
}, 10 );
|
|
5023
5074
|
}
|
|
5024
5075
|
|
|
5025
|
-
resizeIfNecessary( cursor, force )
|
|
5026
|
-
|
|
5076
|
+
resizeIfNecessary( cursor, force )
|
|
5077
|
+
{
|
|
5027
5078
|
const maxLineLength = this.getMaxLineLength();
|
|
5028
5079
|
const numViewportChars = Math.floor( ( this.codeScroller.clientWidth - CodeEditor.LINE_GUTTER_WIDTH ) / this.charWidth );
|
|
5029
5080
|
if( force || ( maxLineLength >= numViewportChars && maxLineLength != this._lastMaxLineLength ) )
|
|
@@ -5037,8 +5088,8 @@ class CodeEditor {
|
|
|
5037
5088
|
}
|
|
5038
5089
|
}
|
|
5039
5090
|
|
|
5040
|
-
resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V )
|
|
5041
|
-
|
|
5091
|
+
resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V )
|
|
5092
|
+
{
|
|
5042
5093
|
if( flag & CodeEditor.RESIZE_SCROLLBAR_V )
|
|
5043
5094
|
{
|
|
5044
5095
|
const totalLinesInViewport = (( this.codeScroller.offsetHeight ) / this.lineHeight)|0;
|
|
@@ -5071,8 +5122,8 @@ class CodeEditor {
|
|
|
5071
5122
|
}
|
|
5072
5123
|
}
|
|
5073
5124
|
|
|
5074
|
-
setScrollBarValue( type = 'vertical', value )
|
|
5075
|
-
|
|
5125
|
+
setScrollBarValue( type = 'vertical', value )
|
|
5126
|
+
{
|
|
5076
5127
|
if( type == 'vertical' )
|
|
5077
5128
|
{
|
|
5078
5129
|
const scrollBarHeight = this.vScrollbar.thumb.parentElement.offsetHeight;
|
|
@@ -5102,8 +5153,8 @@ class CodeEditor {
|
|
|
5102
5153
|
}
|
|
5103
5154
|
}
|
|
5104
5155
|
|
|
5105
|
-
updateHorizontalScrollFromScrollBar( value )
|
|
5106
|
-
|
|
5156
|
+
updateHorizontalScrollFromScrollBar( value )
|
|
5157
|
+
{
|
|
5107
5158
|
value = this.hScrollbar.thumb._left - value;
|
|
5108
5159
|
|
|
5109
5160
|
// Move scrollbar thumb
|
|
@@ -5124,8 +5175,8 @@ class CodeEditor {
|
|
|
5124
5175
|
this._discardScroll = true;
|
|
5125
5176
|
}
|
|
5126
5177
|
|
|
5127
|
-
updateVerticalScrollFromScrollBar( value )
|
|
5128
|
-
|
|
5178
|
+
updateVerticalScrollFromScrollBar( value )
|
|
5179
|
+
{
|
|
5129
5180
|
value = this.vScrollbar.thumb._top - value;
|
|
5130
5181
|
|
|
5131
5182
|
// Move scrollbar thumb
|
|
@@ -5143,12 +5194,13 @@ class CodeEditor {
|
|
|
5143
5194
|
this.codeScroller.scrollTop = currentScroll;
|
|
5144
5195
|
}
|
|
5145
5196
|
|
|
5146
|
-
getCharAtPos( cursor, offset = 0 )
|
|
5197
|
+
getCharAtPos( cursor, offset = 0 )
|
|
5198
|
+
{
|
|
5147
5199
|
return this.code.lines[ cursor.line ][ cursor.position + offset ];
|
|
5148
5200
|
}
|
|
5149
5201
|
|
|
5150
|
-
getWordAtPos( cursor, offset = 0 )
|
|
5151
|
-
|
|
5202
|
+
getWordAtPos( cursor, offset = 0 )
|
|
5203
|
+
{
|
|
5152
5204
|
const col = cursor.line;
|
|
5153
5205
|
const words = this.code.lines[ col ];
|
|
5154
5206
|
|
|
@@ -5197,7 +5249,8 @@ class CodeEditor {
|
|
|
5197
5249
|
return [ word, from, to ];
|
|
5198
5250
|
}
|
|
5199
5251
|
|
|
5200
|
-
_measureChar( char = "a", useFloating = false, getBB = false )
|
|
5252
|
+
_measureChar( char = "a", useFloating = false, getBB = false )
|
|
5253
|
+
{
|
|
5201
5254
|
const parentContainer = LX.makeContainer( null, "lexcodeeditor", "", document.body );
|
|
5202
5255
|
const container = LX.makeContainer( null, "code", "", parentContainer );
|
|
5203
5256
|
const line = document.createElement( "pre" );
|
|
@@ -5211,12 +5264,13 @@ class CodeEditor {
|
|
|
5211
5264
|
return getBB ? bb : bb[ 0 ];
|
|
5212
5265
|
}
|
|
5213
5266
|
|
|
5214
|
-
measureString( str )
|
|
5267
|
+
measureString( str )
|
|
5268
|
+
{
|
|
5215
5269
|
return str.length * this.charWidth;
|
|
5216
5270
|
}
|
|
5217
5271
|
|
|
5218
|
-
runScript( code )
|
|
5219
|
-
|
|
5272
|
+
runScript( code )
|
|
5273
|
+
{
|
|
5220
5274
|
const script = document.createElement( 'script' );
|
|
5221
5275
|
script.type = 'module';
|
|
5222
5276
|
script.innerHTML = code;
|
|
@@ -5226,8 +5280,8 @@ class CodeEditor {
|
|
|
5226
5280
|
document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
|
|
5227
5281
|
}
|
|
5228
5282
|
|
|
5229
|
-
toJSONFormat( text )
|
|
5230
|
-
|
|
5283
|
+
toJSONFormat( text )
|
|
5284
|
+
{
|
|
5231
5285
|
let params = text.split( ':' );
|
|
5232
5286
|
|
|
5233
5287
|
for(let i = 0; i < params.length; i++) {
|
|
@@ -5261,8 +5315,8 @@ class CodeEditor {
|
|
|
5261
5315
|
}
|
|
5262
5316
|
}
|
|
5263
5317
|
|
|
5264
|
-
showAutoCompleteBox( key, cursor )
|
|
5265
|
-
|
|
5318
|
+
showAutoCompleteBox( key, cursor )
|
|
5319
|
+
{
|
|
5266
5320
|
if( !cursor.isMain )
|
|
5267
5321
|
{
|
|
5268
5322
|
return;
|
|
@@ -5355,7 +5409,6 @@ class CodeEditor {
|
|
|
5355
5409
|
}
|
|
5356
5410
|
|
|
5357
5411
|
pre.appendChild( LX.makeIcon( iconName, { iconClass: "mr-1", svgClass: "sm " + iconClass } ) );
|
|
5358
|
-
s
|
|
5359
5412
|
pre.addEventListener( 'click', () => {
|
|
5360
5413
|
this.autoCompleteWord( s );
|
|
5361
5414
|
} );
|
|
@@ -5395,8 +5448,8 @@ s
|
|
|
5395
5448
|
this.isAutoCompleteActive = true;
|
|
5396
5449
|
}
|
|
5397
5450
|
|
|
5398
|
-
hideAutoCompleteBox()
|
|
5399
|
-
|
|
5451
|
+
hideAutoCompleteBox()
|
|
5452
|
+
{
|
|
5400
5453
|
if( !this.autocomplete )
|
|
5401
5454
|
{
|
|
5402
5455
|
return;
|
|
@@ -5410,8 +5463,8 @@ s
|
|
|
5410
5463
|
return isActive != this.isAutoCompleteActive;
|
|
5411
5464
|
}
|
|
5412
5465
|
|
|
5413
|
-
autoCompleteWord( suggestion )
|
|
5414
|
-
|
|
5466
|
+
autoCompleteWord( suggestion )
|
|
5467
|
+
{
|
|
5415
5468
|
if( !this.isAutoCompleteActive )
|
|
5416
5469
|
return;
|
|
5417
5470
|
|
|
@@ -5437,8 +5490,8 @@ s
|
|
|
5437
5490
|
this.hideAutoCompleteBox();
|
|
5438
5491
|
}
|
|
5439
5492
|
|
|
5440
|
-
_getSelectedAutoComplete()
|
|
5441
|
-
|
|
5493
|
+
_getSelectedAutoComplete()
|
|
5494
|
+
{
|
|
5442
5495
|
if( !this.isAutoCompleteActive )
|
|
5443
5496
|
{
|
|
5444
5497
|
return;
|
|
@@ -5464,18 +5517,21 @@ s
|
|
|
5464
5517
|
}
|
|
5465
5518
|
}
|
|
5466
5519
|
|
|
5467
|
-
_moveArrowSelectedAutoComplete( dir )
|
|
5468
|
-
|
|
5520
|
+
_moveArrowSelectedAutoComplete( dir )
|
|
5521
|
+
{
|
|
5469
5522
|
if( !this.isAutoCompleteActive )
|
|
5470
|
-
|
|
5523
|
+
return;
|
|
5471
5524
|
|
|
5472
|
-
const [word, idx] = this._getSelectedAutoComplete();
|
|
5525
|
+
const [ word, idx ] = this._getSelectedAutoComplete();
|
|
5473
5526
|
const offset = dir == 'down' ? 1 : -1;
|
|
5474
5527
|
|
|
5475
|
-
if( dir == 'down' )
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
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;
|
|
5479
5535
|
}
|
|
5480
5536
|
|
|
5481
5537
|
this.autocomplete.scrollTop += offset * 20;
|
|
@@ -5485,8 +5541,8 @@ s
|
|
|
5485
5541
|
this.autocomplete.childNodes[ idx + offset ].classList.add('selected');
|
|
5486
5542
|
}
|
|
5487
5543
|
|
|
5488
|
-
showSearchBox( clear )
|
|
5489
|
-
|
|
5544
|
+
showSearchBox( clear )
|
|
5545
|
+
{
|
|
5490
5546
|
this.hideSearchLineBox();
|
|
5491
5547
|
|
|
5492
5548
|
this.searchbox.classList.add( 'opened' );
|
|
@@ -5514,8 +5570,8 @@ s
|
|
|
5514
5570
|
input.focus();
|
|
5515
5571
|
}
|
|
5516
5572
|
|
|
5517
|
-
hideSearchBox()
|
|
5518
|
-
|
|
5573
|
+
hideSearchBox()
|
|
5574
|
+
{
|
|
5519
5575
|
const active = this.searchboxActive;
|
|
5520
5576
|
|
|
5521
5577
|
if( this.searchboxActive )
|
|
@@ -5532,11 +5588,11 @@ s
|
|
|
5532
5588
|
|
|
5533
5589
|
this.searchResultSelections.classList.remove( 'show' );
|
|
5534
5590
|
|
|
5535
|
-
return active != this.searchboxActive;
|
|
5591
|
+
return ( active != this.searchboxActive );
|
|
5536
5592
|
}
|
|
5537
5593
|
|
|
5538
|
-
search( text, reverse, callback, skipAlert )
|
|
5539
|
-
|
|
5594
|
+
search( text, reverse, callback, skipAlert, forceFocus = true )
|
|
5595
|
+
{
|
|
5540
5596
|
text = text ?? this._lastTextFound;
|
|
5541
5597
|
|
|
5542
5598
|
if( !text )
|
|
@@ -5658,12 +5714,15 @@ s
|
|
|
5658
5714
|
};
|
|
5659
5715
|
|
|
5660
5716
|
// Force focus back to search box
|
|
5661
|
-
|
|
5662
|
-
|
|
5717
|
+
if( forceFocus )
|
|
5718
|
+
{
|
|
5719
|
+
const input = this.searchbox.querySelector( 'input' );
|
|
5720
|
+
input.focus();
|
|
5721
|
+
}
|
|
5663
5722
|
}
|
|
5664
5723
|
|
|
5665
|
-
showSearchLineBox()
|
|
5666
|
-
|
|
5724
|
+
showSearchLineBox()
|
|
5725
|
+
{
|
|
5667
5726
|
this.hideSearchBox();
|
|
5668
5727
|
|
|
5669
5728
|
this.searchlinebox.classList.add( 'opened' );
|
|
@@ -5674,8 +5733,8 @@ s
|
|
|
5674
5733
|
input.focus();
|
|
5675
5734
|
}
|
|
5676
5735
|
|
|
5677
|
-
hideSearchLineBox()
|
|
5678
|
-
|
|
5736
|
+
hideSearchLineBox()
|
|
5737
|
+
{
|
|
5679
5738
|
if( this.searchlineboxActive )
|
|
5680
5739
|
{
|
|
5681
5740
|
this.searchlinebox.classList.remove( 'opened' );
|
|
@@ -5683,8 +5742,8 @@ s
|
|
|
5683
5742
|
}
|
|
5684
5743
|
}
|
|
5685
5744
|
|
|
5686
|
-
goToLine( line )
|
|
5687
|
-
|
|
5745
|
+
goToLine( line )
|
|
5746
|
+
{
|
|
5688
5747
|
if( !this._isNumber( line ) )
|
|
5689
5748
|
return;
|
|
5690
5749
|
|
|
@@ -5695,8 +5754,8 @@ s
|
|
|
5695
5754
|
this.cursorToLine( cursor, line - 1, true );
|
|
5696
5755
|
}
|
|
5697
5756
|
|
|
5698
|
-
selectNextOcurrence( cursor )
|
|
5699
|
-
|
|
5757
|
+
selectNextOcurrence( cursor )
|
|
5758
|
+
{
|
|
5700
5759
|
if( !cursor.selection )
|
|
5701
5760
|
return;
|
|
5702
5761
|
|
|
@@ -5711,11 +5770,12 @@ s
|
|
|
5711
5770
|
this._currentOcurrences[ currentKey ] = true;
|
|
5712
5771
|
}
|
|
5713
5772
|
|
|
5714
|
-
this.search( text, false, (col, ln) => {
|
|
5773
|
+
this.search( text, false, ( col, ln ) => {
|
|
5715
5774
|
|
|
5716
5775
|
const key = [ col, ln ].join( '_' );
|
|
5717
5776
|
|
|
5718
|
-
if( this._currentOcurrences[ key ] )
|
|
5777
|
+
if( this._currentOcurrences[ key ] )
|
|
5778
|
+
{
|
|
5719
5779
|
return;
|
|
5720
5780
|
}
|
|
5721
5781
|
|
|
@@ -5726,11 +5786,11 @@ s
|
|
|
5726
5786
|
|
|
5727
5787
|
this._currentOcurrences[ key ] = true;
|
|
5728
5788
|
|
|
5729
|
-
}, true );
|
|
5789
|
+
}, true, false );
|
|
5730
5790
|
}
|
|
5731
5791
|
|
|
5732
|
-
_updateDataInfoPanel( signal, value )
|
|
5733
|
-
|
|
5792
|
+
_updateDataInfoPanel( signal, value )
|
|
5793
|
+
{
|
|
5734
5794
|
if( !this.skipInfo )
|
|
5735
5795
|
{
|
|
5736
5796
|
if( this.cursors.childElementCount > 1 )
|
|
@@ -5742,8 +5802,8 @@ s
|
|
|
5742
5802
|
}
|
|
5743
5803
|
}
|
|
5744
5804
|
|
|
5745
|
-
_setActiveLine( number )
|
|
5746
|
-
|
|
5805
|
+
_setActiveLine( number )
|
|
5806
|
+
{
|
|
5747
5807
|
number = number ?? this.state.activeLine;
|
|
5748
5808
|
|
|
5749
5809
|
const cursor = this.getCurrentCursor();
|
|
@@ -5769,11 +5829,13 @@ s
|
|
|
5769
5829
|
}
|
|
5770
5830
|
}
|
|
5771
5831
|
|
|
5772
|
-
_hideActiveLine()
|
|
5832
|
+
_hideActiveLine()
|
|
5833
|
+
{
|
|
5773
5834
|
this.code.querySelectorAll( '.active-line' ).forEach( e => e.classList.remove( 'active-line' ) );
|
|
5774
5835
|
}
|
|
5775
5836
|
|
|
5776
|
-
_setFontSize( size )
|
|
5837
|
+
_setFontSize( size )
|
|
5838
|
+
{
|
|
5777
5839
|
// Change font size
|
|
5778
5840
|
this.fontSize = size;
|
|
5779
5841
|
const r = document.querySelector( ':root' );
|
|
@@ -5797,20 +5859,24 @@ s
|
|
|
5797
5859
|
LX.emit( "@font-size", this.fontSize );
|
|
5798
5860
|
}
|
|
5799
5861
|
|
|
5800
|
-
_applyFontSizeOffset( offset = 0 )
|
|
5862
|
+
_applyFontSizeOffset( offset = 0 )
|
|
5863
|
+
{
|
|
5801
5864
|
const newFontSize = LX.clamp( this.fontSize + offset, CodeEditor.CODE_MIN_FONT_SIZE, CodeEditor.CODE_MAX_FONT_SIZE );
|
|
5802
5865
|
this._setFontSize( newFontSize );
|
|
5803
5866
|
}
|
|
5804
5867
|
|
|
5805
|
-
_increaseFontSize()
|
|
5868
|
+
_increaseFontSize()
|
|
5869
|
+
{
|
|
5806
5870
|
this._applyFontSizeOffset( 1 );
|
|
5807
5871
|
}
|
|
5808
5872
|
|
|
5809
|
-
_decreaseFontSize()
|
|
5873
|
+
_decreaseFontSize()
|
|
5874
|
+
{
|
|
5810
5875
|
this._applyFontSizeOffset( -1 );
|
|
5811
5876
|
}
|
|
5812
5877
|
|
|
5813
|
-
_clearTmpVariables()
|
|
5878
|
+
_clearTmpVariables()
|
|
5879
|
+
{
|
|
5814
5880
|
delete this._currentLineString;
|
|
5815
5881
|
delete this._currentLineNumber;
|
|
5816
5882
|
delete this._buildingString;
|
|
@@ -5821,7 +5887,8 @@ s
|
|
|
5821
5887
|
delete this._scopeStack;
|
|
5822
5888
|
}
|
|
5823
5889
|
|
|
5824
|
-
async _requestFileAsync( url, dataType, nocache )
|
|
5890
|
+
async _requestFileAsync( url, dataType, nocache )
|
|
5891
|
+
{
|
|
5825
5892
|
return new Promise( (resolve, reject) => {
|
|
5826
5893
|
dataType = dataType ?? "arraybuffer";
|
|
5827
5894
|
const mimeType = dataType === "arraybuffer" ? "application/octet-stream" : undefined;
|
|
@@ -5852,7 +5919,8 @@ s
|
|
|
5852
5919
|
}
|
|
5853
5920
|
}
|
|
5854
5921
|
|
|
5855
|
-
CodeEditor.languages =
|
|
5922
|
+
CodeEditor.languages =
|
|
5923
|
+
{
|
|
5856
5924
|
'Plain Text': { ext: "txt", blockComments: false, singleLineComments: false, numbers: false, icon: "AlignLeft gray" },
|
|
5857
5925
|
'JavaScript': { ext: "js", icon: "Js goldenrod" },
|
|
5858
5926
|
'TypeScript': { ext: "ts", icon: "Ts pipelineblue" },
|
|
@@ -5872,17 +5940,20 @@ CodeEditor.languages = {
|
|
|
5872
5940
|
'PHP': { ext: "php", icon: "Php blueviolet" },
|
|
5873
5941
|
};
|
|
5874
5942
|
|
|
5875
|
-
CodeEditor.nativeTypes =
|
|
5943
|
+
CodeEditor.nativeTypes =
|
|
5944
|
+
{
|
|
5876
5945
|
'C++': ['int', 'float', 'double', 'bool', 'long', 'short', 'char', 'wchar_t', 'void'],
|
|
5877
5946
|
'WGSL': ['bool', 'u32', 'i32', 'f16', 'f32', 'vec2', 'vec3', 'vec4', 'vec2f', 'vec3f', 'vec4f', 'mat2x2f', 'mat3x3f', 'mat4x4f', 'array', 'vec2u', 'vec3u', 'vec4u', 'ptr', 'sampler']
|
|
5878
5947
|
};
|
|
5879
5948
|
|
|
5880
|
-
CodeEditor.declarationKeywords =
|
|
5949
|
+
CodeEditor.declarationKeywords =
|
|
5950
|
+
{
|
|
5881
5951
|
'JavaScript': ['var', 'let', 'const', 'this', 'static', 'class'],
|
|
5882
5952
|
'C++': [...CodeEditor.nativeTypes["C++"], 'const', 'auto', 'class', 'struct', 'namespace', 'enum', 'extern']
|
|
5883
5953
|
};
|
|
5884
5954
|
|
|
5885
|
-
CodeEditor.keywords =
|
|
5955
|
+
CodeEditor.keywords =
|
|
5956
|
+
{
|
|
5886
5957
|
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null', 'typeof', 'debugger', 'abstract',
|
|
5887
5958
|
'arguments', 'extends', 'instanceof', 'Infinity'],
|
|
5888
5959
|
'TypeScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'class', 'extends', 'instanceof', 'Infinity', 'private', 'public', 'protected', 'interface',
|
|
@@ -5911,7 +5982,9 @@ CodeEditor.keywords = {
|
|
|
5911
5982
|
'enum'],
|
|
5912
5983
|
};
|
|
5913
5984
|
|
|
5914
|
-
|
|
5985
|
+
// These ones don't have hightlight, used as suggestions to autocomplete only...
|
|
5986
|
+
CodeEditor.utils =
|
|
5987
|
+
{
|
|
5915
5988
|
'JavaScript': ['querySelector', 'body', 'addEventListener', 'removeEventListener', 'remove', 'sort', 'keys', 'filter', 'isNaN', 'parseFloat', 'parseInt', 'EPSILON', 'isFinite',
|
|
5916
5989
|
'bind', 'prototype', 'length', 'assign', 'entries', 'values', 'concat', 'substring', 'substr', 'splice', 'slice', 'buffer', 'appendChild', 'createElement', 'prompt',
|
|
5917
5990
|
'alert'],
|
|
@@ -5929,7 +6002,8 @@ CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to
|
|
|
5929
6002
|
'lime', 'teal', 'navy', 'transparent', 'currentcolor', 'inherit', 'initial', 'unset', 'revert', 'none', 'auto', 'fit-content', 'min-content', 'max-content']
|
|
5930
6003
|
};
|
|
5931
6004
|
|
|
5932
|
-
CodeEditor.types =
|
|
6005
|
+
CodeEditor.types =
|
|
6006
|
+
{
|
|
5933
6007
|
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent',
|
|
5934
6008
|
'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
|
|
5935
6009
|
'TypeScript': ['arguments', 'constructor', 'null', 'typeof', 'debugger', 'abstract', 'Object', 'string', 'String', 'Function', 'Boolean', 'boolean', 'Error', 'Number', 'number', 'TextEncoder',
|
|
@@ -5943,7 +6017,8 @@ CodeEditor.types = {
|
|
|
5943
6017
|
'PHP': ['Exception', 'DateTime', 'JsonSerializable'],
|
|
5944
6018
|
};
|
|
5945
6019
|
|
|
5946
|
-
CodeEditor.builtIn =
|
|
6020
|
+
CodeEditor.builtIn =
|
|
6021
|
+
{
|
|
5947
6022
|
'JavaScript': ['document', 'console', 'window', 'navigator', 'performance'],
|
|
5948
6023
|
'CSS': ['*', '!important'],
|
|
5949
6024
|
'C++': ['vector', 'list', 'map'],
|
|
@@ -5953,7 +6028,8 @@ CodeEditor.builtIn = {
|
|
|
5953
6028
|
'PHP': ['echo', 'print'],
|
|
5954
6029
|
};
|
|
5955
6030
|
|
|
5956
|
-
CodeEditor.statements =
|
|
6031
|
+
CodeEditor.statements =
|
|
6032
|
+
{
|
|
5957
6033
|
'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await'],
|
|
5958
6034
|
'TypeScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await', 'as'],
|
|
5959
6035
|
'CSS': ['@', 'import'],
|
|
@@ -5969,7 +6045,8 @@ CodeEditor.statements = {
|
|
|
5969
6045
|
'try', 'catch', 'die', 'do', 'exit', 'finally'],
|
|
5970
6046
|
};
|
|
5971
6047
|
|
|
5972
|
-
CodeEditor.symbols =
|
|
6048
|
+
CodeEditor.symbols =
|
|
6049
|
+
{
|
|
5973
6050
|
'JavaScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|
|
5974
6051
|
'TypeScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|
|
5975
6052
|
'C': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '*', '-', '+'],
|