lexgui 0.1.18 → 0.1.19
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 +248 -33
- package/build/lexgui.css +46 -3
- package/build/lexgui.js +97 -63
- package/build/lexgui.module.js +87 -54
- package/examples/code_editor.html +32 -26
- package/package.json +1 -1
|
@@ -170,11 +170,74 @@ class CodeEditor {
|
|
|
170
170
|
window.editor = this;
|
|
171
171
|
|
|
172
172
|
CodeEditor.__instances.push( this );
|
|
173
|
+
|
|
174
|
+
// File explorer
|
|
175
|
+
if( options.file_explorer ?? false )
|
|
176
|
+
{
|
|
177
|
+
var [explorerArea, codeArea] = area.split({ sizes:["15%","85%"] });
|
|
178
|
+
explorerArea.setLimitBox( 180, 20, 512 );
|
|
179
|
+
this.explorerArea = explorerArea;
|
|
180
|
+
|
|
181
|
+
let panel = new LX.Panel();
|
|
182
|
+
|
|
183
|
+
panel.addTitle( "EXPLORER" );
|
|
184
|
+
|
|
185
|
+
let sceneData = {
|
|
186
|
+
'id': 'WORKSPACE',
|
|
187
|
+
'skipVisibility': true,
|
|
188
|
+
'children': []
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
this.explorer = panel.addTree( null, sceneData, {
|
|
192
|
+
filter: false,
|
|
193
|
+
rename: false,
|
|
194
|
+
skip_default_icon: true,
|
|
195
|
+
onevent: (event) => {
|
|
196
|
+
switch(event.type) {
|
|
197
|
+
// case LX.TreeEvent.NODE_SELECTED:
|
|
198
|
+
// if( !this.tabs.tabDOMs[ event.node.id ] ) break;
|
|
199
|
+
case LX.TreeEvent.NODE_DBLCLICKED:
|
|
200
|
+
this.loadTab( event.node.id );
|
|
201
|
+
break;
|
|
202
|
+
case LX.TreeEvent.NODE_DELETED:
|
|
203
|
+
this.tabs.delete( event.node.id );
|
|
204
|
+
delete this.loadedTabs[ event.node.id ];
|
|
205
|
+
break;
|
|
206
|
+
// case LX.TreeEvent.NODE_CONTEXTMENU:
|
|
207
|
+
// LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
|
|
208
|
+
//
|
|
209
|
+
// });
|
|
210
|
+
// break;
|
|
211
|
+
// case LX.TreeEvent.NODE_DRAGGED:
|
|
212
|
+
// console.log(event.node.id + " is now child of " + event.value.id);
|
|
213
|
+
// break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
this.addExplorerItem = function( item )
|
|
219
|
+
{
|
|
220
|
+
if( !this.explorer.data.children.find( (value, index) => value.id === item.id ) )
|
|
221
|
+
this.explorer.data.children.push( item );
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
explorerArea.attach( panel );
|
|
225
|
+
|
|
226
|
+
// Update area
|
|
227
|
+
area = codeArea;
|
|
228
|
+
}
|
|
173
229
|
|
|
174
230
|
this.base_area = area;
|
|
175
231
|
this.area = new LX.Area( { className: "lexcodeeditor", height: "auto", no_append: true } );
|
|
176
232
|
|
|
177
|
-
this.tabs = this.area.addTabs( { onclose: (name) =>
|
|
233
|
+
this.tabs = this.area.addTabs( { onclose: (name) => {
|
|
234
|
+
delete this.openedTabs[ name ];
|
|
235
|
+
if( Object.keys( this.openedTabs ).length < 2 )
|
|
236
|
+
{
|
|
237
|
+
clearInterval( this.blinker );
|
|
238
|
+
this.cursors.classList.remove('show');
|
|
239
|
+
}
|
|
240
|
+
} } );
|
|
178
241
|
this.tabs.root.addEventListener( 'dblclick', (e) => {
|
|
179
242
|
if( options.allow_add_scripts ?? true ) {
|
|
180
243
|
e.preventDefault();
|
|
@@ -344,7 +407,7 @@ class CodeEditor {
|
|
|
344
407
|
|
|
345
408
|
this.useAutoComplete = options.autocomplete ?? true;
|
|
346
409
|
this.highlight = options.highlight ?? 'Plain Text';
|
|
347
|
-
this.onsave = options.onsave ?? ((code) => {
|
|
410
|
+
this.onsave = options.onsave ?? ((code) => { console.log( code, "save" ) });
|
|
348
411
|
this.onrun = options.onrun ?? ((code) => { this.runScript(code) });
|
|
349
412
|
this.actions = {};
|
|
350
413
|
this.cursorBlinkRate = 550;
|
|
@@ -372,17 +435,17 @@ class CodeEditor {
|
|
|
372
435
|
// setInterval( this.scanWordSuggestions.bind( this ), 2000 );
|
|
373
436
|
|
|
374
437
|
this.languages = {
|
|
375
|
-
'Plain Text': { },
|
|
376
|
-
'JavaScript': { },
|
|
377
|
-
'C++': { },
|
|
378
|
-
'CSS': { },
|
|
379
|
-
'GLSL': { },
|
|
380
|
-
'WGSL': { },
|
|
381
|
-
'JSON': { },
|
|
382
|
-
'XML': { },
|
|
383
|
-
'Python': { singleLineCommentToken: '#' },
|
|
384
|
-
'HTML': { },
|
|
385
|
-
'Batch': { blockComments: false, singleLineCommentToken: '::' }
|
|
438
|
+
'Plain Text': { ext: 'txt' },
|
|
439
|
+
'JavaScript': { ext: 'js' },
|
|
440
|
+
'C++': { ext: 'cpp' },
|
|
441
|
+
'CSS': { ext: 'css' },
|
|
442
|
+
'GLSL': { ext: 'glsl' },
|
|
443
|
+
'WGSL': { ext: 'wgsl' },
|
|
444
|
+
'JSON': { ext: 'json' },
|
|
445
|
+
'XML': { ext: 'xml' },
|
|
446
|
+
'Python': { ext: 'py', singleLineCommentToken: '#' },
|
|
447
|
+
'HTML': { ext: 'html' },
|
|
448
|
+
'Batch': { ext: 'bat', blockComments: false, singleLineCommentToken: '::' }
|
|
386
449
|
};
|
|
387
450
|
|
|
388
451
|
this.specialKeys = [
|
|
@@ -475,7 +538,7 @@ class CodeEditor {
|
|
|
475
538
|
if( this.selection ) {
|
|
476
539
|
this.deleteSelection( cursor );
|
|
477
540
|
// Remove entire line when selecting with triple click
|
|
478
|
-
if(
|
|
541
|
+
if( this._tripleClickSelection )
|
|
479
542
|
{
|
|
480
543
|
this.actions['Backspace'].callback( ln, cursor, e );
|
|
481
544
|
this.lineDown( cursor, true );
|
|
@@ -845,6 +908,7 @@ class CodeEditor {
|
|
|
845
908
|
|
|
846
909
|
// Default code tab
|
|
847
910
|
|
|
911
|
+
this.loadedTabs = { };
|
|
848
912
|
this.openedTabs = { };
|
|
849
913
|
|
|
850
914
|
if( options.allow_add_scripts ?? true )
|
|
@@ -862,6 +926,26 @@ class CodeEditor {
|
|
|
862
926
|
return CodeEditor.__instances;
|
|
863
927
|
}
|
|
864
928
|
|
|
929
|
+
// This received key inputs from the entire document...
|
|
930
|
+
onKeyPressed( e ) {
|
|
931
|
+
|
|
932
|
+
// Toggle visibility of the file explorer
|
|
933
|
+
if( e.key == 'b' && e.ctrlKey && this.explorer )
|
|
934
|
+
{
|
|
935
|
+
this.explorerArea.root.classList.toggle( "hidden" );
|
|
936
|
+
if( this._lastBaseareaWidth )
|
|
937
|
+
{
|
|
938
|
+
this.base_area.root.style.width = this._lastBaseareaWidth;
|
|
939
|
+
delete this._lastBaseareaWidth;
|
|
940
|
+
|
|
941
|
+
} else
|
|
942
|
+
{
|
|
943
|
+
this._lastBaseareaWidth = this.base_area.root.style.width;
|
|
944
|
+
this.base_area.root.style.width = "100%";
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
865
949
|
getText( min ) {
|
|
866
950
|
return this.code.lines.join(min ? ' ' : '\n');
|
|
867
951
|
}
|
|
@@ -951,11 +1035,22 @@ class CodeEditor {
|
|
|
951
1035
|
loadFile( file ) {
|
|
952
1036
|
|
|
953
1037
|
const inner_add_tab = ( text, name, title ) => {
|
|
954
|
-
|
|
955
|
-
|
|
1038
|
+
|
|
1039
|
+
// Set current text and language
|
|
1040
|
+
const lines = text.replaceAll( '\r', '' ).split( '\n' );
|
|
1041
|
+
|
|
1042
|
+
// Add item in the explorer if used
|
|
1043
|
+
if( this.explorer )
|
|
1044
|
+
{
|
|
1045
|
+
this._storedLines = this._storedLines ?? {};
|
|
1046
|
+
this._storedLines[ name ] = lines;
|
|
1047
|
+
this.addExplorerItem( { 'id': name, 'skipVisibility': true, 'icon': this._getFileIcon( name ) } );
|
|
1048
|
+
this.explorer.frefresh( name );
|
|
1049
|
+
}
|
|
1050
|
+
else
|
|
956
1051
|
{
|
|
957
|
-
|
|
958
|
-
this.code.lines =
|
|
1052
|
+
this.addTab(name, true, title);
|
|
1053
|
+
this.code.lines = lines;
|
|
959
1054
|
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
960
1055
|
}
|
|
961
1056
|
};
|
|
@@ -1013,6 +1108,35 @@ class CodeEditor {
|
|
|
1013
1108
|
this.highlight = lang;
|
|
1014
1109
|
this._refreshCodeInfo();
|
|
1015
1110
|
this.processLines();
|
|
1111
|
+
|
|
1112
|
+
const ext = this.languages[ lang ].ext;
|
|
1113
|
+
const icon = this._getFileIcon( null, ext );
|
|
1114
|
+
|
|
1115
|
+
// Update tab icon
|
|
1116
|
+
{
|
|
1117
|
+
const tab = this.tabs.tabDOMs[ this.code.tabName ];
|
|
1118
|
+
tab.firstChild.remove();
|
|
1119
|
+
console.assert( tab != undefined );
|
|
1120
|
+
var iconEl;
|
|
1121
|
+
if( icon.includes( 'fa-' ) )
|
|
1122
|
+
{
|
|
1123
|
+
iconEl = document.createElement( 'i' );
|
|
1124
|
+
iconEl.className = icon;
|
|
1125
|
+
} else {
|
|
1126
|
+
iconEl = document.createElement( 'img' );
|
|
1127
|
+
iconEl.src = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/" + icon;
|
|
1128
|
+
}
|
|
1129
|
+
tab.prepend( iconEl );
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// Update explorer icon
|
|
1133
|
+
if( this.explorer )
|
|
1134
|
+
{
|
|
1135
|
+
const item = this.explorer.data.children.filter( (v) => v.id === this.code.tabName )[ 0 ];
|
|
1136
|
+
console.assert( item != undefined );
|
|
1137
|
+
item.icon = icon;
|
|
1138
|
+
this.explorer.frefresh( this.code.tabName );
|
|
1139
|
+
}
|
|
1016
1140
|
}
|
|
1017
1141
|
|
|
1018
1142
|
_changeLanguageFromExtension( ext ) {
|
|
@@ -1083,23 +1207,40 @@ class CodeEditor {
|
|
|
1083
1207
|
}
|
|
1084
1208
|
}
|
|
1085
1209
|
|
|
1210
|
+
_getFileIcon( name, extension ) {
|
|
1211
|
+
|
|
1212
|
+
const isNewTabButton = name ? ( name === '+' ) : false;
|
|
1213
|
+
const ext = extension ?? LX.getExtension( name );
|
|
1214
|
+
return ext == 'html' ? "fa-solid fa-code orange" :
|
|
1215
|
+
ext == "css" ? "fa-solid fa-hashtag dodgerblue" :
|
|
1216
|
+
ext == "xml" ? "fa-solid fa-rss orange" :
|
|
1217
|
+
ext == "bat" ? "fa-brands fa-windows lightblue" :
|
|
1218
|
+
[ "js", "py", "json", "cpp" ].indexOf( ext ) > -1 ? "images/" + ext + ".png" :
|
|
1219
|
+
!isNewTabButton ? "fa-solid fa-align-left gray" : undefined;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1086
1222
|
_onNewTab( e ) {
|
|
1087
1223
|
|
|
1088
1224
|
this.processFocus(false);
|
|
1089
1225
|
|
|
1090
1226
|
LX.addContextMenu( null, e, m => {
|
|
1091
1227
|
m.add( "Create", this.addTab.bind( this, "unnamed.js", true ) );
|
|
1092
|
-
m.add( "Load", this.
|
|
1228
|
+
m.add( "Load", this.loadTabFromFile.bind( this, "unnamed.js", true ) );
|
|
1093
1229
|
});
|
|
1094
1230
|
}
|
|
1095
1231
|
|
|
1096
1232
|
addTab( name, selected, title ) {
|
|
1097
1233
|
|
|
1098
|
-
|
|
1099
|
-
{
|
|
1100
|
-
|
|
1101
|
-
return
|
|
1102
|
-
}
|
|
1234
|
+
// If already loaded, set new name...
|
|
1235
|
+
const repeats = Object.keys( editor.loadedTabs ).slice( 1 ).reduce( ( v, key ) => {
|
|
1236
|
+
const noRepeatName = key.replace( /[_\d+]/g, '');
|
|
1237
|
+
return v + ( noRepeatName == name );
|
|
1238
|
+
}, 0 );
|
|
1239
|
+
|
|
1240
|
+
if( repeats > 0 )
|
|
1241
|
+
name = name.split( '.' ).join( '_' + repeats + '.' );
|
|
1242
|
+
|
|
1243
|
+
const isNewTabButton = ( name === '+' );
|
|
1103
1244
|
|
|
1104
1245
|
// Create code content
|
|
1105
1246
|
let code = document.createElement( 'div' );
|
|
@@ -1129,20 +1270,25 @@ class CodeEditor {
|
|
|
1129
1270
|
this.loadFile( e.dataTransfer.files[ i ] );
|
|
1130
1271
|
});
|
|
1131
1272
|
|
|
1273
|
+
this.loadedTabs[ name ] = code;
|
|
1132
1274
|
this.openedTabs[ name ] = code;
|
|
1275
|
+
|
|
1276
|
+
const tabIcon = this._getFileIcon( name );
|
|
1133
1277
|
|
|
1134
|
-
|
|
1278
|
+
if( this.explorer && !isNewTabButton )
|
|
1279
|
+
{
|
|
1280
|
+
this.addExplorerItem( { 'id': name, 'skipVisibility': true, 'icon': tabIcon } );
|
|
1281
|
+
this.explorer.frefresh( name );
|
|
1282
|
+
}
|
|
1135
1283
|
|
|
1136
1284
|
this.tabs.add(name, code, {
|
|
1137
1285
|
selected: selected,
|
|
1138
|
-
fixed:
|
|
1286
|
+
fixed: isNewTabButton,
|
|
1139
1287
|
title: code.title,
|
|
1140
|
-
icon:
|
|
1141
|
-
ext == 'js' ? "images/js.png" :
|
|
1142
|
-
ext == 'py' ? "images/py.png" : undefined,
|
|
1288
|
+
icon: tabIcon,
|
|
1143
1289
|
onSelect: (e, tabname) => {
|
|
1144
1290
|
|
|
1145
|
-
if(
|
|
1291
|
+
if( isNewTabButton )
|
|
1146
1292
|
{
|
|
1147
1293
|
this._onNewTab( e );
|
|
1148
1294
|
return;
|
|
@@ -1150,7 +1296,7 @@ class CodeEditor {
|
|
|
1150
1296
|
|
|
1151
1297
|
var cursor = cursor ?? this.cursors.children[ 0 ];
|
|
1152
1298
|
this.saveCursor( cursor, this.code.cursorState );
|
|
1153
|
-
this.code = this.
|
|
1299
|
+
this.code = this.loadedTabs[ tabname ];
|
|
1154
1300
|
this.restoreCursor( cursor, this.code.cursorState );
|
|
1155
1301
|
this.endSelection();
|
|
1156
1302
|
this._changeLanguageFromExtension( LX.getExtension( tabname ) );
|
|
@@ -1170,9 +1316,77 @@ class CodeEditor {
|
|
|
1170
1316
|
this.processLines();
|
|
1171
1317
|
doAsync( () => this._refreshCodeInfo( 0, 0 ), 50 );
|
|
1172
1318
|
}
|
|
1319
|
+
|
|
1320
|
+
// Bc it could be overrided..
|
|
1321
|
+
return name;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
loadTab( name ) {
|
|
1325
|
+
|
|
1326
|
+
// Already open...
|
|
1327
|
+
if( this.openedTabs[ name ] )
|
|
1328
|
+
{
|
|
1329
|
+
this.tabs.select( name );
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
let code = this.loadedTabs[ name ]
|
|
1334
|
+
|
|
1335
|
+
if( !code )
|
|
1336
|
+
{
|
|
1337
|
+
this.addTab( name, true );
|
|
1338
|
+
// Unload lines from file...
|
|
1339
|
+
if( this._storedLines[ name ] )
|
|
1340
|
+
{
|
|
1341
|
+
this.code.lines = this._storedLines[ name ];
|
|
1342
|
+
delete this._storedLines[ name ];
|
|
1343
|
+
}
|
|
1344
|
+
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
this.openedTabs[ name ] = code;
|
|
1349
|
+
|
|
1350
|
+
const isNewTabButton = ( name === '+' );
|
|
1351
|
+
const tabIcon = this._getFileIcon( name );
|
|
1352
|
+
|
|
1353
|
+
this.tabs.add(name, code, {
|
|
1354
|
+
selected: true,
|
|
1355
|
+
fixed: isNewTabButton,
|
|
1356
|
+
title: code.title,
|
|
1357
|
+
icon: tabIcon,
|
|
1358
|
+
onSelect: (e, tabname) => {
|
|
1359
|
+
|
|
1360
|
+
if( isNewTabButton )
|
|
1361
|
+
{
|
|
1362
|
+
this._onNewTab( e );
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
var cursor = cursor ?? this.cursors.children[ 0 ];
|
|
1367
|
+
this.saveCursor( cursor, this.code.cursorState );
|
|
1368
|
+
this.code = this.loadedTabs[ tabname ];
|
|
1369
|
+
this.restoreCursor( cursor, this.code.cursorState );
|
|
1370
|
+
this.endSelection();
|
|
1371
|
+
this._changeLanguageFromExtension( LX.getExtension( tabname ) );
|
|
1372
|
+
this._refreshCodeInfo( cursor.line, cursor.position );
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
// Move into the sizer..
|
|
1377
|
+
this.codeSizer.appendChild( code );
|
|
1378
|
+
|
|
1379
|
+
this.endSelection();
|
|
1380
|
+
|
|
1381
|
+
// Select as current...
|
|
1382
|
+
this.code = code;
|
|
1383
|
+
this.resetCursorPos( CodeEditor.CURSOR_LEFT | CodeEditor.CURSOR_TOP );
|
|
1384
|
+
this.processLines();
|
|
1385
|
+
this._changeLanguageFromExtension( LX.getExtension( name ) );
|
|
1386
|
+
doAsync( () => this._refreshCodeInfo( 0, 0 ), 50 );
|
|
1173
1387
|
}
|
|
1174
1388
|
|
|
1175
|
-
|
|
1389
|
+
loadTabFromFile() {
|
|
1176
1390
|
const input = document.createElement( 'input' );
|
|
1177
1391
|
input.type = 'file';
|
|
1178
1392
|
document.body.appendChild( input );
|
|
@@ -1270,6 +1484,7 @@ class CodeEditor {
|
|
|
1270
1484
|
this.resetCursorPos( CodeEditor.CURSOR_LEFT );
|
|
1271
1485
|
e._shiftKey = true;
|
|
1272
1486
|
this.actions['End'].callback(cursor.line, cursor, e);
|
|
1487
|
+
this._tripleClickSelection = true;
|
|
1273
1488
|
break;
|
|
1274
1489
|
}
|
|
1275
1490
|
}
|
|
@@ -1571,7 +1786,6 @@ class CodeEditor {
|
|
|
1571
1786
|
if( this.selection )
|
|
1572
1787
|
{
|
|
1573
1788
|
this.actions['Backspace'].callback(lidx, cursor, e);
|
|
1574
|
-
lidx = cursor.line; // Update this, since it's from the old code
|
|
1575
1789
|
}
|
|
1576
1790
|
|
|
1577
1791
|
// Append key
|
|
@@ -2286,6 +2500,7 @@ class CodeEditor {
|
|
|
2286
2500
|
this.selections.classList.remove('show');
|
|
2287
2501
|
this.selections.innerHTML = "";
|
|
2288
2502
|
delete this.selection;
|
|
2503
|
+
delete this._tripleClickSelection;
|
|
2289
2504
|
}
|
|
2290
2505
|
|
|
2291
2506
|
cursorToRight( key, cursor ) {
|
package/build/lexgui.css
CHANGED
|
@@ -17,12 +17,15 @@
|
|
|
17
17
|
--global-text-primary: #f4f4ffe6;
|
|
18
18
|
--global-text-secondary: #c6c6cfd9;
|
|
19
19
|
--global-dark-background: #14161a;
|
|
20
|
-
--global-blur-background: #
|
|
20
|
+
--global-blur-background: #28292ba9;
|
|
21
21
|
--transition-time: 1000;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/* Some global colors */
|
|
25
25
|
.orange { color: orange }
|
|
26
|
+
.gray { color: gray }
|
|
27
|
+
.dodgerblue { color: dodgerblue }
|
|
28
|
+
.lightblue { color: rgb(90, 168, 247) }
|
|
26
29
|
|
|
27
30
|
::-webkit-scrollbar {
|
|
28
31
|
height: 3px;
|
|
@@ -129,7 +132,7 @@ body.nocursor * {
|
|
|
129
132
|
background-color: var(--global-blur-background);
|
|
130
133
|
-webkit-backdrop-filter: blur(12px);
|
|
131
134
|
backdrop-filter: blur(12px);
|
|
132
|
-
border-radius:
|
|
135
|
+
border-radius: 8px;
|
|
133
136
|
border: 1px solid #d0d0ec6b;
|
|
134
137
|
width: 30%;
|
|
135
138
|
top: 15%;
|
|
@@ -187,6 +190,26 @@ body.nocursor * {
|
|
|
187
190
|
float: left;
|
|
188
191
|
}
|
|
189
192
|
|
|
193
|
+
#global_search .searchitembox .searchitem i {
|
|
194
|
+
width: 12px;
|
|
195
|
+
font-size: 11px;
|
|
196
|
+
margin-right: 4px;
|
|
197
|
+
margin-top: -2px;
|
|
198
|
+
vertical-align: middle;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#global_search .searchitembox .searchitem img {
|
|
202
|
+
width: 12px;
|
|
203
|
+
margin-right: 4px;
|
|
204
|
+
margin-top: -2px;
|
|
205
|
+
vertical-align: middle;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
#global_search .searchitembox .searchitem .lang-ext {
|
|
209
|
+
color: #676e75;
|
|
210
|
+
font-size: 12px;
|
|
211
|
+
}
|
|
212
|
+
|
|
190
213
|
#global_search .searchitembox .searchitem.last {
|
|
191
214
|
border-bottom-left-radius: 6px;
|
|
192
215
|
border-bottom-right-radius: 6px;
|
|
@@ -1412,6 +1435,22 @@ input[type="range"] {
|
|
|
1412
1435
|
user-select: none; /* Standard syntax */
|
|
1413
1436
|
}
|
|
1414
1437
|
|
|
1438
|
+
.lextree .lextreeitem img {
|
|
1439
|
+
width: 12px;
|
|
1440
|
+
height: 12px;
|
|
1441
|
+
margin-right: 4px;
|
|
1442
|
+
vertical-align: middle;
|
|
1443
|
+
margin-top: -1px;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
.lextree .lextreeitem .tree-item-icon {
|
|
1447
|
+
width: 12px;
|
|
1448
|
+
height: 12px;
|
|
1449
|
+
margin-right: 4px;
|
|
1450
|
+
vertical-align: middle;
|
|
1451
|
+
margin-top: -1px;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1415
1454
|
.lextree .lextreeitem.draggingover {
|
|
1416
1455
|
background: #7b8ae27b;
|
|
1417
1456
|
}
|
|
@@ -2697,9 +2736,11 @@ ul.lexassetscontent {
|
|
|
2697
2736
|
}
|
|
2698
2737
|
|
|
2699
2738
|
.codebasearea .lexareatab i {
|
|
2739
|
+
width: 12px;
|
|
2700
2740
|
font-size: 10px;
|
|
2701
2741
|
margin-right: 4px;
|
|
2702
2742
|
vertical-align: middle;
|
|
2743
|
+
margin-top: -3px;
|
|
2703
2744
|
}
|
|
2704
2745
|
|
|
2705
2746
|
.codebasearea .lexareatab img {
|
|
@@ -2707,6 +2748,7 @@ ul.lexassetscontent {
|
|
|
2707
2748
|
height: 12px;
|
|
2708
2749
|
margin-right: 4px;
|
|
2709
2750
|
vertical-align: middle;
|
|
2751
|
+
margin-top: -2px;
|
|
2710
2752
|
}
|
|
2711
2753
|
|
|
2712
2754
|
.lexcodeeditor ::-webkit-scrollbar {
|
|
@@ -2830,10 +2872,11 @@ ul.lexassetscontent {
|
|
|
2830
2872
|
}
|
|
2831
2873
|
|
|
2832
2874
|
pre .line-gutter {
|
|
2833
|
-
color: #
|
|
2875
|
+
color: #8a8b97;
|
|
2834
2876
|
width: 48px;
|
|
2835
2877
|
height: 20px;
|
|
2836
2878
|
font-size: 14px;
|
|
2879
|
+
font-weight: 400;
|
|
2837
2880
|
line-height: 20px;
|
|
2838
2881
|
text-align: center;
|
|
2839
2882
|
-webkit-user-select: none; /* Safari 3.1+ */
|
package/build/lexgui.js
CHANGED
|
@@ -12,7 +12,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
var LX = global.LX = {
|
|
15
|
-
version: "0.1.
|
|
15
|
+
version: "0.1.19",
|
|
16
16
|
ready: false,
|
|
17
17
|
components: [], // specific pre-build components
|
|
18
18
|
signals: {} // events and triggers
|
|
@@ -24,6 +24,13 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
24
24
|
function clamp (num, min, max) { return Math.min(Math.max(num, min), max) }
|
|
25
25
|
function round(num, n) { return +num.toFixed(n); }
|
|
26
26
|
|
|
27
|
+
function getSupportedDOMName( string )
|
|
28
|
+
{
|
|
29
|
+
return string.replace(/\s/g, '').replaceAll('@', '_').replaceAll('+', '_plus_').replaceAll('.', '');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
LX.getSupportedDOMName = getSupportedDOMName;
|
|
33
|
+
|
|
27
34
|
function has( component_name )
|
|
28
35
|
{
|
|
29
36
|
return (LX.components.indexOf( component_name ) > -1);
|
|
@@ -258,7 +265,16 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
258
265
|
e.stopPropagation();
|
|
259
266
|
global_search.classList.toggle('hidden');
|
|
260
267
|
global_search.querySelector('input').focus();
|
|
261
|
-
add_elements(undefined);
|
|
268
|
+
add_elements( undefined );
|
|
269
|
+
}
|
|
270
|
+
else
|
|
271
|
+
{
|
|
272
|
+
for( let c of LX.components )
|
|
273
|
+
if( LX[c].prototype.onKeyPressed )
|
|
274
|
+
{
|
|
275
|
+
const instances = LX.CodeEditor.getInstances();
|
|
276
|
+
for( let i of instances ) i.onKeyPressed( e );
|
|
277
|
+
}
|
|
262
278
|
}
|
|
263
279
|
});
|
|
264
280
|
|
|
@@ -342,18 +358,24 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
342
358
|
{
|
|
343
359
|
const instances = LX.CodeEditor.getInstances();
|
|
344
360
|
if(!instances.length) return;
|
|
345
|
-
|
|
346
|
-
const languages =
|
|
347
|
-
|
|
348
|
-
for( let l of languages ) {
|
|
349
|
-
|
|
350
|
-
const key = "
|
|
351
|
-
|
|
352
|
-
|
|
361
|
+
|
|
362
|
+
const languages = instances[ 0 ].languages;
|
|
363
|
+
|
|
364
|
+
for( let l of Object.keys( languages ) ) {
|
|
365
|
+
|
|
366
|
+
const key = "Language: " + l;
|
|
367
|
+
const icon = instances[ 0 ]._getFileIcon( null, languages[ l ].ext );
|
|
368
|
+
|
|
369
|
+
let value = icon.includes( 'fa-' ) ? "<i class='" + icon + "'></i>" :
|
|
370
|
+
"<img src='" + ( "https://raw.githubusercontent.com/jxarco/lexgui.js/master/" + icon ) + "'>";
|
|
371
|
+
|
|
372
|
+
value += key + " <span class='lang-ext'>(" + languages[ l ].ext + ")</span>";
|
|
373
|
+
if( key.toLowerCase().includes( filter ) ) {
|
|
374
|
+
add_element( value, () => {
|
|
353
375
|
for( let i of instances ) {
|
|
354
376
|
i._changeLanguage( l );
|
|
355
377
|
}
|
|
356
|
-
}, "", {});
|
|
378
|
+
}, "", {} );
|
|
357
379
|
}
|
|
358
380
|
}
|
|
359
381
|
}
|
|
@@ -1355,14 +1377,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
1355
1377
|
|
|
1356
1378
|
_moveSplit( dt, force_animation = false, force_width = 0 ) {
|
|
1357
1379
|
|
|
1358
|
-
if(!this.type)
|
|
1359
|
-
throw("No split area");
|
|
1380
|
+
if( !this.type )
|
|
1381
|
+
throw( "No split area" );
|
|
1360
1382
|
|
|
1361
|
-
if(dt === undefined) //
|
|
1383
|
+
if( dt === undefined ) // Splitbar didn't move!
|
|
1362
1384
|
return;
|
|
1363
1385
|
|
|
1364
|
-
var a1 = this.sections[0];
|
|
1365
|
-
var a2 = this.sections[1];
|
|
1386
|
+
var a1 = this.sections[ 0 ];
|
|
1387
|
+
var a2 = this.sections[ 1 ];
|
|
1366
1388
|
var splitinfo = " - "+ LX.DEFAULT_SPLITBAR_SIZE + "px";
|
|
1367
1389
|
|
|
1368
1390
|
let transition = null;
|
|
@@ -1371,29 +1393,30 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
1371
1393
|
// Remove transitions for this change..
|
|
1372
1394
|
transition = a1.root.style.transition;
|
|
1373
1395
|
a1.root.style.transition = a2.root.style.transition = "none";
|
|
1374
|
-
flushCss(a1.root);
|
|
1375
|
-
flushCss(a2.root);
|
|
1396
|
+
flushCss( a1.root );
|
|
1397
|
+
flushCss( a2.root );
|
|
1376
1398
|
}
|
|
1377
1399
|
|
|
1378
|
-
if(this.type == "horizontal")
|
|
1379
|
-
|
|
1380
|
-
var size = Math.max(a2.root.offsetWidth + dt, parseInt(a2.minWidth));
|
|
1400
|
+
if( this.type == "horizontal" )
|
|
1401
|
+
{
|
|
1402
|
+
var size = Math.max( a2.root.offsetWidth + dt, parseInt( a2.minWidth ) );
|
|
1381
1403
|
if( force_width ) size = force_width;
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
a1.root.style.minWidth = a1.minWidth + "px";
|
|
1386
|
-
|
|
1404
|
+
a1.root.style.width = "-moz-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1405
|
+
a1.root.style.width = "-webkit-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1406
|
+
a1.root.style.width = "calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1407
|
+
a1.root.style.minWidth = parseInt( a1.minWidth ) + "px";
|
|
1408
|
+
a2.root.style.width = size + "px";
|
|
1409
|
+
if( a1.maxWidth != Infinity ) a2.root.style.minWidth = "calc( 100% - " + parseInt( a1.maxWidth ) + "px" + " )";
|
|
1387
1410
|
}
|
|
1388
|
-
else
|
|
1389
|
-
|
|
1411
|
+
else
|
|
1412
|
+
{
|
|
1390
1413
|
var size = Math.max((a2.root.offsetHeight + dt) + a2.offset, parseInt(a2.minHeight));
|
|
1391
1414
|
if( force_width ) size = force_width;
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1415
|
+
a1.root.style.height = "-moz-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1416
|
+
a1.root.style.height = "-webkit-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1417
|
+
a1.root.style.height = "calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1395
1418
|
a1.root.style.minHeight = a1.minHeight + "px";
|
|
1396
|
-
|
|
1419
|
+
a2.root.style.height = ( size - a2.offset ) + "px";
|
|
1397
1420
|
}
|
|
1398
1421
|
|
|
1399
1422
|
if( !force_animation )
|
|
@@ -1604,9 +1627,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
1604
1627
|
tabEl.addEventListener("mouseup", e => {
|
|
1605
1628
|
e.preventDefault();
|
|
1606
1629
|
e.stopPropagation();
|
|
1607
|
-
if(e.button == 1 ) {
|
|
1608
|
-
if(this.onclose)
|
|
1609
|
-
this.onclose( tabEl.dataset["name"] );
|
|
1630
|
+
if( e.button == 1 ) {
|
|
1610
1631
|
this.delete( tabEl.dataset["name"] );
|
|
1611
1632
|
}
|
|
1612
1633
|
});
|
|
@@ -1617,7 +1638,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
1617
1638
|
e.preventDefault();
|
|
1618
1639
|
return;
|
|
1619
1640
|
}
|
|
1620
|
-
e.dataTransfer.setData("source", e.target.id);
|
|
1641
|
+
e.dataTransfer.setData( "source", e.target.id );
|
|
1621
1642
|
});
|
|
1622
1643
|
|
|
1623
1644
|
// Attach content
|
|
@@ -1646,6 +1667,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
1646
1667
|
if(!tabEl || tabEl.fixed)
|
|
1647
1668
|
return;
|
|
1648
1669
|
|
|
1670
|
+
if( this.onclose )
|
|
1671
|
+
this.onclose( name );
|
|
1672
|
+
|
|
1649
1673
|
// Delete tab element
|
|
1650
1674
|
this.tabDOMs[ name ].remove();
|
|
1651
1675
|
delete this.tabDOMs[ name ];
|
|
@@ -2388,22 +2412,33 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
2388
2412
|
|
|
2389
2413
|
let item = document.createElement('li');
|
|
2390
2414
|
item.className = "lextreeitem " + "datalevel" + level + (is_parent ? " parent" : "") + (is_selected ? " selected" : "");
|
|
2391
|
-
item.id = node.id;
|
|
2415
|
+
item.id = LX.getSupportedDOMName( node.id );
|
|
2392
2416
|
item.tabIndex = "0";
|
|
2393
2417
|
|
|
2394
2418
|
// Select hierarchy icon
|
|
2395
|
-
let icon = "fa-solid fa-square"; // Default: no childs
|
|
2419
|
+
let icon = (this.options.skip_default_icon ?? true) ? "" : "fa-solid fa-square"; // Default: no childs
|
|
2396
2420
|
if( is_parent ) icon = node.closed ? "fa-solid fa-caret-right" : "fa-solid fa-caret-down";
|
|
2397
2421
|
item.innerHTML = "<a class='" + icon + " hierarchy'></a>";
|
|
2398
2422
|
|
|
2399
2423
|
// Add display icon
|
|
2400
2424
|
icon = node.icon;
|
|
2401
|
-
|
|
2425
|
+
|
|
2426
|
+
// Process icon
|
|
2427
|
+
if( node.icon )
|
|
2428
|
+
{
|
|
2429
|
+
if( node.icon.includes( 'fa-' ) ) // It's fontawesome icon...
|
|
2430
|
+
item.innerHTML += "<a class='" + node.icon + " tree-item-icon'></a>";
|
|
2431
|
+
else // an image..
|
|
2432
|
+
{
|
|
2433
|
+
const rootPath = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/";
|
|
2434
|
+
item.innerHTML += "<img src='" + ( rootPath + node.icon ) + "'>";
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2402
2437
|
|
|
2403
2438
|
item.innerHTML += (node.rename ? "" : node.id);
|
|
2404
2439
|
|
|
2405
2440
|
item.setAttribute('draggable', true);
|
|
2406
|
-
item.style.paddingLeft = ((is_parent ? 0 : 3 ) + (3 + (level+1) *
|
|
2441
|
+
item.style.paddingLeft = ((is_parent ? 0 : 3 ) + (3 + (level+1) * 15)) + "px";
|
|
2407
2442
|
list.appendChild(item);
|
|
2408
2443
|
|
|
2409
2444
|
// Callbacks
|
|
@@ -2445,16 +2480,19 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
2445
2480
|
}
|
|
2446
2481
|
});
|
|
2447
2482
|
|
|
2448
|
-
|
|
2449
|
-
|
|
2483
|
+
item.addEventListener("dblclick", function() {
|
|
2484
|
+
if( that.options.rename ?? true )
|
|
2485
|
+
{
|
|
2450
2486
|
// Trigger rename
|
|
2451
2487
|
node.rename = true;
|
|
2452
2488
|
that.refresh();
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2489
|
+
}
|
|
2490
|
+
if( that.onevent )
|
|
2491
|
+
{
|
|
2492
|
+
const event = new TreeEvent(TreeEvent.NODE_DBLCLICKED, node);
|
|
2493
|
+
that.onevent( event );
|
|
2494
|
+
}
|
|
2495
|
+
});
|
|
2458
2496
|
|
|
2459
2497
|
item.addEventListener("contextmenu", e => {
|
|
2460
2498
|
e.preventDefault();
|
|
@@ -2492,7 +2530,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
2492
2530
|
else if( e.key == "ArrowUp" || e.key == "ArrowDown" ) // Unique or zero selected
|
|
2493
2531
|
{
|
|
2494
2532
|
var selected = this.selected.length > 1 ? (e.key == "ArrowUp" ? this.selected.shift() : this.selected.pop()) : this.selected[0];
|
|
2495
|
-
var el = this.domEl.querySelector("#" + selected.id);
|
|
2533
|
+
var el = this.domEl.querySelector("#" + LX.getSupportedDOMName( selected.id ) );
|
|
2496
2534
|
var sibling = e.key == "ArrowUp" ? el.previousSibling : el.nextSibling;
|
|
2497
2535
|
if( sibling ) sibling.click();
|
|
2498
2536
|
}
|
|
@@ -2520,7 +2558,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
2520
2558
|
that.onevent( event );
|
|
2521
2559
|
}
|
|
2522
2560
|
|
|
2523
|
-
node.id = this.value;
|
|
2561
|
+
node.id = LX.getSupportedDOMName( this.value );
|
|
2524
2562
|
delete node.rename;
|
|
2525
2563
|
that.frefresh( node.id );
|
|
2526
2564
|
list.querySelector("#" + this.value).classList.add('selected');
|
|
@@ -2671,21 +2709,21 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
2671
2709
|
}
|
|
2672
2710
|
}
|
|
2673
2711
|
|
|
2674
|
-
refresh(newData, selectedId) {
|
|
2712
|
+
refresh( newData, selectedId ) {
|
|
2675
2713
|
this.data = newData ?? this.data;
|
|
2676
|
-
this.domEl.querySelector("ul").innerHTML = "";
|
|
2714
|
+
this.domEl.querySelector( "ul" ).innerHTML = "";
|
|
2677
2715
|
this._create_item( null, this.data, 0, selectedId );
|
|
2678
2716
|
}
|
|
2679
|
-
|
|
2717
|
+
|
|
2680
2718
|
/* Refreshes the tree and focuses current element */
|
|
2681
2719
|
frefresh( id ) {
|
|
2682
2720
|
this.refresh();
|
|
2683
|
-
var el = this.domEl.querySelector("#" + id);
|
|
2684
|
-
if(el) el.focus();
|
|
2721
|
+
var el = this.domEl.querySelector( "#" + id );
|
|
2722
|
+
if( el ) el.focus();
|
|
2685
2723
|
}
|
|
2686
|
-
|
|
2687
|
-
select(id) {
|
|
2688
|
-
this.refresh(null, id);
|
|
2724
|
+
|
|
2725
|
+
select( id ) {
|
|
2726
|
+
this.refresh( null, id );
|
|
2689
2727
|
}
|
|
2690
2728
|
}
|
|
2691
2729
|
|
|
@@ -5852,7 +5890,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
5852
5890
|
const hasSubmenu = o[ k ].length;
|
|
5853
5891
|
let entry = document.createElement('div');
|
|
5854
5892
|
entry.className = "lexcontextmenuentry" + (o[ 'className' ] ? " " + o[ 'className' ] : "" );
|
|
5855
|
-
entry.id = o.id ?? ("eId" +
|
|
5893
|
+
entry.id = o.id ?? ("eId" + getSupportedDOMName( k ));
|
|
5856
5894
|
entry.innerHTML = "";
|
|
5857
5895
|
const icon = o[ 'icon' ];
|
|
5858
5896
|
if(icon) {
|
|
@@ -5999,7 +6037,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
5999
6037
|
for( let item of this.items )
|
|
6000
6038
|
{
|
|
6001
6039
|
let key = Object.keys(item)[0];
|
|
6002
|
-
let pKey = "eId" +
|
|
6040
|
+
let pKey = "eId" + getSupportedDOMName( key );
|
|
6003
6041
|
|
|
6004
6042
|
// Item already created
|
|
6005
6043
|
const id = "#" + (item.id ?? pKey);
|
|
@@ -6015,10 +6053,6 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
|
|
|
6015
6053
|
|
|
6016
6054
|
this.colors[ token ] = color;
|
|
6017
6055
|
}
|
|
6018
|
-
|
|
6019
|
-
_getSupportedDOMName( key ) {
|
|
6020
|
-
return key.replace(/\s/g, '').replaceAll('@', '_').replaceAll('+', '_plus_');
|
|
6021
|
-
}
|
|
6022
6056
|
};
|
|
6023
6057
|
|
|
6024
6058
|
LX.ContextMenu = ContextMenu;
|
package/build/lexgui.module.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
var LX = {
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.19",
|
|
12
12
|
ready: false,
|
|
13
13
|
components: [], // specific pre-build components
|
|
14
14
|
signals: {} // events and triggers
|
|
@@ -20,6 +20,13 @@ LX.MOUSE_TRIPLE_CLICK = 3;
|
|
|
20
20
|
function clamp (num, min, max) { return Math.min(Math.max(num, min), max) }
|
|
21
21
|
function round(num, n) { return +num.toFixed(n); }
|
|
22
22
|
|
|
23
|
+
function getSupportedDOMName( string )
|
|
24
|
+
{
|
|
25
|
+
return string.replace(/\s/g, '').replaceAll('@', '_').replaceAll('+', '_plus_').replaceAll('.', '');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
LX.getSupportedDOMName = getSupportedDOMName;
|
|
29
|
+
|
|
23
30
|
function has( component_name )
|
|
24
31
|
{
|
|
25
32
|
return (LX.components.indexOf( component_name ) > -1);
|
|
@@ -254,7 +261,16 @@ function create_global_searchbar( root ) {
|
|
|
254
261
|
e.stopPropagation();
|
|
255
262
|
global_search.classList.toggle('hidden');
|
|
256
263
|
global_search.querySelector('input').focus();
|
|
257
|
-
add_elements(undefined);
|
|
264
|
+
add_elements( undefined );
|
|
265
|
+
}
|
|
266
|
+
else
|
|
267
|
+
{
|
|
268
|
+
for( let c of LX.components )
|
|
269
|
+
if( LX[c].prototype.onKeyPressed )
|
|
270
|
+
{
|
|
271
|
+
const instances = LX.CodeEditor.getInstances();
|
|
272
|
+
for( let i of instances ) i.onKeyPressed( e );
|
|
273
|
+
}
|
|
258
274
|
}
|
|
259
275
|
});
|
|
260
276
|
|
|
@@ -339,17 +355,23 @@ function create_global_searchbar( root ) {
|
|
|
339
355
|
const instances = LX.CodeEditor.getInstances();
|
|
340
356
|
if(!instances.length) return;
|
|
341
357
|
|
|
342
|
-
const languages =
|
|
358
|
+
const languages = instances[ 0 ].languages;
|
|
359
|
+
|
|
360
|
+
for( let l of Object.keys( languages ) ) {
|
|
343
361
|
|
|
344
|
-
|
|
362
|
+
const key = "Language: " + l;
|
|
363
|
+
const icon = instances[ 0 ]._getFileIcon( null, languages[ l ].ext );
|
|
345
364
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
365
|
+
let value = icon.includes( 'fa-' ) ? "<i class='" + icon + "'></i>" :
|
|
366
|
+
"<img src='" + ( "https://raw.githubusercontent.com/jxarco/lexgui.js/master/" + icon ) + "'>";
|
|
367
|
+
|
|
368
|
+
value += key + " <span class='lang-ext'>(" + languages[ l ].ext + ")</span>";
|
|
369
|
+
if( key.toLowerCase().includes( filter ) ) {
|
|
370
|
+
add_element( value, () => {
|
|
349
371
|
for( let i of instances ) {
|
|
350
372
|
i._changeLanguage( l );
|
|
351
373
|
}
|
|
352
|
-
}, "", {});
|
|
374
|
+
}, "", {} );
|
|
353
375
|
}
|
|
354
376
|
}
|
|
355
377
|
}
|
|
@@ -1351,14 +1373,14 @@ class Area {
|
|
|
1351
1373
|
|
|
1352
1374
|
_moveSplit( dt, force_animation = false, force_width = 0 ) {
|
|
1353
1375
|
|
|
1354
|
-
if(!this.type)
|
|
1355
|
-
throw("No split area");
|
|
1376
|
+
if( !this.type )
|
|
1377
|
+
throw( "No split area" );
|
|
1356
1378
|
|
|
1357
|
-
if(dt === undefined) //
|
|
1379
|
+
if( dt === undefined ) // Splitbar didn't move!
|
|
1358
1380
|
return;
|
|
1359
1381
|
|
|
1360
|
-
var a1 = this.sections[0];
|
|
1361
|
-
var a2 = this.sections[1];
|
|
1382
|
+
var a1 = this.sections[ 0 ];
|
|
1383
|
+
var a2 = this.sections[ 1 ];
|
|
1362
1384
|
var splitinfo = " - "+ LX.DEFAULT_SPLITBAR_SIZE + "px";
|
|
1363
1385
|
|
|
1364
1386
|
let transition = null;
|
|
@@ -1367,29 +1389,30 @@ class Area {
|
|
|
1367
1389
|
// Remove transitions for this change..
|
|
1368
1390
|
transition = a1.root.style.transition;
|
|
1369
1391
|
a1.root.style.transition = a2.root.style.transition = "none";
|
|
1370
|
-
flushCss(a1.root);
|
|
1371
|
-
flushCss(a2.root);
|
|
1392
|
+
flushCss( a1.root );
|
|
1393
|
+
flushCss( a2.root );
|
|
1372
1394
|
}
|
|
1373
1395
|
|
|
1374
|
-
if(this.type == "horizontal")
|
|
1375
|
-
|
|
1376
|
-
var size = Math.max(a2.root.offsetWidth + dt, parseInt(a2.minWidth));
|
|
1396
|
+
if( this.type == "horizontal" )
|
|
1397
|
+
{
|
|
1398
|
+
var size = Math.max( a2.root.offsetWidth + dt, parseInt( a2.minWidth ) );
|
|
1377
1399
|
if( force_width ) size = force_width;
|
|
1378
1400
|
a1.root.style.width = "-moz-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1379
1401
|
a1.root.style.width = "-webkit-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1380
1402
|
a1.root.style.width = "calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1381
|
-
a1.root.style.minWidth = a1.minWidth + "px";
|
|
1382
|
-
a2.root.style.width = size + "px";
|
|
1403
|
+
a1.root.style.minWidth = parseInt( a1.minWidth ) + "px";
|
|
1404
|
+
a2.root.style.width = size + "px";
|
|
1405
|
+
if( a1.maxWidth != Infinity ) a2.root.style.minWidth = "calc( 100% - " + parseInt( a1.maxWidth ) + "px" + " )";
|
|
1383
1406
|
}
|
|
1384
|
-
else
|
|
1385
|
-
|
|
1407
|
+
else
|
|
1408
|
+
{
|
|
1386
1409
|
var size = Math.max((a2.root.offsetHeight + dt) + a2.offset, parseInt(a2.minHeight));
|
|
1387
1410
|
if( force_width ) size = force_width;
|
|
1388
1411
|
a1.root.style.height = "-moz-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1389
1412
|
a1.root.style.height = "-webkit-calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1390
1413
|
a1.root.style.height = "calc( 100% - " + size + "px " + splitinfo + " )";
|
|
1391
1414
|
a1.root.style.minHeight = a1.minHeight + "px";
|
|
1392
|
-
a2.root.style.height = ( size - a2.offset ) + "px";
|
|
1415
|
+
a2.root.style.height = ( size - a2.offset ) + "px";
|
|
1393
1416
|
}
|
|
1394
1417
|
|
|
1395
1418
|
if( !force_animation )
|
|
@@ -1600,9 +1623,7 @@ class Tabs {
|
|
|
1600
1623
|
tabEl.addEventListener("mouseup", e => {
|
|
1601
1624
|
e.preventDefault();
|
|
1602
1625
|
e.stopPropagation();
|
|
1603
|
-
if(e.button == 1 ) {
|
|
1604
|
-
if(this.onclose)
|
|
1605
|
-
this.onclose( tabEl.dataset["name"] );
|
|
1626
|
+
if( e.button == 1 ) {
|
|
1606
1627
|
this.delete( tabEl.dataset["name"] );
|
|
1607
1628
|
}
|
|
1608
1629
|
});
|
|
@@ -1613,7 +1634,7 @@ class Tabs {
|
|
|
1613
1634
|
e.preventDefault();
|
|
1614
1635
|
return;
|
|
1615
1636
|
}
|
|
1616
|
-
e.dataTransfer.setData("source", e.target.id);
|
|
1637
|
+
e.dataTransfer.setData( "source", e.target.id );
|
|
1617
1638
|
});
|
|
1618
1639
|
|
|
1619
1640
|
// Attach content
|
|
@@ -1642,6 +1663,9 @@ class Tabs {
|
|
|
1642
1663
|
if(!tabEl || tabEl.fixed)
|
|
1643
1664
|
return;
|
|
1644
1665
|
|
|
1666
|
+
if( this.onclose )
|
|
1667
|
+
this.onclose( name );
|
|
1668
|
+
|
|
1645
1669
|
// Delete tab element
|
|
1646
1670
|
this.tabDOMs[ name ].remove();
|
|
1647
1671
|
delete this.tabDOMs[ name ];
|
|
@@ -2384,22 +2408,33 @@ class NodeTree {
|
|
|
2384
2408
|
|
|
2385
2409
|
let item = document.createElement('li');
|
|
2386
2410
|
item.className = "lextreeitem " + "datalevel" + level + (is_parent ? " parent" : "") + (is_selected ? " selected" : "");
|
|
2387
|
-
item.id = node.id;
|
|
2411
|
+
item.id = LX.getSupportedDOMName( node.id );
|
|
2388
2412
|
item.tabIndex = "0";
|
|
2389
2413
|
|
|
2390
2414
|
// Select hierarchy icon
|
|
2391
|
-
let icon = "fa-solid fa-square"; // Default: no childs
|
|
2415
|
+
let icon = (this.options.skip_default_icon ?? true) ? "" : "fa-solid fa-square"; // Default: no childs
|
|
2392
2416
|
if( is_parent ) icon = node.closed ? "fa-solid fa-caret-right" : "fa-solid fa-caret-down";
|
|
2393
2417
|
item.innerHTML = "<a class='" + icon + " hierarchy'></a>";
|
|
2394
2418
|
|
|
2395
2419
|
// Add display icon
|
|
2396
2420
|
icon = node.icon;
|
|
2397
|
-
|
|
2421
|
+
|
|
2422
|
+
// Process icon
|
|
2423
|
+
if( node.icon )
|
|
2424
|
+
{
|
|
2425
|
+
if( node.icon.includes( 'fa-' ) ) // It's fontawesome icon...
|
|
2426
|
+
item.innerHTML += "<a class='" + node.icon + " tree-item-icon'></a>";
|
|
2427
|
+
else // an image..
|
|
2428
|
+
{
|
|
2429
|
+
const rootPath = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/";
|
|
2430
|
+
item.innerHTML += "<img src='" + ( rootPath + node.icon ) + "'>";
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2398
2433
|
|
|
2399
2434
|
item.innerHTML += (node.rename ? "" : node.id);
|
|
2400
2435
|
|
|
2401
2436
|
item.setAttribute('draggable', true);
|
|
2402
|
-
item.style.paddingLeft = ((is_parent ? 0 : 3 ) + (3 + (level+1) *
|
|
2437
|
+
item.style.paddingLeft = ((is_parent ? 0 : 3 ) + (3 + (level+1) * 15)) + "px";
|
|
2403
2438
|
list.appendChild(item);
|
|
2404
2439
|
|
|
2405
2440
|
// Callbacks
|
|
@@ -2441,16 +2476,19 @@ class NodeTree {
|
|
|
2441
2476
|
}
|
|
2442
2477
|
});
|
|
2443
2478
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2479
|
+
item.addEventListener("dblclick", function() {
|
|
2480
|
+
if( that.options.rename ?? true )
|
|
2481
|
+
{
|
|
2446
2482
|
// Trigger rename
|
|
2447
2483
|
node.rename = true;
|
|
2448
2484
|
that.refresh();
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2485
|
+
}
|
|
2486
|
+
if( that.onevent )
|
|
2487
|
+
{
|
|
2488
|
+
const event = new TreeEvent(TreeEvent.NODE_DBLCLICKED, node);
|
|
2489
|
+
that.onevent( event );
|
|
2490
|
+
}
|
|
2491
|
+
});
|
|
2454
2492
|
|
|
2455
2493
|
item.addEventListener("contextmenu", e => {
|
|
2456
2494
|
e.preventDefault();
|
|
@@ -2488,7 +2526,7 @@ class NodeTree {
|
|
|
2488
2526
|
else if( e.key == "ArrowUp" || e.key == "ArrowDown" ) // Unique or zero selected
|
|
2489
2527
|
{
|
|
2490
2528
|
var selected = this.selected.length > 1 ? (e.key == "ArrowUp" ? this.selected.shift() : this.selected.pop()) : this.selected[0];
|
|
2491
|
-
var el = this.domEl.querySelector("#" + selected.id);
|
|
2529
|
+
var el = this.domEl.querySelector("#" + LX.getSupportedDOMName( selected.id ) );
|
|
2492
2530
|
var sibling = e.key == "ArrowUp" ? el.previousSibling : el.nextSibling;
|
|
2493
2531
|
if( sibling ) sibling.click();
|
|
2494
2532
|
}
|
|
@@ -2516,10 +2554,10 @@ class NodeTree {
|
|
|
2516
2554
|
that.onevent( event );
|
|
2517
2555
|
}
|
|
2518
2556
|
|
|
2519
|
-
node.id = this.value;
|
|
2557
|
+
node.id = LX.getSupportedDOMName( this.value );
|
|
2520
2558
|
delete node.rename;
|
|
2521
2559
|
that.frefresh( node.id );
|
|
2522
|
-
list.querySelector("#" +
|
|
2560
|
+
list.querySelector("#" + node.id).classList.add('selected');
|
|
2523
2561
|
}
|
|
2524
2562
|
if(e.key == 'Escape') {
|
|
2525
2563
|
delete node.rename;
|
|
@@ -2667,21 +2705,21 @@ class NodeTree {
|
|
|
2667
2705
|
}
|
|
2668
2706
|
}
|
|
2669
2707
|
|
|
2670
|
-
refresh(newData, selectedId) {
|
|
2708
|
+
refresh( newData, selectedId ) {
|
|
2671
2709
|
this.data = newData ?? this.data;
|
|
2672
|
-
this.domEl.querySelector("ul").innerHTML = "";
|
|
2710
|
+
this.domEl.querySelector( "ul" ).innerHTML = "";
|
|
2673
2711
|
this._create_item( null, this.data, 0, selectedId );
|
|
2674
2712
|
}
|
|
2675
2713
|
|
|
2676
2714
|
/* Refreshes the tree and focuses current element */
|
|
2677
2715
|
frefresh( id ) {
|
|
2678
2716
|
this.refresh();
|
|
2679
|
-
var el = this.domEl.querySelector("#" + id);
|
|
2680
|
-
if(el) el.focus();
|
|
2717
|
+
var el = this.domEl.querySelector( "#" + id );
|
|
2718
|
+
if( el ) el.focus();
|
|
2681
2719
|
}
|
|
2682
2720
|
|
|
2683
|
-
select(id) {
|
|
2684
|
-
this.refresh(null, id);
|
|
2721
|
+
select( id ) {
|
|
2722
|
+
this.refresh( null, id );
|
|
2685
2723
|
}
|
|
2686
2724
|
}
|
|
2687
2725
|
|
|
@@ -5848,7 +5886,7 @@ class ContextMenu {
|
|
|
5848
5886
|
const hasSubmenu = o[ k ].length;
|
|
5849
5887
|
let entry = document.createElement('div');
|
|
5850
5888
|
entry.className = "lexcontextmenuentry" + (o[ 'className' ] ? " " + o[ 'className' ] : "" );
|
|
5851
|
-
entry.id = o.id ?? ("eId" +
|
|
5889
|
+
entry.id = o.id ?? ("eId" + getSupportedDOMName( k ));
|
|
5852
5890
|
entry.innerHTML = "";
|
|
5853
5891
|
const icon = o[ 'icon' ];
|
|
5854
5892
|
if(icon) {
|
|
@@ -5995,7 +6033,7 @@ class ContextMenu {
|
|
|
5995
6033
|
for( let item of this.items )
|
|
5996
6034
|
{
|
|
5997
6035
|
let key = Object.keys(item)[0];
|
|
5998
|
-
let pKey = "eId" +
|
|
6036
|
+
let pKey = "eId" + getSupportedDOMName( key );
|
|
5999
6037
|
|
|
6000
6038
|
// Item already created
|
|
6001
6039
|
const id = "#" + (item.id ?? pKey);
|
|
@@ -6011,11 +6049,6 @@ class ContextMenu {
|
|
|
6011
6049
|
|
|
6012
6050
|
this.colors[ token ] = color;
|
|
6013
6051
|
}
|
|
6014
|
-
|
|
6015
|
-
_getSupportedDOMName( key ) {
|
|
6016
|
-
return key.replace(/\s/g, '').replaceAll('@', '_').replaceAll('+', '_plus_');
|
|
6017
|
-
}
|
|
6018
|
-
|
|
6019
6052
|
};
|
|
6020
6053
|
|
|
6021
6054
|
LX.ContextMenu = ContextMenu;
|
|
@@ -24,47 +24,53 @@
|
|
|
24
24
|
let area = LX.init();
|
|
25
25
|
|
|
26
26
|
// split main area
|
|
27
|
-
var [leftArea, rightArea] = area.split({ sizes:["55%","45%"] });
|
|
27
|
+
// var [leftArea, rightArea] = area.split({ sizes:["55%","45%"] });
|
|
28
28
|
|
|
29
29
|
// add canvas to leftArea
|
|
30
|
-
var canvas = document.createElement('canvas');
|
|
31
|
-
canvas.id = "mycanvas";
|
|
32
|
-
canvas.width = leftArea.root.clientWidth;
|
|
33
|
-
canvas.height = leftArea.root.clientHeight;
|
|
34
|
-
canvas.style.width = "100%";
|
|
35
|
-
canvas.style.height = "100%";
|
|
36
|
-
leftArea.attach( canvas );
|
|
30
|
+
// var canvas = document.createElement('canvas');
|
|
31
|
+
// canvas.id = "mycanvas";
|
|
32
|
+
// canvas.width = leftArea.root.clientWidth;
|
|
33
|
+
// canvas.height = leftArea.root.clientHeight;
|
|
34
|
+
// canvas.style.width = "100%";
|
|
35
|
+
// canvas.style.height = "100%";
|
|
36
|
+
// leftArea.attach( canvas );
|
|
37
37
|
|
|
38
38
|
// add on resize event to control canvas size
|
|
39
|
-
leftArea.onresize = function( bounding ) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
39
|
+
// leftArea.onresize = function( bounding ) {
|
|
40
|
+
// canvas.width = bounding.width;
|
|
41
|
+
// canvas.height = bounding.height;
|
|
42
|
+
// };
|
|
43
43
|
|
|
44
|
-
let editor = new LX.CodeEditor(
|
|
44
|
+
let editor = new LX.CodeEditor(area, {
|
|
45
45
|
// allow_add_scripts: false,
|
|
46
46
|
// autocomplete: false,
|
|
47
|
-
// disable_edition: true
|
|
47
|
+
// disable_edition: true,
|
|
48
|
+
file_explorer: true
|
|
48
49
|
});
|
|
49
50
|
|
|
50
|
-
editor.loadFile( "../
|
|
51
|
+
editor.loadFile( "../data/test.json" );
|
|
52
|
+
editor.loadFile( "../data/style.css" );
|
|
53
|
+
editor.loadFile( "../data/engine.cpp" );
|
|
54
|
+
editor.loadFile( "../data/script.js" );
|
|
55
|
+
editor.loadFile( "../data/xml_test.xml" );
|
|
56
|
+
editor.loadFile( "../localhost.bat" );
|
|
51
57
|
|
|
52
|
-
var ctx = canvas.getContext("2d");
|
|
53
|
-
ctx.fillStyle = "#b7a9b1";
|
|
54
|
-
ctx.font = "48px Monospace";
|
|
55
|
-
ctx.strokeStyle = "#ff1999";
|
|
58
|
+
// var ctx = canvas.getContext("2d");
|
|
59
|
+
// ctx.fillStyle = "#b7a9b1";
|
|
60
|
+
// ctx.font = "48px Monospace";
|
|
61
|
+
// ctx.strokeStyle = "#ff1999";
|
|
56
62
|
|
|
57
|
-
function loop(dt) {
|
|
63
|
+
// function loop(dt) {
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
// var ctx = canvas.getContext("2d");
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
// ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
68
|
+
// ctx.strokeText("Lexgui.js @jxarco", 200, 300);
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
}
|
|
70
|
+
// requestAnimationFrame(loop);
|
|
71
|
+
// }
|
|
66
72
|
|
|
67
|
-
requestAnimationFrame(loop);
|
|
73
|
+
// requestAnimationFrame(loop);
|
|
68
74
|
|
|
69
75
|
</script>
|
|
70
76
|
</html>
|