lexgui 0.7.9 → 0.7.11

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/lexgui.js CHANGED
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
14
14
  */
15
15
 
16
16
  const LX = {
17
- version: "0.7.9",
17
+ version: "0.7.11",
18
18
  ready: false,
19
19
  extensions: [], // Store extensions used
20
20
  signals: {}, // Events and triggers
@@ -654,10 +654,11 @@ class TreeEvent {
654
654
  static NODE_VISIBILITY = 7;
655
655
  static NODE_CARETCHANGED = 8;
656
656
 
657
- constructor( type, node, value ) {
657
+ constructor( type, node, value, event ) {
658
658
  this.type = type || TreeEvent.NONE;
659
659
  this.node = node;
660
660
  this.value = value;
661
+ this.event = event;
661
662
  this.multiple = false; // Multiple selection
662
663
  this.panel = null;
663
664
  }
@@ -2584,9 +2585,11 @@ class Tabs {
2584
2585
 
2585
2586
  if( isSelected && this.thumb )
2586
2587
  {
2588
+ this.thumb.classList.add( "no-transition" );
2587
2589
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2588
2590
  this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2589
2591
  this.thumb.item = tabEl;
2592
+ this.thumb.classList.remove( "no-transition" );
2590
2593
  }
2591
2594
 
2592
2595
  }, 10 );
@@ -5542,47 +5545,49 @@ function makeCodeSnippet( code, size, options = { } )
5542
5545
  disableEdition: true,
5543
5546
  allowAddScripts: false,
5544
5547
  name: options.tabName,
5545
- // showTab: options.showTab ?? true
5546
- } );
5547
- editor.setText( code, options.language ?? "Plain Text" );
5548
-
5549
- if( options.linesAdded )
5550
- {
5551
- const code = editor.root.querySelector( ".code" );
5552
- for( let l of options.linesAdded )
5548
+ callback: () =>
5553
5549
  {
5554
- if( l.constructor == Number )
5555
- {
5556
- code.childNodes[ l - 1 ].classList.add( "added" );
5557
- }
5558
- else if( l.constructor == Array ) // It's a range
5550
+ if( options.linesAdded )
5559
5551
  {
5560
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5552
+ const code = editor.root.querySelector( ".code" );
5553
+ for( let l of options.linesAdded )
5561
5554
  {
5562
- code.childNodes[ i ].classList.add( "added" );
5555
+ if( l.constructor == Number )
5556
+ {
5557
+ code.childNodes[ l - 1 ].classList.add( "added" );
5558
+ }
5559
+ else if( l.constructor == Array ) // It's a range
5560
+ {
5561
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5562
+ {
5563
+ code.childNodes[ i ].classList.add( "added" );
5564
+ }
5565
+ }
5563
5566
  }
5564
5567
  }
5565
- }
5566
- }
5567
5568
 
5568
- if( options.linesRemoved )
5569
- {
5570
- const code = editor.root.querySelector( ".code" );
5571
- for( let l of options.linesRemoved )
5572
- {
5573
- if( l.constructor == Number )
5574
- {
5575
- code.childNodes[ l - 1 ].classList.add( "removed" );
5576
- }
5577
- else if( l.constructor == Array ) // It's a range
5569
+ if( options.linesRemoved )
5578
5570
  {
5579
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5571
+ const code = editor.root.querySelector( ".code" );
5572
+ for( let l of options.linesRemoved )
5580
5573
  {
5581
- code.childNodes[ i ].classList.add( "removed" );
5574
+ if( l.constructor == Number )
5575
+ {
5576
+ code.childNodes[ l - 1 ].classList.add( "removed" );
5577
+ }
5578
+ else if( l.constructor == Array ) // It's a range
5579
+ {
5580
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5581
+ {
5582
+ code.childNodes[ i ].classList.add( "removed" );
5583
+ }
5584
+ }
5582
5585
  }
5583
5586
  }
5584
5587
  }
5585
- }
5588
+ } );
5589
+
5590
+ editor.setText( code, options.language ?? "Plain Text" );
5586
5591
 
5587
5592
  if( options.windowMode )
5588
5593
  {
@@ -5607,6 +5612,7 @@ function makeCodeSnippet( code, size, options = { } )
5607
5612
  }
5608
5613
 
5609
5614
  snippet.appendChild( area.root );
5615
+
5610
5616
  return snippet;
5611
5617
  }
5612
5618
 
@@ -7539,21 +7545,25 @@ class Area {
7539
7545
  let [ area1, area2 ] = this.sections;
7540
7546
  this.splitExtended = true;
7541
7547
 
7548
+ area1.root.classList.add( `maximize-${ this.type }` );
7549
+ area2.root.classList.add( `minimize-${ this.type }` );
7550
+ area2.root.classList.add( `fadeout-${ this.type }` );
7551
+ area2.root.classList.remove( `fadein-${ this.type }` );
7552
+
7542
7553
  if( this.type == "vertical" )
7543
7554
  {
7544
7555
  this.offset = area2.root.offsetHeight;
7545
- area2.root.classList.add("fadeout-vertical");
7546
7556
  this._moveSplit( -Infinity, true );
7547
-
7548
7557
  }
7549
7558
  else
7550
7559
  {
7551
7560
  this.offset = area2.root.offsetWidth - 8; // Force some height here...
7552
- area2.root.classList.add("fadeout-horizontal");
7553
7561
  this._moveSplit( -Infinity, true, 8 );
7554
7562
  }
7555
7563
 
7556
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7564
+ LX.doAsync( () => {
7565
+ this.propagateEvent( 'onresize' );
7566
+ }, 100 );
7557
7567
  }
7558
7568
 
7559
7569
  /**
@@ -7563,23 +7573,24 @@ class Area {
7563
7573
  reduce() {
7564
7574
 
7565
7575
  if( !this.splitExtended )
7566
- return;
7576
+ {
7577
+ return;
7578
+ }
7567
7579
 
7568
7580
  this.splitExtended = false;
7569
- let [area1, area2] = this.sections;
7570
7581
 
7571
- if( this.type == "vertical")
7572
- {
7573
- area2.root.classList.add("fadein-vertical");
7574
- this._moveSplit(this.offset);
7575
- }
7576
- else
7577
- {
7578
- area2.root.classList.add("fadein-horizontal");
7579
- this._moveSplit(this.offset);
7580
- }
7582
+ let [ area1, area2 ] = this.sections;
7581
7583
 
7582
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7584
+ area1.root.classList.add( `minimize-${ this.type }` );
7585
+ area2.root.classList.add( `maximize-${ this.type }` );
7586
+ area2.root.classList.add( `fadein-${ this.type }` );
7587
+ area2.root.classList.remove( `fadeout-${ this.type }` );
7588
+
7589
+ this._moveSplit( this.offset );
7590
+
7591
+ LX.doAsync( () => {
7592
+ this.propagateEvent( 'onresize' );
7593
+ }, 100 );
7583
7594
  }
7584
7595
 
7585
7596
  /**
@@ -7942,8 +7953,8 @@ class BaseComponent {
7942
7953
  BaseComponent.PROGRESS
7943
7954
  ];
7944
7955
 
7945
- constructor( type, name, value, options = {} ) {
7946
-
7956
+ constructor( type, name, value, options = {} )
7957
+ {
7947
7958
  this.type = type;
7948
7959
  this.name = name;
7949
7960
  this.options = options;
@@ -8041,13 +8052,14 @@ class BaseComponent {
8041
8052
  this.options = options;
8042
8053
  }
8043
8054
 
8044
- static _dispatchEvent( element, type, data, bubbles, cancelable ) {
8055
+ static _dispatchEvent( element, type, data, bubbles, cancelable )
8056
+ {
8045
8057
  let event = new CustomEvent( type, { 'detail': data, 'bubbles': bubbles, 'cancelable': cancelable } );
8046
8058
  element.dispatchEvent( event );
8047
8059
  }
8048
8060
 
8049
- _addResetProperty( container, callback ) {
8050
-
8061
+ _addResetProperty( container, callback )
8062
+ {
8051
8063
  const domEl = LX.makeIcon( "Undo2", { iconClass: "ml-0 mr-1 px-1", title: "Reset" } );
8052
8064
  domEl.style.display = "none";
8053
8065
  domEl.addEventListener( "click", callback );
@@ -8055,7 +8067,8 @@ class BaseComponent {
8055
8067
  return domEl;
8056
8068
  }
8057
8069
 
8058
- _canPaste() {
8070
+ _canPaste()
8071
+ {
8059
8072
  let pasteAllowed = this.type === BaseComponent.CUSTOM ?
8060
8073
  ( navigator.clipboard.customIdx !== undefined && this.customIdx == navigator.clipboard.customIdx ) : navigator.clipboard.type === this.type;
8061
8074
 
@@ -8069,8 +8082,8 @@ class BaseComponent {
8069
8082
  return pasteAllowed;
8070
8083
  }
8071
8084
 
8072
- _trigger( event, callback, scope = this ) {
8073
-
8085
+ _trigger( event, callback, scope = this )
8086
+ {
8074
8087
  if( !callback )
8075
8088
  {
8076
8089
  return;
@@ -8079,8 +8092,8 @@ class BaseComponent {
8079
8092
  callback.call( scope, event.value, event.domEvent, event.name );
8080
8093
  }
8081
8094
 
8082
- value() {
8083
-
8095
+ value()
8096
+ {
8084
8097
  if( this.onGetValue )
8085
8098
  {
8086
8099
  return this.onGetValue();
@@ -8089,8 +8102,8 @@ class BaseComponent {
8089
8102
  console.warn( "Can't get value of " + this.typeName() );
8090
8103
  }
8091
8104
 
8092
- set( value, skipCallback, event ) {
8093
-
8105
+ set( value, skipCallback, event )
8106
+ {
8094
8107
  if( this.onSetValue )
8095
8108
  {
8096
8109
  let resetButton = this.root.querySelector( ".lexcomponentname .lexicon" );
@@ -8098,12 +8111,13 @@ class BaseComponent {
8098
8111
  {
8099
8112
  resetButton.style.display = ( value != this.value() ? "block" : "none" );
8100
8113
 
8101
- const equalInitial = value.constructor === Array ? (function arraysEqual(a, b) {
8102
- if (a === b) return true;
8103
- if (a == null || b == null) return false;
8104
- if (a.length !== b.length) return false;
8105
- for (var i = 0; i < a.length; ++i) {
8106
- if (a[ i ] !== b[ i ]) return false;
8114
+ const equalInitial = value.constructor === Array ? (function arraysEqual( a, b ) {
8115
+ if( a === b ) return true;
8116
+ if( a == null || b == null ) return false;
8117
+ if( a.length !== b.length ) return false;
8118
+ for( var i = 0; i < a.length; ++i )
8119
+ {
8120
+ if( a[ i ] !== b[ i ] ) return false;
8107
8121
  }
8108
8122
  return true;
8109
8123
  })( value, this._initialValue ) : ( value == this._initialValue );
@@ -8114,11 +8128,11 @@ class BaseComponent {
8114
8128
  return this.onSetValue( value, skipCallback ?? false, event );
8115
8129
  }
8116
8130
 
8117
- console.warn("Can't set value of " + this.typeName());
8131
+ console.warn( `Can't set value of ${ this.typeName() }`);
8118
8132
  }
8119
8133
 
8120
- oncontextmenu( e ) {
8121
-
8134
+ oncontextmenu( e )
8135
+ {
8122
8136
  if( BaseComponent.NO_CONTEXT_TYPES.includes( this.type ) )
8123
8137
  {
8124
8138
  return;
@@ -8130,14 +8144,16 @@ class BaseComponent {
8130
8144
  });
8131
8145
  }
8132
8146
 
8133
- copy() {
8147
+ copy()
8148
+ {
8134
8149
  navigator.clipboard.type = this.type;
8135
8150
  navigator.clipboard.customIdx = this.customIdx;
8136
8151
  navigator.clipboard.data = this.value();
8137
8152
  navigator.clipboard.writeText( navigator.clipboard.data );
8138
8153
  }
8139
8154
 
8140
- paste() {
8155
+ paste()
8156
+ {
8141
8157
  if( !this._canPaste() )
8142
8158
  {
8143
8159
  return;
@@ -8146,8 +8162,8 @@ class BaseComponent {
8146
8162
  this.set( navigator.clipboard.data );
8147
8163
  }
8148
8164
 
8149
- typeName() {
8150
-
8165
+ typeName()
8166
+ {
8151
8167
  switch( this.type )
8152
8168
  {
8153
8169
  case BaseComponent.TEXT: return "Text";
@@ -8199,8 +8215,8 @@ function ADD_CUSTOM_COMPONENT( customComponentName, options = {} )
8199
8215
  {
8200
8216
  let customIdx = LX.guidGenerator();
8201
8217
 
8202
- LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback ) {
8203
-
8218
+ LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback )
8219
+ {
8204
8220
  const userParams = Array.from( arguments ).slice( 3 );
8205
8221
 
8206
8222
  let component = new BaseComponent( BaseComponent.CUSTOM, name, null, options );
@@ -8386,8 +8402,8 @@ LX.ADD_CUSTOM_COMPONENT = ADD_CUSTOM_COMPONENT;
8386
8402
 
8387
8403
  class NodeTree {
8388
8404
 
8389
- constructor( domEl, data, options ) {
8390
-
8405
+ constructor( domEl, data, options )
8406
+ {
8391
8407
  this.domEl = domEl;
8392
8408
  this.data = data;
8393
8409
  this.onevent = options.onevent;
@@ -8409,8 +8425,8 @@ class NodeTree {
8409
8425
  }
8410
8426
  }
8411
8427
 
8412
- _createItem( parent, node, level = 0, selectedId ) {
8413
-
8428
+ _createItem( parent, node, level = 0, selectedId )
8429
+ {
8414
8430
  const that = this;
8415
8431
  const nodeFilterInput = this.domEl.querySelector( ".lexnodetreefilter" );
8416
8432
 
@@ -8436,7 +8452,7 @@ class NodeTree {
8436
8452
  if( this.options.onlyFolders )
8437
8453
  {
8438
8454
  let hasFolders = false;
8439
- node.children.forEach( c => hasFolders |= (c.type == 'folder') );
8455
+ node.children.forEach( c => hasFolders |= ( c.type == 'folder' ) );
8440
8456
  isParent = !!hasFolders;
8441
8457
  }
8442
8458
 
@@ -8516,7 +8532,7 @@ class NodeTree {
8516
8532
  node.closed = false;
8517
8533
  if( that.onevent )
8518
8534
  {
8519
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed );
8535
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8520
8536
  that.onevent( event );
8521
8537
  }
8522
8538
  that.frefresh( node.id );
@@ -8524,13 +8540,13 @@ class NodeTree {
8524
8540
 
8525
8541
  if( that.onevent )
8526
8542
  {
8527
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_SELECTED, e.shiftKey ? this.selected : node );
8543
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_SELECTED, node, this.selected, e );
8528
8544
  event.multiple = e.shiftKey;
8529
8545
  that.onevent( event );
8530
8546
  }
8531
8547
  });
8532
8548
 
8533
- item.addEventListener("dblclick", function() {
8549
+ item.addEventListener("dblclick", function(e) {
8534
8550
 
8535
8551
  if( that.options.rename ?? true )
8536
8552
  {
@@ -8541,7 +8557,7 @@ class NodeTree {
8541
8557
 
8542
8558
  if( that.onevent )
8543
8559
  {
8544
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node );
8560
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node, null, e );
8545
8561
  that.onevent( event );
8546
8562
  }
8547
8563
  });
@@ -8555,10 +8571,10 @@ class NodeTree {
8555
8571
  return;
8556
8572
  }
8557
8573
 
8558
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CONTEXTMENU, this.selected.length > 1 ? this.selected : node, e);
8574
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CONTEXTMENU, node, this.selected, e );
8559
8575
  event.multiple = this.selected.length > 1;
8560
8576
 
8561
- LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
8577
+ LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.event, m => {
8562
8578
  event.panel = m;
8563
8579
  });
8564
8580
 
@@ -8607,7 +8623,7 @@ class NodeTree {
8607
8623
 
8608
8624
  if( ok && that.onevent )
8609
8625
  {
8610
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, e );
8626
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, [ node ], null );
8611
8627
  that.onevent( event );
8612
8628
  }
8613
8629
 
@@ -8640,7 +8656,7 @@ class NodeTree {
8640
8656
  // Send event now so we have the info in selected array..
8641
8657
  if( nodesDeleted.length && that.onevent )
8642
8658
  {
8643
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, nodesDeleted.length > 1 ? nodesDeleted : node, e );
8659
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, nodesDeleted, e );
8644
8660
  event.multiple = nodesDeleted.length > 1;
8645
8661
  that.onevent( event );
8646
8662
  }
@@ -8682,7 +8698,7 @@ class NodeTree {
8682
8698
 
8683
8699
  if( that.onevent )
8684
8700
  {
8685
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_RENAMED, node, this.value);
8701
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_RENAMED, node, this.value, e );
8686
8702
  that.onevent( event );
8687
8703
  }
8688
8704
 
@@ -8756,7 +8772,7 @@ class NodeTree {
8756
8772
  // Trigger node dragger event
8757
8773
  if( that.onevent )
8758
8774
  {
8759
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_DRAGGED, dragged, target);
8775
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DRAGGED, dragged, target, e );
8760
8776
  that.onevent( event );
8761
8777
  }
8762
8778
 
@@ -8797,7 +8813,7 @@ class NodeTree {
8797
8813
 
8798
8814
  if( that.onevent )
8799
8815
  {
8800
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CARETCHANGED, node, node.closed);
8816
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8801
8817
  that.onevent( event );
8802
8818
  }
8803
8819
  that.frefresh( node.id );
@@ -8814,28 +8830,34 @@ class NodeTree {
8814
8830
  for( let i = 0; i < node.actions.length; ++i )
8815
8831
  {
8816
8832
  const action = node.actions[ i ];
8817
- const actionIcon = LX.makeIcon( action.icon, { title: action.name } );
8818
- actionIcon.addEventListener("click", function( e ) {
8833
+ const actionBtn = new LX.Button( null, "", ( swapValue, event ) => {
8834
+ event.stopPropagation();
8819
8835
  if( action.callback )
8820
8836
  {
8821
- action.callback( node, actionIcon );
8822
- e.stopPropagation();
8837
+ action.callback( node, swapValue, event );
8823
8838
  }
8824
- });
8839
+ }, { icon: action.icon, swap: action.swap, title: action.name, hideName:true, className: "p-0 m-0", buttonClass: "p-0 m-0 bg-none" } );
8840
+ actionBtn.root.style.minWidth = "fit-content";
8841
+ actionBtn.root.style.margin = "0"; // adding classes does not work
8842
+ actionBtn.root.style.padding = "0"; // adding classes does not work
8843
+ const _btn = actionBtn.root.querySelector("button");
8844
+ _btn.style.minWidth = "fit-content";
8845
+ _btn.style.margin = "0"; // adding classes does not work
8846
+ _btn.style.padding = "0"; // adding classes does not work
8825
8847
 
8826
- inputContainer.appendChild( actionIcon );
8848
+ inputContainer.appendChild( actionBtn.root );
8827
8849
  }
8828
8850
  }
8829
8851
 
8830
8852
  if( !node.skipVisibility ?? false )
8831
8853
  {
8832
- const visibilityBtn = new LX.Button( null, "", ( swapValue, event ) => {
8833
- event.stopPropagation();
8854
+ const visibilityBtn = new LX.Button( null, "", ( swapValue, e ) => {
8855
+ e.stopPropagation();
8834
8856
  node.visible = node.visible === undefined ? false : !node.visible;
8835
8857
  // Trigger visibility event
8836
8858
  if( that.onevent )
8837
8859
  {
8838
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible );
8860
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible, e );
8839
8861
  that.onevent( event );
8840
8862
  }
8841
8863
  }, { icon: node.visible ? "Eye" : "EyeOff", swap: node.visible ? "EyeOff" : "Eye", title: "Toggle visible", className: "p-0 m-0", buttonClass: "bg-none" } );
@@ -8891,22 +8913,35 @@ class NodeTree {
8891
8913
  }
8892
8914
 
8893
8915
  /* Refreshes the tree and focuses current element */
8894
- frefresh( id ) {
8895
-
8916
+ frefresh( id )
8917
+ {
8896
8918
  this.refresh();
8897
- var el = this.domEl.querySelector( "#" + id );
8919
+ var el = this.domEl.querySelector( `#${ id }` );
8898
8920
  if( el )
8899
8921
  {
8900
8922
  el.focus();
8901
8923
  }
8902
8924
  }
8903
8925
 
8904
- select( id ) {
8926
+ select( id )
8927
+ {
8928
+ const nodeFilter = this.domEl.querySelector( ".lexnodetreefilter" );
8929
+ if( nodeFilter )
8930
+ {
8931
+ nodeFilter.value = "";
8932
+ }
8905
8933
 
8906
8934
  this.refresh( null, id );
8907
8935
 
8908
8936
  this.domEl.querySelectorAll( ".selected" ).forEach( i => i.classList.remove( "selected" ) );
8909
8937
 
8938
+ // Unselect
8939
+ if( !id )
8940
+ {
8941
+ this.selected.length = 0;
8942
+ return;
8943
+ }
8944
+
8910
8945
  // Element should exist, since tree was refreshed to show it
8911
8946
  const el = this.domEl.querySelector( "#" + id );
8912
8947
  console.assert( el, "NodeTree: Can't select node " + id );
@@ -8916,8 +8951,8 @@ class NodeTree {
8916
8951
  el.focus();
8917
8952
  }
8918
8953
 
8919
- deleteNode( node ) {
8920
-
8954
+ deleteNode( node )
8955
+ {
8921
8956
  const dataAsArray = ( this.data.constructor === Array );
8922
8957
 
8923
8958
  // Can be either Array or Object type data
@@ -8953,10 +8988,10 @@ LX.NodeTree = NodeTree;
8953
8988
  * @description Blank Component
8954
8989
  */
8955
8990
 
8956
- class Blank extends BaseComponent {
8957
-
8958
- constructor( width, height ) {
8959
-
8991
+ class Blank extends BaseComponent
8992
+ {
8993
+ constructor( width, height )
8994
+ {
8960
8995
  super( BaseComponent.BLANK );
8961
8996
 
8962
8997
  this.root.style.width = width ?? "auto";
@@ -8971,10 +9006,10 @@ LX.Blank = Blank;
8971
9006
  * @description Title Component
8972
9007
  */
8973
9008
 
8974
- class Title extends BaseComponent {
8975
-
8976
- constructor( name, options = {} ) {
8977
-
9009
+ class Title extends BaseComponent
9010
+ {
9011
+ constructor( name, options = {} )
9012
+ {
8978
9013
  console.assert( name, "Can't create Title Component without text!" );
8979
9014
 
8980
9015
  // Note: Titles are not registered in Panel.components by now
@@ -9015,10 +9050,10 @@ LX.Title = Title;
9015
9050
  * @description TextInput Component
9016
9051
  */
9017
9052
 
9018
- class TextInput extends BaseComponent {
9019
-
9020
- constructor( name, value, callback, options = {} ) {
9021
-
9053
+ class TextInput extends BaseComponent
9054
+ {
9055
+ constructor( name, value, callback, options = {} )
9056
+ {
9022
9057
  super( BaseComponent.TEXT, name, String( value ), options );
9023
9058
 
9024
9059
  this.onGetValue = () => {
@@ -9105,7 +9140,7 @@ class TextInput extends BaseComponent {
9105
9140
  });
9106
9141
  }
9107
9142
 
9108
- wValue.addEventListener( "mousedown", function( e ){
9143
+ wValue.addEventListener( "mousedown", function( e ) {
9109
9144
  e.stopImmediatePropagation();
9110
9145
  e.stopPropagation();
9111
9146
  });
@@ -9155,10 +9190,10 @@ LX.TextInput = TextInput;
9155
9190
  * @description TextArea Component
9156
9191
  */
9157
9192
 
9158
- class TextArea extends BaseComponent {
9159
-
9160
- constructor( name, value, callback, options = {} ) {
9161
-
9193
+ class TextArea extends BaseComponent
9194
+ {
9195
+ constructor( name, value, callback, options = {} )
9196
+ {
9162
9197
  super( BaseComponent.TEXTAREA, name, value, options );
9163
9198
 
9164
9199
  this.onGetValue = () => {
@@ -9256,10 +9291,10 @@ LX.TextArea = TextArea;
9256
9291
  * @description Button Component
9257
9292
  */
9258
9293
 
9259
- class Button extends BaseComponent {
9260
-
9261
- constructor( name, value, callback, options = {} ) {
9262
-
9294
+ class Button extends BaseComponent
9295
+ {
9296
+ constructor( name, value, callback, options = {} )
9297
+ {
9263
9298
  super( BaseComponent.BUTTON, name, null, options );
9264
9299
 
9265
9300
  this.onGetValue = () => {
@@ -9478,10 +9513,10 @@ LX.Button = Button;
9478
9513
  * @description ComboButtons Component
9479
9514
  */
9480
9515
 
9481
- class ComboButtons extends BaseComponent {
9482
-
9483
- constructor( name, values, options = {} ) {
9484
-
9516
+ class ComboButtons extends BaseComponent
9517
+ {
9518
+ constructor( name, values, options = {} )
9519
+ {
9485
9520
  const shouldSelect = !( options.noSelection ?? false );
9486
9521
  let shouldToggle = shouldSelect && ( options.toggle ?? false );
9487
9522
 
@@ -9639,10 +9674,10 @@ LX.ComboButtons = ComboButtons;
9639
9674
  * @description Card Component
9640
9675
  */
9641
9676
 
9642
- class Card extends BaseComponent {
9643
-
9644
- constructor( name, options = {} ) {
9645
-
9677
+ class Card extends BaseComponent
9678
+ {
9679
+ constructor( name, options = {} )
9680
+ {
9646
9681
  options.hideName = true;
9647
9682
 
9648
9683
  super( BaseComponent.CARD, name, null, options );
@@ -9702,10 +9737,10 @@ LX.Card = Card;
9702
9737
  * @description Form Component
9703
9738
  */
9704
9739
 
9705
- class Form extends BaseComponent {
9706
-
9707
- constructor( name, data, callback, options = {} ) {
9708
-
9740
+ class Form extends BaseComponent
9741
+ {
9742
+ constructor( name, data, callback, options = {} )
9743
+ {
9709
9744
  if( data.constructor != Object )
9710
9745
  {
9711
9746
  console.error( "Form data must be an Object" );
@@ -9817,10 +9852,10 @@ LX.Form = Form;
9817
9852
  * @description Select Component
9818
9853
  */
9819
9854
 
9820
- class Select extends BaseComponent {
9821
-
9822
- constructor( name, values, value, callback, options = {} ) {
9823
-
9855
+ class Select extends BaseComponent
9856
+ {
9857
+ constructor( name, values, value, callback, options = {} )
9858
+ {
9824
9859
  super( BaseComponent.SELECT, name, value, options );
9825
9860
 
9826
9861
  this.onGetValue = () => {
@@ -10229,10 +10264,10 @@ LX.Select = Select;
10229
10264
  * @description Curve Component
10230
10265
  */
10231
10266
 
10232
- class Curve extends BaseComponent {
10233
-
10234
- constructor( name, values, callback, options = {} ) {
10235
-
10267
+ class Curve extends BaseComponent
10268
+ {
10269
+ constructor( name, values, callback, options = {} )
10270
+ {
10236
10271
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10237
10272
 
10238
10273
  super( BaseComponent.CURVE, name, defaultValues, options );
@@ -10290,10 +10325,10 @@ LX.Curve = Curve;
10290
10325
  * @description Dial Component
10291
10326
  */
10292
10327
 
10293
- class Dial extends BaseComponent {
10294
-
10295
- constructor( name, values, callback, options = {} ) {
10296
-
10328
+ class Dial extends BaseComponent
10329
+ {
10330
+ constructor( name, values, callback, options = {} )
10331
+ {
10297
10332
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10298
10333
 
10299
10334
  super( BaseComponent.DIAL, name, defaultValues, options );
@@ -10347,10 +10382,10 @@ LX.Dial = Dial;
10347
10382
  * @description Layers Component
10348
10383
  */
10349
10384
 
10350
- class Layers extends BaseComponent {
10351
-
10352
- constructor( name, value, callback, options = {} ) {
10353
-
10385
+ class Layers extends BaseComponent
10386
+ {
10387
+ constructor( name, value, callback, options = {} )
10388
+ {
10354
10389
  super( BaseComponent.LAYERS, name, value, options );
10355
10390
 
10356
10391
  this.onGetValue = () => {
@@ -10431,10 +10466,10 @@ LX.Layers = Layers;
10431
10466
  * @description ItemArray Component
10432
10467
  */
10433
10468
 
10434
- class ItemArray extends BaseComponent {
10435
-
10436
- constructor( name, values = [], callback, options = {} ) {
10437
-
10469
+ class ItemArray extends BaseComponent
10470
+ {
10471
+ constructor( name, values = [], callback, options = {} )
10472
+ {
10438
10473
  options.nameWidth = "100%";
10439
10474
 
10440
10475
  super( BaseComponent.ARRAY, name, null, options );
@@ -10549,10 +10584,10 @@ LX.ItemArray = ItemArray;
10549
10584
  * @description List Component
10550
10585
  */
10551
10586
 
10552
- class List extends BaseComponent {
10553
-
10554
- constructor( name, values, value, callback, options = {} ) {
10555
-
10587
+ class List extends BaseComponent
10588
+ {
10589
+ constructor( name, values, value, callback, options = {} )
10590
+ {
10556
10591
  super( BaseComponent.LIST, name, value, options );
10557
10592
 
10558
10593
  this.onGetValue = () => {
@@ -10649,10 +10684,10 @@ LX.List = List;
10649
10684
  * @description Tags Component
10650
10685
  */
10651
10686
 
10652
- class Tags extends BaseComponent {
10653
-
10654
- constructor( name, value, callback, options = {} ) {
10655
-
10687
+ class Tags extends BaseComponent
10688
+ {
10689
+ constructor( name, value, callback, options = {} )
10690
+ {
10656
10691
  value = value.replace( /\s/g, '' ).split( ',' );
10657
10692
 
10658
10693
  let defaultValue = [].concat( value );
@@ -10738,10 +10773,10 @@ LX.Tags = Tags;
10738
10773
  * @description Checkbox Component
10739
10774
  */
10740
10775
 
10741
- class Checkbox extends BaseComponent {
10742
-
10743
- constructor( name, value, callback, options = {} ) {
10744
-
10776
+ class Checkbox extends BaseComponent
10777
+ {
10778
+ constructor( name, value, callback, options = {} )
10779
+ {
10745
10780
  if( !name && !options.label )
10746
10781
  {
10747
10782
  throw( "Set Component Name or at least a label!" );
@@ -10821,10 +10856,10 @@ LX.Checkbox = Checkbox;
10821
10856
  * @description Toggle Component
10822
10857
  */
10823
10858
 
10824
- class Toggle extends BaseComponent {
10825
-
10826
- constructor( name, value, callback, options = {} ) {
10827
-
10859
+ class Toggle extends BaseComponent
10860
+ {
10861
+ constructor( name, value, callback, options = {} )
10862
+ {
10828
10863
  if( !name && !options.label )
10829
10864
  {
10830
10865
  throw( "Set Component Name or at least a label!" );
@@ -10905,10 +10940,10 @@ LX.Toggle = Toggle;
10905
10940
  * @description RadioGroup Component
10906
10941
  */
10907
10942
 
10908
- class RadioGroup extends BaseComponent {
10909
-
10910
- constructor( name, label, values, callback, options = {} ) {
10911
-
10943
+ class RadioGroup extends BaseComponent
10944
+ {
10945
+ constructor( name, label, values, callback, options = {} )
10946
+ {
10912
10947
  super( BaseComponent.RADIO, name, null, options );
10913
10948
 
10914
10949
  let currentIndex = null;
@@ -10984,10 +11019,10 @@ LX.RadioGroup = RadioGroup;
10984
11019
  * @description ColorInput Component
10985
11020
  */
10986
11021
 
10987
- class ColorInput extends BaseComponent {
10988
-
10989
- constructor( name, value, callback, options = {} ) {
10990
-
11022
+ class ColorInput extends BaseComponent
11023
+ {
11024
+ constructor( name, value, callback, options = {} )
11025
+ {
10991
11026
  value = value ?? "#000000";
10992
11027
 
10993
11028
  const useAlpha = options.useAlpha ??
@@ -11107,10 +11142,10 @@ LX.ColorInput = ColorInput;
11107
11142
  * @description RangeInput Component
11108
11143
  */
11109
11144
 
11110
- class RangeInput extends BaseComponent {
11111
-
11112
- constructor( name, value, callback, options = {} ) {
11113
-
11145
+ class RangeInput extends BaseComponent
11146
+ {
11147
+ constructor( name, value, callback, options = {} )
11148
+ {
11114
11149
  const ogValue = LX.deepCopy( value );
11115
11150
 
11116
11151
  super( BaseComponent.RANGE, name, LX.deepCopy( ogValue ), options );
@@ -11321,10 +11356,10 @@ LX.RangeInput = RangeInput;
11321
11356
  * @description NumberInput Component
11322
11357
  */
11323
11358
 
11324
- class NumberInput extends BaseComponent {
11325
-
11326
- constructor( name, value, callback, options = {} ) {
11327
-
11359
+ class NumberInput extends BaseComponent
11360
+ {
11361
+ constructor( name, value, callback, options = {} )
11362
+ {
11328
11363
  super( BaseComponent.NUMBER, name, value, options );
11329
11364
 
11330
11365
  this.onGetValue = () => {
@@ -11543,10 +11578,10 @@ LX.NumberInput = NumberInput;
11543
11578
  * @description Vector Component
11544
11579
  */
11545
11580
 
11546
- class Vector extends BaseComponent {
11547
-
11548
- constructor( numComponents, name, value, callback, options = {} ) {
11549
-
11581
+ class Vector extends BaseComponent
11582
+ {
11583
+ constructor( numComponents, name, value, callback, options = {} )
11584
+ {
11550
11585
  numComponents = LX.clamp( numComponents, 2, 4 );
11551
11586
  value = value ?? new Array( numComponents ).fill( 0 );
11552
11587
 
@@ -11793,10 +11828,10 @@ LX.Vector = Vector;
11793
11828
  * @description SizeInput Component
11794
11829
  */
11795
11830
 
11796
- class SizeInput extends BaseComponent {
11797
-
11798
- constructor( name, value, callback, options = {} ) {
11799
-
11831
+ class SizeInput extends BaseComponent
11832
+ {
11833
+ constructor( name, value, callback, options = {} )
11834
+ {
11800
11835
  super( BaseComponent.SIZE, name, value, options );
11801
11836
 
11802
11837
  this.onGetValue = () => {
@@ -11881,10 +11916,10 @@ LX.SizeInput = SizeInput;
11881
11916
  * @description OTPInput Component
11882
11917
  */
11883
11918
 
11884
- class OTPInput extends BaseComponent {
11885
-
11886
- constructor( name, value, callback, options = {} ) {
11887
-
11919
+ class OTPInput extends BaseComponent
11920
+ {
11921
+ constructor( name, value, callback, options = {} )
11922
+ {
11888
11923
  const pattern = options.pattern ?? "xxx-xxx";
11889
11924
  const patternSize = ( pattern.match(/x/g) || [] ).length;
11890
11925
 
@@ -12039,10 +12074,10 @@ LX.OTPInput = OTPInput;
12039
12074
  * @description Pad Component
12040
12075
  */
12041
12076
 
12042
- class Pad extends BaseComponent {
12043
-
12044
- constructor( name, value, callback, options = {} ) {
12045
-
12077
+ class Pad extends BaseComponent
12078
+ {
12079
+ constructor( name, value, callback, options = {} )
12080
+ {
12046
12081
  super( BaseComponent.PAD, name, null, options );
12047
12082
 
12048
12083
  this.onGetValue = () => {
@@ -12159,10 +12194,10 @@ LX.Pad = Pad;
12159
12194
  * @description Progress Component
12160
12195
  */
12161
12196
 
12162
- class Progress extends BaseComponent {
12163
-
12164
- constructor( name, value, options = {} ) {
12165
-
12197
+ class Progress extends BaseComponent
12198
+ {
12199
+ constructor( name, value, options = {} )
12200
+ {
12166
12201
  super( BaseComponent.PROGRESS, name, value, options );
12167
12202
 
12168
12203
  this.onGetValue = () => {
@@ -12296,10 +12331,10 @@ LX.Progress = Progress;
12296
12331
  * @description FileInput Component
12297
12332
  */
12298
12333
 
12299
- class FileInput extends BaseComponent {
12300
-
12301
- constructor( name, callback, options = { } ) {
12302
-
12334
+ class FileInput extends BaseComponent
12335
+ {
12336
+ constructor( name, callback, options = { } )
12337
+ {
12303
12338
  super( BaseComponent.FILE, name, null, options );
12304
12339
 
12305
12340
  let local = options.local ?? true;
@@ -12381,10 +12416,10 @@ LX.FileInput = FileInput;
12381
12416
  * @description Tree Component
12382
12417
  */
12383
12418
 
12384
- class Tree extends BaseComponent {
12385
-
12386
- constructor( name, data, options = {} ) {
12387
-
12419
+ class Tree extends BaseComponent
12420
+ {
12421
+ constructor( name, data, options = {} )
12422
+ {
12388
12423
  options.hideName = true;
12389
12424
 
12390
12425
  super( BaseComponent.TREE, name, null, options );
@@ -12463,10 +12498,10 @@ LX.Tree = Tree;
12463
12498
  * @description TabSections Component
12464
12499
  */
12465
12500
 
12466
- class TabSections extends BaseComponent {
12467
-
12468
- constructor( name, tabs, options = {} ) {
12469
-
12501
+ class TabSections extends BaseComponent
12502
+ {
12503
+ constructor( name, tabs, options = {} )
12504
+ {
12470
12505
  options.hideName = true;
12471
12506
 
12472
12507
  super( BaseComponent.TABS, name, null, options );
@@ -12570,10 +12605,10 @@ LX.TabSections = TabSections;
12570
12605
  * @description Counter Component
12571
12606
  */
12572
12607
 
12573
- class Counter extends BaseComponent {
12574
-
12575
- constructor( name, value, callback, options = { } ) {
12576
-
12608
+ class Counter extends BaseComponent
12609
+ {
12610
+ constructor( name, value, callback, options = { } )
12611
+ {
12577
12612
  super( BaseComponent.COUNTER, name, value, options );
12578
12613
 
12579
12614
  this.onGetValue = () => {
@@ -12640,10 +12675,10 @@ LX.Counter = Counter;
12640
12675
  * @description Table Component
12641
12676
  */
12642
12677
 
12643
- class Table extends BaseComponent {
12644
-
12645
- constructor( name, data, options = { } ) {
12646
-
12678
+ class Table extends BaseComponent
12679
+ {
12680
+ constructor( name, data, options = { } )
12681
+ {
12647
12682
  if( !data )
12648
12683
  {
12649
12684
  throw( "Data is needed to create a table!" );
@@ -12676,12 +12711,12 @@ class Table extends BaseComponent {
12676
12711
  data.body = data.body ?? [];
12677
12712
  data.checkMap = { };
12678
12713
  data.colVisibilityMap = { };
12679
- data.head.forEach( (col, index) => { data.colVisibilityMap[ index ] = true; });
12714
+ data.head.forEach( ( col, index ) => { data.colVisibilityMap[ index ] = true; });
12680
12715
  this.data = data;
12681
12716
 
12682
- const compareFn = ( idx, order, a, b) => {
12683
- if (a[idx] < b[idx]) return -order;
12684
- else if (a[idx] > b[idx]) return order;
12717
+ const compareFn = ( idx, order, a, b ) => {
12718
+ if( a[ idx ] < b[ idx ] ) return -order;
12719
+ else if( a[ idx ] > b[ idx ] ) return order;
12685
12720
  return 0;
12686
12721
  };
12687
12722
 
@@ -12851,10 +12886,10 @@ class Table extends BaseComponent {
12851
12886
  icon: "Check",
12852
12887
  callback: () => {
12853
12888
  data.colVisibilityMap[ idx ] = !data.colVisibilityMap[ idx ];
12854
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12855
- cells.forEach(cell => {
12856
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12857
- });
12889
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
12890
+ cells.forEach( cell => {
12891
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
12892
+ } );
12858
12893
  }
12859
12894
  };
12860
12895
  if( !data.colVisibilityMap[ idx ] ) delete item.icon;
@@ -12949,9 +12984,9 @@ class Table extends BaseComponent {
12949
12984
  name: "Hide", icon: "EyeOff", callback: () => {
12950
12985
  data.colVisibilityMap[ idx ] = false;
12951
12986
  const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12952
- cells.forEach(cell => {
12953
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12954
- });
12987
+ cells.forEach( cell => {
12988
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
12989
+ } );
12955
12990
  }
12956
12991
  }
12957
12992
  );
@@ -13323,10 +13358,10 @@ class Table extends BaseComponent {
13323
13358
  const idx = parseInt( v );
13324
13359
  if( !data.colVisibilityMap[ idx ] )
13325
13360
  {
13326
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
13327
- cells.forEach(cell => {
13328
- cell.style.display = (cell.style.display === "none") ? "" : "none";
13329
- });
13361
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
13362
+ cells.forEach( cell => {
13363
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
13364
+ } );
13330
13365
  }
13331
13366
  }
13332
13367
  };
@@ -13336,8 +13371,8 @@ class Table extends BaseComponent {
13336
13371
  LX.doAsync( this.onResize.bind( this ) );
13337
13372
  }
13338
13373
 
13339
- getSelectedRows() {
13340
-
13374
+ getSelectedRows()
13375
+ {
13341
13376
  const selectedRows = [];
13342
13377
 
13343
13378
  for( const row of this.data.body )
@@ -13352,8 +13387,8 @@ class Table extends BaseComponent {
13352
13387
  return selectedRows;
13353
13388
  }
13354
13389
 
13355
- _setCentered( v ) {
13356
-
13390
+ _setCentered( v )
13391
+ {
13357
13392
  if( v.constructor == Boolean )
13358
13393
  {
13359
13394
  const container = this.root.querySelector( ".lextable" );
@@ -13386,10 +13421,10 @@ LX.Table = Table;
13386
13421
  * @description DatePicker Component
13387
13422
  */
13388
13423
 
13389
- class DatePicker extends BaseComponent {
13390
-
13391
- constructor( name, dateValue, callback, options = { } ) {
13392
-
13424
+ class DatePicker extends BaseComponent
13425
+ {
13426
+ constructor( name, dateValue, callback, options = { } )
13427
+ {
13393
13428
  super( BaseComponent.DATE, name, null, options );
13394
13429
 
13395
13430
  const dateAsRange = ( dateValue?.constructor === Array );
@@ -13504,10 +13539,10 @@ LX.DatePicker = DatePicker;
13504
13539
  * @description Map2D Component
13505
13540
  */
13506
13541
 
13507
- class Map2D extends BaseComponent {
13508
-
13509
- constructor( name, points, callback, options = {} ) {
13510
-
13542
+ class Map2D extends BaseComponent
13543
+ {
13544
+ constructor( name, points, callback, options = {} )
13545
+ {
13511
13546
  super( BaseComponent.MAP2D, name, null, options );
13512
13547
 
13513
13548
  this.onGetValue = () => {
@@ -13551,13 +13586,13 @@ LX.Map2D = Map2D;
13551
13586
  * @description Rate Component
13552
13587
  */
13553
13588
 
13554
- class Rate extends BaseComponent {
13555
-
13556
- constructor( name, value, callback, options = {} ) {
13557
-
13589
+ class Rate extends BaseComponent
13590
+ {
13591
+ constructor( name, value, callback, options = {} )
13592
+ {
13558
13593
  const allowHalf = options.allowHalf ?? false;
13559
13594
 
13560
- if( !allowHalf)
13595
+ if( !allowHalf )
13561
13596
  {
13562
13597
  value = Math.floor( value );
13563
13598
  }
@@ -15100,8 +15135,8 @@ LX.Branch = Branch;
15100
15135
 
15101
15136
  class Menubar {
15102
15137
 
15103
- constructor( items, options = {} ) {
15104
-
15138
+ constructor( items, options = {} )
15139
+ {
15105
15140
  this.root = document.createElement( "div" );
15106
15141
  this.root.className = "lexmenubar";
15107
15142
 
@@ -15118,8 +15153,8 @@ class Menubar {
15118
15153
  this.createEntries();
15119
15154
  }
15120
15155
 
15121
- _resetMenubar( focus ) {
15122
-
15156
+ _resetMenubar( focus )
15157
+ {
15123
15158
  this.root.querySelectorAll(".lexmenuentry").forEach( e => {
15124
15159
  e.classList.remove( 'selected' );
15125
15160
  delete e.dataset[ "built" ];
@@ -15139,8 +15174,8 @@ class Menubar {
15139
15174
  * @method createEntries
15140
15175
  */
15141
15176
 
15142
- createEntries() {
15143
-
15177
+ createEntries()
15178
+ {
15144
15179
  for( let item of this.items )
15145
15180
  {
15146
15181
  let key = item.name;
@@ -15206,7 +15241,8 @@ class Menubar {
15206
15241
  * @param {String} name
15207
15242
  */
15208
15243
 
15209
- getButton( name ) {
15244
+ getButton( name )
15245
+ {
15210
15246
  return this.buttons[ name ];
15211
15247
  }
15212
15248
 
@@ -15215,26 +15251,23 @@ class Menubar {
15215
15251
  * @param {Object} item: parent item
15216
15252
  * @param {Array} tokens: split path strings
15217
15253
  */
15218
- getSubitem( item, tokens ) {
15219
-
15220
- let subitem = null;
15221
- let path = tokens[ 0 ];
15222
-
15223
- for( let i = 0; i < item.length; i++ )
15254
+ getSubitem( item, tokens )
15255
+ {
15256
+ for( const s of item )
15224
15257
  {
15225
- if( item[ i ][ path ] )
15258
+ if ( s?.name != tokens[ 0 ] )
15226
15259
  {
15227
- if( tokens.length == 1 )
15228
- {
15229
- subitem = item[ i ];
15230
- return subitem;
15231
- }
15232
- else
15233
- {
15234
- tokens.splice( 0, 1 );
15235
- return this.getSubitem( item[ i ][ path ], tokens );
15236
- }
15260
+ continue;
15261
+ }
15237
15262
 
15263
+ if( tokens.length == 1 )
15264
+ {
15265
+ return s;
15266
+ }
15267
+ else if ( s.submenu )
15268
+ {
15269
+ tokens.shift();
15270
+ return this.getSubitem( s.submenu, tokens );
15238
15271
  }
15239
15272
  }
15240
15273
  }
@@ -15243,12 +15276,11 @@ class Menubar {
15243
15276
  * @method getItem
15244
15277
  * @param {String} path
15245
15278
  */
15246
- getItem( path ) {
15247
-
15248
- // process path
15249
- const tokens = path.split("/");
15250
-
15251
- return this.getSubitem(this.items, tokens)
15279
+ getItem( path )
15280
+ {
15281
+ // Process path
15282
+ const tokens = path.split( '/' );
15283
+ return this.getSubitem( this.items, tokens );
15252
15284
  }
15253
15285
 
15254
15286
  /**
@@ -15259,8 +15291,8 @@ class Menubar {
15259
15291
  * @param {Object} options
15260
15292
  */
15261
15293
 
15262
- setButtonIcon( name, icon, callback, options = {} ) {
15263
-
15294
+ setButtonIcon( name, icon, callback, options = {} )
15295
+ {
15264
15296
  if( !name )
15265
15297
  {
15266
15298
  throw( "Set Button Name!" );
@@ -15315,8 +15347,8 @@ class Menubar {
15315
15347
  * @param {Object} options
15316
15348
  */
15317
15349
 
15318
- setButtonImage( name, src, callback, options = {} ) {
15319
-
15350
+ setButtonImage( name, src, callback, options = {} )
15351
+ {
15320
15352
  if( !name )
15321
15353
  {
15322
15354
  throw( "Set Button Name!" );
@@ -15325,14 +15357,14 @@ class Menubar {
15325
15357
  let button = this.buttons[ name ];
15326
15358
  if( button )
15327
15359
  {
15328
- button.querySelector('img').src = src;
15360
+ button.querySelector( 'img' ).src = src;
15329
15361
  return;
15330
15362
  }
15331
15363
 
15332
15364
  // Otherwise, create it
15333
- button = document.createElement('div');
15365
+ button = document.createElement( 'div' );
15334
15366
  const disabled = options.disabled ?? false;
15335
- button.className = "lexmenubutton main" + (disabled ? " disabled" : "");
15367
+ button.className = "lexmenubutton main" + ( disabled ? " disabled" : "" );
15336
15368
  button.title = name;
15337
15369
  button.innerHTML = "<a><image src='" + src + "' class='lexicon' style='height:32px;'></a>";
15338
15370
 
@@ -15356,11 +15388,11 @@ class Menubar {
15356
15388
 
15357
15389
  const _b = button.querySelector('a');
15358
15390
 
15359
- _b.addEventListener( "mousedown", (e) => {
15391
+ _b.addEventListener( "mousedown", e => {
15360
15392
  e.preventDefault();
15361
15393
  });
15362
15394
 
15363
- _b.addEventListener( "mouseup", (e) => {
15395
+ _b.addEventListener( "mouseup", e => {
15364
15396
  if( callback && !disabled )
15365
15397
  {
15366
15398
  callback.call( this, _b, e );
@@ -15377,8 +15409,8 @@ class Menubar {
15377
15409
  * float: center (Default), right
15378
15410
  */
15379
15411
 
15380
- addButtons( buttons, options = {} ) {
15381
-
15412
+ addButtons( buttons, options = {} )
15413
+ {
15382
15414
  if( !buttons )
15383
15415
  {
15384
15416
  throw( "No buttons to add!" );
@@ -15405,9 +15437,8 @@ class Menubar {
15405
15437
  }
15406
15438
  }
15407
15439
 
15408
- for( let i = 0; i < buttons.length; ++i )
15440
+ for( const data of buttons )
15409
15441
  {
15410
- const data = buttons[ i ];
15411
15442
  const title = data.title;
15412
15443
  const button = new LX.Button( title, data.label, data.callback, {
15413
15444
  title,
@@ -16595,13 +16626,13 @@ class AssetView {
16595
16626
  const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
16596
16627
 
16597
16628
  this.filter = filter ?? ( this.filter ?? "None" );
16598
- this.searchValue = searchValue ?? (this.searchValue ?? "");
16629
+ this.searchValue = searchValue ?? ( this.searchValue ?? "" );
16599
16630
  this.content.innerHTML = "";
16600
16631
  this.content.className = `lexassetscontent${ isCompactLayout ? " compact" : ( isListLayout ? " list" : "" ) }`;
16601
16632
  let that = this;
16602
16633
 
16603
- const _addItem = function(item) {
16604
-
16634
+ const _addItem = function( item )
16635
+ {
16605
16636
  const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
16606
16637
  const extension = LX.getExtension( item.id );
16607
16638
  const isFolder = type === "Folder";
@@ -16620,10 +16651,11 @@ class AssetView {
16620
16651
  {
16621
16652
  let desc = document.createElement( 'span' );
16622
16653
  desc.className = 'lexitemdesc';
16623
- desc.innerHTML = "File: " + item.id + "<br>Type: " + type;
16654
+ desc.id = `floatingTitle_${ item.id }`;
16655
+ desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
16624
16656
  that.content.appendChild( desc );
16625
16657
 
16626
- itemEl.addEventListener("mousemove", e => {
16658
+ itemEl.addEventListener( "mousemove", e => {
16627
16659
 
16628
16660
  if( !isGridLayout )
16629
16661
  {
@@ -16651,23 +16683,7 @@ class AssetView {
16651
16683
 
16652
16684
  desc.style.left = ( localOffsetX ) + "px";
16653
16685
  desc.style.top = ( localOffsetY - 36 ) + "px";
16654
- });
16655
-
16656
- itemEl.addEventListener("mouseenter", () => {
16657
- if( isGridLayout )
16658
- {
16659
- desc.style.display = "unset";
16660
- }
16661
- });
16662
-
16663
- itemEl.addEventListener("mouseleave", () => {
16664
- if( isGridLayout )
16665
- {
16666
- setTimeout( () => {
16667
- desc.style.display = "none";
16668
- }, 100 );
16669
- }
16670
- });
16686
+ } );
16671
16687
  }
16672
16688
  else
16673
16689
  {
@@ -16702,26 +16718,49 @@ class AssetView {
16702
16718
 
16703
16719
  if( !that.skipPreview )
16704
16720
  {
16721
+ if( item.type === 'video' )
16722
+ {
16723
+ const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
16724
+ itemVideo.setAttribute( 'disablePictureInPicture', false );
16725
+ itemVideo.setAttribute( 'disableRemotePlayback', false );
16726
+ itemVideo.setAttribute( 'loop', true );
16727
+ itemVideo.setAttribute( 'async', true );
16728
+ itemVideo.style.transition = 'opacity 0.2s ease-out';
16729
+ itemVideo.style.opacity = item.preview ? '0' : '1';
16730
+ itemVideo.src = item.src;
16731
+ itemVideo.volume = item.videoVolume ?? 0.4;
16732
+ }
16733
+
16705
16734
  let preview = null;
16706
- const hasImage = item.src && (['png', 'jpg'].indexOf( LX.getExtension( item.src ) ) > -1 || item.src.includes("data:image/") ); // Support b64 image as src
16707
16735
 
16708
- if( hasImage || isFolder || !isGridLayout)
16736
+ const previewSrc = item.preview ?? item.src;
16737
+ const hasImage = previewSrc && (
16738
+ (() => {
16739
+ const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
16740
+ return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
16741
+ })()
16742
+ || previewSrc.startsWith( 'data:image/' )
16743
+ );
16744
+
16745
+ if( hasImage || isFolder || !isGridLayout )
16709
16746
  {
16747
+ const defaultPreviewPath = `${ that.rootPath }images/file.png`;
16748
+ const defaultFolderPath = `${ that.rootPath }images/folder.png`;
16749
+
16710
16750
  preview = document.createElement('img');
16711
- let real_src = item.unknown_extension ? that.rootPath + "images/file.png" : (isFolder ? that.rootPath + "images/folder.png" : item.src);
16712
- preview.src = (isGridLayout || isFolder ? real_src : that.rootPath + "images/file.png");
16751
+ let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
16752
+ preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
16713
16753
  itemEl.appendChild( preview );
16714
16754
  }
16715
16755
  else
16716
16756
  {
16717
- preview = document.createElement('svg');
16718
- preview.className = "asset-file-preview";
16719
- itemEl.appendChild(preview);
16757
+ preview = document.createElement( 'svg' );
16758
+ preview.className = 'asset-file-preview';
16759
+ itemEl.appendChild( preview );
16720
16760
 
16721
- let textEl = document.createElement('text');
16722
- preview.appendChild(textEl);
16723
- // If no extension, e.g. Clip, use the type...
16724
- textEl.innerText = (!extension || extension == item.id) ? item.type.toUpperCase() : ("." + extension.toUpperCase());
16761
+ let textEl = document.createElement( 'text' );
16762
+ textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `.${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
16763
+ preview.appendChild( textEl );
16725
16764
 
16726
16765
  var newLength = textEl.innerText.length;
16727
16766
  var charsPerLine = 2.5;
@@ -16731,8 +16770,8 @@ class AssetView {
16731
16770
  if( newEmSize < 1 )
16732
16771
  {
16733
16772
  var newFontSize = newEmSize * textBaseSize;
16734
- textEl.style.fontSize = newFontSize + "px";
16735
- preview.style.paddingTop = "calc(50% - " + (textEl.offsetHeight * 0.5 + 10) + "px)";
16773
+ textEl.style.fontSize = newFontSize + 'px';
16774
+ preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
16736
16775
  }
16737
16776
  }
16738
16777
  }
@@ -16746,7 +16785,7 @@ class AssetView {
16746
16785
  if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
16747
16786
  }
16748
16787
 
16749
- LX.makeContainer( [ "auto", "auto" ], "lexassetinfo", itemInfoHtml, itemEl );
16788
+ LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
16750
16789
 
16751
16790
  itemEl.addEventListener('click', function( e ) {
16752
16791
  e.stopImmediatePropagation();
@@ -16758,10 +16797,10 @@ class AssetView {
16758
16797
  {
16759
16798
  if( !e.shiftKey )
16760
16799
  {
16761
- that.content.querySelectorAll('.lexassetitem').forEach( i => i.classList.remove('selected') );
16800
+ that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16762
16801
  }
16763
16802
 
16764
- this.classList.add('selected');
16803
+ this.classList.add( 'selected' );
16765
16804
  that.selectedItem = item;
16766
16805
 
16767
16806
  if( !that.skipPreview )
@@ -16814,6 +16853,42 @@ class AssetView {
16814
16853
  e.preventDefault();
16815
16854
  }, false );
16816
16855
 
16856
+ itemEl.addEventListener( "mouseenter", ( e ) => {
16857
+
16858
+ if( !that.useNativeTitle && isGridLayout )
16859
+ {
16860
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16861
+ if( desc ) desc.style.display = "unset";
16862
+ }
16863
+
16864
+ if( item.type !== "video" ) return;
16865
+ e.preventDefault();
16866
+ const video = itemEl.querySelector( "video" );
16867
+ video.style.opacity = "1";
16868
+ video.play();
16869
+ } );
16870
+
16871
+ itemEl.addEventListener( "mouseleave", ( e ) => {
16872
+
16873
+ if( !that.useNativeTitle && isGridLayout )
16874
+ {
16875
+ setTimeout( () => {
16876
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16877
+ if( desc ) desc.style.display = "none";
16878
+ }, 100 );
16879
+ }
16880
+
16881
+ if( item.type !== "video" ) return;
16882
+ e.preventDefault();
16883
+ const video = itemEl.querySelector( "video" );
16884
+ video.pause();
16885
+ video.currentTime = 0;
16886
+ if( item.preview )
16887
+ {
16888
+ video.style.opacity = "0";
16889
+ }
16890
+ } );
16891
+
16817
16892
  return itemEl;
16818
16893
  };
16819
16894
 
@@ -16958,7 +17033,7 @@ class AssetView {
16958
17033
  item.type = "mesh"; break;
16959
17034
  default:
16960
17035
  item.type = ext;
16961
- item.unknown_extension = true;
17036
+ item.unknownExtension = true;
16962
17037
  break;
16963
17038
  }
16964
17039