lexgui 0.7.8 → 0.7.10
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 +402 -321
- package/build/extensions/timeline.js +72 -19
- package/build/extensions/videoeditor.js +300 -170
- package/build/lexgui.css +33 -5
- package/build/lexgui.js +164 -96
- package/build/lexgui.min.css +2 -2
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +188 -120
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +43 -1
- package/examples/area-tabs.html +1 -1
- package/examples/asset-view.html +27 -1
- package/examples/timeline.html +23 -13
- package/examples/video-editor.html +152 -3
- package/examples/video-editor2.html +5 -5
- 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
|
|
|
@@ -1290,6 +1299,10 @@ class CodeEditor {
|
|
|
1290
1299
|
this.codeArea.root.style.height = `calc(100% - ${ this._fullVerticalOffset }px)`;
|
|
1291
1300
|
}, 50 );
|
|
1292
1301
|
|
|
1302
|
+
if( options.callback )
|
|
1303
|
+
{
|
|
1304
|
+
options.callback.call( this, this );
|
|
1305
|
+
}
|
|
1293
1306
|
});
|
|
1294
1307
|
|
|
1295
1308
|
window.editor = this;
|
|
@@ -1338,7 +1351,8 @@ class CodeEditor {
|
|
|
1338
1351
|
}
|
|
1339
1352
|
|
|
1340
1353
|
// Clear signals
|
|
1341
|
-
clear()
|
|
1354
|
+
clear()
|
|
1355
|
+
{
|
|
1342
1356
|
console.assert( this.rightStatusPanel && this.leftStatusPanel, "No panels to clear." );
|
|
1343
1357
|
this.rightStatusPanel.clear();
|
|
1344
1358
|
this.leftStatusPanel.clear();
|
|
@@ -1350,8 +1364,8 @@ class CodeEditor {
|
|
|
1350
1364
|
}
|
|
1351
1365
|
|
|
1352
1366
|
// This received key inputs from the entire document...
|
|
1353
|
-
onKeyPressed( e )
|
|
1354
|
-
|
|
1367
|
+
onKeyPressed( e )
|
|
1368
|
+
{
|
|
1355
1369
|
// Toggle visibility of the file explorer
|
|
1356
1370
|
if( e.key == 'b' && e.ctrlKey && this.useFileExplorer )
|
|
1357
1371
|
{
|
|
@@ -1369,13 +1383,14 @@ class CodeEditor {
|
|
|
1369
1383
|
}
|
|
1370
1384
|
}
|
|
1371
1385
|
|
|
1372
|
-
getText( min )
|
|
1386
|
+
getText( min )
|
|
1387
|
+
{
|
|
1373
1388
|
return this.code.lines.join( min ? ' ' : '\n' );
|
|
1374
1389
|
}
|
|
1375
1390
|
|
|
1376
1391
|
// This can be used to empty all text...
|
|
1377
|
-
setText( text = "", lang )
|
|
1378
|
-
|
|
1392
|
+
setText( text = "", lang )
|
|
1393
|
+
{
|
|
1379
1394
|
let newLines = text.split( '\n' );
|
|
1380
1395
|
this.code.lines = [].concat( newLines );
|
|
1381
1396
|
|
|
@@ -1397,8 +1412,8 @@ class CodeEditor {
|
|
|
1397
1412
|
this._processLinesIfNecessary();
|
|
1398
1413
|
}
|
|
1399
1414
|
|
|
1400
|
-
appendText( text, cursor )
|
|
1401
|
-
|
|
1415
|
+
appendText( text, cursor )
|
|
1416
|
+
{
|
|
1402
1417
|
let lidx = cursor.line;
|
|
1403
1418
|
|
|
1404
1419
|
if( cursor.selection )
|
|
@@ -1468,8 +1483,18 @@ class CodeEditor {
|
|
|
1468
1483
|
} );
|
|
1469
1484
|
}
|
|
1470
1485
|
|
|
1471
|
-
|
|
1486
|
+
setCustomSuggestions( suggestions )
|
|
1487
|
+
{
|
|
1488
|
+
if( !suggestions || suggestions.constructor !== Array )
|
|
1489
|
+
{
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
this.customSuggestions = suggestions;
|
|
1494
|
+
}
|
|
1472
1495
|
|
|
1496
|
+
async loadFile( file, options = {} )
|
|
1497
|
+
{
|
|
1473
1498
|
const _innerAddTab = ( text, name, title ) => {
|
|
1474
1499
|
|
|
1475
1500
|
// Remove Carriage Return in some cases and sub tabs using spaces
|
|
@@ -1540,8 +1565,8 @@ class CodeEditor {
|
|
|
1540
1565
|
}
|
|
1541
1566
|
}
|
|
1542
1567
|
|
|
1543
|
-
_addUndoStep( cursor, force, deleteRedo = true )
|
|
1544
|
-
|
|
1568
|
+
_addUndoStep( cursor, force, deleteRedo = true )
|
|
1569
|
+
{
|
|
1545
1570
|
// Only the mainc cursor stores undo steps
|
|
1546
1571
|
if( !cursor.isMain )
|
|
1547
1572
|
return;
|
|
@@ -1582,10 +1607,12 @@ class CodeEditor {
|
|
|
1582
1607
|
} );
|
|
1583
1608
|
}
|
|
1584
1609
|
|
|
1585
|
-
_doUndo( cursor )
|
|
1586
|
-
|
|
1610
|
+
_doUndo( cursor )
|
|
1611
|
+
{
|
|
1587
1612
|
if( !this.code.undoSteps.length )
|
|
1613
|
+
{
|
|
1588
1614
|
return;
|
|
1615
|
+
}
|
|
1589
1616
|
|
|
1590
1617
|
this._addRedoStep( cursor );
|
|
1591
1618
|
|
|
@@ -1612,8 +1639,8 @@ class CodeEditor {
|
|
|
1612
1639
|
this._hideActiveLine();
|
|
1613
1640
|
}
|
|
1614
1641
|
|
|
1615
|
-
_addRedoStep( cursor )
|
|
1616
|
-
|
|
1642
|
+
_addRedoStep( cursor )
|
|
1643
|
+
{
|
|
1617
1644
|
// Only the mainc cursor stores redo steps
|
|
1618
1645
|
if( !cursor.isMain )
|
|
1619
1646
|
{
|
|
@@ -1626,10 +1653,12 @@ class CodeEditor {
|
|
|
1626
1653
|
} );
|
|
1627
1654
|
}
|
|
1628
1655
|
|
|
1629
|
-
_doRedo( cursor )
|
|
1630
|
-
|
|
1656
|
+
_doRedo( cursor )
|
|
1657
|
+
{
|
|
1631
1658
|
if( !this.code.redoSteps.length )
|
|
1659
|
+
{
|
|
1632
1660
|
return;
|
|
1661
|
+
}
|
|
1633
1662
|
|
|
1634
1663
|
this._addUndoStep( cursor, true, false);
|
|
1635
1664
|
|
|
@@ -1656,8 +1685,8 @@ class CodeEditor {
|
|
|
1656
1685
|
}
|
|
1657
1686
|
}
|
|
1658
1687
|
|
|
1659
|
-
_changeLanguage( lang, langExtension, override = false )
|
|
1660
|
-
|
|
1688
|
+
_changeLanguage( lang, langExtension, override = false )
|
|
1689
|
+
{
|
|
1661
1690
|
this.code.language = lang;
|
|
1662
1691
|
this.highlight = lang;
|
|
1663
1692
|
|
|
@@ -1702,8 +1731,8 @@ class CodeEditor {
|
|
|
1702
1731
|
}
|
|
1703
1732
|
}
|
|
1704
1733
|
|
|
1705
|
-
_changeLanguageFromExtension( ext )
|
|
1706
|
-
|
|
1734
|
+
_changeLanguageFromExtension( ext )
|
|
1735
|
+
{
|
|
1707
1736
|
if( !ext )
|
|
1708
1737
|
{
|
|
1709
1738
|
return this._changeLanguage( this.code.language );
|
|
@@ -1733,8 +1762,8 @@ class CodeEditor {
|
|
|
1733
1762
|
this._changeLanguage( 'Plain Text' );
|
|
1734
1763
|
}
|
|
1735
1764
|
|
|
1736
|
-
_createStatusPanel( options )
|
|
1737
|
-
|
|
1765
|
+
_createStatusPanel( options )
|
|
1766
|
+
{
|
|
1738
1767
|
if( this.skipInfo )
|
|
1739
1768
|
{
|
|
1740
1769
|
return;
|
|
@@ -1833,8 +1862,8 @@ class CodeEditor {
|
|
|
1833
1862
|
return panel;
|
|
1834
1863
|
}
|
|
1835
1864
|
|
|
1836
|
-
_getFileIcon( name, extension, lang )
|
|
1837
|
-
|
|
1865
|
+
_getFileIcon( name, extension, lang )
|
|
1866
|
+
{
|
|
1838
1867
|
const isNewTabButton = name ? ( name === '+' ) : false;
|
|
1839
1868
|
if( isNewTabButton )
|
|
1840
1869
|
{
|
|
@@ -1888,8 +1917,8 @@ class CodeEditor {
|
|
|
1888
1917
|
return "AlignLeft gray";
|
|
1889
1918
|
}
|
|
1890
1919
|
|
|
1891
|
-
_onNewTab( e )
|
|
1892
|
-
|
|
1920
|
+
_onNewTab( e )
|
|
1921
|
+
{
|
|
1893
1922
|
this.processFocus( false );
|
|
1894
1923
|
|
|
1895
1924
|
if( this.onNewTab )
|
|
@@ -1906,8 +1935,8 @@ class CodeEditor {
|
|
|
1906
1935
|
new LX.DropdownMenu( e.target, dmOptions, { side: "bottom", align: "start" });
|
|
1907
1936
|
}
|
|
1908
1937
|
|
|
1909
|
-
_onCreateNewFile()
|
|
1910
|
-
|
|
1938
|
+
_onCreateNewFile()
|
|
1939
|
+
{
|
|
1911
1940
|
let options = {};
|
|
1912
1941
|
|
|
1913
1942
|
if( this.onCreateFile )
|
|
@@ -1923,8 +1952,8 @@ class CodeEditor {
|
|
|
1923
1952
|
this.addTab( name, true, name, { indexOffset: options.indexOffset, language: options.language ?? "JavaScript" } );
|
|
1924
1953
|
}
|
|
1925
1954
|
|
|
1926
|
-
_onSelectTab( isNewTabButton, event, name )
|
|
1927
|
-
|
|
1955
|
+
_onSelectTab( isNewTabButton, event, name )
|
|
1956
|
+
{
|
|
1928
1957
|
if( this.disableEdition )
|
|
1929
1958
|
{
|
|
1930
1959
|
return;
|
|
@@ -1973,8 +2002,8 @@ class CodeEditor {
|
|
|
1973
2002
|
}
|
|
1974
2003
|
}
|
|
1975
2004
|
|
|
1976
|
-
_onContextMenuTab( isNewTabButton, event, name, )
|
|
1977
|
-
|
|
2005
|
+
_onContextMenuTab( isNewTabButton, event, name, )
|
|
2006
|
+
{
|
|
1978
2007
|
if( isNewTabButton )
|
|
1979
2008
|
{
|
|
1980
2009
|
return;
|
|
@@ -2003,8 +2032,8 @@ class CodeEditor {
|
|
|
2003
2032
|
], { side: "bottom", align: "start", event });
|
|
2004
2033
|
}
|
|
2005
2034
|
|
|
2006
|
-
addTab( name, selected, title, options = {} )
|
|
2007
|
-
|
|
2035
|
+
addTab( name, selected, title, options = {} )
|
|
2036
|
+
{
|
|
2008
2037
|
// If already loaded, set new name...
|
|
2009
2038
|
const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
|
|
2010
2039
|
const noRepeatName = key.replace( /[_\d+]/g, '');
|
|
@@ -2120,8 +2149,8 @@ class CodeEditor {
|
|
|
2120
2149
|
return name;
|
|
2121
2150
|
}
|
|
2122
2151
|
|
|
2123
|
-
loadCode( name )
|
|
2124
|
-
|
|
2152
|
+
loadCode( name )
|
|
2153
|
+
{
|
|
2125
2154
|
// Hide all others
|
|
2126
2155
|
this.codeSizer.querySelectorAll( ".code" ).forEach( c => c.classList.add( "hidden" ) );
|
|
2127
2156
|
|
|
@@ -2179,8 +2208,8 @@ class CodeEditor {
|
|
|
2179
2208
|
this._updateDataInfoPanel( "@tab-name", code.tabName );
|
|
2180
2209
|
}
|
|
2181
2210
|
|
|
2182
|
-
loadTab( name )
|
|
2183
|
-
|
|
2211
|
+
loadTab( name )
|
|
2212
|
+
{
|
|
2184
2213
|
// Already open...
|
|
2185
2214
|
if( this.openedTabs[ name ] )
|
|
2186
2215
|
{
|
|
@@ -2245,8 +2274,8 @@ class CodeEditor {
|
|
|
2245
2274
|
this._updateDataInfoPanel( "@tab-name", code.tabName );
|
|
2246
2275
|
}
|
|
2247
2276
|
|
|
2248
|
-
closeTab( name, eraseAll )
|
|
2249
|
-
|
|
2277
|
+
closeTab( name, eraseAll )
|
|
2278
|
+
{
|
|
2250
2279
|
if( !this.allowClosingTabs )
|
|
2251
2280
|
{
|
|
2252
2281
|
return;
|
|
@@ -2262,12 +2291,13 @@ class CodeEditor {
|
|
|
2262
2291
|
}
|
|
2263
2292
|
}
|
|
2264
2293
|
|
|
2265
|
-
getSelectedTabName()
|
|
2294
|
+
getSelectedTabName()
|
|
2295
|
+
{
|
|
2266
2296
|
return this.tabs.selected;
|
|
2267
2297
|
}
|
|
2268
2298
|
|
|
2269
|
-
loadTabFromFile()
|
|
2270
|
-
|
|
2299
|
+
loadTabFromFile()
|
|
2300
|
+
{
|
|
2271
2301
|
const input = document.createElement( 'input' );
|
|
2272
2302
|
input.type = 'file';
|
|
2273
2303
|
document.body.appendChild( input );
|
|
@@ -2281,8 +2311,8 @@ class CodeEditor {
|
|
|
2281
2311
|
});
|
|
2282
2312
|
}
|
|
2283
2313
|
|
|
2284
|
-
processFocus( active )
|
|
2285
|
-
|
|
2314
|
+
processFocus( active )
|
|
2315
|
+
{
|
|
2286
2316
|
if( active )
|
|
2287
2317
|
{
|
|
2288
2318
|
this.restartBlink();
|
|
@@ -2294,8 +2324,8 @@ class CodeEditor {
|
|
|
2294
2324
|
}
|
|
2295
2325
|
}
|
|
2296
2326
|
|
|
2297
|
-
processMouse( e )
|
|
2298
|
-
|
|
2327
|
+
processMouse( e )
|
|
2328
|
+
{
|
|
2299
2329
|
if( !e.target.classList.contains('code') && !e.target.classList.contains('lexcodearea') ) return;
|
|
2300
2330
|
if( !this.code ) return;
|
|
2301
2331
|
|
|
@@ -2435,8 +2465,8 @@ class CodeEditor {
|
|
|
2435
2465
|
}
|
|
2436
2466
|
}
|
|
2437
2467
|
|
|
2438
|
-
_onMouseUp( e )
|
|
2439
|
-
|
|
2468
|
+
_onMouseUp( e )
|
|
2469
|
+
{
|
|
2440
2470
|
if( ( LX.getTime() - this.lastMouseDown ) < 120 )
|
|
2441
2471
|
{
|
|
2442
2472
|
this.state.selectingText = false;
|
|
@@ -2453,8 +2483,8 @@ class CodeEditor {
|
|
|
2453
2483
|
delete this._lastSelectionKeyDir;
|
|
2454
2484
|
}
|
|
2455
2485
|
|
|
2456
|
-
processClick( e )
|
|
2457
|
-
|
|
2486
|
+
processClick( e )
|
|
2487
|
+
{
|
|
2458
2488
|
var cursor = this.getCurrentCursor();
|
|
2459
2489
|
var code_rect = this.codeScroller.getBoundingClientRect();
|
|
2460
2490
|
var position = [( e.clientX - code_rect.x ) + this.getScrollLeft(), (e.clientY - code_rect.y) + this.getScrollTop()];
|
|
@@ -2485,8 +2515,8 @@ class CodeEditor {
|
|
|
2485
2515
|
this.hideAutoCompleteBox();
|
|
2486
2516
|
}
|
|
2487
2517
|
|
|
2488
|
-
updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2489
|
-
|
|
2518
|
+
updateSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2519
|
+
{
|
|
2490
2520
|
for( let cursor of this.cursors.children )
|
|
2491
2521
|
{
|
|
2492
2522
|
if( !cursor.selection )
|
|
@@ -2498,16 +2528,16 @@ class CodeEditor {
|
|
|
2498
2528
|
}
|
|
2499
2529
|
}
|
|
2500
2530
|
|
|
2501
|
-
processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2502
|
-
|
|
2531
|
+
processSelections( e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2532
|
+
{
|
|
2503
2533
|
for( let cursor of this.cursors.children )
|
|
2504
2534
|
{
|
|
2505
2535
|
this._processSelection( cursor, e, keepRange, flags );
|
|
2506
2536
|
}
|
|
2507
2537
|
}
|
|
2508
2538
|
|
|
2509
|
-
_processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2510
|
-
|
|
2539
|
+
_processSelection( cursor, e, keepRange, flags = CodeEditor.SELECTION_X_Y )
|
|
2540
|
+
{
|
|
2511
2541
|
const isMouseEvent = e && ( e.constructor == MouseEvent );
|
|
2512
2542
|
|
|
2513
2543
|
if( isMouseEvent )
|
|
@@ -2668,8 +2698,8 @@ class CodeEditor {
|
|
|
2668
2698
|
}
|
|
2669
2699
|
}
|
|
2670
2700
|
|
|
2671
|
-
async processKey( e )
|
|
2672
|
-
|
|
2701
|
+
async processKey( e )
|
|
2702
|
+
{
|
|
2673
2703
|
const numCursors = this.cursors.childElementCount;
|
|
2674
2704
|
|
|
2675
2705
|
if( !this.code || e.srcElement.constructor != HTMLDivElement )
|
|
@@ -2737,8 +2767,8 @@ class CodeEditor {
|
|
|
2737
2767
|
delete this._lastProcessedCursorIndex;
|
|
2738
2768
|
}
|
|
2739
2769
|
|
|
2740
|
-
async processKeyAtTargetCursor( e, key, targetIdx )
|
|
2741
|
-
|
|
2770
|
+
async processKeyAtTargetCursor( e, key, targetIdx )
|
|
2771
|
+
{
|
|
2742
2772
|
let cursor = this.cursors.children[ targetIdx ];
|
|
2743
2773
|
|
|
2744
2774
|
// We could delete secondary cursor while iterating..
|
|
@@ -2749,13 +2779,14 @@ class CodeEditor {
|
|
|
2749
2779
|
this._processGlobalKeys( e, key );
|
|
2750
2780
|
}
|
|
2751
2781
|
|
|
2752
|
-
_processGlobalKeys( e, key )
|
|
2753
|
-
|
|
2782
|
+
_processGlobalKeys( e, key )
|
|
2783
|
+
{
|
|
2754
2784
|
let cursor = this.getCurrentCursor();
|
|
2755
2785
|
|
|
2756
2786
|
if( e.ctrlKey || e.metaKey )
|
|
2757
2787
|
{
|
|
2758
|
-
switch( key.toLowerCase() )
|
|
2788
|
+
switch( key.toLowerCase() )
|
|
2789
|
+
{
|
|
2759
2790
|
case 'a': // select all
|
|
2760
2791
|
e.preventDefault();
|
|
2761
2792
|
this.selectAll();
|
|
@@ -2831,8 +2862,8 @@ class CodeEditor {
|
|
|
2831
2862
|
return false;
|
|
2832
2863
|
}
|
|
2833
2864
|
|
|
2834
|
-
async _processKeyAtCursor( e, key, cursor )
|
|
2835
|
-
|
|
2865
|
+
async _processKeyAtCursor( e, key, cursor )
|
|
2866
|
+
{
|
|
2836
2867
|
const skipUndo = e.detail.skipUndo ?? false;
|
|
2837
2868
|
|
|
2838
2869
|
// keys with length > 1 are probably special keys
|
|
@@ -2994,8 +3025,8 @@ class CodeEditor {
|
|
|
2994
3025
|
}
|
|
2995
3026
|
}
|
|
2996
3027
|
|
|
2997
|
-
async _pasteContent( cursor )
|
|
2998
|
-
|
|
3028
|
+
async _pasteContent( cursor )
|
|
3029
|
+
{
|
|
2999
3030
|
const mustDetectLanguage = ( !this.getText().length );
|
|
3000
3031
|
|
|
3001
3032
|
let text = await navigator.clipboard.readText();
|
|
@@ -3025,8 +3056,8 @@ class CodeEditor {
|
|
|
3025
3056
|
}
|
|
3026
3057
|
}
|
|
3027
3058
|
|
|
3028
|
-
async _copyContent( cursor )
|
|
3029
|
-
|
|
3059
|
+
async _copyContent( cursor )
|
|
3060
|
+
{
|
|
3030
3061
|
let textToCopy = "";
|
|
3031
3062
|
|
|
3032
3063
|
if( !cursor.selection )
|
|
@@ -3060,8 +3091,8 @@ class CodeEditor {
|
|
|
3060
3091
|
// .then(() => console.log("Successfully copied"), (err) => console.error("Error"));
|
|
3061
3092
|
}
|
|
3062
3093
|
|
|
3063
|
-
async _cutContent( cursor )
|
|
3064
|
-
|
|
3094
|
+
async _cutContent( cursor )
|
|
3095
|
+
{
|
|
3065
3096
|
let lidx = cursor.line;
|
|
3066
3097
|
let textToCut = "";
|
|
3067
3098
|
|
|
@@ -3107,8 +3138,8 @@ class CodeEditor {
|
|
|
3107
3138
|
// .then(() => console.log("Successfully cut"), (err) => console.error("Error"));
|
|
3108
3139
|
}
|
|
3109
3140
|
|
|
3110
|
-
_duplicateLine( lidx, cursor )
|
|
3111
|
-
|
|
3141
|
+
_duplicateLine( lidx, cursor )
|
|
3142
|
+
{
|
|
3112
3143
|
this.endSelection();
|
|
3113
3144
|
this._addUndoStep( cursor, true );
|
|
3114
3145
|
this.code.lines.splice( lidx, 0, this.code.lines[ lidx ] );
|
|
@@ -3117,8 +3148,8 @@ class CodeEditor {
|
|
|
3117
3148
|
this.hideAutoCompleteBox();
|
|
3118
3149
|
}
|
|
3119
3150
|
|
|
3120
|
-
_commentLines( cursor, useCommentBlock )
|
|
3121
|
-
|
|
3151
|
+
_commentLines( cursor, useCommentBlock )
|
|
3152
|
+
{
|
|
3122
3153
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3123
3154
|
|
|
3124
3155
|
this.state.keyChain = null;
|
|
@@ -3195,8 +3226,8 @@ class CodeEditor {
|
|
|
3195
3226
|
this._hideActiveLine();
|
|
3196
3227
|
}
|
|
3197
3228
|
|
|
3198
|
-
_commentLine( cursor, line, minNonspaceIdx, updateCursor = true )
|
|
3199
|
-
|
|
3229
|
+
_commentLine( cursor, line, minNonspaceIdx, updateCursor = true )
|
|
3230
|
+
{
|
|
3200
3231
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3201
3232
|
if( !( lang.singleLineComments ?? true ) )
|
|
3202
3233
|
return;
|
|
@@ -3225,8 +3256,8 @@ class CodeEditor {
|
|
|
3225
3256
|
}
|
|
3226
3257
|
}
|
|
3227
3258
|
|
|
3228
|
-
_uncommentLines( cursor )
|
|
3229
|
-
|
|
3259
|
+
_uncommentLines( cursor )
|
|
3260
|
+
{
|
|
3230
3261
|
this.state.keyChain = null;
|
|
3231
3262
|
|
|
3232
3263
|
if( cursor.selection )
|
|
@@ -3252,8 +3283,8 @@ class CodeEditor {
|
|
|
3252
3283
|
this._hideActiveLine();
|
|
3253
3284
|
}
|
|
3254
3285
|
|
|
3255
|
-
_uncommentLine( cursor, line )
|
|
3256
|
-
|
|
3286
|
+
_uncommentLine( cursor, line )
|
|
3287
|
+
{
|
|
3257
3288
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3258
3289
|
|
|
3259
3290
|
if( !( lang.singleLineComments ?? true ))
|
|
@@ -3274,8 +3305,8 @@ class CodeEditor {
|
|
|
3274
3305
|
}
|
|
3275
3306
|
}
|
|
3276
3307
|
|
|
3277
|
-
action( key, deleteSelection, fn, eventSkipDelete )
|
|
3278
|
-
|
|
3308
|
+
action( key, deleteSelection, fn, eventSkipDelete )
|
|
3309
|
+
{
|
|
3279
3310
|
this.actions[ key ] = {
|
|
3280
3311
|
"key": key,
|
|
3281
3312
|
"callback": fn,
|
|
@@ -3284,13 +3315,14 @@ class CodeEditor {
|
|
|
3284
3315
|
};
|
|
3285
3316
|
}
|
|
3286
3317
|
|
|
3287
|
-
_actionMustDelete( cursor, action, e )
|
|
3318
|
+
_actionMustDelete( cursor, action, e )
|
|
3319
|
+
{
|
|
3288
3320
|
return cursor.selection && action.deleteSelection &&
|
|
3289
3321
|
( action.eventSkipDelete ? !e[ action.eventSkipDelete ] : true );
|
|
3290
3322
|
}
|
|
3291
3323
|
|
|
3292
|
-
scanWordSuggestions()
|
|
3293
|
-
|
|
3324
|
+
scanWordSuggestions()
|
|
3325
|
+
{
|
|
3294
3326
|
this.code.tokens = {};
|
|
3295
3327
|
|
|
3296
3328
|
for( let i = 0; i < this.code.lines.length; ++i )
|
|
@@ -3301,16 +3333,19 @@ class CodeEditor {
|
|
|
3301
3333
|
}
|
|
3302
3334
|
}
|
|
3303
3335
|
|
|
3304
|
-
toLocalLine( line )
|
|
3336
|
+
toLocalLine( line )
|
|
3337
|
+
{
|
|
3305
3338
|
const d = Math.max( this.firstLineInViewport - this.lineScrollMargin.x, 0 );
|
|
3306
3339
|
return Math.min( Math.max( line - d, 0 ), this.code.lines.length - 1 );
|
|
3307
3340
|
}
|
|
3308
3341
|
|
|
3309
|
-
getMaxLineLength()
|
|
3342
|
+
getMaxLineLength()
|
|
3343
|
+
{
|
|
3310
3344
|
return Math.max(...this.code.lines.map( v => v.length ));
|
|
3311
3345
|
}
|
|
3312
3346
|
|
|
3313
|
-
_processLinesIfNecessary()
|
|
3347
|
+
_processLinesIfNecessary()
|
|
3348
|
+
{
|
|
3314
3349
|
if( this.mustProcessLines )
|
|
3315
3350
|
{
|
|
3316
3351
|
this.mustProcessLines = false;
|
|
@@ -3318,8 +3353,8 @@ class CodeEditor {
|
|
|
3318
3353
|
}
|
|
3319
3354
|
}
|
|
3320
3355
|
|
|
3321
|
-
processLines( mode )
|
|
3322
|
-
|
|
3356
|
+
processLines( mode )
|
|
3357
|
+
{
|
|
3323
3358
|
if( !this.code )
|
|
3324
3359
|
{
|
|
3325
3360
|
return;
|
|
@@ -3373,8 +3408,8 @@ class CodeEditor {
|
|
|
3373
3408
|
this.resize();
|
|
3374
3409
|
}
|
|
3375
3410
|
|
|
3376
|
-
processLine( lineNumber, force, skipPropagation )
|
|
3377
|
-
|
|
3411
|
+
processLine( lineNumber, force, skipPropagation )
|
|
3412
|
+
{
|
|
3378
3413
|
if( this._scopeStack )
|
|
3379
3414
|
{
|
|
3380
3415
|
this.code.lineScopes[ lineNumber ] = [ ...this._scopeStack ];
|
|
@@ -3596,14 +3631,15 @@ class CodeEditor {
|
|
|
3596
3631
|
return this._updateLine( force, lineNumber, lineInnerHtml, skipPropagation, symbols, tokensToEvaluate );
|
|
3597
3632
|
}
|
|
3598
3633
|
|
|
3599
|
-
_getLineSignatureFromTokens( tokens )
|
|
3634
|
+
_getLineSignatureFromTokens( tokens )
|
|
3635
|
+
{
|
|
3600
3636
|
const structuralChars = new Set( [ '{', '}'] );
|
|
3601
3637
|
const sign = tokens.filter( t => structuralChars.has( t ) );
|
|
3602
3638
|
return sign.join( "_" );
|
|
3603
3639
|
}
|
|
3604
3640
|
|
|
3605
|
-
_updateBlockComments( section, lineNumber, tokens )
|
|
3606
|
-
|
|
3641
|
+
_updateBlockComments( section, lineNumber, tokens )
|
|
3642
|
+
{
|
|
3607
3643
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3608
3644
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
3609
3645
|
const lineOpensBlock = ( section[ 0 ].x === lineNumber );
|
|
@@ -3682,8 +3718,8 @@ class CodeEditor {
|
|
|
3682
3718
|
}
|
|
3683
3719
|
}
|
|
3684
3720
|
|
|
3685
|
-
_processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation )
|
|
3686
|
-
|
|
3721
|
+
_processExtraLineIfNecessary( lineNumber, tokens, oldSymbols, skipPropagation )
|
|
3722
|
+
{
|
|
3687
3723
|
if( !this._scopeStack )
|
|
3688
3724
|
{
|
|
3689
3725
|
console.warn( "CodeEditor: No scope available" );
|
|
@@ -3750,8 +3786,8 @@ class CodeEditor {
|
|
|
3750
3786
|
}
|
|
3751
3787
|
}
|
|
3752
3788
|
|
|
3753
|
-
_updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] )
|
|
3754
|
-
|
|
3789
|
+
_updateLine( force, lineNumber, html, skipPropagation, symbols = [], tokens = [] )
|
|
3790
|
+
{
|
|
3755
3791
|
const gutterLineHtml = `<span class='line-gutter'>${ lineNumber + 1 }</span>`;
|
|
3756
3792
|
const oldSymbols = this._updateLineSymbols( lineNumber, symbols );
|
|
3757
3793
|
const lineScope = CodeEditor.debugScopes && this.code.lineScopes[ lineNumber ] ? this.code.lineScopes[ lineNumber ].map( s => `${ s.type }` ).join( ", " ) : "";
|
|
@@ -3809,8 +3845,8 @@ class CodeEditor {
|
|
|
3809
3845
|
/**
|
|
3810
3846
|
* Parses a single line of code and extract declared symbols
|
|
3811
3847
|
*/
|
|
3812
|
-
_parseLineForSymbols( lineNumber, lineString, tokens, pushedScope )
|
|
3813
|
-
|
|
3848
|
+
_parseLineForSymbols( lineNumber, lineString, tokens, pushedScope )
|
|
3849
|
+
{
|
|
3814
3850
|
const scope = this._scopeStack.at( pushedScope ? -2 : -1 );
|
|
3815
3851
|
|
|
3816
3852
|
if( !scope || this._inBlockCommentSection( lineNumber ) )
|
|
@@ -3946,8 +3982,8 @@ class CodeEditor {
|
|
|
3946
3982
|
* - Removes old symbols from that line
|
|
3947
3983
|
* - Inserts the new symbols
|
|
3948
3984
|
*/
|
|
3949
|
-
_updateLineSymbols( lineNumber, newSymbols )
|
|
3950
|
-
|
|
3985
|
+
_updateLineSymbols( lineNumber, newSymbols )
|
|
3986
|
+
{
|
|
3951
3987
|
this.code.lineSymbols[ lineNumber ] = this.code.lineSymbols[ lineNumber ] ?? [];
|
|
3952
3988
|
const oldSymbols = LX.deepCopy( this.code.lineSymbols[ lineNumber ] );
|
|
3953
3989
|
|
|
@@ -3986,8 +4022,8 @@ class CodeEditor {
|
|
|
3986
4022
|
return oldSymbols;
|
|
3987
4023
|
}
|
|
3988
4024
|
|
|
3989
|
-
_lineHasComment( lineString )
|
|
3990
|
-
|
|
4025
|
+
_lineHasComment( lineString )
|
|
4026
|
+
{
|
|
3991
4027
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
3992
4028
|
|
|
3993
4029
|
if( !(lang.singleLineComments ?? true) )
|
|
@@ -4012,8 +4048,8 @@ class CodeEditor {
|
|
|
4012
4048
|
}
|
|
4013
4049
|
}
|
|
4014
4050
|
|
|
4015
|
-
_getTokensFromLine( lineString, skipNonWords )
|
|
4016
|
-
|
|
4051
|
+
_getTokensFromLine( lineString, skipNonWords )
|
|
4052
|
+
{
|
|
4017
4053
|
if( !lineString || !lineString.length )
|
|
4018
4054
|
{
|
|
4019
4055
|
return [];
|
|
@@ -4072,8 +4108,8 @@ class CodeEditor {
|
|
|
4072
4108
|
return this._processTokens( tokensToEvaluate );
|
|
4073
4109
|
}
|
|
4074
4110
|
|
|
4075
|
-
_processTokens( tokens, offset = 0 )
|
|
4076
|
-
|
|
4111
|
+
_processTokens( tokens, offset = 0 )
|
|
4112
|
+
{
|
|
4077
4113
|
if( this.highlight == 'C++' || this.highlight == 'CSS' )
|
|
4078
4114
|
{
|
|
4079
4115
|
var idx = tokens.slice( offset ).findIndex( ( value, index ) => this._isNumber( value ) );
|
|
@@ -4142,8 +4178,8 @@ class CodeEditor {
|
|
|
4142
4178
|
return tokens;
|
|
4143
4179
|
}
|
|
4144
4180
|
|
|
4145
|
-
_mustHightlightWord( token, wordCategory, lang )
|
|
4146
|
-
|
|
4181
|
+
_mustHightlightWord( token, wordCategory, lang )
|
|
4182
|
+
{
|
|
4147
4183
|
if( !lang )
|
|
4148
4184
|
{
|
|
4149
4185
|
lang = CodeEditor.languages[ this.highlight ];
|
|
@@ -4159,8 +4195,8 @@ class CodeEditor {
|
|
|
4159
4195
|
return wordCategory[ this.highlight ] && wordCategory[ this.highlight ].has( t );
|
|
4160
4196
|
}
|
|
4161
4197
|
|
|
4162
|
-
_getTokenHighlighting( ctx, highlight )
|
|
4163
|
-
|
|
4198
|
+
_getTokenHighlighting( ctx, highlight )
|
|
4199
|
+
{
|
|
4164
4200
|
const rules = [ ...HighlightRules.common, ...( HighlightRules[ highlight ] || [] ), ...HighlightRules.post_common ];
|
|
4165
4201
|
|
|
4166
4202
|
for( const rule of rules )
|
|
@@ -4178,8 +4214,8 @@ class CodeEditor {
|
|
|
4178
4214
|
return null;
|
|
4179
4215
|
}
|
|
4180
4216
|
|
|
4181
|
-
_evaluateToken( ctxData )
|
|
4182
|
-
|
|
4217
|
+
_evaluateToken( ctxData )
|
|
4218
|
+
{
|
|
4183
4219
|
let { token, prev, next, tokenIndex, isFirstToken, isLastToken } = ctxData;
|
|
4184
4220
|
|
|
4185
4221
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
@@ -4276,8 +4312,8 @@ class CodeEditor {
|
|
|
4276
4312
|
return `<span class="${ highlight } ${ tokenClass }">${ token }</span>`;
|
|
4277
4313
|
}
|
|
4278
4314
|
|
|
4279
|
-
_appendStringToken( token )
|
|
4280
|
-
|
|
4315
|
+
_appendStringToken( token )
|
|
4316
|
+
{
|
|
4281
4317
|
if( !this._pendingString )
|
|
4282
4318
|
{
|
|
4283
4319
|
this._pendingString = "";
|
|
@@ -4288,14 +4324,15 @@ class CodeEditor {
|
|
|
4288
4324
|
return true;
|
|
4289
4325
|
}
|
|
4290
4326
|
|
|
4291
|
-
_getCurrentString()
|
|
4327
|
+
_getCurrentString()
|
|
4328
|
+
{
|
|
4292
4329
|
const chars = this._pendingString;
|
|
4293
4330
|
delete this._pendingString;
|
|
4294
4331
|
return chars;
|
|
4295
4332
|
}
|
|
4296
4333
|
|
|
4297
|
-
_enclosedByTokens( token, tokenIndex, tagStart, tagEnd )
|
|
4298
|
-
|
|
4334
|
+
_enclosedByTokens( token, tokenIndex, tagStart, tagEnd )
|
|
4335
|
+
{
|
|
4299
4336
|
const tokenStartIndex = this._currentTokenPositions[ tokenIndex ];
|
|
4300
4337
|
const tagStartIndex = indexOfFrom( this._currentLineString, tagStart, tokenStartIndex, true );
|
|
4301
4338
|
if( tagStartIndex < 0 ) // Not found..
|
|
@@ -4313,8 +4350,8 @@ class CodeEditor {
|
|
|
4313
4350
|
}
|
|
4314
4351
|
}
|
|
4315
4352
|
|
|
4316
|
-
_inBlockCommentSection( lineNumber, tokenPosition, tokenLength )
|
|
4317
|
-
|
|
4353
|
+
_inBlockCommentSection( lineNumber, tokenPosition, tokenLength )
|
|
4354
|
+
{
|
|
4318
4355
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
4319
4356
|
const blockCommentsTokens = lang.blockCommentsTokens ?? this.defaultBlockCommentTokens;
|
|
4320
4357
|
|
|
@@ -4341,8 +4378,8 @@ class CodeEditor {
|
|
|
4341
4378
|
}
|
|
4342
4379
|
}
|
|
4343
4380
|
|
|
4344
|
-
_isKeyword( ctxData )
|
|
4345
|
-
|
|
4381
|
+
_isKeyword( ctxData )
|
|
4382
|
+
{
|
|
4346
4383
|
const { token, tokenIndex, tokens, lang } = ctxData;
|
|
4347
4384
|
|
|
4348
4385
|
let isKwd = this._mustHightlightWord( token, CodeEditor.keywords ) || this.highlight == 'XML';
|
|
@@ -4373,8 +4410,8 @@ class CodeEditor {
|
|
|
4373
4410
|
return isKwd;
|
|
4374
4411
|
}
|
|
4375
4412
|
|
|
4376
|
-
_isNumber( token )
|
|
4377
|
-
|
|
4413
|
+
_isNumber( token )
|
|
4414
|
+
{
|
|
4378
4415
|
const lang = CodeEditor.languages[ this.highlight ];
|
|
4379
4416
|
if( !( lang.numbers ?? true ) )
|
|
4380
4417
|
{
|
|
@@ -4412,8 +4449,8 @@ class CodeEditor {
|
|
|
4412
4449
|
return token.length && token != ' ' && !Number.isNaN( +token );
|
|
4413
4450
|
}
|
|
4414
4451
|
|
|
4415
|
-
_encloseSelectedWordWithKey( key, lidx, cursor )
|
|
4416
|
-
|
|
4452
|
+
_encloseSelectedWordWithKey( key, lidx, cursor )
|
|
4453
|
+
{
|
|
4417
4454
|
if( !cursor.selection || ( cursor.selection.fromY != cursor.selection.toY ) )
|
|
4418
4455
|
{
|
|
4419
4456
|
return false;
|
|
@@ -4460,8 +4497,8 @@ class CodeEditor {
|
|
|
4460
4497
|
return true;
|
|
4461
4498
|
}
|
|
4462
4499
|
|
|
4463
|
-
_detectLanguage( text )
|
|
4464
|
-
|
|
4500
|
+
_detectLanguage( text )
|
|
4501
|
+
{
|
|
4465
4502
|
const tokenSet = new Set( this._getTokensFromLine( text, true ) );
|
|
4466
4503
|
const scores = {};
|
|
4467
4504
|
|
|
@@ -4500,8 +4537,8 @@ class CodeEditor {
|
|
|
4500
4537
|
return sorted[0][1] > 0 ? sorted[0][0] : undefined;
|
|
4501
4538
|
}
|
|
4502
4539
|
|
|
4503
|
-
lineUp( cursor, resetLeft )
|
|
4504
|
-
|
|
4540
|
+
lineUp( cursor, resetLeft )
|
|
4541
|
+
{
|
|
4505
4542
|
if( this.code.lines[ cursor.line - 1 ] == undefined )
|
|
4506
4543
|
return false;
|
|
4507
4544
|
|
|
@@ -4512,8 +4549,8 @@ class CodeEditor {
|
|
|
4512
4549
|
return true;
|
|
4513
4550
|
}
|
|
4514
4551
|
|
|
4515
|
-
lineDown( cursor, resetLeft )
|
|
4516
|
-
|
|
4552
|
+
lineDown( cursor, resetLeft )
|
|
4553
|
+
{
|
|
4517
4554
|
if( this.code.lines[ cursor.line + 1 ] == undefined )
|
|
4518
4555
|
return false;
|
|
4519
4556
|
|
|
@@ -4524,8 +4561,8 @@ class CodeEditor {
|
|
|
4524
4561
|
return true;
|
|
4525
4562
|
}
|
|
4526
4563
|
|
|
4527
|
-
restartBlink()
|
|
4528
|
-
|
|
4564
|
+
restartBlink()
|
|
4565
|
+
{
|
|
4529
4566
|
if( !this.code ) return;
|
|
4530
4567
|
|
|
4531
4568
|
clearInterval( this.blinker );
|
|
@@ -4539,8 +4576,8 @@ class CodeEditor {
|
|
|
4539
4576
|
this.cursors.classList.remove( 'show' );
|
|
4540
4577
|
}
|
|
4541
4578
|
|
|
4542
|
-
startSelection( cursor )
|
|
4543
|
-
|
|
4579
|
+
startSelection( cursor )
|
|
4580
|
+
{
|
|
4544
4581
|
// Show elements
|
|
4545
4582
|
let selectionContainer = document.createElement( 'div' );
|
|
4546
4583
|
selectionContainer.className = 'selections';
|
|
@@ -4553,8 +4590,8 @@ class CodeEditor {
|
|
|
4553
4590
|
cursor.selection = new CodeSelection( this, cursor );
|
|
4554
4591
|
}
|
|
4555
4592
|
|
|
4556
|
-
deleteSelection( cursor )
|
|
4557
|
-
|
|
4593
|
+
deleteSelection( cursor )
|
|
4594
|
+
{
|
|
4558
4595
|
// I think it's not necessary but...
|
|
4559
4596
|
if( this.disableEdition )
|
|
4560
4597
|
{
|
|
@@ -4586,8 +4623,8 @@ class CodeEditor {
|
|
|
4586
4623
|
this.processLines();
|
|
4587
4624
|
}
|
|
4588
4625
|
|
|
4589
|
-
endSelection( cursor )
|
|
4590
|
-
|
|
4626
|
+
endSelection( cursor )
|
|
4627
|
+
{
|
|
4591
4628
|
delete this._tripleClickSelection;
|
|
4592
4629
|
delete this._lastSelectionKeyDir;
|
|
4593
4630
|
delete this._currentOcurrences;
|
|
@@ -4610,7 +4647,9 @@ class CodeEditor {
|
|
|
4610
4647
|
}
|
|
4611
4648
|
}
|
|
4612
4649
|
|
|
4613
|
-
selectAll()
|
|
4650
|
+
selectAll()
|
|
4651
|
+
{
|
|
4652
|
+
this.endSelection();
|
|
4614
4653
|
|
|
4615
4654
|
// Use main cursor
|
|
4616
4655
|
this._removeSecondaryCursors();
|
|
@@ -4632,8 +4671,8 @@ class CodeEditor {
|
|
|
4632
4671
|
this.hideAutoCompleteBox();
|
|
4633
4672
|
}
|
|
4634
4673
|
|
|
4635
|
-
cursorToRight( key, cursor )
|
|
4636
|
-
|
|
4674
|
+
cursorToRight( key, cursor )
|
|
4675
|
+
{
|
|
4637
4676
|
if( !key ) return;
|
|
4638
4677
|
|
|
4639
4678
|
cursor._left += this.charWidth;
|
|
@@ -4651,8 +4690,8 @@ class CodeEditor {
|
|
|
4651
4690
|
}
|
|
4652
4691
|
}
|
|
4653
4692
|
|
|
4654
|
-
cursorToLeft( key, cursor )
|
|
4655
|
-
|
|
4693
|
+
cursorToLeft( key, cursor )
|
|
4694
|
+
{
|
|
4656
4695
|
if( !key ) return;
|
|
4657
4696
|
|
|
4658
4697
|
cursor._left -= this.charWidth;
|
|
@@ -4672,8 +4711,8 @@ class CodeEditor {
|
|
|
4672
4711
|
}
|
|
4673
4712
|
}
|
|
4674
4713
|
|
|
4675
|
-
cursorToTop( cursor, resetLeft = false )
|
|
4676
|
-
|
|
4714
|
+
cursorToTop( cursor, resetLeft = false )
|
|
4715
|
+
{
|
|
4677
4716
|
cursor._top -= this.lineHeight;
|
|
4678
4717
|
cursor._top = Math.max( cursor._top, 0 );
|
|
4679
4718
|
cursor.style.top = `calc(${ cursor._top }px)`;
|
|
@@ -4692,8 +4731,8 @@ class CodeEditor {
|
|
|
4692
4731
|
}
|
|
4693
4732
|
}
|
|
4694
4733
|
|
|
4695
|
-
cursorToBottom( cursor, resetLeft = false )
|
|
4696
|
-
|
|
4734
|
+
cursorToBottom( cursor, resetLeft = false )
|
|
4735
|
+
{
|
|
4697
4736
|
cursor._top += this.lineHeight;
|
|
4698
4737
|
cursor.style.top = `calc(${ cursor._top }px)`;
|
|
4699
4738
|
|
|
@@ -4713,8 +4752,8 @@ class CodeEditor {
|
|
|
4713
4752
|
}
|
|
4714
4753
|
}
|
|
4715
4754
|
|
|
4716
|
-
cursorToString( cursor, text, reverse )
|
|
4717
|
-
|
|
4755
|
+
cursorToString( cursor, text, reverse )
|
|
4756
|
+
{
|
|
4718
4757
|
if( !text.length )
|
|
4719
4758
|
{
|
|
4720
4759
|
return;
|
|
@@ -4726,23 +4765,23 @@ class CodeEditor {
|
|
|
4726
4765
|
}
|
|
4727
4766
|
}
|
|
4728
4767
|
|
|
4729
|
-
cursorToPosition( cursor, position )
|
|
4730
|
-
|
|
4768
|
+
cursorToPosition( cursor, position )
|
|
4769
|
+
{
|
|
4731
4770
|
cursor.position = position;
|
|
4732
4771
|
cursor._left = position * this.charWidth;
|
|
4733
4772
|
cursor.style.left = `calc( ${ cursor._left }px + ${ this.xPadding } )`;
|
|
4734
4773
|
}
|
|
4735
4774
|
|
|
4736
|
-
cursorToLine( cursor, line, resetLeft = false )
|
|
4737
|
-
|
|
4775
|
+
cursorToLine( cursor, line, resetLeft = false )
|
|
4776
|
+
{
|
|
4738
4777
|
cursor.line = line;
|
|
4739
4778
|
cursor._top = this.lineHeight * line;
|
|
4740
4779
|
cursor.style.top = cursor._top + "px";
|
|
4741
4780
|
if( resetLeft ) this.resetCursorPos( CodeEditor.CURSOR_LEFT, cursor );
|
|
4742
4781
|
}
|
|
4743
4782
|
|
|
4744
|
-
saveCursor( cursor, state = {} )
|
|
4745
|
-
|
|
4783
|
+
saveCursor( cursor, state = {} )
|
|
4784
|
+
{
|
|
4746
4785
|
state.position = cursor.position;
|
|
4747
4786
|
state.line = cursor.line;
|
|
4748
4787
|
state.selection = cursor.selection ? cursor.selection.save() : undefined;
|
|
@@ -4750,8 +4789,8 @@ class CodeEditor {
|
|
|
4750
4789
|
return state;
|
|
4751
4790
|
}
|
|
4752
4791
|
|
|
4753
|
-
saveCursors()
|
|
4754
|
-
|
|
4792
|
+
saveCursors()
|
|
4793
|
+
{
|
|
4755
4794
|
var cursors = [];
|
|
4756
4795
|
|
|
4757
4796
|
for( let cursor of this.cursors.children )
|
|
@@ -4762,8 +4801,8 @@ class CodeEditor {
|
|
|
4762
4801
|
return cursors;
|
|
4763
4802
|
}
|
|
4764
4803
|
|
|
4765
|
-
getCurrentCursor( removeOthers )
|
|
4766
|
-
|
|
4804
|
+
getCurrentCursor( removeOthers )
|
|
4805
|
+
{
|
|
4767
4806
|
if( removeOthers )
|
|
4768
4807
|
{
|
|
4769
4808
|
this._removeSecondaryCursors();
|
|
@@ -4772,8 +4811,8 @@ class CodeEditor {
|
|
|
4772
4811
|
return this.cursors.children[ 0 ];
|
|
4773
4812
|
}
|
|
4774
4813
|
|
|
4775
|
-
relocateCursors()
|
|
4776
|
-
|
|
4814
|
+
relocateCursors()
|
|
4815
|
+
{
|
|
4777
4816
|
for( let cursor of this.cursors.children )
|
|
4778
4817
|
{
|
|
4779
4818
|
cursor._left = cursor.position * this.charWidth;
|
|
@@ -4783,8 +4822,8 @@ class CodeEditor {
|
|
|
4783
4822
|
}
|
|
4784
4823
|
}
|
|
4785
4824
|
|
|
4786
|
-
mergeCursors( line )
|
|
4787
|
-
|
|
4825
|
+
mergeCursors( line )
|
|
4826
|
+
{
|
|
4788
4827
|
console.assert( line >= 0 );
|
|
4789
4828
|
const cursorsInLine = Array.from( this.cursors.children ).filter( v => v.line == line );
|
|
4790
4829
|
|
|
@@ -4792,8 +4831,8 @@ class CodeEditor {
|
|
|
4792
4831
|
this.removeCursor( cursorsInLine.pop() );
|
|
4793
4832
|
}
|
|
4794
4833
|
|
|
4795
|
-
restoreCursor( cursor, state )
|
|
4796
|
-
|
|
4834
|
+
restoreCursor( cursor, state )
|
|
4835
|
+
{
|
|
4797
4836
|
cursor.position = state.position ?? 0;
|
|
4798
4837
|
cursor.line = state.line ?? 0;
|
|
4799
4838
|
|
|
@@ -4814,15 +4853,15 @@ class CodeEditor {
|
|
|
4814
4853
|
}
|
|
4815
4854
|
}
|
|
4816
4855
|
|
|
4817
|
-
removeCursor( cursor )
|
|
4818
|
-
|
|
4856
|
+
removeCursor( cursor )
|
|
4857
|
+
{
|
|
4819
4858
|
LX.deleteElement( this.selections[ cursor.name ] );
|
|
4820
4859
|
delete this.selections[ cursor.name ];
|
|
4821
4860
|
LX.deleteElement( cursor );
|
|
4822
4861
|
}
|
|
4823
4862
|
|
|
4824
|
-
resetCursorPos( flag, cursor )
|
|
4825
|
-
|
|
4863
|
+
resetCursorPos( flag, cursor )
|
|
4864
|
+
{
|
|
4826
4865
|
cursor = cursor ?? this.getCurrentCursor();
|
|
4827
4866
|
|
|
4828
4867
|
if( flag & CodeEditor.CURSOR_LEFT )
|
|
@@ -4840,8 +4879,8 @@ class CodeEditor {
|
|
|
4840
4879
|
}
|
|
4841
4880
|
}
|
|
4842
4881
|
|
|
4843
|
-
_addCursor( line = 0, position = 0, force, isMain = false )
|
|
4844
|
-
|
|
4882
|
+
_addCursor( line = 0, position = 0, force, isMain = false )
|
|
4883
|
+
{
|
|
4845
4884
|
// If cursor in that position exists, remove it instead..
|
|
4846
4885
|
const exists = Array.from( this.cursors.children ).find( v => v.position == position && v.line == line );
|
|
4847
4886
|
if( exists && !force )
|
|
@@ -4891,30 +4930,42 @@ class CodeEditor {
|
|
|
4891
4930
|
return cursor;
|
|
4892
4931
|
}
|
|
4893
4932
|
|
|
4894
|
-
_removeSecondaryCursors()
|
|
4895
|
-
|
|
4933
|
+
_removeSecondaryCursors()
|
|
4934
|
+
{
|
|
4896
4935
|
while( this.cursors.childElementCount > 1 )
|
|
4936
|
+
{
|
|
4897
4937
|
this.cursors.lastChild.remove();
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
|
|
4941
|
+
_getLastCursor()
|
|
4942
|
+
{
|
|
4943
|
+
return this.cursors.lastChild;
|
|
4898
4944
|
}
|
|
4899
4945
|
|
|
4900
|
-
|
|
4946
|
+
_isLastCursor( cursor )
|
|
4947
|
+
{
|
|
4948
|
+
return cursor === this._getLastCursor();
|
|
4949
|
+
}
|
|
4901
4950
|
|
|
4951
|
+
_logCursors()
|
|
4952
|
+
{
|
|
4902
4953
|
for( let cursor of this.cursors.children )
|
|
4903
4954
|
{
|
|
4904
4955
|
cursor.print();
|
|
4905
4956
|
}
|
|
4906
4957
|
}
|
|
4907
4958
|
|
|
4908
|
-
_addSpaceTabs( cursor, n )
|
|
4909
|
-
|
|
4959
|
+
_addSpaceTabs( cursor, n )
|
|
4960
|
+
{
|
|
4910
4961
|
for( var i = 0; i < n; ++i )
|
|
4911
4962
|
{
|
|
4912
4963
|
this.actions[ 'Tab' ].callback( cursor.line, cursor, null );
|
|
4913
4964
|
}
|
|
4914
4965
|
}
|
|
4915
4966
|
|
|
4916
|
-
_addSpaces( n )
|
|
4917
|
-
|
|
4967
|
+
_addSpaces( n )
|
|
4968
|
+
{
|
|
4918
4969
|
for( var i = 0; i < n; ++i )
|
|
4919
4970
|
{
|
|
4920
4971
|
this.root.dispatchEvent( new CustomEvent( 'keydown', { 'detail': {
|
|
@@ -4925,8 +4976,8 @@ class CodeEditor {
|
|
|
4925
4976
|
}
|
|
4926
4977
|
}
|
|
4927
4978
|
|
|
4928
|
-
_removeSpaces( cursor )
|
|
4929
|
-
|
|
4979
|
+
_removeSpaces( cursor )
|
|
4980
|
+
{
|
|
4930
4981
|
const lidx = cursor.line;
|
|
4931
4982
|
|
|
4932
4983
|
// Remove indentation
|
|
@@ -4965,17 +5016,20 @@ class CodeEditor {
|
|
|
4965
5016
|
}
|
|
4966
5017
|
}
|
|
4967
5018
|
|
|
4968
|
-
getScrollLeft()
|
|
5019
|
+
getScrollLeft()
|
|
5020
|
+
{
|
|
4969
5021
|
if( !this.codeScroller ) return 0;
|
|
4970
5022
|
return this.codeScroller.scrollLeft;
|
|
4971
5023
|
}
|
|
4972
5024
|
|
|
4973
|
-
getScrollTop()
|
|
5025
|
+
getScrollTop()
|
|
5026
|
+
{
|
|
4974
5027
|
if( !this.codeScroller ) return 0;
|
|
4975
5028
|
return this.codeScroller.scrollTop;
|
|
4976
5029
|
}
|
|
4977
5030
|
|
|
4978
|
-
setScrollLeft( value )
|
|
5031
|
+
setScrollLeft( value )
|
|
5032
|
+
{
|
|
4979
5033
|
if( !this.codeScroller ) return;
|
|
4980
5034
|
LX.doAsync( () => {
|
|
4981
5035
|
this.codeScroller.scrollLeft = value;
|
|
@@ -4983,7 +5037,8 @@ class CodeEditor {
|
|
|
4983
5037
|
}, 20 );
|
|
4984
5038
|
}
|
|
4985
5039
|
|
|
4986
|
-
setScrollTop( value )
|
|
5040
|
+
setScrollTop( value )
|
|
5041
|
+
{
|
|
4987
5042
|
if( !this.codeScroller ) return;
|
|
4988
5043
|
LX.doAsync( () => {
|
|
4989
5044
|
this.codeScroller.scrollTop = value;
|
|
@@ -4991,8 +5046,8 @@ class CodeEditor {
|
|
|
4991
5046
|
}, 20 );
|
|
4992
5047
|
}
|
|
4993
5048
|
|
|
4994
|
-
resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize )
|
|
4995
|
-
|
|
5049
|
+
resize( flag = CodeEditor.RESIZE_SCROLLBAR_H_V, pMaxLength, onResize )
|
|
5050
|
+
{
|
|
4996
5051
|
setTimeout( () => {
|
|
4997
5052
|
|
|
4998
5053
|
let scrollWidth, scrollHeight;
|
|
@@ -5022,8 +5077,8 @@ class CodeEditor {
|
|
|
5022
5077
|
}, 10 );
|
|
5023
5078
|
}
|
|
5024
5079
|
|
|
5025
|
-
resizeIfNecessary( cursor, force )
|
|
5026
|
-
|
|
5080
|
+
resizeIfNecessary( cursor, force )
|
|
5081
|
+
{
|
|
5027
5082
|
const maxLineLength = this.getMaxLineLength();
|
|
5028
5083
|
const numViewportChars = Math.floor( ( this.codeScroller.clientWidth - CodeEditor.LINE_GUTTER_WIDTH ) / this.charWidth );
|
|
5029
5084
|
if( force || ( maxLineLength >= numViewportChars && maxLineLength != this._lastMaxLineLength ) )
|
|
@@ -5037,8 +5092,8 @@ class CodeEditor {
|
|
|
5037
5092
|
}
|
|
5038
5093
|
}
|
|
5039
5094
|
|
|
5040
|
-
resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V )
|
|
5041
|
-
|
|
5095
|
+
resizeScrollBars( flag = CodeEditor.RESIZE_SCROLLBAR_H_V )
|
|
5096
|
+
{
|
|
5042
5097
|
if( flag & CodeEditor.RESIZE_SCROLLBAR_V )
|
|
5043
5098
|
{
|
|
5044
5099
|
const totalLinesInViewport = (( this.codeScroller.offsetHeight ) / this.lineHeight)|0;
|
|
@@ -5071,8 +5126,8 @@ class CodeEditor {
|
|
|
5071
5126
|
}
|
|
5072
5127
|
}
|
|
5073
5128
|
|
|
5074
|
-
setScrollBarValue( type = 'vertical', value )
|
|
5075
|
-
|
|
5129
|
+
setScrollBarValue( type = 'vertical', value )
|
|
5130
|
+
{
|
|
5076
5131
|
if( type == 'vertical' )
|
|
5077
5132
|
{
|
|
5078
5133
|
const scrollBarHeight = this.vScrollbar.thumb.parentElement.offsetHeight;
|
|
@@ -5102,8 +5157,8 @@ class CodeEditor {
|
|
|
5102
5157
|
}
|
|
5103
5158
|
}
|
|
5104
5159
|
|
|
5105
|
-
updateHorizontalScrollFromScrollBar( value )
|
|
5106
|
-
|
|
5160
|
+
updateHorizontalScrollFromScrollBar( value )
|
|
5161
|
+
{
|
|
5107
5162
|
value = this.hScrollbar.thumb._left - value;
|
|
5108
5163
|
|
|
5109
5164
|
// Move scrollbar thumb
|
|
@@ -5124,8 +5179,8 @@ class CodeEditor {
|
|
|
5124
5179
|
this._discardScroll = true;
|
|
5125
5180
|
}
|
|
5126
5181
|
|
|
5127
|
-
updateVerticalScrollFromScrollBar( value )
|
|
5128
|
-
|
|
5182
|
+
updateVerticalScrollFromScrollBar( value )
|
|
5183
|
+
{
|
|
5129
5184
|
value = this.vScrollbar.thumb._top - value;
|
|
5130
5185
|
|
|
5131
5186
|
// Move scrollbar thumb
|
|
@@ -5143,12 +5198,13 @@ class CodeEditor {
|
|
|
5143
5198
|
this.codeScroller.scrollTop = currentScroll;
|
|
5144
5199
|
}
|
|
5145
5200
|
|
|
5146
|
-
getCharAtPos( cursor, offset = 0 )
|
|
5201
|
+
getCharAtPos( cursor, offset = 0 )
|
|
5202
|
+
{
|
|
5147
5203
|
return this.code.lines[ cursor.line ][ cursor.position + offset ];
|
|
5148
5204
|
}
|
|
5149
5205
|
|
|
5150
|
-
getWordAtPos( cursor, offset = 0 )
|
|
5151
|
-
|
|
5206
|
+
getWordAtPos( cursor, offset = 0 )
|
|
5207
|
+
{
|
|
5152
5208
|
const col = cursor.line;
|
|
5153
5209
|
const words = this.code.lines[ col ];
|
|
5154
5210
|
|
|
@@ -5197,7 +5253,8 @@ class CodeEditor {
|
|
|
5197
5253
|
return [ word, from, to ];
|
|
5198
5254
|
}
|
|
5199
5255
|
|
|
5200
|
-
_measureChar( char = "a", useFloating = false, getBB = false )
|
|
5256
|
+
_measureChar( char = "a", useFloating = false, getBB = false )
|
|
5257
|
+
{
|
|
5201
5258
|
const parentContainer = LX.makeContainer( null, "lexcodeeditor", "", document.body );
|
|
5202
5259
|
const container = LX.makeContainer( null, "code", "", parentContainer );
|
|
5203
5260
|
const line = document.createElement( "pre" );
|
|
@@ -5211,12 +5268,13 @@ class CodeEditor {
|
|
|
5211
5268
|
return getBB ? bb : bb[ 0 ];
|
|
5212
5269
|
}
|
|
5213
5270
|
|
|
5214
|
-
measureString( str )
|
|
5271
|
+
measureString( str )
|
|
5272
|
+
{
|
|
5215
5273
|
return str.length * this.charWidth;
|
|
5216
5274
|
}
|
|
5217
5275
|
|
|
5218
|
-
runScript( code )
|
|
5219
|
-
|
|
5276
|
+
runScript( code )
|
|
5277
|
+
{
|
|
5220
5278
|
const script = document.createElement( 'script' );
|
|
5221
5279
|
script.type = 'module';
|
|
5222
5280
|
script.innerHTML = code;
|
|
@@ -5226,8 +5284,8 @@ class CodeEditor {
|
|
|
5226
5284
|
document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
|
|
5227
5285
|
}
|
|
5228
5286
|
|
|
5229
|
-
toJSONFormat( text )
|
|
5230
|
-
|
|
5287
|
+
toJSONFormat( text )
|
|
5288
|
+
{
|
|
5231
5289
|
let params = text.split( ':' );
|
|
5232
5290
|
|
|
5233
5291
|
for(let i = 0; i < params.length; i++) {
|
|
@@ -5261,8 +5319,8 @@ class CodeEditor {
|
|
|
5261
5319
|
}
|
|
5262
5320
|
}
|
|
5263
5321
|
|
|
5264
|
-
showAutoCompleteBox( key, cursor )
|
|
5265
|
-
|
|
5322
|
+
showAutoCompleteBox( key, cursor )
|
|
5323
|
+
{
|
|
5266
5324
|
if( !cursor.isMain )
|
|
5267
5325
|
{
|
|
5268
5326
|
return;
|
|
@@ -5355,7 +5413,6 @@ class CodeEditor {
|
|
|
5355
5413
|
}
|
|
5356
5414
|
|
|
5357
5415
|
pre.appendChild( LX.makeIcon( iconName, { iconClass: "mr-1", svgClass: "sm " + iconClass } ) );
|
|
5358
|
-
s
|
|
5359
5416
|
pre.addEventListener( 'click', () => {
|
|
5360
5417
|
this.autoCompleteWord( s );
|
|
5361
5418
|
} );
|
|
@@ -5395,8 +5452,8 @@ s
|
|
|
5395
5452
|
this.isAutoCompleteActive = true;
|
|
5396
5453
|
}
|
|
5397
5454
|
|
|
5398
|
-
hideAutoCompleteBox()
|
|
5399
|
-
|
|
5455
|
+
hideAutoCompleteBox()
|
|
5456
|
+
{
|
|
5400
5457
|
if( !this.autocomplete )
|
|
5401
5458
|
{
|
|
5402
5459
|
return;
|
|
@@ -5410,8 +5467,8 @@ s
|
|
|
5410
5467
|
return isActive != this.isAutoCompleteActive;
|
|
5411
5468
|
}
|
|
5412
5469
|
|
|
5413
|
-
autoCompleteWord( suggestion )
|
|
5414
|
-
|
|
5470
|
+
autoCompleteWord( suggestion )
|
|
5471
|
+
{
|
|
5415
5472
|
if( !this.isAutoCompleteActive )
|
|
5416
5473
|
return;
|
|
5417
5474
|
|
|
@@ -5437,8 +5494,8 @@ s
|
|
|
5437
5494
|
this.hideAutoCompleteBox();
|
|
5438
5495
|
}
|
|
5439
5496
|
|
|
5440
|
-
_getSelectedAutoComplete()
|
|
5441
|
-
|
|
5497
|
+
_getSelectedAutoComplete()
|
|
5498
|
+
{
|
|
5442
5499
|
if( !this.isAutoCompleteActive )
|
|
5443
5500
|
{
|
|
5444
5501
|
return;
|
|
@@ -5464,18 +5521,21 @@ s
|
|
|
5464
5521
|
}
|
|
5465
5522
|
}
|
|
5466
5523
|
|
|
5467
|
-
_moveArrowSelectedAutoComplete( dir )
|
|
5468
|
-
|
|
5524
|
+
_moveArrowSelectedAutoComplete( dir )
|
|
5525
|
+
{
|
|
5469
5526
|
if( !this.isAutoCompleteActive )
|
|
5470
|
-
|
|
5527
|
+
return;
|
|
5471
5528
|
|
|
5472
|
-
const [word, idx] = this._getSelectedAutoComplete();
|
|
5529
|
+
const [ word, idx ] = this._getSelectedAutoComplete();
|
|
5473
5530
|
const offset = dir == 'down' ? 1 : -1;
|
|
5474
5531
|
|
|
5475
|
-
if( dir == 'down' )
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5532
|
+
if( dir == 'down' )
|
|
5533
|
+
{
|
|
5534
|
+
if( ( idx + offset ) >= this.autocomplete.childElementCount ) return;
|
|
5535
|
+
}
|
|
5536
|
+
else if( dir == 'up')
|
|
5537
|
+
{
|
|
5538
|
+
if( ( idx + offset ) < 0 ) return;
|
|
5479
5539
|
}
|
|
5480
5540
|
|
|
5481
5541
|
this.autocomplete.scrollTop += offset * 20;
|
|
@@ -5485,8 +5545,8 @@ s
|
|
|
5485
5545
|
this.autocomplete.childNodes[ idx + offset ].classList.add('selected');
|
|
5486
5546
|
}
|
|
5487
5547
|
|
|
5488
|
-
showSearchBox( clear )
|
|
5489
|
-
|
|
5548
|
+
showSearchBox( clear )
|
|
5549
|
+
{
|
|
5490
5550
|
this.hideSearchLineBox();
|
|
5491
5551
|
|
|
5492
5552
|
this.searchbox.classList.add( 'opened' );
|
|
@@ -5514,8 +5574,8 @@ s
|
|
|
5514
5574
|
input.focus();
|
|
5515
5575
|
}
|
|
5516
5576
|
|
|
5517
|
-
hideSearchBox()
|
|
5518
|
-
|
|
5577
|
+
hideSearchBox()
|
|
5578
|
+
{
|
|
5519
5579
|
const active = this.searchboxActive;
|
|
5520
5580
|
|
|
5521
5581
|
if( this.searchboxActive )
|
|
@@ -5532,11 +5592,11 @@ s
|
|
|
5532
5592
|
|
|
5533
5593
|
this.searchResultSelections.classList.remove( 'show' );
|
|
5534
5594
|
|
|
5535
|
-
return active != this.searchboxActive;
|
|
5595
|
+
return ( active != this.searchboxActive );
|
|
5536
5596
|
}
|
|
5537
5597
|
|
|
5538
|
-
search( text, reverse, callback, skipAlert )
|
|
5539
|
-
|
|
5598
|
+
search( text, reverse, callback, skipAlert, forceFocus = true )
|
|
5599
|
+
{
|
|
5540
5600
|
text = text ?? this._lastTextFound;
|
|
5541
5601
|
|
|
5542
5602
|
if( !text )
|
|
@@ -5658,12 +5718,15 @@ s
|
|
|
5658
5718
|
};
|
|
5659
5719
|
|
|
5660
5720
|
// Force focus back to search box
|
|
5661
|
-
|
|
5662
|
-
|
|
5721
|
+
if( forceFocus )
|
|
5722
|
+
{
|
|
5723
|
+
const input = this.searchbox.querySelector( 'input' );
|
|
5724
|
+
input.focus();
|
|
5725
|
+
}
|
|
5663
5726
|
}
|
|
5664
5727
|
|
|
5665
|
-
showSearchLineBox()
|
|
5666
|
-
|
|
5728
|
+
showSearchLineBox()
|
|
5729
|
+
{
|
|
5667
5730
|
this.hideSearchBox();
|
|
5668
5731
|
|
|
5669
5732
|
this.searchlinebox.classList.add( 'opened' );
|
|
@@ -5674,8 +5737,8 @@ s
|
|
|
5674
5737
|
input.focus();
|
|
5675
5738
|
}
|
|
5676
5739
|
|
|
5677
|
-
hideSearchLineBox()
|
|
5678
|
-
|
|
5740
|
+
hideSearchLineBox()
|
|
5741
|
+
{
|
|
5679
5742
|
if( this.searchlineboxActive )
|
|
5680
5743
|
{
|
|
5681
5744
|
this.searchlinebox.classList.remove( 'opened' );
|
|
@@ -5683,8 +5746,8 @@ s
|
|
|
5683
5746
|
}
|
|
5684
5747
|
}
|
|
5685
5748
|
|
|
5686
|
-
goToLine( line )
|
|
5687
|
-
|
|
5749
|
+
goToLine( line )
|
|
5750
|
+
{
|
|
5688
5751
|
if( !this._isNumber( line ) )
|
|
5689
5752
|
return;
|
|
5690
5753
|
|
|
@@ -5695,8 +5758,8 @@ s
|
|
|
5695
5758
|
this.cursorToLine( cursor, line - 1, true );
|
|
5696
5759
|
}
|
|
5697
5760
|
|
|
5698
|
-
selectNextOcurrence( cursor )
|
|
5699
|
-
|
|
5761
|
+
selectNextOcurrence( cursor )
|
|
5762
|
+
{
|
|
5700
5763
|
if( !cursor.selection )
|
|
5701
5764
|
return;
|
|
5702
5765
|
|
|
@@ -5711,11 +5774,12 @@ s
|
|
|
5711
5774
|
this._currentOcurrences[ currentKey ] = true;
|
|
5712
5775
|
}
|
|
5713
5776
|
|
|
5714
|
-
this.search( text, false, (col, ln) => {
|
|
5777
|
+
this.search( text, false, ( col, ln ) => {
|
|
5715
5778
|
|
|
5716
5779
|
const key = [ col, ln ].join( '_' );
|
|
5717
5780
|
|
|
5718
|
-
if( this._currentOcurrences[ key ] )
|
|
5781
|
+
if( this._currentOcurrences[ key ] )
|
|
5782
|
+
{
|
|
5719
5783
|
return;
|
|
5720
5784
|
}
|
|
5721
5785
|
|
|
@@ -5726,11 +5790,11 @@ s
|
|
|
5726
5790
|
|
|
5727
5791
|
this._currentOcurrences[ key ] = true;
|
|
5728
5792
|
|
|
5729
|
-
}, true );
|
|
5793
|
+
}, true, false );
|
|
5730
5794
|
}
|
|
5731
5795
|
|
|
5732
|
-
_updateDataInfoPanel( signal, value )
|
|
5733
|
-
|
|
5796
|
+
_updateDataInfoPanel( signal, value )
|
|
5797
|
+
{
|
|
5734
5798
|
if( !this.skipInfo )
|
|
5735
5799
|
{
|
|
5736
5800
|
if( this.cursors.childElementCount > 1 )
|
|
@@ -5742,8 +5806,8 @@ s
|
|
|
5742
5806
|
}
|
|
5743
5807
|
}
|
|
5744
5808
|
|
|
5745
|
-
_setActiveLine( number )
|
|
5746
|
-
|
|
5809
|
+
_setActiveLine( number )
|
|
5810
|
+
{
|
|
5747
5811
|
number = number ?? this.state.activeLine;
|
|
5748
5812
|
|
|
5749
5813
|
const cursor = this.getCurrentCursor();
|
|
@@ -5769,11 +5833,13 @@ s
|
|
|
5769
5833
|
}
|
|
5770
5834
|
}
|
|
5771
5835
|
|
|
5772
|
-
_hideActiveLine()
|
|
5836
|
+
_hideActiveLine()
|
|
5837
|
+
{
|
|
5773
5838
|
this.code.querySelectorAll( '.active-line' ).forEach( e => e.classList.remove( 'active-line' ) );
|
|
5774
5839
|
}
|
|
5775
5840
|
|
|
5776
|
-
_setFontSize( size )
|
|
5841
|
+
_setFontSize( size )
|
|
5842
|
+
{
|
|
5777
5843
|
// Change font size
|
|
5778
5844
|
this.fontSize = size;
|
|
5779
5845
|
const r = document.querySelector( ':root' );
|
|
@@ -5797,20 +5863,24 @@ s
|
|
|
5797
5863
|
LX.emit( "@font-size", this.fontSize );
|
|
5798
5864
|
}
|
|
5799
5865
|
|
|
5800
|
-
_applyFontSizeOffset( offset = 0 )
|
|
5866
|
+
_applyFontSizeOffset( offset = 0 )
|
|
5867
|
+
{
|
|
5801
5868
|
const newFontSize = LX.clamp( this.fontSize + offset, CodeEditor.CODE_MIN_FONT_SIZE, CodeEditor.CODE_MAX_FONT_SIZE );
|
|
5802
5869
|
this._setFontSize( newFontSize );
|
|
5803
5870
|
}
|
|
5804
5871
|
|
|
5805
|
-
_increaseFontSize()
|
|
5872
|
+
_increaseFontSize()
|
|
5873
|
+
{
|
|
5806
5874
|
this._applyFontSizeOffset( 1 );
|
|
5807
5875
|
}
|
|
5808
5876
|
|
|
5809
|
-
_decreaseFontSize()
|
|
5877
|
+
_decreaseFontSize()
|
|
5878
|
+
{
|
|
5810
5879
|
this._applyFontSizeOffset( -1 );
|
|
5811
5880
|
}
|
|
5812
5881
|
|
|
5813
|
-
_clearTmpVariables()
|
|
5882
|
+
_clearTmpVariables()
|
|
5883
|
+
{
|
|
5814
5884
|
delete this._currentLineString;
|
|
5815
5885
|
delete this._currentLineNumber;
|
|
5816
5886
|
delete this._buildingString;
|
|
@@ -5821,7 +5891,8 @@ s
|
|
|
5821
5891
|
delete this._scopeStack;
|
|
5822
5892
|
}
|
|
5823
5893
|
|
|
5824
|
-
async _requestFileAsync( url, dataType, nocache )
|
|
5894
|
+
async _requestFileAsync( url, dataType, nocache )
|
|
5895
|
+
{
|
|
5825
5896
|
return new Promise( (resolve, reject) => {
|
|
5826
5897
|
dataType = dataType ?? "arraybuffer";
|
|
5827
5898
|
const mimeType = dataType === "arraybuffer" ? "application/octet-stream" : undefined;
|
|
@@ -5852,7 +5923,8 @@ s
|
|
|
5852
5923
|
}
|
|
5853
5924
|
}
|
|
5854
5925
|
|
|
5855
|
-
CodeEditor.languages =
|
|
5926
|
+
CodeEditor.languages =
|
|
5927
|
+
{
|
|
5856
5928
|
'Plain Text': { ext: "txt", blockComments: false, singleLineComments: false, numbers: false, icon: "AlignLeft gray" },
|
|
5857
5929
|
'JavaScript': { ext: "js", icon: "Js goldenrod" },
|
|
5858
5930
|
'TypeScript': { ext: "ts", icon: "Ts pipelineblue" },
|
|
@@ -5872,17 +5944,20 @@ CodeEditor.languages = {
|
|
|
5872
5944
|
'PHP': { ext: "php", icon: "Php blueviolet" },
|
|
5873
5945
|
};
|
|
5874
5946
|
|
|
5875
|
-
CodeEditor.nativeTypes =
|
|
5947
|
+
CodeEditor.nativeTypes =
|
|
5948
|
+
{
|
|
5876
5949
|
'C++': ['int', 'float', 'double', 'bool', 'long', 'short', 'char', 'wchar_t', 'void'],
|
|
5877
5950
|
'WGSL': ['bool', 'u32', 'i32', 'f16', 'f32', 'vec2', 'vec3', 'vec4', 'vec2f', 'vec3f', 'vec4f', 'mat2x2f', 'mat3x3f', 'mat4x4f', 'array', 'vec2u', 'vec3u', 'vec4u', 'ptr', 'sampler']
|
|
5878
5951
|
};
|
|
5879
5952
|
|
|
5880
|
-
CodeEditor.declarationKeywords =
|
|
5953
|
+
CodeEditor.declarationKeywords =
|
|
5954
|
+
{
|
|
5881
5955
|
'JavaScript': ['var', 'let', 'const', 'this', 'static', 'class'],
|
|
5882
5956
|
'C++': [...CodeEditor.nativeTypes["C++"], 'const', 'auto', 'class', 'struct', 'namespace', 'enum', 'extern']
|
|
5883
5957
|
};
|
|
5884
5958
|
|
|
5885
|
-
CodeEditor.keywords =
|
|
5959
|
+
CodeEditor.keywords =
|
|
5960
|
+
{
|
|
5886
5961
|
'JavaScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'NaN', 'static', 'class', 'constructor', 'null', 'typeof', 'debugger', 'abstract',
|
|
5887
5962
|
'arguments', 'extends', 'instanceof', 'Infinity'],
|
|
5888
5963
|
'TypeScript': ['var', 'let', 'const', 'this', 'in', 'of', 'true', 'false', 'new', 'function', 'class', 'extends', 'instanceof', 'Infinity', 'private', 'public', 'protected', 'interface',
|
|
@@ -5911,7 +5986,9 @@ CodeEditor.keywords = {
|
|
|
5911
5986
|
'enum'],
|
|
5912
5987
|
};
|
|
5913
5988
|
|
|
5914
|
-
|
|
5989
|
+
// These ones don't have hightlight, used as suggestions to autocomplete only...
|
|
5990
|
+
CodeEditor.utils =
|
|
5991
|
+
{
|
|
5915
5992
|
'JavaScript': ['querySelector', 'body', 'addEventListener', 'removeEventListener', 'remove', 'sort', 'keys', 'filter', 'isNaN', 'parseFloat', 'parseInt', 'EPSILON', 'isFinite',
|
|
5916
5993
|
'bind', 'prototype', 'length', 'assign', 'entries', 'values', 'concat', 'substring', 'substr', 'splice', 'slice', 'buffer', 'appendChild', 'createElement', 'prompt',
|
|
5917
5994
|
'alert'],
|
|
@@ -5929,7 +6006,8 @@ CodeEditor.utils = { // These ones don't have hightlight, used as suggestions to
|
|
|
5929
6006
|
'lime', 'teal', 'navy', 'transparent', 'currentcolor', 'inherit', 'initial', 'unset', 'revert', 'none', 'auto', 'fit-content', 'min-content', 'max-content']
|
|
5930
6007
|
};
|
|
5931
6008
|
|
|
5932
|
-
CodeEditor.types =
|
|
6009
|
+
CodeEditor.types =
|
|
6010
|
+
{
|
|
5933
6011
|
'JavaScript': ['Object', 'String', 'Function', 'Boolean', 'Symbol', 'Error', 'Number', 'TextEncoder', 'TextDecoder', 'Array', 'ArrayBuffer', 'InputEvent', 'MouseEvent',
|
|
5934
6012
|
'Int8Array', 'Int16Array', 'Int32Array', 'Float32Array', 'Float64Array', 'Element'],
|
|
5935
6013
|
'TypeScript': ['arguments', 'constructor', 'null', 'typeof', 'debugger', 'abstract', 'Object', 'string', 'String', 'Function', 'Boolean', 'boolean', 'Error', 'Number', 'number', 'TextEncoder',
|
|
@@ -5943,7 +6021,8 @@ CodeEditor.types = {
|
|
|
5943
6021
|
'PHP': ['Exception', 'DateTime', 'JsonSerializable'],
|
|
5944
6022
|
};
|
|
5945
6023
|
|
|
5946
|
-
CodeEditor.builtIn =
|
|
6024
|
+
CodeEditor.builtIn =
|
|
6025
|
+
{
|
|
5947
6026
|
'JavaScript': ['document', 'console', 'window', 'navigator', 'performance'],
|
|
5948
6027
|
'CSS': ['*', '!important'],
|
|
5949
6028
|
'C++': ['vector', 'list', 'map'],
|
|
@@ -5953,7 +6032,8 @@ CodeEditor.builtIn = {
|
|
|
5953
6032
|
'PHP': ['echo', 'print'],
|
|
5954
6033
|
};
|
|
5955
6034
|
|
|
5956
|
-
CodeEditor.statements =
|
|
6035
|
+
CodeEditor.statements =
|
|
6036
|
+
{
|
|
5957
6037
|
'JavaScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await'],
|
|
5958
6038
|
'TypeScript': ['for', 'if', 'else', 'case', 'switch', 'return', 'while', 'continue', 'break', 'do', 'import', 'from', 'throw', 'async', 'try', 'catch', 'await', 'as'],
|
|
5959
6039
|
'CSS': ['@', 'import'],
|
|
@@ -5969,7 +6049,8 @@ CodeEditor.statements = {
|
|
|
5969
6049
|
'try', 'catch', 'die', 'do', 'exit', 'finally'],
|
|
5970
6050
|
};
|
|
5971
6051
|
|
|
5972
|
-
CodeEditor.symbols =
|
|
6052
|
+
CodeEditor.symbols =
|
|
6053
|
+
{
|
|
5973
6054
|
'JavaScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|
|
5974
6055
|
'TypeScript': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '??'],
|
|
5975
6056
|
'C': ['<', '>', '[', ']', '{', '}', '(', ')', ';', '=', '|', '||', '&', '&&', '?', '*', '-', '+'],
|