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.
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  const LX = {
10
- version: "0.7.9",
10
+ version: "0.7.11",
11
11
  ready: false,
12
12
  extensions: [], // Store extensions used
13
13
  signals: {}, // Events and triggers
@@ -647,10 +647,11 @@ class TreeEvent {
647
647
  static NODE_VISIBILITY = 7;
648
648
  static NODE_CARETCHANGED = 8;
649
649
 
650
- constructor( type, node, value ) {
650
+ constructor( type, node, value, event ) {
651
651
  this.type = type || TreeEvent.NONE;
652
652
  this.node = node;
653
653
  this.value = value;
654
+ this.event = event;
654
655
  this.multiple = false; // Multiple selection
655
656
  this.panel = null;
656
657
  }
@@ -2577,9 +2578,11 @@ class Tabs {
2577
2578
 
2578
2579
  if( isSelected && this.thumb )
2579
2580
  {
2581
+ this.thumb.classList.add( "no-transition" );
2580
2582
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2581
2583
  this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2582
2584
  this.thumb.item = tabEl;
2585
+ this.thumb.classList.remove( "no-transition" );
2583
2586
  }
2584
2587
 
2585
2588
  }, 10 );
@@ -5535,47 +5538,49 @@ function makeCodeSnippet( code, size, options = { } )
5535
5538
  disableEdition: true,
5536
5539
  allowAddScripts: false,
5537
5540
  name: options.tabName,
5538
- // showTab: options.showTab ?? true
5539
- } );
5540
- editor.setText( code, options.language ?? "Plain Text" );
5541
-
5542
- if( options.linesAdded )
5543
- {
5544
- const code = editor.root.querySelector( ".code" );
5545
- for( let l of options.linesAdded )
5541
+ callback: () =>
5546
5542
  {
5547
- if( l.constructor == Number )
5548
- {
5549
- code.childNodes[ l - 1 ].classList.add( "added" );
5550
- }
5551
- else if( l.constructor == Array ) // It's a range
5543
+ if( options.linesAdded )
5552
5544
  {
5553
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5545
+ const code = editor.root.querySelector( ".code" );
5546
+ for( let l of options.linesAdded )
5554
5547
  {
5555
- code.childNodes[ i ].classList.add( "added" );
5548
+ if( l.constructor == Number )
5549
+ {
5550
+ code.childNodes[ l - 1 ].classList.add( "added" );
5551
+ }
5552
+ else if( l.constructor == Array ) // It's a range
5553
+ {
5554
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5555
+ {
5556
+ code.childNodes[ i ].classList.add( "added" );
5557
+ }
5558
+ }
5556
5559
  }
5557
5560
  }
5558
- }
5559
- }
5560
5561
 
5561
- if( options.linesRemoved )
5562
- {
5563
- const code = editor.root.querySelector( ".code" );
5564
- for( let l of options.linesRemoved )
5565
- {
5566
- if( l.constructor == Number )
5567
- {
5568
- code.childNodes[ l - 1 ].classList.add( "removed" );
5569
- }
5570
- else if( l.constructor == Array ) // It's a range
5562
+ if( options.linesRemoved )
5571
5563
  {
5572
- for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5564
+ const code = editor.root.querySelector( ".code" );
5565
+ for( let l of options.linesRemoved )
5573
5566
  {
5574
- code.childNodes[ i ].classList.add( "removed" );
5567
+ if( l.constructor == Number )
5568
+ {
5569
+ code.childNodes[ l - 1 ].classList.add( "removed" );
5570
+ }
5571
+ else if( l.constructor == Array ) // It's a range
5572
+ {
5573
+ for( let i = ( l[ 0 ] - 1 ); i <= ( l[ 1 ] - 1 ); i++ )
5574
+ {
5575
+ code.childNodes[ i ].classList.add( "removed" );
5576
+ }
5577
+ }
5575
5578
  }
5576
5579
  }
5577
5580
  }
5578
- }
5581
+ } );
5582
+
5583
+ editor.setText( code, options.language ?? "Plain Text" );
5579
5584
 
5580
5585
  if( options.windowMode )
5581
5586
  {
@@ -5600,6 +5605,7 @@ function makeCodeSnippet( code, size, options = { } )
5600
5605
  }
5601
5606
 
5602
5607
  snippet.appendChild( area.root );
5608
+
5603
5609
  return snippet;
5604
5610
  }
5605
5611
 
@@ -7532,21 +7538,25 @@ class Area {
7532
7538
  let [ area1, area2 ] = this.sections;
7533
7539
  this.splitExtended = true;
7534
7540
 
7541
+ area1.root.classList.add( `maximize-${ this.type }` );
7542
+ area2.root.classList.add( `minimize-${ this.type }` );
7543
+ area2.root.classList.add( `fadeout-${ this.type }` );
7544
+ area2.root.classList.remove( `fadein-${ this.type }` );
7545
+
7535
7546
  if( this.type == "vertical" )
7536
7547
  {
7537
7548
  this.offset = area2.root.offsetHeight;
7538
- area2.root.classList.add("fadeout-vertical");
7539
7549
  this._moveSplit( -Infinity, true );
7540
-
7541
7550
  }
7542
7551
  else
7543
7552
  {
7544
7553
  this.offset = area2.root.offsetWidth - 8; // Force some height here...
7545
- area2.root.classList.add("fadeout-horizontal");
7546
7554
  this._moveSplit( -Infinity, true, 8 );
7547
7555
  }
7548
7556
 
7549
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7557
+ LX.doAsync( () => {
7558
+ this.propagateEvent( 'onresize' );
7559
+ }, 100 );
7550
7560
  }
7551
7561
 
7552
7562
  /**
@@ -7556,23 +7566,24 @@ class Area {
7556
7566
  reduce() {
7557
7567
 
7558
7568
  if( !this.splitExtended )
7559
- return;
7569
+ {
7570
+ return;
7571
+ }
7560
7572
 
7561
7573
  this.splitExtended = false;
7562
- let [area1, area2] = this.sections;
7563
7574
 
7564
- if( this.type == "vertical")
7565
- {
7566
- area2.root.classList.add("fadein-vertical");
7567
- this._moveSplit(this.offset);
7568
- }
7569
- else
7570
- {
7571
- area2.root.classList.add("fadein-horizontal");
7572
- this._moveSplit(this.offset);
7573
- }
7575
+ let [ area1, area2 ] = this.sections;
7574
7576
 
7575
- LX.doAsync( () => this.propagateEvent('onresize'), 150 );
7577
+ area1.root.classList.add( `minimize-${ this.type }` );
7578
+ area2.root.classList.add( `maximize-${ this.type }` );
7579
+ area2.root.classList.add( `fadein-${ this.type }` );
7580
+ area2.root.classList.remove( `fadeout-${ this.type }` );
7581
+
7582
+ this._moveSplit( this.offset );
7583
+
7584
+ LX.doAsync( () => {
7585
+ this.propagateEvent( 'onresize' );
7586
+ }, 100 );
7576
7587
  }
7577
7588
 
7578
7589
  /**
@@ -7935,8 +7946,8 @@ class BaseComponent {
7935
7946
  BaseComponent.PROGRESS
7936
7947
  ];
7937
7948
 
7938
- constructor( type, name, value, options = {} ) {
7939
-
7949
+ constructor( type, name, value, options = {} )
7950
+ {
7940
7951
  this.type = type;
7941
7952
  this.name = name;
7942
7953
  this.options = options;
@@ -8034,13 +8045,14 @@ class BaseComponent {
8034
8045
  this.options = options;
8035
8046
  }
8036
8047
 
8037
- static _dispatchEvent( element, type, data, bubbles, cancelable ) {
8048
+ static _dispatchEvent( element, type, data, bubbles, cancelable )
8049
+ {
8038
8050
  let event = new CustomEvent( type, { 'detail': data, 'bubbles': bubbles, 'cancelable': cancelable } );
8039
8051
  element.dispatchEvent( event );
8040
8052
  }
8041
8053
 
8042
- _addResetProperty( container, callback ) {
8043
-
8054
+ _addResetProperty( container, callback )
8055
+ {
8044
8056
  const domEl = LX.makeIcon( "Undo2", { iconClass: "ml-0 mr-1 px-1", title: "Reset" } );
8045
8057
  domEl.style.display = "none";
8046
8058
  domEl.addEventListener( "click", callback );
@@ -8048,7 +8060,8 @@ class BaseComponent {
8048
8060
  return domEl;
8049
8061
  }
8050
8062
 
8051
- _canPaste() {
8063
+ _canPaste()
8064
+ {
8052
8065
  let pasteAllowed = this.type === BaseComponent.CUSTOM ?
8053
8066
  ( navigator.clipboard.customIdx !== undefined && this.customIdx == navigator.clipboard.customIdx ) : navigator.clipboard.type === this.type;
8054
8067
 
@@ -8062,8 +8075,8 @@ class BaseComponent {
8062
8075
  return pasteAllowed;
8063
8076
  }
8064
8077
 
8065
- _trigger( event, callback, scope = this ) {
8066
-
8078
+ _trigger( event, callback, scope = this )
8079
+ {
8067
8080
  if( !callback )
8068
8081
  {
8069
8082
  return;
@@ -8072,8 +8085,8 @@ class BaseComponent {
8072
8085
  callback.call( scope, event.value, event.domEvent, event.name );
8073
8086
  }
8074
8087
 
8075
- value() {
8076
-
8088
+ value()
8089
+ {
8077
8090
  if( this.onGetValue )
8078
8091
  {
8079
8092
  return this.onGetValue();
@@ -8082,8 +8095,8 @@ class BaseComponent {
8082
8095
  console.warn( "Can't get value of " + this.typeName() );
8083
8096
  }
8084
8097
 
8085
- set( value, skipCallback, event ) {
8086
-
8098
+ set( value, skipCallback, event )
8099
+ {
8087
8100
  if( this.onSetValue )
8088
8101
  {
8089
8102
  let resetButton = this.root.querySelector( ".lexcomponentname .lexicon" );
@@ -8091,12 +8104,13 @@ class BaseComponent {
8091
8104
  {
8092
8105
  resetButton.style.display = ( value != this.value() ? "block" : "none" );
8093
8106
 
8094
- const equalInitial = value.constructor === Array ? (function arraysEqual(a, b) {
8095
- if (a === b) return true;
8096
- if (a == null || b == null) return false;
8097
- if (a.length !== b.length) return false;
8098
- for (var i = 0; i < a.length; ++i) {
8099
- if (a[ i ] !== b[ i ]) return false;
8107
+ const equalInitial = value.constructor === Array ? (function arraysEqual( a, b ) {
8108
+ if( a === b ) return true;
8109
+ if( a == null || b == null ) return false;
8110
+ if( a.length !== b.length ) return false;
8111
+ for( var i = 0; i < a.length; ++i )
8112
+ {
8113
+ if( a[ i ] !== b[ i ] ) return false;
8100
8114
  }
8101
8115
  return true;
8102
8116
  })( value, this._initialValue ) : ( value == this._initialValue );
@@ -8107,11 +8121,11 @@ class BaseComponent {
8107
8121
  return this.onSetValue( value, skipCallback ?? false, event );
8108
8122
  }
8109
8123
 
8110
- console.warn("Can't set value of " + this.typeName());
8124
+ console.warn( `Can't set value of ${ this.typeName() }`);
8111
8125
  }
8112
8126
 
8113
- oncontextmenu( e ) {
8114
-
8127
+ oncontextmenu( e )
8128
+ {
8115
8129
  if( BaseComponent.NO_CONTEXT_TYPES.includes( this.type ) )
8116
8130
  {
8117
8131
  return;
@@ -8123,14 +8137,16 @@ class BaseComponent {
8123
8137
  });
8124
8138
  }
8125
8139
 
8126
- copy() {
8140
+ copy()
8141
+ {
8127
8142
  navigator.clipboard.type = this.type;
8128
8143
  navigator.clipboard.customIdx = this.customIdx;
8129
8144
  navigator.clipboard.data = this.value();
8130
8145
  navigator.clipboard.writeText( navigator.clipboard.data );
8131
8146
  }
8132
8147
 
8133
- paste() {
8148
+ paste()
8149
+ {
8134
8150
  if( !this._canPaste() )
8135
8151
  {
8136
8152
  return;
@@ -8139,8 +8155,8 @@ class BaseComponent {
8139
8155
  this.set( navigator.clipboard.data );
8140
8156
  }
8141
8157
 
8142
- typeName() {
8143
-
8158
+ typeName()
8159
+ {
8144
8160
  switch( this.type )
8145
8161
  {
8146
8162
  case BaseComponent.TEXT: return "Text";
@@ -8192,8 +8208,8 @@ function ADD_CUSTOM_COMPONENT( customComponentName, options = {} )
8192
8208
  {
8193
8209
  let customIdx = LX.guidGenerator();
8194
8210
 
8195
- LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback ) {
8196
-
8211
+ LX.Panel.prototype[ 'add' + customComponentName ] = function( name, instance, callback )
8212
+ {
8197
8213
  const userParams = Array.from( arguments ).slice( 3 );
8198
8214
 
8199
8215
  let component = new BaseComponent( BaseComponent.CUSTOM, name, null, options );
@@ -8379,8 +8395,8 @@ LX.ADD_CUSTOM_COMPONENT = ADD_CUSTOM_COMPONENT;
8379
8395
 
8380
8396
  class NodeTree {
8381
8397
 
8382
- constructor( domEl, data, options ) {
8383
-
8398
+ constructor( domEl, data, options )
8399
+ {
8384
8400
  this.domEl = domEl;
8385
8401
  this.data = data;
8386
8402
  this.onevent = options.onevent;
@@ -8402,8 +8418,8 @@ class NodeTree {
8402
8418
  }
8403
8419
  }
8404
8420
 
8405
- _createItem( parent, node, level = 0, selectedId ) {
8406
-
8421
+ _createItem( parent, node, level = 0, selectedId )
8422
+ {
8407
8423
  const that = this;
8408
8424
  const nodeFilterInput = this.domEl.querySelector( ".lexnodetreefilter" );
8409
8425
 
@@ -8429,7 +8445,7 @@ class NodeTree {
8429
8445
  if( this.options.onlyFolders )
8430
8446
  {
8431
8447
  let hasFolders = false;
8432
- node.children.forEach( c => hasFolders |= (c.type == 'folder') );
8448
+ node.children.forEach( c => hasFolders |= ( c.type == 'folder' ) );
8433
8449
  isParent = !!hasFolders;
8434
8450
  }
8435
8451
 
@@ -8509,7 +8525,7 @@ class NodeTree {
8509
8525
  node.closed = false;
8510
8526
  if( that.onevent )
8511
8527
  {
8512
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed );
8528
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8513
8529
  that.onevent( event );
8514
8530
  }
8515
8531
  that.frefresh( node.id );
@@ -8517,13 +8533,13 @@ class NodeTree {
8517
8533
 
8518
8534
  if( that.onevent )
8519
8535
  {
8520
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_SELECTED, e.shiftKey ? this.selected : node );
8536
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_SELECTED, node, this.selected, e );
8521
8537
  event.multiple = e.shiftKey;
8522
8538
  that.onevent( event );
8523
8539
  }
8524
8540
  });
8525
8541
 
8526
- item.addEventListener("dblclick", function() {
8542
+ item.addEventListener("dblclick", function(e) {
8527
8543
 
8528
8544
  if( that.options.rename ?? true )
8529
8545
  {
@@ -8534,7 +8550,7 @@ class NodeTree {
8534
8550
 
8535
8551
  if( that.onevent )
8536
8552
  {
8537
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node );
8553
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DBLCLICKED, node, null, e );
8538
8554
  that.onevent( event );
8539
8555
  }
8540
8556
  });
@@ -8548,10 +8564,10 @@ class NodeTree {
8548
8564
  return;
8549
8565
  }
8550
8566
 
8551
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CONTEXTMENU, this.selected.length > 1 ? this.selected : node, e);
8567
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CONTEXTMENU, node, this.selected, e );
8552
8568
  event.multiple = this.selected.length > 1;
8553
8569
 
8554
- LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.value, m => {
8570
+ LX.addContextMenu( event.multiple ? "Selected Nodes" : event.node.id, event.event, m => {
8555
8571
  event.panel = m;
8556
8572
  });
8557
8573
 
@@ -8600,7 +8616,7 @@ class NodeTree {
8600
8616
 
8601
8617
  if( ok && that.onevent )
8602
8618
  {
8603
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, e );
8619
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, [ node ], null );
8604
8620
  that.onevent( event );
8605
8621
  }
8606
8622
 
@@ -8633,7 +8649,7 @@ class NodeTree {
8633
8649
  // Send event now so we have the info in selected array..
8634
8650
  if( nodesDeleted.length && that.onevent )
8635
8651
  {
8636
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, nodesDeleted.length > 1 ? nodesDeleted : node, e );
8652
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DELETED, node, nodesDeleted, e );
8637
8653
  event.multiple = nodesDeleted.length > 1;
8638
8654
  that.onevent( event );
8639
8655
  }
@@ -8675,7 +8691,7 @@ class NodeTree {
8675
8691
 
8676
8692
  if( that.onevent )
8677
8693
  {
8678
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_RENAMED, node, this.value);
8694
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_RENAMED, node, this.value, e );
8679
8695
  that.onevent( event );
8680
8696
  }
8681
8697
 
@@ -8749,7 +8765,7 @@ class NodeTree {
8749
8765
  // Trigger node dragger event
8750
8766
  if( that.onevent )
8751
8767
  {
8752
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_DRAGGED, dragged, target);
8768
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_DRAGGED, dragged, target, e );
8753
8769
  that.onevent( event );
8754
8770
  }
8755
8771
 
@@ -8790,7 +8806,7 @@ class NodeTree {
8790
8806
 
8791
8807
  if( that.onevent )
8792
8808
  {
8793
- const event = new LX.TreeEvent(LX.TreeEvent.NODE_CARETCHANGED, node, node.closed);
8809
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_CARETCHANGED, node, node.closed, e );
8794
8810
  that.onevent( event );
8795
8811
  }
8796
8812
  that.frefresh( node.id );
@@ -8807,28 +8823,34 @@ class NodeTree {
8807
8823
  for( let i = 0; i < node.actions.length; ++i )
8808
8824
  {
8809
8825
  const action = node.actions[ i ];
8810
- const actionIcon = LX.makeIcon( action.icon, { title: action.name } );
8811
- actionIcon.addEventListener("click", function( e ) {
8826
+ const actionBtn = new LX.Button( null, "", ( swapValue, event ) => {
8827
+ event.stopPropagation();
8812
8828
  if( action.callback )
8813
8829
  {
8814
- action.callback( node, actionIcon );
8815
- e.stopPropagation();
8830
+ action.callback( node, swapValue, event );
8816
8831
  }
8817
- });
8832
+ }, { icon: action.icon, swap: action.swap, title: action.name, hideName:true, className: "p-0 m-0", buttonClass: "p-0 m-0 bg-none" } );
8833
+ actionBtn.root.style.minWidth = "fit-content";
8834
+ actionBtn.root.style.margin = "0"; // adding classes does not work
8835
+ actionBtn.root.style.padding = "0"; // adding classes does not work
8836
+ const _btn = actionBtn.root.querySelector("button");
8837
+ _btn.style.minWidth = "fit-content";
8838
+ _btn.style.margin = "0"; // adding classes does not work
8839
+ _btn.style.padding = "0"; // adding classes does not work
8818
8840
 
8819
- inputContainer.appendChild( actionIcon );
8841
+ inputContainer.appendChild( actionBtn.root );
8820
8842
  }
8821
8843
  }
8822
8844
 
8823
8845
  if( !node.skipVisibility ?? false )
8824
8846
  {
8825
- const visibilityBtn = new LX.Button( null, "", ( swapValue, event ) => {
8826
- event.stopPropagation();
8847
+ const visibilityBtn = new LX.Button( null, "", ( swapValue, e ) => {
8848
+ e.stopPropagation();
8827
8849
  node.visible = node.visible === undefined ? false : !node.visible;
8828
8850
  // Trigger visibility event
8829
8851
  if( that.onevent )
8830
8852
  {
8831
- const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible );
8853
+ const event = new LX.TreeEvent( LX.TreeEvent.NODE_VISIBILITY, node, node.visible, e );
8832
8854
  that.onevent( event );
8833
8855
  }
8834
8856
  }, { icon: node.visible ? "Eye" : "EyeOff", swap: node.visible ? "EyeOff" : "Eye", title: "Toggle visible", className: "p-0 m-0", buttonClass: "bg-none" } );
@@ -8884,22 +8906,35 @@ class NodeTree {
8884
8906
  }
8885
8907
 
8886
8908
  /* Refreshes the tree and focuses current element */
8887
- frefresh( id ) {
8888
-
8909
+ frefresh( id )
8910
+ {
8889
8911
  this.refresh();
8890
- var el = this.domEl.querySelector( "#" + id );
8912
+ var el = this.domEl.querySelector( `#${ id }` );
8891
8913
  if( el )
8892
8914
  {
8893
8915
  el.focus();
8894
8916
  }
8895
8917
  }
8896
8918
 
8897
- select( id ) {
8919
+ select( id )
8920
+ {
8921
+ const nodeFilter = this.domEl.querySelector( ".lexnodetreefilter" );
8922
+ if( nodeFilter )
8923
+ {
8924
+ nodeFilter.value = "";
8925
+ }
8898
8926
 
8899
8927
  this.refresh( null, id );
8900
8928
 
8901
8929
  this.domEl.querySelectorAll( ".selected" ).forEach( i => i.classList.remove( "selected" ) );
8902
8930
 
8931
+ // Unselect
8932
+ if( !id )
8933
+ {
8934
+ this.selected.length = 0;
8935
+ return;
8936
+ }
8937
+
8903
8938
  // Element should exist, since tree was refreshed to show it
8904
8939
  const el = this.domEl.querySelector( "#" + id );
8905
8940
  console.assert( el, "NodeTree: Can't select node " + id );
@@ -8909,8 +8944,8 @@ class NodeTree {
8909
8944
  el.focus();
8910
8945
  }
8911
8946
 
8912
- deleteNode( node ) {
8913
-
8947
+ deleteNode( node )
8948
+ {
8914
8949
  const dataAsArray = ( this.data.constructor === Array );
8915
8950
 
8916
8951
  // Can be either Array or Object type data
@@ -8946,10 +8981,10 @@ LX.NodeTree = NodeTree;
8946
8981
  * @description Blank Component
8947
8982
  */
8948
8983
 
8949
- class Blank extends BaseComponent {
8950
-
8951
- constructor( width, height ) {
8952
-
8984
+ class Blank extends BaseComponent
8985
+ {
8986
+ constructor( width, height )
8987
+ {
8953
8988
  super( BaseComponent.BLANK );
8954
8989
 
8955
8990
  this.root.style.width = width ?? "auto";
@@ -8964,10 +8999,10 @@ LX.Blank = Blank;
8964
8999
  * @description Title Component
8965
9000
  */
8966
9001
 
8967
- class Title extends BaseComponent {
8968
-
8969
- constructor( name, options = {} ) {
8970
-
9002
+ class Title extends BaseComponent
9003
+ {
9004
+ constructor( name, options = {} )
9005
+ {
8971
9006
  console.assert( name, "Can't create Title Component without text!" );
8972
9007
 
8973
9008
  // Note: Titles are not registered in Panel.components by now
@@ -9008,10 +9043,10 @@ LX.Title = Title;
9008
9043
  * @description TextInput Component
9009
9044
  */
9010
9045
 
9011
- class TextInput extends BaseComponent {
9012
-
9013
- constructor( name, value, callback, options = {} ) {
9014
-
9046
+ class TextInput extends BaseComponent
9047
+ {
9048
+ constructor( name, value, callback, options = {} )
9049
+ {
9015
9050
  super( BaseComponent.TEXT, name, String( value ), options );
9016
9051
 
9017
9052
  this.onGetValue = () => {
@@ -9098,7 +9133,7 @@ class TextInput extends BaseComponent {
9098
9133
  });
9099
9134
  }
9100
9135
 
9101
- wValue.addEventListener( "mousedown", function( e ){
9136
+ wValue.addEventListener( "mousedown", function( e ) {
9102
9137
  e.stopImmediatePropagation();
9103
9138
  e.stopPropagation();
9104
9139
  });
@@ -9148,10 +9183,10 @@ LX.TextInput = TextInput;
9148
9183
  * @description TextArea Component
9149
9184
  */
9150
9185
 
9151
- class TextArea extends BaseComponent {
9152
-
9153
- constructor( name, value, callback, options = {} ) {
9154
-
9186
+ class TextArea extends BaseComponent
9187
+ {
9188
+ constructor( name, value, callback, options = {} )
9189
+ {
9155
9190
  super( BaseComponent.TEXTAREA, name, value, options );
9156
9191
 
9157
9192
  this.onGetValue = () => {
@@ -9249,10 +9284,10 @@ LX.TextArea = TextArea;
9249
9284
  * @description Button Component
9250
9285
  */
9251
9286
 
9252
- class Button extends BaseComponent {
9253
-
9254
- constructor( name, value, callback, options = {} ) {
9255
-
9287
+ class Button extends BaseComponent
9288
+ {
9289
+ constructor( name, value, callback, options = {} )
9290
+ {
9256
9291
  super( BaseComponent.BUTTON, name, null, options );
9257
9292
 
9258
9293
  this.onGetValue = () => {
@@ -9471,10 +9506,10 @@ LX.Button = Button;
9471
9506
  * @description ComboButtons Component
9472
9507
  */
9473
9508
 
9474
- class ComboButtons extends BaseComponent {
9475
-
9476
- constructor( name, values, options = {} ) {
9477
-
9509
+ class ComboButtons extends BaseComponent
9510
+ {
9511
+ constructor( name, values, options = {} )
9512
+ {
9478
9513
  const shouldSelect = !( options.noSelection ?? false );
9479
9514
  let shouldToggle = shouldSelect && ( options.toggle ?? false );
9480
9515
 
@@ -9632,10 +9667,10 @@ LX.ComboButtons = ComboButtons;
9632
9667
  * @description Card Component
9633
9668
  */
9634
9669
 
9635
- class Card extends BaseComponent {
9636
-
9637
- constructor( name, options = {} ) {
9638
-
9670
+ class Card extends BaseComponent
9671
+ {
9672
+ constructor( name, options = {} )
9673
+ {
9639
9674
  options.hideName = true;
9640
9675
 
9641
9676
  super( BaseComponent.CARD, name, null, options );
@@ -9695,10 +9730,10 @@ LX.Card = Card;
9695
9730
  * @description Form Component
9696
9731
  */
9697
9732
 
9698
- class Form extends BaseComponent {
9699
-
9700
- constructor( name, data, callback, options = {} ) {
9701
-
9733
+ class Form extends BaseComponent
9734
+ {
9735
+ constructor( name, data, callback, options = {} )
9736
+ {
9702
9737
  if( data.constructor != Object )
9703
9738
  {
9704
9739
  console.error( "Form data must be an Object" );
@@ -9810,10 +9845,10 @@ LX.Form = Form;
9810
9845
  * @description Select Component
9811
9846
  */
9812
9847
 
9813
- class Select extends BaseComponent {
9814
-
9815
- constructor( name, values, value, callback, options = {} ) {
9816
-
9848
+ class Select extends BaseComponent
9849
+ {
9850
+ constructor( name, values, value, callback, options = {} )
9851
+ {
9817
9852
  super( BaseComponent.SELECT, name, value, options );
9818
9853
 
9819
9854
  this.onGetValue = () => {
@@ -10222,10 +10257,10 @@ LX.Select = Select;
10222
10257
  * @description Curve Component
10223
10258
  */
10224
10259
 
10225
- class Curve extends BaseComponent {
10226
-
10227
- constructor( name, values, callback, options = {} ) {
10228
-
10260
+ class Curve extends BaseComponent
10261
+ {
10262
+ constructor( name, values, callback, options = {} )
10263
+ {
10229
10264
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10230
10265
 
10231
10266
  super( BaseComponent.CURVE, name, defaultValues, options );
@@ -10283,10 +10318,10 @@ LX.Curve = Curve;
10283
10318
  * @description Dial Component
10284
10319
  */
10285
10320
 
10286
- class Dial extends BaseComponent {
10287
-
10288
- constructor( name, values, callback, options = {} ) {
10289
-
10321
+ class Dial extends BaseComponent
10322
+ {
10323
+ constructor( name, values, callback, options = {} )
10324
+ {
10290
10325
  let defaultValues = JSON.parse( JSON.stringify( values ) );
10291
10326
 
10292
10327
  super( BaseComponent.DIAL, name, defaultValues, options );
@@ -10340,10 +10375,10 @@ LX.Dial = Dial;
10340
10375
  * @description Layers Component
10341
10376
  */
10342
10377
 
10343
- class Layers extends BaseComponent {
10344
-
10345
- constructor( name, value, callback, options = {} ) {
10346
-
10378
+ class Layers extends BaseComponent
10379
+ {
10380
+ constructor( name, value, callback, options = {} )
10381
+ {
10347
10382
  super( BaseComponent.LAYERS, name, value, options );
10348
10383
 
10349
10384
  this.onGetValue = () => {
@@ -10424,10 +10459,10 @@ LX.Layers = Layers;
10424
10459
  * @description ItemArray Component
10425
10460
  */
10426
10461
 
10427
- class ItemArray extends BaseComponent {
10428
-
10429
- constructor( name, values = [], callback, options = {} ) {
10430
-
10462
+ class ItemArray extends BaseComponent
10463
+ {
10464
+ constructor( name, values = [], callback, options = {} )
10465
+ {
10431
10466
  options.nameWidth = "100%";
10432
10467
 
10433
10468
  super( BaseComponent.ARRAY, name, null, options );
@@ -10542,10 +10577,10 @@ LX.ItemArray = ItemArray;
10542
10577
  * @description List Component
10543
10578
  */
10544
10579
 
10545
- class List extends BaseComponent {
10546
-
10547
- constructor( name, values, value, callback, options = {} ) {
10548
-
10580
+ class List extends BaseComponent
10581
+ {
10582
+ constructor( name, values, value, callback, options = {} )
10583
+ {
10549
10584
  super( BaseComponent.LIST, name, value, options );
10550
10585
 
10551
10586
  this.onGetValue = () => {
@@ -10642,10 +10677,10 @@ LX.List = List;
10642
10677
  * @description Tags Component
10643
10678
  */
10644
10679
 
10645
- class Tags extends BaseComponent {
10646
-
10647
- constructor( name, value, callback, options = {} ) {
10648
-
10680
+ class Tags extends BaseComponent
10681
+ {
10682
+ constructor( name, value, callback, options = {} )
10683
+ {
10649
10684
  value = value.replace( /\s/g, '' ).split( ',' );
10650
10685
 
10651
10686
  let defaultValue = [].concat( value );
@@ -10731,10 +10766,10 @@ LX.Tags = Tags;
10731
10766
  * @description Checkbox Component
10732
10767
  */
10733
10768
 
10734
- class Checkbox extends BaseComponent {
10735
-
10736
- constructor( name, value, callback, options = {} ) {
10737
-
10769
+ class Checkbox extends BaseComponent
10770
+ {
10771
+ constructor( name, value, callback, options = {} )
10772
+ {
10738
10773
  if( !name && !options.label )
10739
10774
  {
10740
10775
  throw( "Set Component Name or at least a label!" );
@@ -10814,10 +10849,10 @@ LX.Checkbox = Checkbox;
10814
10849
  * @description Toggle Component
10815
10850
  */
10816
10851
 
10817
- class Toggle extends BaseComponent {
10818
-
10819
- constructor( name, value, callback, options = {} ) {
10820
-
10852
+ class Toggle extends BaseComponent
10853
+ {
10854
+ constructor( name, value, callback, options = {} )
10855
+ {
10821
10856
  if( !name && !options.label )
10822
10857
  {
10823
10858
  throw( "Set Component Name or at least a label!" );
@@ -10898,10 +10933,10 @@ LX.Toggle = Toggle;
10898
10933
  * @description RadioGroup Component
10899
10934
  */
10900
10935
 
10901
- class RadioGroup extends BaseComponent {
10902
-
10903
- constructor( name, label, values, callback, options = {} ) {
10904
-
10936
+ class RadioGroup extends BaseComponent
10937
+ {
10938
+ constructor( name, label, values, callback, options = {} )
10939
+ {
10905
10940
  super( BaseComponent.RADIO, name, null, options );
10906
10941
 
10907
10942
  let currentIndex = null;
@@ -10977,10 +11012,10 @@ LX.RadioGroup = RadioGroup;
10977
11012
  * @description ColorInput Component
10978
11013
  */
10979
11014
 
10980
- class ColorInput extends BaseComponent {
10981
-
10982
- constructor( name, value, callback, options = {} ) {
10983
-
11015
+ class ColorInput extends BaseComponent
11016
+ {
11017
+ constructor( name, value, callback, options = {} )
11018
+ {
10984
11019
  value = value ?? "#000000";
10985
11020
 
10986
11021
  const useAlpha = options.useAlpha ??
@@ -11100,10 +11135,10 @@ LX.ColorInput = ColorInput;
11100
11135
  * @description RangeInput Component
11101
11136
  */
11102
11137
 
11103
- class RangeInput extends BaseComponent {
11104
-
11105
- constructor( name, value, callback, options = {} ) {
11106
-
11138
+ class RangeInput extends BaseComponent
11139
+ {
11140
+ constructor( name, value, callback, options = {} )
11141
+ {
11107
11142
  const ogValue = LX.deepCopy( value );
11108
11143
 
11109
11144
  super( BaseComponent.RANGE, name, LX.deepCopy( ogValue ), options );
@@ -11314,10 +11349,10 @@ LX.RangeInput = RangeInput;
11314
11349
  * @description NumberInput Component
11315
11350
  */
11316
11351
 
11317
- class NumberInput extends BaseComponent {
11318
-
11319
- constructor( name, value, callback, options = {} ) {
11320
-
11352
+ class NumberInput extends BaseComponent
11353
+ {
11354
+ constructor( name, value, callback, options = {} )
11355
+ {
11321
11356
  super( BaseComponent.NUMBER, name, value, options );
11322
11357
 
11323
11358
  this.onGetValue = () => {
@@ -11536,10 +11571,10 @@ LX.NumberInput = NumberInput;
11536
11571
  * @description Vector Component
11537
11572
  */
11538
11573
 
11539
- class Vector extends BaseComponent {
11540
-
11541
- constructor( numComponents, name, value, callback, options = {} ) {
11542
-
11574
+ class Vector extends BaseComponent
11575
+ {
11576
+ constructor( numComponents, name, value, callback, options = {} )
11577
+ {
11543
11578
  numComponents = LX.clamp( numComponents, 2, 4 );
11544
11579
  value = value ?? new Array( numComponents ).fill( 0 );
11545
11580
 
@@ -11786,10 +11821,10 @@ LX.Vector = Vector;
11786
11821
  * @description SizeInput Component
11787
11822
  */
11788
11823
 
11789
- class SizeInput extends BaseComponent {
11790
-
11791
- constructor( name, value, callback, options = {} ) {
11792
-
11824
+ class SizeInput extends BaseComponent
11825
+ {
11826
+ constructor( name, value, callback, options = {} )
11827
+ {
11793
11828
  super( BaseComponent.SIZE, name, value, options );
11794
11829
 
11795
11830
  this.onGetValue = () => {
@@ -11874,10 +11909,10 @@ LX.SizeInput = SizeInput;
11874
11909
  * @description OTPInput Component
11875
11910
  */
11876
11911
 
11877
- class OTPInput extends BaseComponent {
11878
-
11879
- constructor( name, value, callback, options = {} ) {
11880
-
11912
+ class OTPInput extends BaseComponent
11913
+ {
11914
+ constructor( name, value, callback, options = {} )
11915
+ {
11881
11916
  const pattern = options.pattern ?? "xxx-xxx";
11882
11917
  const patternSize = ( pattern.match(/x/g) || [] ).length;
11883
11918
 
@@ -12032,10 +12067,10 @@ LX.OTPInput = OTPInput;
12032
12067
  * @description Pad Component
12033
12068
  */
12034
12069
 
12035
- class Pad extends BaseComponent {
12036
-
12037
- constructor( name, value, callback, options = {} ) {
12038
-
12070
+ class Pad extends BaseComponent
12071
+ {
12072
+ constructor( name, value, callback, options = {} )
12073
+ {
12039
12074
  super( BaseComponent.PAD, name, null, options );
12040
12075
 
12041
12076
  this.onGetValue = () => {
@@ -12152,10 +12187,10 @@ LX.Pad = Pad;
12152
12187
  * @description Progress Component
12153
12188
  */
12154
12189
 
12155
- class Progress extends BaseComponent {
12156
-
12157
- constructor( name, value, options = {} ) {
12158
-
12190
+ class Progress extends BaseComponent
12191
+ {
12192
+ constructor( name, value, options = {} )
12193
+ {
12159
12194
  super( BaseComponent.PROGRESS, name, value, options );
12160
12195
 
12161
12196
  this.onGetValue = () => {
@@ -12289,10 +12324,10 @@ LX.Progress = Progress;
12289
12324
  * @description FileInput Component
12290
12325
  */
12291
12326
 
12292
- class FileInput extends BaseComponent {
12293
-
12294
- constructor( name, callback, options = { } ) {
12295
-
12327
+ class FileInput extends BaseComponent
12328
+ {
12329
+ constructor( name, callback, options = { } )
12330
+ {
12296
12331
  super( BaseComponent.FILE, name, null, options );
12297
12332
 
12298
12333
  let local = options.local ?? true;
@@ -12374,10 +12409,10 @@ LX.FileInput = FileInput;
12374
12409
  * @description Tree Component
12375
12410
  */
12376
12411
 
12377
- class Tree extends BaseComponent {
12378
-
12379
- constructor( name, data, options = {} ) {
12380
-
12412
+ class Tree extends BaseComponent
12413
+ {
12414
+ constructor( name, data, options = {} )
12415
+ {
12381
12416
  options.hideName = true;
12382
12417
 
12383
12418
  super( BaseComponent.TREE, name, null, options );
@@ -12456,10 +12491,10 @@ LX.Tree = Tree;
12456
12491
  * @description TabSections Component
12457
12492
  */
12458
12493
 
12459
- class TabSections extends BaseComponent {
12460
-
12461
- constructor( name, tabs, options = {} ) {
12462
-
12494
+ class TabSections extends BaseComponent
12495
+ {
12496
+ constructor( name, tabs, options = {} )
12497
+ {
12463
12498
  options.hideName = true;
12464
12499
 
12465
12500
  super( BaseComponent.TABS, name, null, options );
@@ -12563,10 +12598,10 @@ LX.TabSections = TabSections;
12563
12598
  * @description Counter Component
12564
12599
  */
12565
12600
 
12566
- class Counter extends BaseComponent {
12567
-
12568
- constructor( name, value, callback, options = { } ) {
12569
-
12601
+ class Counter extends BaseComponent
12602
+ {
12603
+ constructor( name, value, callback, options = { } )
12604
+ {
12570
12605
  super( BaseComponent.COUNTER, name, value, options );
12571
12606
 
12572
12607
  this.onGetValue = () => {
@@ -12633,10 +12668,10 @@ LX.Counter = Counter;
12633
12668
  * @description Table Component
12634
12669
  */
12635
12670
 
12636
- class Table extends BaseComponent {
12637
-
12638
- constructor( name, data, options = { } ) {
12639
-
12671
+ class Table extends BaseComponent
12672
+ {
12673
+ constructor( name, data, options = { } )
12674
+ {
12640
12675
  if( !data )
12641
12676
  {
12642
12677
  throw( "Data is needed to create a table!" );
@@ -12669,12 +12704,12 @@ class Table extends BaseComponent {
12669
12704
  data.body = data.body ?? [];
12670
12705
  data.checkMap = { };
12671
12706
  data.colVisibilityMap = { };
12672
- data.head.forEach( (col, index) => { data.colVisibilityMap[ index ] = true; });
12707
+ data.head.forEach( ( col, index ) => { data.colVisibilityMap[ index ] = true; });
12673
12708
  this.data = data;
12674
12709
 
12675
- const compareFn = ( idx, order, a, b) => {
12676
- if (a[idx] < b[idx]) return -order;
12677
- else if (a[idx] > b[idx]) return order;
12710
+ const compareFn = ( idx, order, a, b ) => {
12711
+ if( a[ idx ] < b[ idx ] ) return -order;
12712
+ else if( a[ idx ] > b[ idx ] ) return order;
12678
12713
  return 0;
12679
12714
  };
12680
12715
 
@@ -12844,10 +12879,10 @@ class Table extends BaseComponent {
12844
12879
  icon: "Check",
12845
12880
  callback: () => {
12846
12881
  data.colVisibilityMap[ idx ] = !data.colVisibilityMap[ idx ];
12847
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12848
- cells.forEach(cell => {
12849
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12850
- });
12882
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
12883
+ cells.forEach( cell => {
12884
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
12885
+ } );
12851
12886
  }
12852
12887
  };
12853
12888
  if( !data.colVisibilityMap[ idx ] ) delete item.icon;
@@ -12942,9 +12977,9 @@ class Table extends BaseComponent {
12942
12977
  name: "Hide", icon: "EyeOff", callback: () => {
12943
12978
  data.colVisibilityMap[ idx ] = false;
12944
12979
  const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
12945
- cells.forEach(cell => {
12946
- cell.style.display = (cell.style.display === "none") ? "" : "none";
12947
- });
12980
+ cells.forEach( cell => {
12981
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
12982
+ } );
12948
12983
  }
12949
12984
  }
12950
12985
  );
@@ -13316,10 +13351,10 @@ class Table extends BaseComponent {
13316
13351
  const idx = parseInt( v );
13317
13352
  if( !data.colVisibilityMap[ idx ] )
13318
13353
  {
13319
- const cells = table.querySelectorAll(`tr > *:nth-child(${idx + this.rowOffsetCount + 1})`);
13320
- cells.forEach(cell => {
13321
- cell.style.display = (cell.style.display === "none") ? "" : "none";
13322
- });
13354
+ const cells = table.querySelectorAll( `tr > *:nth-child(${idx + this.rowOffsetCount + 1})` );
13355
+ cells.forEach( cell => {
13356
+ cell.style.display = ( cell.style.display === "none" ) ? "" : "none";
13357
+ } );
13323
13358
  }
13324
13359
  }
13325
13360
  };
@@ -13329,8 +13364,8 @@ class Table extends BaseComponent {
13329
13364
  LX.doAsync( this.onResize.bind( this ) );
13330
13365
  }
13331
13366
 
13332
- getSelectedRows() {
13333
-
13367
+ getSelectedRows()
13368
+ {
13334
13369
  const selectedRows = [];
13335
13370
 
13336
13371
  for( const row of this.data.body )
@@ -13345,8 +13380,8 @@ class Table extends BaseComponent {
13345
13380
  return selectedRows;
13346
13381
  }
13347
13382
 
13348
- _setCentered( v ) {
13349
-
13383
+ _setCentered( v )
13384
+ {
13350
13385
  if( v.constructor == Boolean )
13351
13386
  {
13352
13387
  const container = this.root.querySelector( ".lextable" );
@@ -13379,10 +13414,10 @@ LX.Table = Table;
13379
13414
  * @description DatePicker Component
13380
13415
  */
13381
13416
 
13382
- class DatePicker extends BaseComponent {
13383
-
13384
- constructor( name, dateValue, callback, options = { } ) {
13385
-
13417
+ class DatePicker extends BaseComponent
13418
+ {
13419
+ constructor( name, dateValue, callback, options = { } )
13420
+ {
13386
13421
  super( BaseComponent.DATE, name, null, options );
13387
13422
 
13388
13423
  const dateAsRange = ( dateValue?.constructor === Array );
@@ -13497,10 +13532,10 @@ LX.DatePicker = DatePicker;
13497
13532
  * @description Map2D Component
13498
13533
  */
13499
13534
 
13500
- class Map2D extends BaseComponent {
13501
-
13502
- constructor( name, points, callback, options = {} ) {
13503
-
13535
+ class Map2D extends BaseComponent
13536
+ {
13537
+ constructor( name, points, callback, options = {} )
13538
+ {
13504
13539
  super( BaseComponent.MAP2D, name, null, options );
13505
13540
 
13506
13541
  this.onGetValue = () => {
@@ -13544,13 +13579,13 @@ LX.Map2D = Map2D;
13544
13579
  * @description Rate Component
13545
13580
  */
13546
13581
 
13547
- class Rate extends BaseComponent {
13548
-
13549
- constructor( name, value, callback, options = {} ) {
13550
-
13582
+ class Rate extends BaseComponent
13583
+ {
13584
+ constructor( name, value, callback, options = {} )
13585
+ {
13551
13586
  const allowHalf = options.allowHalf ?? false;
13552
13587
 
13553
- if( !allowHalf)
13588
+ if( !allowHalf )
13554
13589
  {
13555
13590
  value = Math.floor( value );
13556
13591
  }
@@ -15093,8 +15128,8 @@ LX.Branch = Branch;
15093
15128
 
15094
15129
  class Menubar {
15095
15130
 
15096
- constructor( items, options = {} ) {
15097
-
15131
+ constructor( items, options = {} )
15132
+ {
15098
15133
  this.root = document.createElement( "div" );
15099
15134
  this.root.className = "lexmenubar";
15100
15135
 
@@ -15111,8 +15146,8 @@ class Menubar {
15111
15146
  this.createEntries();
15112
15147
  }
15113
15148
 
15114
- _resetMenubar( focus ) {
15115
-
15149
+ _resetMenubar( focus )
15150
+ {
15116
15151
  this.root.querySelectorAll(".lexmenuentry").forEach( e => {
15117
15152
  e.classList.remove( 'selected' );
15118
15153
  delete e.dataset[ "built" ];
@@ -15132,8 +15167,8 @@ class Menubar {
15132
15167
  * @method createEntries
15133
15168
  */
15134
15169
 
15135
- createEntries() {
15136
-
15170
+ createEntries()
15171
+ {
15137
15172
  for( let item of this.items )
15138
15173
  {
15139
15174
  let key = item.name;
@@ -15199,7 +15234,8 @@ class Menubar {
15199
15234
  * @param {String} name
15200
15235
  */
15201
15236
 
15202
- getButton( name ) {
15237
+ getButton( name )
15238
+ {
15203
15239
  return this.buttons[ name ];
15204
15240
  }
15205
15241
 
@@ -15208,26 +15244,23 @@ class Menubar {
15208
15244
  * @param {Object} item: parent item
15209
15245
  * @param {Array} tokens: split path strings
15210
15246
  */
15211
- getSubitem( item, tokens ) {
15212
-
15213
- let subitem = null;
15214
- let path = tokens[ 0 ];
15215
-
15216
- for( let i = 0; i < item.length; i++ )
15247
+ getSubitem( item, tokens )
15248
+ {
15249
+ for( const s of item )
15217
15250
  {
15218
- if( item[ i ][ path ] )
15251
+ if ( s?.name != tokens[ 0 ] )
15219
15252
  {
15220
- if( tokens.length == 1 )
15221
- {
15222
- subitem = item[ i ];
15223
- return subitem;
15224
- }
15225
- else
15226
- {
15227
- tokens.splice( 0, 1 );
15228
- return this.getSubitem( item[ i ][ path ], tokens );
15229
- }
15253
+ continue;
15254
+ }
15230
15255
 
15256
+ if( tokens.length == 1 )
15257
+ {
15258
+ return s;
15259
+ }
15260
+ else if ( s.submenu )
15261
+ {
15262
+ tokens.shift();
15263
+ return this.getSubitem( s.submenu, tokens );
15231
15264
  }
15232
15265
  }
15233
15266
  }
@@ -15236,12 +15269,11 @@ class Menubar {
15236
15269
  * @method getItem
15237
15270
  * @param {String} path
15238
15271
  */
15239
- getItem( path ) {
15240
-
15241
- // process path
15242
- const tokens = path.split("/");
15243
-
15244
- return this.getSubitem(this.items, tokens)
15272
+ getItem( path )
15273
+ {
15274
+ // Process path
15275
+ const tokens = path.split( '/' );
15276
+ return this.getSubitem( this.items, tokens );
15245
15277
  }
15246
15278
 
15247
15279
  /**
@@ -15252,8 +15284,8 @@ class Menubar {
15252
15284
  * @param {Object} options
15253
15285
  */
15254
15286
 
15255
- setButtonIcon( name, icon, callback, options = {} ) {
15256
-
15287
+ setButtonIcon( name, icon, callback, options = {} )
15288
+ {
15257
15289
  if( !name )
15258
15290
  {
15259
15291
  throw( "Set Button Name!" );
@@ -15308,8 +15340,8 @@ class Menubar {
15308
15340
  * @param {Object} options
15309
15341
  */
15310
15342
 
15311
- setButtonImage( name, src, callback, options = {} ) {
15312
-
15343
+ setButtonImage( name, src, callback, options = {} )
15344
+ {
15313
15345
  if( !name )
15314
15346
  {
15315
15347
  throw( "Set Button Name!" );
@@ -15318,14 +15350,14 @@ class Menubar {
15318
15350
  let button = this.buttons[ name ];
15319
15351
  if( button )
15320
15352
  {
15321
- button.querySelector('img').src = src;
15353
+ button.querySelector( 'img' ).src = src;
15322
15354
  return;
15323
15355
  }
15324
15356
 
15325
15357
  // Otherwise, create it
15326
- button = document.createElement('div');
15358
+ button = document.createElement( 'div' );
15327
15359
  const disabled = options.disabled ?? false;
15328
- button.className = "lexmenubutton main" + (disabled ? " disabled" : "");
15360
+ button.className = "lexmenubutton main" + ( disabled ? " disabled" : "" );
15329
15361
  button.title = name;
15330
15362
  button.innerHTML = "<a><image src='" + src + "' class='lexicon' style='height:32px;'></a>";
15331
15363
 
@@ -15349,11 +15381,11 @@ class Menubar {
15349
15381
 
15350
15382
  const _b = button.querySelector('a');
15351
15383
 
15352
- _b.addEventListener( "mousedown", (e) => {
15384
+ _b.addEventListener( "mousedown", e => {
15353
15385
  e.preventDefault();
15354
15386
  });
15355
15387
 
15356
- _b.addEventListener( "mouseup", (e) => {
15388
+ _b.addEventListener( "mouseup", e => {
15357
15389
  if( callback && !disabled )
15358
15390
  {
15359
15391
  callback.call( this, _b, e );
@@ -15370,8 +15402,8 @@ class Menubar {
15370
15402
  * float: center (Default), right
15371
15403
  */
15372
15404
 
15373
- addButtons( buttons, options = {} ) {
15374
-
15405
+ addButtons( buttons, options = {} )
15406
+ {
15375
15407
  if( !buttons )
15376
15408
  {
15377
15409
  throw( "No buttons to add!" );
@@ -15398,9 +15430,8 @@ class Menubar {
15398
15430
  }
15399
15431
  }
15400
15432
 
15401
- for( let i = 0; i < buttons.length; ++i )
15433
+ for( const data of buttons )
15402
15434
  {
15403
- const data = buttons[ i ];
15404
15435
  const title = data.title;
15405
15436
  const button = new LX.Button( title, data.label, data.callback, {
15406
15437
  title,
@@ -16588,13 +16619,13 @@ class AssetView {
16588
16619
  const isListLayout = ( this.layout == AssetView.LAYOUT_LIST );
16589
16620
 
16590
16621
  this.filter = filter ?? ( this.filter ?? "None" );
16591
- this.searchValue = searchValue ?? (this.searchValue ?? "");
16622
+ this.searchValue = searchValue ?? ( this.searchValue ?? "" );
16592
16623
  this.content.innerHTML = "";
16593
16624
  this.content.className = `lexassetscontent${ isCompactLayout ? " compact" : ( isListLayout ? " list" : "" ) }`;
16594
16625
  let that = this;
16595
16626
 
16596
- const _addItem = function(item) {
16597
-
16627
+ const _addItem = function( item )
16628
+ {
16598
16629
  const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
16599
16630
  const extension = LX.getExtension( item.id );
16600
16631
  const isFolder = type === "Folder";
@@ -16613,10 +16644,11 @@ class AssetView {
16613
16644
  {
16614
16645
  let desc = document.createElement( 'span' );
16615
16646
  desc.className = 'lexitemdesc';
16616
- desc.innerHTML = "File: " + item.id + "<br>Type: " + type;
16647
+ desc.id = `floatingTitle_${ item.id }`;
16648
+ desc.innerHTML = `File: ${ item.id }<br>Type: ${ type }`;
16617
16649
  that.content.appendChild( desc );
16618
16650
 
16619
- itemEl.addEventListener("mousemove", e => {
16651
+ itemEl.addEventListener( "mousemove", e => {
16620
16652
 
16621
16653
  if( !isGridLayout )
16622
16654
  {
@@ -16644,23 +16676,7 @@ class AssetView {
16644
16676
 
16645
16677
  desc.style.left = ( localOffsetX ) + "px";
16646
16678
  desc.style.top = ( localOffsetY - 36 ) + "px";
16647
- });
16648
-
16649
- itemEl.addEventListener("mouseenter", () => {
16650
- if( isGridLayout )
16651
- {
16652
- desc.style.display = "unset";
16653
- }
16654
- });
16655
-
16656
- itemEl.addEventListener("mouseleave", () => {
16657
- if( isGridLayout )
16658
- {
16659
- setTimeout( () => {
16660
- desc.style.display = "none";
16661
- }, 100 );
16662
- }
16663
- });
16679
+ } );
16664
16680
  }
16665
16681
  else
16666
16682
  {
@@ -16695,26 +16711,49 @@ class AssetView {
16695
16711
 
16696
16712
  if( !that.skipPreview )
16697
16713
  {
16714
+ if( item.type === 'video' )
16715
+ {
16716
+ const itemVideo = LX.makeElement( 'video', 'absolute left-0 top-0 w-full border-none pointer-events-none', '', itemEl );
16717
+ itemVideo.setAttribute( 'disablePictureInPicture', false );
16718
+ itemVideo.setAttribute( 'disableRemotePlayback', false );
16719
+ itemVideo.setAttribute( 'loop', true );
16720
+ itemVideo.setAttribute( 'async', true );
16721
+ itemVideo.style.transition = 'opacity 0.2s ease-out';
16722
+ itemVideo.style.opacity = item.preview ? '0' : '1';
16723
+ itemVideo.src = item.src;
16724
+ itemVideo.volume = item.videoVolume ?? 0.4;
16725
+ }
16726
+
16698
16727
  let preview = null;
16699
- const hasImage = item.src && (['png', 'jpg'].indexOf( LX.getExtension( item.src ) ) > -1 || item.src.includes("data:image/") ); // Support b64 image as src
16700
16728
 
16701
- if( hasImage || isFolder || !isGridLayout)
16729
+ const previewSrc = item.preview ?? item.src;
16730
+ const hasImage = previewSrc && (
16731
+ (() => {
16732
+ const ext = LX.getExtension( previewSrc.split( '?' )[ 0 ].split( '#' )[ 0 ]); // get final source without url parameters/anchors
16733
+ return ext ? ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'avif'].includes( ext.toLowerCase() ) : false;
16734
+ })()
16735
+ || previewSrc.startsWith( 'data:image/' )
16736
+ );
16737
+
16738
+ if( hasImage || isFolder || !isGridLayout )
16702
16739
  {
16740
+ const defaultPreviewPath = `${ that.rootPath }images/file.png`;
16741
+ const defaultFolderPath = `${ that.rootPath }images/folder.png`;
16742
+
16703
16743
  preview = document.createElement('img');
16704
- let real_src = item.unknown_extension ? that.rootPath + "images/file.png" : (isFolder ? that.rootPath + "images/folder.png" : item.src);
16705
- preview.src = (isGridLayout || isFolder ? real_src : that.rootPath + "images/file.png");
16744
+ let realSrc = item.unknownExtension ? defaultPreviewPath : ( isFolder ? defaultFolderPath : previewSrc );
16745
+ preview.src = ( isGridLayout || isFolder ? realSrc : defaultPreviewPath );
16706
16746
  itemEl.appendChild( preview );
16707
16747
  }
16708
16748
  else
16709
16749
  {
16710
- preview = document.createElement('svg');
16711
- preview.className = "asset-file-preview";
16712
- itemEl.appendChild(preview);
16750
+ preview = document.createElement( 'svg' );
16751
+ preview.className = 'asset-file-preview';
16752
+ itemEl.appendChild( preview );
16713
16753
 
16714
- let textEl = document.createElement('text');
16715
- preview.appendChild(textEl);
16716
- // If no extension, e.g. Clip, use the type...
16717
- textEl.innerText = (!extension || extension == item.id) ? item.type.toUpperCase() : ("." + extension.toUpperCase());
16754
+ let textEl = document.createElement( 'text' );
16755
+ textEl.innerText = ( !extension || extension == item.id ) ? item.type.toUpperCase() : ( `.${ extension.toUpperCase() }` ); // If no extension, e.g. Clip, use the type...
16756
+ preview.appendChild( textEl );
16718
16757
 
16719
16758
  var newLength = textEl.innerText.length;
16720
16759
  var charsPerLine = 2.5;
@@ -16724,8 +16763,8 @@ class AssetView {
16724
16763
  if( newEmSize < 1 )
16725
16764
  {
16726
16765
  var newFontSize = newEmSize * textBaseSize;
16727
- textEl.style.fontSize = newFontSize + "px";
16728
- preview.style.paddingTop = "calc(50% - " + (textEl.offsetHeight * 0.5 + 10) + "px)";
16766
+ textEl.style.fontSize = newFontSize + 'px';
16767
+ preview.style.paddingTop = `calc(50% - ${ ( textEl.offsetHeight * 0.5 + 10 ) }px)`;
16729
16768
  }
16730
16769
  }
16731
16770
  }
@@ -16739,7 +16778,7 @@ class AssetView {
16739
16778
  if( item.lastModifiedDate ) itemInfoHtml += ` | ${ item.lastModifiedDate }`;
16740
16779
  }
16741
16780
 
16742
- LX.makeContainer( [ "auto", "auto" ], "lexassetinfo", itemInfoHtml, itemEl );
16781
+ LX.makeContainer( [ 'auto', 'auto' ], 'lexassetinfo', itemInfoHtml, itemEl );
16743
16782
 
16744
16783
  itemEl.addEventListener('click', function( e ) {
16745
16784
  e.stopImmediatePropagation();
@@ -16751,10 +16790,10 @@ class AssetView {
16751
16790
  {
16752
16791
  if( !e.shiftKey )
16753
16792
  {
16754
- that.content.querySelectorAll('.lexassetitem').forEach( i => i.classList.remove('selected') );
16793
+ that.content.querySelectorAll( '.lexassetitem').forEach( i => i.classList.remove( 'selected' ) );
16755
16794
  }
16756
16795
 
16757
- this.classList.add('selected');
16796
+ this.classList.add( 'selected' );
16758
16797
  that.selectedItem = item;
16759
16798
 
16760
16799
  if( !that.skipPreview )
@@ -16807,6 +16846,42 @@ class AssetView {
16807
16846
  e.preventDefault();
16808
16847
  }, false );
16809
16848
 
16849
+ itemEl.addEventListener( "mouseenter", ( e ) => {
16850
+
16851
+ if( !that.useNativeTitle && isGridLayout )
16852
+ {
16853
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16854
+ if( desc ) desc.style.display = "unset";
16855
+ }
16856
+
16857
+ if( item.type !== "video" ) return;
16858
+ e.preventDefault();
16859
+ const video = itemEl.querySelector( "video" );
16860
+ video.style.opacity = "1";
16861
+ video.play();
16862
+ } );
16863
+
16864
+ itemEl.addEventListener( "mouseleave", ( e ) => {
16865
+
16866
+ if( !that.useNativeTitle && isGridLayout )
16867
+ {
16868
+ setTimeout( () => {
16869
+ const desc = that.content.querySelector( `#floatingTitle_${ item.id }` );
16870
+ if( desc ) desc.style.display = "none";
16871
+ }, 100 );
16872
+ }
16873
+
16874
+ if( item.type !== "video" ) return;
16875
+ e.preventDefault();
16876
+ const video = itemEl.querySelector( "video" );
16877
+ video.pause();
16878
+ video.currentTime = 0;
16879
+ if( item.preview )
16880
+ {
16881
+ video.style.opacity = "0";
16882
+ }
16883
+ } );
16884
+
16810
16885
  return itemEl;
16811
16886
  };
16812
16887
 
@@ -16951,7 +17026,7 @@ class AssetView {
16951
17026
  item.type = "mesh"; break;
16952
17027
  default:
16953
17028
  item.type = ext;
16954
- item.unknown_extension = true;
17029
+ item.unknownExtension = true;
16955
17030
  break;
16956
17031
  }
16957
17032