lexgui 0.5.7 → 0.5.8

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.
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  var LX = {
9
- version: "0.5.7",
9
+ version: "0.5.8",
10
10
  ready: false,
11
11
  components: [], // Specific pre-build components
12
12
  signals: {}, // Events and triggers
@@ -128,6 +128,56 @@ function stripHTML( html )
128
128
 
129
129
  LX.stripHTML = stripHTML;
130
130
 
131
+ /**
132
+ * @method parsePixelSize
133
+ * @description Parses any css size and returns a number of pixels
134
+ * @param {Number|String} size
135
+ * @param {Number} total
136
+ */
137
+ const parsePixelSize = ( size, total ) => {
138
+
139
+ if( size.constructor === Number ) { return size; } // Assuming pixels..
140
+
141
+ if( size.constructor === String )
142
+ {
143
+ const value = parseFloat( size );
144
+
145
+ if( size.endsWith( "px" ) ) { return value; } // String pixels
146
+ if( size.endsWith( '%' ) ) { return ( value / 100 ) * total; } // Percentage
147
+ if( size.endsWith( "rem" ) || size.endsWith( "em" ) ) { const rootFontSize = 16; /*parseFloat(getComputedStyle(document.documentElement).fontSize);*/ return value * rootFontSize; } // rem unit: assume 16px = 1rem
148
+ if( size.endsWith( "vw" ) ) { return ( value / 100 ) * window.innerWidth; } // wViewport units
149
+ if( size.endsWith( "vh" ) ) { return ( value / 100 ) * window.innerHeight; } // hViewport units
150
+
151
+ // Any CSS calc expression (e.g., "calc(30% - 4px)")
152
+ if( size.startsWith( "calc(" ) )
153
+ {
154
+ const expr = size.slice( 5, -1 );
155
+ const parts = expr.split( /([+\-])/ ); // ["30% ", "-", "4px"]
156
+ let result = 0;
157
+ let op = "+";
158
+ for( let part of parts )
159
+ {
160
+ part = part.trim();
161
+ if( part === "+" || part === "-" )
162
+ {
163
+ op = part;
164
+ }
165
+ else
166
+ {
167
+ let value = parsePixelSize( part, total );
168
+ result = ( op === "+" ) ? result + value : result - value;
169
+ }
170
+ }
171
+
172
+ return result;
173
+ }
174
+ }
175
+
176
+ throw( "Bad size format!" );
177
+ }
178
+
179
+ LX.parsePixelSize = parsePixelSize;
180
+
131
181
  /**
132
182
  * @method deepCopy
133
183
  * @description Create a deep copy with no references from an object
@@ -2251,6 +2301,8 @@ class ColorPicker {
2251
2301
 
2252
2302
  doAsync( this._svToPosition.bind( this, this.currentColor.hsv.s, this.currentColor.hsv.v ) );
2253
2303
 
2304
+ let pickerRect = null;
2305
+
2254
2306
  let innerMouseDown = e => {
2255
2307
  var doc = this.root.ownerDocument;
2256
2308
  doc.addEventListener( 'mousemove', innerMouseMove );
@@ -2265,15 +2317,15 @@ class ColorPicker {
2265
2317
  this.intSatMarker.style.top = currentTop + "px";
2266
2318
  this._positionToSv( currentLeft, currentTop );
2267
2319
  this._updateColorValue();
2320
+
2321
+ pickerRect = this.colorPickerBackground.getBoundingClientRect();
2268
2322
  }
2269
2323
 
2270
2324
  let innerMouseMove = e => {
2271
2325
  const dX = e.movementX;
2272
2326
  const dY = e.movementY;
2273
-
2274
- const rect = this.colorPickerBackground.getBoundingClientRect();
2275
- const mouseX = e.offsetX - rect.x;
2276
- const mouseY = e.offsetY - rect.y;
2327
+ const mouseX = e.x - pickerRect.x;
2328
+ const mouseY = e.y - pickerRect.y;
2277
2329
 
2278
2330
  if ( dX != 0 && ( mouseX >= 0 || dX < 0 ) && ( mouseX < this.colorPickerBackground.offsetWidth || dX > 0 ) )
2279
2331
  {
@@ -2343,6 +2395,8 @@ class ColorPicker {
2343
2395
  this._updateColorValue();
2344
2396
  };
2345
2397
 
2398
+ let hueTrackerRect = null;
2399
+
2346
2400
  let innerMouseDownHue = e => {
2347
2401
  const doc = this.root.ownerDocument;
2348
2402
  doc.addEventListener( 'mousemove', innerMouseMoveHue );
@@ -2353,15 +2407,15 @@ class ColorPicker {
2353
2407
 
2354
2408
  const hueX = clamp( e.offsetX - this.markerHalfSize, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
2355
2409
  _fromHueX( hueX );
2410
+
2411
+ hueTrackerRect = this.colorPickerTracker.getBoundingClientRect();
2356
2412
  }
2357
2413
 
2358
2414
  let innerMouseMoveHue = e => {
2359
- let dX = e.movementX;
2360
-
2361
- const rect = this.colorPickerTracker.getBoundingClientRect();
2362
- const mouseX = e.offsetX - rect.x;
2415
+ const dX = e.movementX;
2416
+ const mouseX = e.x - hueTrackerRect.x;
2363
2417
 
2364
- if ( dX != 0 && ( mouseX >= 0 || dX < 0 ) && ( mouseX < this.colorPickerTracker.offsetWidth || dX > 0 ) )
2418
+ if ( dX != 0 && ( mouseX >= this.markerHalfSize || dX < 0 ) && ( mouseX < ( this.colorPickerTracker.offsetWidth - this.markerHalfSize ) || dX > 0 ) )
2365
2419
  {
2366
2420
  const hueX = LX.clamp( parseInt( this.hueMarker.style.left ) + dX, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
2367
2421
  _fromHueX( hueX )
@@ -2406,6 +2460,8 @@ class ColorPicker {
2406
2460
  this.alphaMarker.style.backgroundColor = `rgb(${ this.currentColor.css.r }, ${ this.currentColor.css.g }, ${ this.currentColor.css.b },${ this.currentColor.css.a })`;
2407
2461
  };
2408
2462
 
2463
+ let alphaTrackerRect = null;
2464
+
2409
2465
  let innerMouseDownAlpha = e => {
2410
2466
  const doc = this.root.ownerDocument;
2411
2467
  doc.addEventListener( 'mousemove', innerMouseMoveAlpha );
@@ -2415,15 +2471,14 @@ class ColorPicker {
2415
2471
  e.stopPropagation();
2416
2472
  const alphaX = clamp( e.offsetX - this.markerHalfSize, 0, this.alphaTracker.offsetWidth - this.markerSize );
2417
2473
  _fromAlphaX( alphaX );
2474
+ alphaTrackerRect = this.alphaTracker.getBoundingClientRect();
2418
2475
  }
2419
2476
 
2420
2477
  let innerMouseMoveAlpha = e => {
2421
- let dX = e.movementX;
2422
-
2423
- const rect = this.alphaTracker.getBoundingClientRect();
2424
- const mouseX = e.offsetX - rect.x;
2478
+ const dX = e.movementX;
2479
+ const mouseX = e.x - alphaTrackerRect.x;
2425
2480
 
2426
- if ( dX != 0 && ( mouseX >= 0 || dX < 0 ) && ( mouseX < this.alphaTracker.offsetWidth || dX > 0 ) )
2481
+ if ( dX != 0 && ( mouseX >= this.markerHalfSize || dX < 0 ) && ( mouseX < ( this.alphaTracker.offsetWidth - this.markerHalfSize ) || dX > 0 ) )
2427
2482
  {
2428
2483
  const alphaX = LX.clamp( parseInt( this.alphaMarker.style.left ) + dX, 0, this.alphaTracker.offsetWidth - this.markerSize );
2429
2484
  _fromAlphaX( alphaX );
@@ -2861,7 +2916,7 @@ class Area {
2861
2916
  * @method split
2862
2917
  * @param {Object} options
2863
2918
  * type: Split mode (horizontal, vertical) ["horizontal"]
2864
- * sizes: Size of each new area (Array) ["50%", "50%"]
2919
+ * sizes: CSS Size of each new area (Array) ["50%", "50%"]
2865
2920
  * resize: Allow area manual resizing [true]
2866
2921
  * sizes: "Allow the area to be minimized [false]
2867
2922
  */
@@ -2876,11 +2931,12 @@ class Area {
2876
2931
  this.root = this.sections[ 1 ].root;
2877
2932
  }
2878
2933
 
2879
- const type = options.type || "horizontal";
2934
+ const type = options.type ?? "horizontal";
2880
2935
  const sizes = options.sizes || [ "50%", "50%" ];
2881
2936
  const auto = (options.sizes === 'auto') || ( options.sizes && options.sizes[ 0 ] == "auto" && options.sizes[ 1 ] == "auto" );
2882
2937
 
2883
- if( !sizes[ 1 ] )
2938
+ // Secondary area fills space
2939
+ if( !sizes[ 1 ] || ( sizes[ 0 ] != "auto" && sizes[ 1 ] == "auto" ) )
2884
2940
  {
2885
2941
  let size = sizes[ 0 ];
2886
2942
  let margin = options.top ? options.top : 0;
@@ -2893,17 +2949,13 @@ class Area {
2893
2949
  sizes[ 1 ] = "calc( 100% - " + size + " )";
2894
2950
  }
2895
2951
 
2896
- // Create areas
2897
- let area1 = new Area( { skipAppend: true, className: "split" + ( options.menubar || options.sidebar ? "" : " origin" ) } );
2898
- let area2 = new Area( { skipAppend: true, className: "split" } );
2899
-
2900
- area1.parentArea = this;
2901
- area2.parentArea = this;
2902
-
2903
2952
  let minimizable = options.minimizable ?? false;
2904
2953
  let resize = ( options.resize ?? true ) || minimizable;
2954
+ let fixedSize = options.fixedSize ?? !resize;
2955
+ let splitbarOffset = 0;
2956
+ let primarySize = [];
2957
+ let secondarySize = [];
2905
2958
 
2906
- let data = "0px";
2907
2959
  this.offset = 0;
2908
2960
 
2909
2961
  if( resize )
@@ -2923,93 +2975,104 @@ class Area {
2923
2975
 
2924
2976
  this.splitBar.addEventListener( 'mousedown', innerMouseDown );
2925
2977
 
2926
- data = ( LX.DEFAULT_SPLITBAR_SIZE / 2 ) + "px"; // updates
2927
-
2928
- // Being minimizable means it's also resizeable!
2929
- if( minimizable )
2930
- {
2931
- this.splitExtended = false;
2932
-
2933
- // Keep state of the animation when ends...
2934
- area2.root.addEventListener('animationend', e => {
2935
- const opacity = getComputedStyle( area2.root ).opacity;
2936
- area2.root.classList.remove( e.animationName + "-" + type );
2937
- area2.root.style.opacity = opacity;
2938
- flushCss(area2.root);
2939
- });
2940
-
2941
- this.splitBar.addEventListener("contextmenu", e => {
2942
- e.preventDefault();
2943
- addContextMenu(null, e, c => {
2944
- c.add("Extend", { disabled: this.splitExtended, callback: () => { this.extend() } });
2945
- c.add("Reduce", { disabled: !this.splitExtended, callback: () => { this.reduce() } });
2946
- });
2947
- });
2948
- }
2978
+ splitbarOffset = ( LX.DEFAULT_SPLITBAR_SIZE / 2 ); // updates
2949
2979
  }
2950
2980
 
2951
2981
  if( type == "horizontal" )
2952
2982
  {
2953
- let width1 = sizes[ 0 ],
2954
- width2 = sizes[ 1 ];
2983
+ this.root.style.display = "flex";
2955
2984
 
2956
- if( width1.constructor == Number )
2985
+ if( !fixedSize )
2957
2986
  {
2958
- width1 += "px";
2959
- }
2987
+ const parentWidth = this.root.offsetWidth;
2988
+ const leftPx = parsePixelSize( sizes[ 0 ], parentWidth );
2989
+ const rightPx = parsePixelSize( sizes[ 1 ], parentWidth );
2990
+ const leftPercent = ( leftPx / parentWidth ) * 100;
2991
+ const rightPercent = ( rightPx / parentWidth ) * 100;
2960
2992
 
2961
- if( width2.constructor == Number )
2993
+ // Style using percentages
2994
+ primarySize[ 0 ] = `calc(${ leftPercent }% - ${ splitbarOffset }px)`;
2995
+ secondarySize[ 0 ] = `calc(${ rightPercent }% - ${ splitbarOffset }px)`;
2996
+ }
2997
+ else
2962
2998
  {
2963
- width2 += "px";
2999
+ primarySize[ 0 ] = `calc(${ sizes[ 0 ] } - ${ splitbarOffset }px)`;
3000
+ secondarySize[ 0 ] = `calc(${ sizes[ 1 ] } - ${ splitbarOffset }px)`;
2964
3001
  }
2965
3002
 
2966
- area1.root.style.width = "calc( " + width1 + " - " + data + " )";
2967
- area1.root.style.height = "calc(100% - 0px)";
2968
- area2.root.style.width = "calc( " + width2 + " - " + data + " )";
2969
- area2.root.style.height = "calc(100% - 0px)";
2970
- this.root.style.display = "flex";
3003
+ primarySize[ 1 ] = "100%";
3004
+ secondarySize[ 1 ] = "100%";
2971
3005
  }
2972
3006
  else // vertical
2973
3007
  {
2974
- area1.root.style.width = "100%";
2975
- area2.root.style.width = "100%";
2976
-
2977
3008
  if( auto )
2978
3009
  {
2979
- area1.root.style.height = "auto";
2980
-
2981
- // Listen resize event on first area
2982
- const resizeObserver = new ResizeObserver( entries => {
2983
- for ( const entry of entries )
2984
- {
2985
- const size = entry.target.getComputedSize();
2986
- area2.root.style.height = "calc(100% - " + ( size.height ) + "px )";
2987
- }
2988
- });
3010
+ primarySize[ 1 ] = "auto";
3011
+ }
3012
+ else if( !fixedSize )
3013
+ {
3014
+ const parentHeight = this.root.offsetHeight;
3015
+ const topPx = parsePixelSize( sizes[ 0 ], parentHeight );
3016
+ const bottomPx = parsePixelSize( sizes[ 1 ], parentHeight );
3017
+ const topPercent = ( topPx / parentHeight ) * 100;
3018
+ const bottomPercent = ( bottomPx / parentHeight ) * 100;
2989
3019
 
2990
- resizeObserver.observe( area1.root );
3020
+ primarySize[ 1 ] = ( sizes[ 0 ] == "auto" ? "auto" : `calc(${ topPercent }% - ${ splitbarOffset }px)`);
3021
+ secondarySize[ 1 ] = ( sizes[ 1 ] == "auto" ? "auto" : `calc(${ bottomPercent }% - ${ splitbarOffset }px)`);
2991
3022
  }
2992
3023
  else
2993
3024
  {
2994
- let height1 = sizes[ 0 ],
2995
- height2 = sizes[ 1 ];
3025
+ primarySize[ 1 ] = ( sizes[ 0 ] == "auto" ? "auto" : `calc(${ sizes[ 0 ] } - ${ splitbarOffset }px)`);
3026
+ secondarySize[ 1 ] = ( sizes[ 1 ] == "auto" ? "auto" : `calc(${ sizes[ 1 ] } - ${ splitbarOffset }px)`);
3027
+ }
2996
3028
 
2997
- if( height1.constructor == Number )
2998
- {
2999
- height1 += "px";
3000
- }
3029
+ primarySize[ 0 ] = "100%";
3030
+ secondarySize[ 0 ] = "100%";
3031
+ }
3032
+
3033
+ // Create areas
3034
+ let area1 = new Area( { width: primarySize[ 0 ], height: primarySize[ 1 ], skipAppend: true, className: "split" + ( options.menubar || options.sidebar ? "" : " origin" ) } );
3035
+ let area2 = new Area( { width: secondarySize[ 0 ], height: secondarySize[ 1 ], skipAppend: true, className: "split" } );
3001
3036
 
3002
- if( height2.constructor == Number )
3037
+ if( auto && type == "vertical" )
3038
+ {
3039
+ // Listen resize event on first area
3040
+ const resizeObserver = new ResizeObserver( entries => {
3041
+ for ( const entry of entries )
3003
3042
  {
3004
- height2 += "px";
3043
+ const size = entry.target.getComputedSize();
3044
+ area2.root.style.height = "calc(100% - " + ( size.height ) + "px )";
3005
3045
  }
3046
+ });
3006
3047
 
3007
- area1.root.style.width = "100%";
3008
- area1.root.style.height = ( height1 == "auto" ? height1 : "calc( " + height1 + " - " + data + " )");
3009
- area2.root.style.height = ( height2 == "auto" ? height2 : "calc( " + height2 + " - " + data + " )");
3010
- }
3048
+ resizeObserver.observe( area1.root );
3049
+ }
3050
+
3051
+ // Being minimizable means it's also resizeable!
3052
+ if( resize && minimizable )
3053
+ {
3054
+ this.splitExtended = false;
3055
+
3056
+ // Keep state of the animation when ends...
3057
+ area2.root.addEventListener('animationend', e => {
3058
+ const opacity = getComputedStyle( area2.root ).opacity;
3059
+ area2.root.classList.remove( e.animationName + "-" + type );
3060
+ area2.root.style.opacity = opacity;
3061
+ flushCss( area2.root );
3062
+ });
3063
+
3064
+ this.splitBar.addEventListener("contextmenu", e => {
3065
+ e.preventDefault();
3066
+ addContextMenu(null, e, c => {
3067
+ c.add("Extend", { disabled: this.splitExtended, callback: () => { this.extend() } });
3068
+ c.add("Reduce", { disabled: !this.splitExtended, callback: () => { this.reduce() } });
3069
+ });
3070
+ });
3011
3071
  }
3012
3072
 
3073
+ area1.parentArea = this;
3074
+ area2.parentArea = this;
3075
+
3013
3076
  this.root.appendChild( area1.root );
3014
3077
 
3015
3078
  if( resize )
@@ -3018,6 +3081,7 @@ class Area {
3018
3081
  }
3019
3082
 
3020
3083
  this.root.appendChild( area2.root );
3084
+
3021
3085
  this.sections = [ area1, area2 ];
3022
3086
  this.type = type;
3023
3087
 
@@ -3131,10 +3195,10 @@ class Area {
3131
3195
  return;
3132
3196
  }
3133
3197
 
3134
- let [area1, area2] = this.sections;
3198
+ let [ area1, area2 ] = this.sections;
3135
3199
  this.splitExtended = true;
3136
3200
 
3137
- if( this.type == "vertical")
3201
+ if( this.type == "vertical" )
3138
3202
  {
3139
3203
  this.offset = area2.root.offsetHeight;
3140
3204
  area2.root.classList.add("fadeout-vertical");
@@ -3145,7 +3209,7 @@ class Area {
3145
3209
  {
3146
3210
  this.offset = area2.root.offsetWidth - 8; // Force some height here...
3147
3211
  area2.root.classList.add("fadeout-horizontal");
3148
- this._moveSplit(-Infinity, true, 8);
3212
+ this._moveSplit( -Infinity, true, 8 );
3149
3213
  }
3150
3214
 
3151
3215
  doAsync( () => this.propagateEvent('onresize'), 150 );
@@ -3252,8 +3316,7 @@ class Area {
3252
3316
 
3253
3317
  LX.menubars.push( menubar );
3254
3318
 
3255
- const height = 48; // pixels
3256
- const [ bar, content ] = this.split({ type: 'vertical', sizes: [height, null], resize: false, menubar: true });
3319
+ const [ bar, content ] = this.split({ type: 'vertical', sizes: ["48px", null], resize: false, menubar: true });
3257
3320
  menubar.siblingArea = content;
3258
3321
 
3259
3322
  bar.attach( menubar );
@@ -3370,7 +3433,8 @@ class Area {
3370
3433
  img: b.img,
3371
3434
  className: b.class ?? "",
3372
3435
  title: b.name,
3373
- overflowContainerX: overlayPanel.root
3436
+ overflowContainerX: overlayPanel.root,
3437
+ swap: b.swap
3374
3438
  };
3375
3439
 
3376
3440
  if( group )
@@ -3507,7 +3571,7 @@ class Area {
3507
3571
 
3508
3572
  const a2 = this.sections[ 1 ];
3509
3573
  const a2Root = a2.root;
3510
- const splitData = " - "+ LX.DEFAULT_SPLITBAR_SIZE + "px";
3574
+ const splitData = "- "+ LX.DEFAULT_SPLITBAR_SIZE + "px";
3511
3575
 
3512
3576
  let transition = null;
3513
3577
  if( !forceAnimation )
@@ -3515,30 +3579,47 @@ class Area {
3515
3579
  // Remove transitions for this change..
3516
3580
  transition = a1Root.style.transition;
3517
3581
  a1Root.style.transition = a2Root.style.transition = "none";
3518
- flushCss( a1Root );
3519
- flushCss( a2Root );
3582
+ // flushCss( a1Root );
3520
3583
  }
3521
3584
 
3522
3585
  if( this.type == "horizontal" )
3523
3586
  {
3524
3587
  var size = Math.max( a2Root.offsetWidth + dt, parseInt( a2.minWidth ) );
3525
3588
  if( forceWidth ) size = forceWidth;
3526
- a1Root.style.width = "-moz-calc( 100% - " + size + "px " + splitData + " )";
3527
- a1Root.style.width = "-webkit-calc( 100% - " + size + "px " + splitData + " )";
3528
- a1Root.style.width = "calc( 100% - " + size + "px " + splitData + " )";
3529
- a1Root.style.minWidth = parseInt( a1.minWidth ) + "px";
3530
- a2Root.style.width = size + "px";
3531
- if( a1.maxWidth != Infinity ) a2Root.style.minWidth = "calc( 100% - " + parseInt( a1.maxWidth ) + "px" + " )";
3589
+
3590
+ const parentWidth = this.size[ 0 ];
3591
+ const rightPercent = ( size / parentWidth ) * 100;
3592
+ const leftPercent = Math.max( 0, 100 - rightPercent );
3593
+
3594
+ a1Root.style.width = `-moz-calc(${ leftPercent }% ${ splitData })`;
3595
+ a1Root.style.width = `-webkit-calc( ${ leftPercent }% ${ splitData })`;
3596
+ a1Root.style.width = `calc( ${ leftPercent }% ${ splitData })`;
3597
+ a2Root.style.width = `${ rightPercent }%`;
3598
+ a2Root.style.width = `${ rightPercent }%`;
3599
+ a2Root.style.width = `${ rightPercent }%`;
3600
+
3601
+ if( a1.maxWidth != Infinity )
3602
+ {
3603
+ a2Root.style.minWidth = "calc( 100% - " + parseInt( a1.maxWidth ) + "px" + " )";
3604
+ }
3532
3605
  }
3533
3606
  else
3534
3607
  {
3535
- var size = Math.max((a2Root.offsetHeight + dt) + a2.offset, parseInt(a2.minHeight));
3608
+ var size = Math.max( ( a2Root.offsetHeight + dt ) + a2.offset, parseInt(a2.minHeight) );
3536
3609
  if( forceWidth ) size = forceWidth;
3537
- a1Root.style.height = "-moz-calc( 100% - " + size + "px " + splitData + " )";
3538
- a1Root.style.height = "-webkit-calc( 100% - " + size + "px " + splitData + " )";
3539
- a1Root.style.height = "calc( 100% - " + size + "px " + splitData + " )";
3610
+
3611
+ const parentHeight = this.size[ 1 ];
3612
+ const bottomPercent = ( size / parentHeight ) * 100;
3613
+ const topPercent = Math.max( 0, 100 - bottomPercent );
3614
+
3615
+ a1Root.style.height = `-moz-calc(${ topPercent }% ${ splitData })`;
3616
+ a1Root.style.height = `-webkit-calc( ${ topPercent }% ${ splitData })`;
3617
+ a1Root.style.height = `calc( ${ topPercent }% ${ splitData })`;
3618
+ a2Root.style.height = `${ bottomPercent }%`;
3619
+ a2Root.style.height = `${ bottomPercent }%`;
3620
+ a2Root.style.height = `${ bottomPercent }%`;
3621
+
3540
3622
  a1Root.style.minHeight = a1.minHeight + "px";
3541
- a2Root.style.height = ( size - a2.offset ) + "px";
3542
3623
  }
3543
3624
 
3544
3625
  if( !forceAnimation )
@@ -3547,10 +3628,10 @@ class Area {
3547
3628
  a1Root.style.transition = a2Root.style.transition = transition;
3548
3629
  }
3549
3630
 
3550
- this._update();
3551
-
3552
- // Resize events
3553
- this.propagateEvent( 'onresize' );
3631
+ doAsync( () => {
3632
+ this._update();
3633
+ this.propagateEvent( 'onresize' );
3634
+ }, 10 );
3554
3635
  }
3555
3636
 
3556
3637
  _disableSplitResize() {
@@ -6116,7 +6197,17 @@ class NodeTree {
6116
6197
 
6117
6198
  this.data = newData ?? this.data;
6118
6199
  this.domEl.querySelector( "ul" ).innerHTML = "";
6119
- this._createItem( null, this.data, 0, selectedId );
6200
+ if( this.data.constructor === Object )
6201
+ {
6202
+ this._createItem( null, this.data, 0, selectedId );
6203
+ }
6204
+ else
6205
+ {
6206
+ for( let d of this.data )
6207
+ {
6208
+ this._createItem( null, d, 0, selectedId );
6209
+ }
6210
+ }
6120
6211
  }
6121
6212
 
6122
6213
  /* Refreshes the tree and focuses current element */
@@ -6243,8 +6334,8 @@ class TextInput extends Widget {
6243
6334
  };
6244
6335
 
6245
6336
  this.onResize = ( rect ) => {
6246
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
6247
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
6337
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
6338
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
6248
6339
  };
6249
6340
 
6250
6341
  this.valid = ( v ) => {
@@ -6382,8 +6473,8 @@ class TextArea extends Widget {
6382
6473
  };
6383
6474
 
6384
6475
  this.onResize = ( rect ) => {
6385
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
6386
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
6476
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
6477
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
6387
6478
  };
6388
6479
 
6389
6480
  let container = document.createElement( "div" );
@@ -6476,8 +6567,8 @@ class Button extends Widget {
6476
6567
  };
6477
6568
 
6478
6569
  this.onResize = ( rect ) => {
6479
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
6480
- wValue.style.width = `calc( 100% - ${ realNameWidth }px)`;
6570
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
6571
+ wValue.style.width = `calc( 100% - ${ realNameWidth })`;
6481
6572
  };
6482
6573
 
6483
6574
  var wValue = document.createElement( 'button' );
@@ -6739,8 +6830,8 @@ class ComboButtons extends Widget {
6739
6830
  };
6740
6831
 
6741
6832
  this.onResize = ( rect ) => {
6742
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
6743
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
6833
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
6834
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
6744
6835
  };
6745
6836
 
6746
6837
  this.root.appendChild( container );
@@ -6956,8 +7047,8 @@ class Select extends Widget {
6956
7047
  };
6957
7048
 
6958
7049
  this.onResize = ( rect ) => {
6959
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
6960
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
7050
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7051
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
6961
7052
  };
6962
7053
 
6963
7054
  let container = document.createElement( "div" );
@@ -7304,11 +7395,8 @@ class Curve extends Widget {
7304
7395
  };
7305
7396
 
7306
7397
  this.onResize = ( rect ) => {
7307
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7308
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
7309
- flushCss( container );
7310
- curveInstance.canvas.width = container.offsetWidth;
7311
- curveInstance.redraw();
7398
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7399
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
7312
7400
  };
7313
7401
 
7314
7402
  var container = document.createElement( "div" );
@@ -7325,6 +7413,16 @@ class Curve extends Widget {
7325
7413
  container.appendChild( curveInstance.element );
7326
7414
  this.curveInstance = curveInstance;
7327
7415
 
7416
+ const observer = new ResizeObserver( entries => {
7417
+ for ( const entry of entries )
7418
+ {
7419
+ curveInstance.canvas.width = entry.contentRect.width;
7420
+ curveInstance.redraw();
7421
+ }
7422
+ });
7423
+
7424
+ observer.observe( container );
7425
+
7328
7426
  doAsync( this.onResize.bind( this ) );
7329
7427
  }
7330
7428
  }
@@ -7358,8 +7456,8 @@ class Dial extends Widget {
7358
7456
  };
7359
7457
 
7360
7458
  this.onResize = ( rect ) => {
7361
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7362
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
7459
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7460
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
7363
7461
  flushCss( container );
7364
7462
  dialInstance.element.style.height = dialInstance.element.offsetWidth + "px";
7365
7463
  dialInstance.canvas.width = dialInstance.element.offsetWidth;
@@ -7413,8 +7511,8 @@ class Layers extends Widget {
7413
7511
  };
7414
7512
 
7415
7513
  this.onResize = ( rect ) => {
7416
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7417
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
7514
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7515
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
7418
7516
  };
7419
7517
 
7420
7518
  var container = document.createElement( "div" );
@@ -7638,8 +7736,8 @@ class List extends Widget {
7638
7736
  };
7639
7737
 
7640
7738
  this.onResize = ( rect ) => {
7641
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7642
- listContainer.style.width = `calc( 100% - ${ realNameWidth }px)`;
7739
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7740
+ listContainer.style.width = `calc( 100% - ${ realNameWidth })`;
7643
7741
  };
7644
7742
 
7645
7743
  this._updateValues = ( newValues ) => {
@@ -7715,8 +7813,8 @@ class Tags extends Widget {
7715
7813
  };
7716
7814
 
7717
7815
  this.onResize = ( rect ) => {
7718
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7719
- tagsContainer.style.width = `calc( 100% - ${ realNameWidth }px)`;
7816
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7817
+ tagsContainer.style.width = `calc( 100% - ${ realNameWidth })`;
7720
7818
  };
7721
7819
 
7722
7820
  // Show tags
@@ -7816,8 +7914,8 @@ class Checkbox extends Widget {
7816
7914
  };
7817
7915
 
7818
7916
  this.onResize = ( rect ) => {
7819
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7820
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
7917
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
7918
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
7821
7919
  };
7822
7920
 
7823
7921
  var container = document.createElement( "div" );
@@ -7899,8 +7997,8 @@ class Toggle extends Widget {
7899
7997
  };
7900
7998
 
7901
7999
  this.onResize = ( rect ) => {
7902
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
7903
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
8000
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8001
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
7904
8002
  };
7905
8003
 
7906
8004
  var container = document.createElement('div');
@@ -8082,8 +8180,8 @@ class ColorInput extends Widget {
8082
8180
  };
8083
8181
 
8084
8182
  this.onResize = ( rect ) => {
8085
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
8086
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
8183
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8184
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
8087
8185
  };
8088
8186
 
8089
8187
  var container = document.createElement( 'span' );
@@ -8173,8 +8271,8 @@ class RangeInput extends Widget {
8173
8271
  };
8174
8272
 
8175
8273
  this.onResize = ( rect ) => {
8176
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
8177
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
8274
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8275
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
8178
8276
  };
8179
8277
 
8180
8278
  const container = document.createElement( 'div' );
@@ -8287,8 +8385,8 @@ class NumberInput extends Widget {
8287
8385
  };
8288
8386
 
8289
8387
  this.onResize = ( rect ) => {
8290
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
8291
- container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth }px)`;
8388
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8389
+ container.style.width = options.inputWidth ?? `calc( 100% - ${ realNameWidth })`;
8292
8390
  };
8293
8391
 
8294
8392
  var container = document.createElement( 'div' );
@@ -8523,8 +8621,8 @@ class Vector extends Widget {
8523
8621
  };
8524
8622
 
8525
8623
  this.onResize = ( rect ) => {
8526
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
8527
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
8624
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8625
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
8528
8626
  };
8529
8627
 
8530
8628
  const vectorInputs = [];
@@ -8877,8 +8975,8 @@ class OTPInput extends Widget {
8877
8975
  };
8878
8976
 
8879
8977
  this.onResize = ( rect ) => {
8880
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
8881
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
8978
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
8979
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
8882
8980
  };
8883
8981
 
8884
8982
  this.disabled = options.disabled ?? false;
@@ -9023,8 +9121,8 @@ class Pad extends Widget {
9023
9121
  };
9024
9122
 
9025
9123
  this.onResize = ( rect ) => {
9026
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
9027
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
9124
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
9125
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
9028
9126
  };
9029
9127
 
9030
9128
  var container = document.createElement( 'div' );
@@ -9143,8 +9241,8 @@ class Progress extends Widget {
9143
9241
  };
9144
9242
 
9145
9243
  this.onResize = ( rect ) => {
9146
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
9147
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
9244
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
9245
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
9148
9246
  };
9149
9247
 
9150
9248
  const container = document.createElement('div');
@@ -9270,8 +9368,8 @@ class FileInput extends Widget {
9270
9368
  let read = options.read ?? true;
9271
9369
 
9272
9370
  this.onResize = ( rect ) => {
9273
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
9274
- input.style.width = `calc( 100% - ${ realNameWidth }px)`;
9371
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
9372
+ input.style.width = `calc( 100% - ${ realNameWidth })`;
9275
9373
  };
9276
9374
 
9277
9375
  // Create hidden input
@@ -9597,8 +9695,8 @@ class Table extends Widget {
9597
9695
  super( Widget.TABLE, name, null, options );
9598
9696
 
9599
9697
  this.onResize = ( rect ) => {
9600
- const realNameWidth = ( this.root.domName?.offsetWidth ?? 0 );
9601
- container.style.width = `calc( 100% - ${ realNameWidth }px)`;
9698
+ const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
9699
+ container.style.width = `calc( 100% - ${ realNameWidth })`;
9602
9700
  };
9603
9701
 
9604
9702
  const container = document.createElement('div');
@@ -12349,12 +12447,6 @@ class CanvasCurve {
12349
12447
  if( o.xrange ) element.xrange = o.xrange;
12350
12448
  if( o.yrange ) element.yrange = o.yrange;
12351
12449
  if( o.smooth ) element.smooth = o.smooth;
12352
- var rect = canvas.parentElement.getBoundingClientRect();
12353
- if( canvas.parentElement.parentElement ) rect = canvas.parentElement.parentElement.getBoundingClientRect();
12354
- if( rect && canvas.width != rect.width && rect.width && rect.width < 1000 )
12355
- {
12356
- canvas.width = rect.width;
12357
- }
12358
12450
 
12359
12451
  var ctx = canvas.getContext( "2d" );
12360
12452
  ctx.setTransform( 1, 0, 0, 1, 0, 0 );
@@ -12689,12 +12781,6 @@ class CanvasDial {
12689
12781
  if( o.xrange ) element.xrange = o.xrange;
12690
12782
  if( o.yrange ) element.yrange = o.yrange;
12691
12783
  if( o.smooth ) element.smooth = o.smooth;
12692
- var rect = canvas.parentElement.getBoundingClientRect();
12693
- if( canvas.parentElement.parentElement ) rect = canvas.parentElement.parentElement.getBoundingClientRect();
12694
- if( rect && canvas.width != rect.width && rect.width && rect.width < 1000 )
12695
- {
12696
- canvas.width = rect.width;
12697
- }
12698
12784
 
12699
12785
  var ctx = canvas.getContext( "2d" );
12700
12786
  ctx.setTransform( 1, 0, 0, 1, 0, 0 );