dockview-react 4.0.1 → 4.1.0

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-react
3
- * @version 4.0.1
3
+ * @version 4.1.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -219,14 +219,6 @@
219
219
  }
220
220
  Emitter.ENABLE_TRACKING = false;
221
221
  Emitter.MEMORY_LEAK_WATCHER = new LeakageMonitor();
222
- function addDisposableWindowListener(element, type, listener, options) {
223
- element.addEventListener(type, listener, options);
224
- return {
225
- dispose: () => {
226
- element.removeEventListener(type, listener, options);
227
- },
228
- };
229
- }
230
222
  function addDisposableListener(element, type, listener, options) {
231
223
  element.addEventListener(type, listener, options);
232
224
  return {
@@ -405,9 +397,6 @@
405
397
  }
406
398
  return false;
407
399
  }
408
- function getElementsByTagName(tag) {
409
- return Array.prototype.slice.call(document.getElementsByTagName(tag), 0);
410
- }
411
400
  function trackFocus(element) {
412
401
  return new FocusTracker(element);
413
402
  }
@@ -454,14 +443,8 @@
454
443
  }
455
444
  }
456
445
  };
457
- if (element instanceof HTMLElement) {
458
- this.addDisposables(addDisposableListener(element, 'focus', onFocus, true));
459
- this.addDisposables(addDisposableListener(element, 'blur', onBlur, true));
460
- }
461
- else {
462
- this.addDisposables(addDisposableWindowListener(element, 'focus', onFocus, true));
463
- this.addDisposables(addDisposableWindowListener(element, 'blur', onBlur, true));
464
- }
446
+ this.addDisposables(addDisposableListener(element, 'focus', onFocus, true));
447
+ this.addDisposables(addDisposableListener(element, 'blur', onBlur, true));
465
448
  }
466
449
  refreshState() {
467
450
  this._refreshStateHandler();
@@ -535,11 +518,30 @@
535
518
  function addTestId(element, id) {
536
519
  element.setAttribute('data-testid', id);
537
520
  }
538
- function disableIframePointEvents() {
539
- const iframes = [
540
- ...getElementsByTagName('iframe'),
541
- ...getElementsByTagName('webview'),
542
- ];
521
+ /**
522
+ * Should be more efficient than element.querySelectorAll("*") since there
523
+ * is no need to store every element in-memory using this approach
524
+ */
525
+ function allTagsNamesInclusiveOfShadowDoms(tagNames) {
526
+ const iframes = [];
527
+ function findIframesInNode(node) {
528
+ if (node.nodeType === Node.ELEMENT_NODE) {
529
+ if (tagNames.includes(node.tagName)) {
530
+ iframes.push(node);
531
+ }
532
+ if (node.shadowRoot) {
533
+ findIframesInNode(node.shadowRoot);
534
+ }
535
+ for (const child of node.children) {
536
+ findIframesInNode(child);
537
+ }
538
+ }
539
+ }
540
+ findIframesInNode(document.documentElement);
541
+ return iframes;
542
+ }
543
+ function disableIframePointEvents(rootNode = document) {
544
+ const iframes = allTagsNamesInclusiveOfShadowDoms(['IFRAME', 'WEBVIEW']);
543
545
  const original = new WeakMap(); // don't hold onto HTMLElement references longer than required
544
546
  for (const iframe of iframes) {
545
547
  original.set(iframe, iframe.style.pointerEvents);
@@ -591,6 +593,7 @@
591
593
  }
592
594
  }
593
595
  }
596
+ const DEBOUCE_DELAY = 100;
594
597
  function isChildEntirelyVisibleWithinParent(child, parent) {
595
598
  //
596
599
  const childPosition = getDomNodePagePosition(child);
@@ -604,6 +607,41 @@
604
607
  }
605
608
  return true;
606
609
  }
610
+ function onDidWindowMoveEnd(window) {
611
+ const emitter = new Emitter();
612
+ let previousScreenX = window.screenX;
613
+ let previousScreenY = window.screenY;
614
+ let timeout;
615
+ const checkMovement = () => {
616
+ if (window.closed) {
617
+ return;
618
+ }
619
+ const currentScreenX = window.screenX;
620
+ const currentScreenY = window.screenY;
621
+ if (currentScreenX !== previousScreenX ||
622
+ currentScreenY !== previousScreenY) {
623
+ clearTimeout(timeout);
624
+ timeout = setTimeout(() => {
625
+ emitter.fire();
626
+ }, DEBOUCE_DELAY);
627
+ previousScreenX = currentScreenX;
628
+ previousScreenY = currentScreenY;
629
+ }
630
+ requestAnimationFrame(checkMovement);
631
+ };
632
+ checkMovement();
633
+ return emitter;
634
+ }
635
+ function onDidWindowResizeEnd(element, cb) {
636
+ let resizeTimeout;
637
+ const disposable = new CompositeDisposable(addDisposableListener(element, 'resize', () => {
638
+ clearTimeout(resizeTimeout);
639
+ resizeTimeout = setTimeout(() => {
640
+ cb();
641
+ }, DEBOUCE_DELAY);
642
+ }));
643
+ return disposable;
644
+ }
607
645
 
608
646
  function tail(arr) {
609
647
  if (arr.length === 0) {
@@ -3543,6 +3581,12 @@
3543
3581
  get onUnhandledDragOverEvent() {
3544
3582
  return this.component.onUnhandledDragOverEvent;
3545
3583
  }
3584
+ get onDidPopoutGroupSizeChange() {
3585
+ return this.component.onDidPopoutGroupSizeChange;
3586
+ }
3587
+ get onDidPopoutGroupPositionChange() {
3588
+ return this.component.onDidPopoutGroupPositionChange;
3589
+ }
3546
3590
  /**
3547
3591
  * All panel objects.
3548
3592
  */
@@ -4508,26 +4552,25 @@
4508
4552
  this._headerVisible = value;
4509
4553
  this.header.style.display = value ? '' : 'none';
4510
4554
  }
4511
- constructor(id, component, headerComponent, orientation, isExpanded, isHeaderVisible) {
4512
- super(id, component, new PaneviewPanelApiImpl(id, component));
4513
- this.headerComponent = headerComponent;
4555
+ constructor(options) {
4556
+ super(options.id, options.component, new PaneviewPanelApiImpl(options.id, options.component));
4514
4557
  this._onDidChangeExpansionState = new Emitter({ replay: true });
4515
4558
  this.onDidChangeExpansionState = this._onDidChangeExpansionState.event;
4516
4559
  this._onDidChange = new Emitter();
4517
4560
  this.onDidChange = this._onDidChange.event;
4518
- this.headerSize = 22;
4519
4561
  this._orthogonalSize = 0;
4520
4562
  this._size = 0;
4521
- this._minimumBodySize = 100;
4522
- this._maximumBodySize = Number.POSITIVE_INFINITY;
4523
4563
  this._isExpanded = false;
4524
- this.expandedSize = 0;
4525
4564
  this.api.pane = this; // TODO cannot use 'this' before 'super'
4526
4565
  this.api.initialize(this);
4527
- this._isExpanded = isExpanded;
4528
- this._headerVisible = isHeaderVisible;
4566
+ this.headerSize = options.headerSize;
4567
+ this.headerComponent = options.headerComponent;
4568
+ this._minimumBodySize = options.minimumBodySize;
4569
+ this._maximumBodySize = options.maximumBodySize;
4570
+ this._isExpanded = options.isExpanded;
4571
+ this._headerVisible = options.isHeaderVisible;
4529
4572
  this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
4530
- this._orientation = orientation;
4573
+ this._orientation = options.orientation;
4531
4574
  this.element.classList.add('dv-pane');
4532
4575
  this.addDisposables(this.api.onWillVisibilityChange((event) => {
4533
4576
  const { isVisible } = event;
@@ -4594,9 +4637,6 @@
4594
4637
  const [width, height] = this.orientation === exports.Orientation.HORIZONTAL
4595
4638
  ? [size, orthogonalSize]
4596
4639
  : [orthogonalSize, size];
4597
- if (this.isExpanded()) {
4598
- this.expandedSize = width;
4599
- }
4600
4640
  super.layout(width, height);
4601
4641
  }
4602
4642
  init(parameters) {
@@ -4653,15 +4693,25 @@
4653
4693
  }
4654
4694
 
4655
4695
  class DraggablePaneviewPanel extends PaneviewPanel {
4656
- constructor(accessor, id, component, headerComponent, orientation, isExpanded, disableDnd) {
4657
- super(id, component, headerComponent, orientation, isExpanded, true);
4658
- this.accessor = accessor;
4696
+ constructor(options) {
4697
+ super({
4698
+ id: options.id,
4699
+ component: options.component,
4700
+ headerComponent: options.headerComponent,
4701
+ orientation: options.orientation,
4702
+ isExpanded: options.isExpanded,
4703
+ isHeaderVisible: true,
4704
+ headerSize: options.headerSize,
4705
+ minimumBodySize: options.minimumBodySize,
4706
+ maximumBodySize: options.maximumBodySize,
4707
+ });
4659
4708
  this._onDidDrop = new Emitter();
4660
4709
  this.onDidDrop = this._onDidDrop.event;
4661
4710
  this._onUnhandledDragOverEvent = new Emitter();
4662
4711
  this.onUnhandledDragOverEvent = this._onUnhandledDragOverEvent.event;
4712
+ this.accessor = options.accessor;
4663
4713
  this.addDisposables(this._onDidDrop, this._onUnhandledDragOverEvent);
4664
- if (!disableDnd) {
4714
+ if (!options.disableDnd) {
4665
4715
  this.initDragFeatures();
4666
4716
  }
4667
4717
  }
@@ -7295,7 +7345,7 @@
7295
7345
  dispose: () => {
7296
7346
  iframes.release();
7297
7347
  },
7298
- }, addDisposableWindowListener(window, 'pointermove', (e) => {
7348
+ }, addDisposableListener(window, 'pointermove', (e) => {
7299
7349
  const containerRect = this.options.container.getBoundingClientRect();
7300
7350
  const x = e.clientX - containerRect.left;
7301
7351
  const y = e.clientY - containerRect.top;
@@ -7332,7 +7382,7 @@
7332
7382
  bounds.right = right;
7333
7383
  }
7334
7384
  this.setBounds(bounds);
7335
- }), addDisposableWindowListener(window, 'pointerup', () => {
7385
+ }), addDisposableListener(window, 'pointerup', () => {
7336
7386
  toggleClass(this._element, 'dv-resize-container-dragging', false);
7337
7387
  move.dispose();
7338
7388
  this._onDidChangeEnd.fire();
@@ -7377,7 +7427,7 @@
7377
7427
  e.preventDefault();
7378
7428
  let startPosition = null;
7379
7429
  const iframes = disableIframePointEvents();
7380
- move.value = new CompositeDisposable(addDisposableWindowListener(window, 'pointermove', (e) => {
7430
+ move.value = new CompositeDisposable(addDisposableListener(window, 'pointermove', (e) => {
7381
7431
  const containerRect = this.options.container.getBoundingClientRect();
7382
7432
  const overlayRect = this._element.getBoundingClientRect();
7383
7433
  const y = e.clientY - containerRect.top;
@@ -7501,7 +7551,7 @@
7501
7551
  dispose: () => {
7502
7552
  iframes.release();
7503
7553
  },
7504
- }, addDisposableWindowListener(window, 'pointerup', () => {
7554
+ }, addDisposableListener(window, 'pointerup', () => {
7505
7555
  move.dispose();
7506
7556
  this._onDidChangeEnd.fire();
7507
7557
  }));
@@ -7784,7 +7834,7 @@
7784
7834
  this._window = { value: externalWindow, disposable };
7785
7835
  disposable.addDisposables(exports.DockviewDisposable.from(() => {
7786
7836
  externalWindow.close();
7787
- }), addDisposableWindowListener(window, 'beforeunload', () => {
7837
+ }), addDisposableListener(window, 'beforeunload', () => {
7788
7838
  /**
7789
7839
  * before the main window closes we should close this popup too
7790
7840
  * to be good citizens
@@ -7819,7 +7869,7 @@
7819
7869
  * beforeunload must be registered after load for reasons I could not determine
7820
7870
  * otherwise the beforeunload event will not fire when the window is closed
7821
7871
  */
7822
- addDisposableWindowListener(externalWindow, 'beforeunload', () => {
7872
+ addDisposableListener(externalWindow, 'beforeunload', () => {
7823
7873
  /**
7824
7874
  * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
7825
7875
  */
@@ -7916,7 +7966,7 @@
7916
7966
  wrapper.style.left = `${position.x - offsetX}px`;
7917
7967
  this._element.appendChild(wrapper);
7918
7968
  this._active = wrapper;
7919
- this._activeDisposable.value = new CompositeDisposable(addDisposableWindowListener(window, 'pointerdown', (event) => {
7969
+ this._activeDisposable.value = new CompositeDisposable(addDisposableListener(window, 'pointerdown', (event) => {
7920
7970
  var _a;
7921
7971
  const target = event.target;
7922
7972
  if (!(target instanceof HTMLElement)) {
@@ -8095,6 +8145,10 @@
8095
8145
  this.onDidRemovePanel = this._onDidRemovePanel.event;
8096
8146
  this._onDidAddPanel = new Emitter();
8097
8147
  this.onDidAddPanel = this._onDidAddPanel.event;
8148
+ this._onDidPopoutGroupSizeChange = new Emitter();
8149
+ this.onDidPopoutGroupSizeChange = this._onDidPopoutGroupSizeChange.event;
8150
+ this._onDidPopoutGroupPositionChange = new Emitter();
8151
+ this.onDidPopoutGroupPositionChange = this._onDidPopoutGroupPositionChange.event;
8098
8152
  this._onDidLayoutFromJSON = new Emitter();
8099
8153
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
8100
8154
  this._onDidActivePanelChange = new Emitter();
@@ -8124,7 +8178,7 @@
8124
8178
  if (options.debug) {
8125
8179
  this.addDisposables(new StrictEventsSequencing(this));
8126
8180
  }
8127
- this.addDisposables(this.rootDropTargetContainer, this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onDidMovePanel, this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this._onUnhandledDragOverEvent, this._onDidMaximizedGroupChange, this._onDidOptionsChange, this.onDidViewVisibilityChangeMicroTaskQueue(() => {
8181
+ this.addDisposables(this.rootDropTargetContainer, this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onDidMovePanel, this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this._onUnhandledDragOverEvent, this._onDidMaximizedGroupChange, this._onDidOptionsChange, this._onDidPopoutGroupSizeChange, this._onDidPopoutGroupPositionChange, this.onDidViewVisibilityChangeMicroTaskQueue(() => {
8128
8182
  this.updateWatermark();
8129
8183
  }), this.onDidAdd((event) => {
8130
8184
  if (!this._moving) {
@@ -8145,7 +8199,7 @@
8145
8199
  });
8146
8200
  }), exports.DockviewEvent.any(this.onDidAdd, this.onDidRemove)(() => {
8147
8201
  this.updateWatermark();
8148
- }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidAddGroup, this.onDidRemove, this.onDidMovePanel, this.onDidActivePanelChange)(() => {
8202
+ }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidAddGroup, this.onDidRemove, this.onDidMovePanel, this.onDidActivePanelChange, this.onDidPopoutGroupPositionChange, this.onDidPopoutGroupSizeChange)(() => {
8149
8203
  this._bufferOnDidLayoutChange.fire();
8150
8204
  }), exports.DockviewDisposable.from(() => {
8151
8205
  // iterate over a copy of the array since .dispose() mutates the original array
@@ -8406,13 +8460,26 @@
8406
8460
  },
8407
8461
  },
8408
8462
  };
8409
- popoutWindowDisposable.addDisposables(
8463
+ const _onDidWindowPositionChange = onDidWindowMoveEnd(_window.window);
8464
+ popoutWindowDisposable.addDisposables(_onDidWindowPositionChange, onDidWindowResizeEnd(_window.window, () => {
8465
+ this._onDidPopoutGroupSizeChange.fire({
8466
+ width: _window.window.innerWidth,
8467
+ height: _window.window.innerHeight,
8468
+ group,
8469
+ });
8470
+ }), _onDidWindowPositionChange.event(() => {
8471
+ this._onDidPopoutGroupPositionChange.fire({
8472
+ screenX: _window.window.screenX,
8473
+ screenY: _window.window.screenX,
8474
+ group,
8475
+ });
8476
+ }),
8410
8477
  /**
8411
8478
  * ResizeObserver seems slow here, I do not know why but we don't need it
8412
8479
  * since we can reply on the window resize event as we will occupy the full
8413
8480
  * window dimensions
8414
8481
  */
8415
- addDisposableWindowListener(_window.window, 'resize', () => {
8482
+ addDisposableListener(_window.window, 'resize', () => {
8416
8483
  group.layout(_window.window.innerWidth, _window.window.innerHeight);
8417
8484
  }), overlayRenderContainer, exports.DockviewDisposable.from(() => {
8418
8485
  if (this.isDisposed) {
@@ -8626,7 +8693,7 @@
8626
8693
  }
8627
8694
  this.updateWatermark();
8628
8695
  }
8629
- orthogonalize(position) {
8696
+ orthogonalize(position, options) {
8630
8697
  switch (position) {
8631
8698
  case 'top':
8632
8699
  case 'bottom':
@@ -8649,10 +8716,10 @@
8649
8716
  case 'top':
8650
8717
  case 'left':
8651
8718
  case 'center':
8652
- return this.createGroupAtLocation([0]); // insert into first position
8719
+ return this.createGroupAtLocation([0], undefined, options); // insert into first position
8653
8720
  case 'bottom':
8654
8721
  case 'right':
8655
- return this.createGroupAtLocation([this.gridview.length]); // insert into last position
8722
+ return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position
8656
8723
  default:
8657
8724
  throw new Error(`unsupported position ${position}`);
8658
8725
  }
@@ -9148,7 +9215,7 @@
9148
9215
  }
9149
9216
  }
9150
9217
  else {
9151
- const group = this.orthogonalize(directionToPosition(options.direction));
9218
+ const group = this.orthogonalize(directionToPosition(options.direction), options);
9152
9219
  if (!options.skipSetActive) {
9153
9220
  this.doSetGroupAndPanelActive(group);
9154
9221
  }
@@ -9590,8 +9657,8 @@
9590
9657
  });
9591
9658
  return panel;
9592
9659
  }
9593
- createGroupAtLocation(location, size) {
9594
- const group = this.createGroup();
9660
+ createGroupAtLocation(location, size, options) {
9661
+ const group = this.createGroup(options);
9595
9662
  this.doAddGroup(group, location, size);
9596
9663
  return group;
9597
9664
  }
@@ -9925,6 +9992,9 @@
9925
9992
  return this._splitview;
9926
9993
  }
9927
9994
  set splitview(value) {
9995
+ if (this._splitview) {
9996
+ this._splitview.dispose();
9997
+ }
9928
9998
  this._splitview = value;
9929
9999
  this._splitviewChangeDisposable.value = new CompositeDisposable(this._splitview.onDidSashEnd(() => {
9930
10000
  this._onDidLayoutChange.fire(undefined);
@@ -10228,9 +10298,23 @@
10228
10298
  }
10229
10299
 
10230
10300
  const nextLayoutId = sequentialNumberGenerator();
10301
+ const HEADER_SIZE = 22;
10302
+ const MINIMUM_BODY_SIZE = 0;
10303
+ const MAXIMUM_BODY_SIZE = Number.MAX_SAFE_INTEGER;
10231
10304
  class PaneFramework extends DraggablePaneviewPanel {
10232
10305
  constructor(options) {
10233
- super(options.accessor, options.id, options.component, options.headerComponent, options.orientation, options.isExpanded, options.disableDnd);
10306
+ super({
10307
+ accessor: options.accessor,
10308
+ id: options.id,
10309
+ component: options.component,
10310
+ headerComponent: options.headerComponent,
10311
+ orientation: options.orientation,
10312
+ isExpanded: options.isExpanded,
10313
+ disableDnd: options.disableDnd,
10314
+ headerSize: options.headerSize,
10315
+ minimumBodySize: options.minimumBodySize,
10316
+ maximumBodySize: options.maximumBodySize,
10317
+ });
10234
10318
  this.options = options;
10235
10319
  }
10236
10320
  getBodyComponent() {
@@ -10325,7 +10409,7 @@
10325
10409
  this._options = Object.assign(Object.assign({}, this.options), options);
10326
10410
  }
10327
10411
  addPanel(options) {
10328
- var _a;
10412
+ var _a, _b;
10329
10413
  const body = this.options.createComponent({
10330
10414
  id: options.id,
10331
10415
  name: options.component,
@@ -10350,12 +10434,15 @@
10350
10434
  isExpanded: !!options.isExpanded,
10351
10435
  disableDnd: !!this.options.disableDnd,
10352
10436
  accessor: this,
10437
+ headerSize: (_a = options.headerSize) !== null && _a !== void 0 ? _a : HEADER_SIZE,
10438
+ minimumBodySize: MINIMUM_BODY_SIZE,
10439
+ maximumBodySize: MAXIMUM_BODY_SIZE,
10353
10440
  });
10354
10441
  this.doAddPanel(view);
10355
10442
  const size = typeof options.size === 'number' ? options.size : exports.Sizing.Distribute;
10356
10443
  const index = typeof options.index === 'number' ? options.index : undefined;
10357
10444
  view.init({
10358
- params: (_a = options.params) !== null && _a !== void 0 ? _a : {},
10445
+ params: (_b = options.params) !== null && _b !== void 0 ? _b : {},
10359
10446
  minimumBodySize: options.minimumBodySize,
10360
10447
  maximumBodySize: options.maximumBodySize,
10361
10448
  isExpanded: options.isExpanded,
@@ -10400,6 +10487,7 @@
10400
10487
  data: view.toJSON(),
10401
10488
  minimumSize: minimum(view.minimumBodySize),
10402
10489
  maximumSize: maximum(view.maximumBodySize),
10490
+ headerSize: view.headerSize,
10403
10491
  expanded: view.isExpanded(),
10404
10492
  };
10405
10493
  });
@@ -10420,6 +10508,7 @@
10420
10508
  descriptor: {
10421
10509
  size,
10422
10510
  views: views.map((view) => {
10511
+ var _a, _b, _c;
10423
10512
  const data = view.data;
10424
10513
  const body = this.options.createComponent({
10425
10514
  id: data.id,
@@ -10446,6 +10535,9 @@
10446
10535
  isExpanded: !!view.expanded,
10447
10536
  disableDnd: !!this.options.disableDnd,
10448
10537
  accessor: this,
10538
+ headerSize: (_a = view.headerSize) !== null && _a !== void 0 ? _a : HEADER_SIZE,
10539
+ minimumBodySize: (_b = view.minimumSize) !== null && _b !== void 0 ? _b : MINIMUM_BODY_SIZE,
10540
+ maximumBodySize: (_c = view.maximumSize) !== null && _c !== void 0 ? _c : MAXIMUM_BODY_SIZE,
10449
10541
  });
10450
10542
  this.doAddPanel(panel);
10451
10543
  queue.push(() => {