lexgui 0.1.41 → 0.1.42
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/components/codeeditor.js +87 -31
- package/build/components/timeline.js +165 -109
- package/build/lexgui.css +22 -1
- package/build/lexgui.js +297 -146
- package/build/lexgui.module.js +295 -144
- package/changelog.md +22 -3
- package/demo.js +7 -9
- package/examples/asset_view.html +3 -2
- package/examples/code_editor.html +8 -6
- package/package.json +1 -1
|
@@ -239,7 +239,10 @@ class CodeEditor {
|
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* @param {*} options
|
|
242
|
-
*
|
|
242
|
+
* name:
|
|
243
|
+
* skipInfo:
|
|
244
|
+
* fileExplorer:
|
|
245
|
+
* allowAddScripts:
|
|
243
246
|
*/
|
|
244
247
|
|
|
245
248
|
constructor( area, options = {} ) {
|
|
@@ -249,9 +252,9 @@ class CodeEditor {
|
|
|
249
252
|
CodeEditor.__instances.push( this );
|
|
250
253
|
|
|
251
254
|
// File explorer
|
|
252
|
-
if( options.
|
|
255
|
+
if( options.fileExplorer ?? false )
|
|
253
256
|
{
|
|
254
|
-
var [explorerArea, codeArea] = area.split({ sizes:["15%","85%"] });
|
|
257
|
+
var [ explorerArea, codeArea ] = area.split({ sizes:[ "15%","85%" ] });
|
|
255
258
|
explorerArea.setLimitBox( 180, 20, 512 );
|
|
256
259
|
this.explorerArea = explorerArea;
|
|
257
260
|
|
|
@@ -259,6 +262,8 @@ class CodeEditor {
|
|
|
259
262
|
|
|
260
263
|
panel.addTitle( "EXPLORER" );
|
|
261
264
|
|
|
265
|
+
this._tabStorage = {};
|
|
266
|
+
|
|
262
267
|
let sceneData = {
|
|
263
268
|
'id': 'WORKSPACE',
|
|
264
269
|
'skipVisibility': true,
|
|
@@ -305,7 +310,7 @@ class CodeEditor {
|
|
|
305
310
|
}
|
|
306
311
|
|
|
307
312
|
this.base_area = area;
|
|
308
|
-
this.area = new LX.Area( { className: "lexcodeeditor", height: "100%",
|
|
313
|
+
this.area = new LX.Area( { className: "lexcodeeditor", height: "100%", skipAppend: true } );
|
|
309
314
|
|
|
310
315
|
this.tabs = this.area.addTabs( { onclose: (name) => {
|
|
311
316
|
delete this.openedTabs[ name ];
|
|
@@ -315,8 +320,9 @@ class CodeEditor {
|
|
|
315
320
|
this.cursors.classList.remove( 'show' );
|
|
316
321
|
}
|
|
317
322
|
} } );
|
|
323
|
+
|
|
318
324
|
this.tabs.root.addEventListener( 'dblclick', (e) => {
|
|
319
|
-
if( options.
|
|
325
|
+
if( options.allowAddScripts ?? true ) {
|
|
320
326
|
e.preventDefault();
|
|
321
327
|
this.addTab("unnamed.js", true);
|
|
322
328
|
}
|
|
@@ -332,8 +338,8 @@ class CodeEditor {
|
|
|
332
338
|
this.root.tabIndex = -1;
|
|
333
339
|
area.attach( this.root );
|
|
334
340
|
|
|
335
|
-
this.skipCodeInfo = options.
|
|
336
|
-
this.disableEdition = options.
|
|
341
|
+
this.skipCodeInfo = options.skipInfo ?? false;
|
|
342
|
+
this.disableEdition = options.disableEdition ?? false;
|
|
337
343
|
|
|
338
344
|
if( !this.disableEdition )
|
|
339
345
|
{
|
|
@@ -1045,10 +1051,12 @@ class CodeEditor {
|
|
|
1045
1051
|
this.loadedTabs = { };
|
|
1046
1052
|
this.openedTabs = { };
|
|
1047
1053
|
|
|
1048
|
-
if( options.
|
|
1054
|
+
if( options.allowAddScripts ?? true )
|
|
1055
|
+
{
|
|
1049
1056
|
this.addTab("+", false, "New File");
|
|
1057
|
+
}
|
|
1050
1058
|
|
|
1051
|
-
this.addTab( options.name || "untitled", true, options.title );
|
|
1059
|
+
this.addTab( options.name || "untitled", true, options.title, { language: "CSS" } );
|
|
1052
1060
|
|
|
1053
1061
|
// Create inspector panel
|
|
1054
1062
|
let panel = this._createPanelInfo();
|
|
@@ -1191,7 +1199,7 @@ class CodeEditor {
|
|
|
1191
1199
|
}
|
|
1192
1200
|
}
|
|
1193
1201
|
|
|
1194
|
-
loadFile( file ) {
|
|
1202
|
+
loadFile( file, options = {} ) {
|
|
1195
1203
|
|
|
1196
1204
|
const inner_add_tab = ( text, name, title ) => {
|
|
1197
1205
|
|
|
@@ -1207,16 +1215,25 @@ class CodeEditor {
|
|
|
1207
1215
|
|
|
1208
1216
|
if( this.explorer )
|
|
1209
1217
|
{
|
|
1210
|
-
this.
|
|
1211
|
-
|
|
1212
|
-
|
|
1218
|
+
this._tabStorage[ name ] = {
|
|
1219
|
+
lines: lines,
|
|
1220
|
+
options: options
|
|
1221
|
+
};
|
|
1222
|
+
|
|
1223
|
+
const ext = this.languages[ options.language ] ?. ext;
|
|
1224
|
+
this.addExplorerItem( { 'id': name, 'skipVisibility': true, 'icon': this._getFileIcon( name, ext ) } );
|
|
1213
1225
|
this.explorer.frefresh( name );
|
|
1214
1226
|
}
|
|
1215
1227
|
else
|
|
1216
1228
|
{
|
|
1217
|
-
this.addTab(name, true, title);
|
|
1229
|
+
this.addTab( name, true, title, options );
|
|
1218
1230
|
this.code.lines = lines;
|
|
1219
|
-
|
|
1231
|
+
|
|
1232
|
+
// Default inferred language if not specified
|
|
1233
|
+
if( !options.language )
|
|
1234
|
+
{
|
|
1235
|
+
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1236
|
+
}
|
|
1220
1237
|
}
|
|
1221
1238
|
};
|
|
1222
1239
|
|
|
@@ -1224,7 +1241,6 @@ class CodeEditor {
|
|
|
1224
1241
|
{
|
|
1225
1242
|
let filename = file;
|
|
1226
1243
|
LX.request({ url: filename, success: text => {
|
|
1227
|
-
|
|
1228
1244
|
const name = filename.substring(filename.lastIndexOf( '/' ) + 1);
|
|
1229
1245
|
inner_add_tab( text, name, filename );
|
|
1230
1246
|
} });
|
|
@@ -1417,10 +1433,16 @@ class CodeEditor {
|
|
|
1417
1433
|
}
|
|
1418
1434
|
}
|
|
1419
1435
|
|
|
1420
|
-
_changeLanguage( lang ) {
|
|
1436
|
+
_changeLanguage( lang, override = false ) {
|
|
1421
1437
|
|
|
1422
1438
|
this.code.language = lang;
|
|
1423
1439
|
this.highlight = lang;
|
|
1440
|
+
|
|
1441
|
+
if( override )
|
|
1442
|
+
{
|
|
1443
|
+
this.code.languageOverride = lang;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1424
1446
|
this._updateDataInfoPanel( "@highlight", lang );
|
|
1425
1447
|
this.processLines();
|
|
1426
1448
|
|
|
@@ -1491,8 +1513,12 @@ class CodeEditor {
|
|
|
1491
1513
|
}, { width: "10%", nameWidth: "15%", signal: "@tab-spaces" });
|
|
1492
1514
|
panel.addButton( "<b>{ }</b>", this.highlight, ( value, event ) => {
|
|
1493
1515
|
LX.addContextMenu( "Language", event, m => {
|
|
1494
|
-
for( const lang of Object.keys(this.languages) )
|
|
1495
|
-
|
|
1516
|
+
for( const lang of Object.keys( this.languages ) )
|
|
1517
|
+
{
|
|
1518
|
+
m.add( lang, v => {
|
|
1519
|
+
this._changeLanguage( v, true )
|
|
1520
|
+
} );
|
|
1521
|
+
}
|
|
1496
1522
|
});
|
|
1497
1523
|
}, { width: "17.5%", nameWidth: "15%", signal: "@highlight" });
|
|
1498
1524
|
panel.endLine();
|
|
@@ -1553,8 +1579,16 @@ class CodeEditor {
|
|
|
1553
1579
|
this.restoreCursor( cursor, this.code.cursorState );
|
|
1554
1580
|
|
|
1555
1581
|
this.endSelection();
|
|
1556
|
-
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1557
1582
|
this._updateDataInfoPanel( "@tab-name", name );
|
|
1583
|
+
|
|
1584
|
+
if( this.code.languageOverride )
|
|
1585
|
+
{
|
|
1586
|
+
this._changeLanguage( this.code.languageOverride );
|
|
1587
|
+
}
|
|
1588
|
+
else
|
|
1589
|
+
{
|
|
1590
|
+
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1591
|
+
}
|
|
1558
1592
|
}
|
|
1559
1593
|
|
|
1560
1594
|
_onContextMenuTab( isNewTabButton, event, name, ) {
|
|
@@ -1569,7 +1603,7 @@ class CodeEditor {
|
|
|
1569
1603
|
});
|
|
1570
1604
|
}
|
|
1571
1605
|
|
|
1572
|
-
addTab( name, selected, title ) {
|
|
1606
|
+
addTab( name, selected, title, options = {} ) {
|
|
1573
1607
|
|
|
1574
1608
|
// If already loaded, set new name...
|
|
1575
1609
|
const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
|
|
@@ -1586,7 +1620,7 @@ class CodeEditor {
|
|
|
1586
1620
|
let code = document.createElement( 'div' );
|
|
1587
1621
|
code.className = 'code';
|
|
1588
1622
|
code.lines = [ "" ];
|
|
1589
|
-
code.language = "Plain Text";
|
|
1623
|
+
code.language = options.language ?? "Plain Text";
|
|
1590
1624
|
code.cursorState = {};
|
|
1591
1625
|
code.undoSteps = [];
|
|
1592
1626
|
code.redoSteps = [];
|
|
@@ -1643,6 +1677,12 @@ class CodeEditor {
|
|
|
1643
1677
|
this.processLines();
|
|
1644
1678
|
}
|
|
1645
1679
|
|
|
1680
|
+
if( options.language )
|
|
1681
|
+
{
|
|
1682
|
+
code.languageOverride = options.language;
|
|
1683
|
+
this._changeLanguage( code.languageOverride );
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1646
1686
|
this._updateDataInfoPanel( "@tab-name", name );
|
|
1647
1687
|
|
|
1648
1688
|
// Bc it could be overrided..
|
|
@@ -1663,13 +1703,25 @@ class CodeEditor {
|
|
|
1663
1703
|
if( !code )
|
|
1664
1704
|
{
|
|
1665
1705
|
this.addTab( name, true );
|
|
1666
|
-
|
|
1667
|
-
|
|
1706
|
+
|
|
1707
|
+
// Unload lines from storage...
|
|
1708
|
+
const tabData = this._tabStorage[ name ];
|
|
1709
|
+
if( tabData )
|
|
1668
1710
|
{
|
|
1669
|
-
this.code.lines =
|
|
1670
|
-
|
|
1711
|
+
this.code.lines = tabData.lines;
|
|
1712
|
+
|
|
1713
|
+
if( tabData.options.language )
|
|
1714
|
+
{
|
|
1715
|
+
this._changeLanguage( tabData.options.language, true );
|
|
1716
|
+
}
|
|
1717
|
+
else
|
|
1718
|
+
{
|
|
1719
|
+
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
delete this._tabStorage[ name ];
|
|
1671
1723
|
}
|
|
1672
|
-
|
|
1724
|
+
|
|
1673
1725
|
return;
|
|
1674
1726
|
}
|
|
1675
1727
|
|
|
@@ -1697,7 +1749,7 @@ class CodeEditor {
|
|
|
1697
1749
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT | CodeEditor.CURSOR_TOP );
|
|
1698
1750
|
this.processLines();
|
|
1699
1751
|
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1700
|
-
this._updateDataInfoPanel( "@tab-name", tabname );
|
|
1752
|
+
this._updateDataInfoPanel( "@tab-name", code.tabname );
|
|
1701
1753
|
}
|
|
1702
1754
|
|
|
1703
1755
|
loadTabFromFile() {
|
|
@@ -2910,7 +2962,7 @@ class CodeEditor {
|
|
|
2910
2962
|
else if( this._buildingString != undefined )
|
|
2911
2963
|
discardToken = this._appendStringToken( token );
|
|
2912
2964
|
|
|
2913
|
-
else if( this._mustHightlightWord( token, CodeEditor.keywords ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2965
|
+
else if( ( this._mustHightlightWord( token, CodeEditor.keywords ) || highlight == 'xml' ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
2914
2966
|
token_classname = "cm-kwd";
|
|
2915
2967
|
|
|
2916
2968
|
else if( this._mustHightlightWord( token, CodeEditor.builtin ) && ( lang.tags ?? false ? ( this._enclosedByTokens( token, tokenIndex, '<', '>' ) ) : true ) )
|
|
@@ -3016,11 +3068,14 @@ class CodeEditor {
|
|
|
3016
3068
|
const tagStartIndex = indexOfFrom( this._currentLineString, tagStart, tokenStartIndex, true );
|
|
3017
3069
|
if( tagStartIndex < 0 ) // Not found..
|
|
3018
3070
|
return;
|
|
3071
|
+
const tagStartIndexOpposite = indexOfFrom( this._currentLineString, tagEnd, tokenStartIndex, true );
|
|
3072
|
+
if( tagStartIndexOpposite >= 0 && tagStartIndexOpposite > tagStartIndex ) // Found the opposite first while reversing..
|
|
3073
|
+
return;
|
|
3019
3074
|
const tagEndIndex = indexOfFrom( this._currentLineString, tagEnd, tokenStartIndex );
|
|
3020
3075
|
if( tagEndIndex < 0 ) // Not found..
|
|
3021
3076
|
return;
|
|
3022
3077
|
|
|
3023
|
-
return ( tagStartIndex < tokenStartIndex ) && ( tagEndIndex >= ( tokenStartIndex + token.length ) );
|
|
3078
|
+
return ( tagStartIndex < tokenStartIndex ) && ( tagEndIndex >= ( tokenStartIndex + token.length ) ) && !this._mustHightlightWord( token, CodeEditor.symbols );
|
|
3024
3079
|
}
|
|
3025
3080
|
|
|
3026
3081
|
_inBlockCommentSection( line ) {
|
|
@@ -4358,7 +4413,8 @@ CodeEditor.symbols = {
|
|
|
4358
4413
|
'Rust': ['<', '>', '[', ']', '(', ')', '='],
|
|
4359
4414
|
'Python': ['<', '>', '[', ']', '(', ')', '='],
|
|
4360
4415
|
'Batch': ['[', ']', '(', ')', '%'],
|
|
4361
|
-
'HTML': ['<', '>', '/']
|
|
4416
|
+
'HTML': ['<', '>', '/'],
|
|
4417
|
+
'XML': ['<', '>', '/']
|
|
4362
4418
|
};
|
|
4363
4419
|
|
|
4364
4420
|
LX.CodeEditor = CodeEditor;
|