dockview-core 1.11.0 → 1.13.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.
Files changed (73) hide show
  1. package/dist/cjs/api/component.api.d.ts +2 -1
  2. package/dist/cjs/api/component.api.js +7 -0
  3. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +5 -1
  4. package/dist/cjs/api/dockviewGroupPanelApi.js +19 -1
  5. package/dist/cjs/api/dockviewPanelApi.d.ts +6 -0
  6. package/dist/cjs/api/panelApi.d.ts +4 -0
  7. package/dist/cjs/dnd/droptarget.d.ts +1 -1
  8. package/dist/cjs/dnd/droptarget.js +4 -10
  9. package/dist/cjs/dockview/components/panel/content.js +2 -10
  10. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +12 -1
  11. package/dist/cjs/dockview/dockviewComponent.d.ts +8 -4
  12. package/dist/cjs/dockview/dockviewComponent.js +83 -68
  13. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +12 -1
  14. package/dist/cjs/dockview/dockviewGroupPanelModel.js +48 -21
  15. package/dist/cjs/dockview/dockviewPanelModel.js +21 -24
  16. package/dist/cjs/dockview/framework.d.ts +38 -0
  17. package/dist/cjs/dockview/framework.js +2 -0
  18. package/dist/cjs/dockview/options.d.ts +68 -46
  19. package/dist/cjs/dockview/options.js +43 -1
  20. package/dist/cjs/dockview/types.d.ts +4 -10
  21. package/dist/cjs/framwork.d.ts +4 -0
  22. package/dist/cjs/framwork.js +2 -0
  23. package/dist/cjs/index.d.ts +2 -1
  24. package/dist/cjs/index.js +1 -1
  25. package/dist/cjs/overlayRenderContainer.d.ts +1 -1
  26. package/dist/dockview-core.amd.js +1972 -1886
  27. package/dist/dockview-core.amd.js.map +1 -1
  28. package/dist/dockview-core.amd.min.js +2 -2
  29. package/dist/dockview-core.amd.min.js.map +1 -1
  30. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  31. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  32. package/dist/dockview-core.amd.noStyle.js +1972 -1886
  33. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  34. package/dist/dockview-core.cjs.js +1972 -1886
  35. package/dist/dockview-core.cjs.js.map +1 -1
  36. package/dist/dockview-core.esm.js +1971 -1887
  37. package/dist/dockview-core.esm.js.map +1 -1
  38. package/dist/dockview-core.esm.min.js +2 -2
  39. package/dist/dockview-core.esm.min.js.map +1 -1
  40. package/dist/dockview-core.js +1972 -1886
  41. package/dist/dockview-core.js.map +1 -1
  42. package/dist/dockview-core.min.js +2 -2
  43. package/dist/dockview-core.min.js.map +1 -1
  44. package/dist/dockview-core.min.noStyle.js +2 -2
  45. package/dist/dockview-core.min.noStyle.js.map +1 -1
  46. package/dist/dockview-core.noStyle.js +1972 -1886
  47. package/dist/dockview-core.noStyle.js.map +1 -1
  48. package/dist/esm/api/component.api.d.ts +2 -1
  49. package/dist/esm/api/component.api.js +3 -0
  50. package/dist/esm/api/dockviewGroupPanelApi.d.ts +5 -1
  51. package/dist/esm/api/dockviewGroupPanelApi.js +18 -1
  52. package/dist/esm/api/dockviewPanelApi.d.ts +6 -0
  53. package/dist/esm/api/panelApi.d.ts +4 -0
  54. package/dist/esm/dnd/droptarget.d.ts +1 -1
  55. package/dist/esm/dnd/droptarget.js +4 -10
  56. package/dist/esm/dockview/components/panel/content.js +2 -10
  57. package/dist/esm/dockview/components/titlebar/tabsContainer.js +12 -1
  58. package/dist/esm/dockview/dockviewComponent.d.ts +8 -4
  59. package/dist/esm/dockview/dockviewComponent.js +78 -69
  60. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +12 -1
  61. package/dist/esm/dockview/dockviewGroupPanelModel.js +36 -21
  62. package/dist/esm/dockview/dockviewPanelModel.js +21 -13
  63. package/dist/esm/dockview/framework.d.ts +38 -0
  64. package/dist/esm/dockview/framework.js +1 -0
  65. package/dist/esm/dockview/options.d.ts +68 -46
  66. package/dist/esm/dockview/options.js +36 -0
  67. package/dist/esm/dockview/types.d.ts +4 -10
  68. package/dist/esm/framwork.d.ts +4 -0
  69. package/dist/esm/framwork.js +1 -0
  70. package/dist/esm/index.d.ts +2 -1
  71. package/dist/esm/index.js +1 -1
  72. package/dist/esm/overlayRenderContainer.d.ts +1 -1
  73. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 1.11.0
3
+ * @version 1.13.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -2468,6 +2468,261 @@ class Gridview {
2468
2468
  }
2469
2469
  }
2470
2470
 
2471
+ class Resizable extends CompositeDisposable {
2472
+ get element() {
2473
+ return this._element;
2474
+ }
2475
+ get disableResizing() {
2476
+ return this._disableResizing;
2477
+ }
2478
+ set disableResizing(value) {
2479
+ this._disableResizing = value;
2480
+ }
2481
+ constructor(parentElement, disableResizing = false) {
2482
+ super();
2483
+ this._disableResizing = disableResizing;
2484
+ this._element = parentElement;
2485
+ this.addDisposables(watchElementResize(this._element, (entry) => {
2486
+ if (this.isDisposed) {
2487
+ /**
2488
+ * resize is delayed through requestAnimationFrame so there is a small chance
2489
+ * the component has already been disposed of
2490
+ */
2491
+ return;
2492
+ }
2493
+ if (this.disableResizing) {
2494
+ return;
2495
+ }
2496
+ if (!this._element.offsetParent) {
2497
+ /**
2498
+ * offsetParent === null is equivalent to display: none being set on the element or one
2499
+ * of it's parents. In the display: none case the size will become (0, 0) which we do
2500
+ * not want to propagate.
2501
+ *
2502
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
2503
+ *
2504
+ * You could use checkVisibility() but at the time of writing it's not supported across
2505
+ * all Browsers
2506
+ *
2507
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility
2508
+ */
2509
+ return;
2510
+ }
2511
+ if (!isInDocument(this._element)) {
2512
+ /**
2513
+ * since the event is dispatched through requestAnimationFrame there is a small chance
2514
+ * the component is no longer attached to the DOM, if that is the case the dimensions
2515
+ * are mostly likely all zero and meaningless. we should skip this case.
2516
+ */
2517
+ return;
2518
+ }
2519
+ const { width, height } = entry.contentRect;
2520
+ this.layout(width, height);
2521
+ }));
2522
+ }
2523
+ }
2524
+
2525
+ const nextLayoutId$1 = sequentialNumberGenerator();
2526
+ function toTarget(direction) {
2527
+ switch (direction) {
2528
+ case 'left':
2529
+ return 'left';
2530
+ case 'right':
2531
+ return 'right';
2532
+ case 'above':
2533
+ return 'top';
2534
+ case 'below':
2535
+ return 'bottom';
2536
+ case 'within':
2537
+ default:
2538
+ return 'center';
2539
+ }
2540
+ }
2541
+ class BaseGrid extends Resizable {
2542
+ get id() {
2543
+ return this._id;
2544
+ }
2545
+ get size() {
2546
+ return this._groups.size;
2547
+ }
2548
+ get groups() {
2549
+ return Array.from(this._groups.values()).map((_) => _.value);
2550
+ }
2551
+ get width() {
2552
+ return this.gridview.width;
2553
+ }
2554
+ get height() {
2555
+ return this.gridview.height;
2556
+ }
2557
+ get minimumHeight() {
2558
+ return this.gridview.minimumHeight;
2559
+ }
2560
+ get maximumHeight() {
2561
+ return this.gridview.maximumHeight;
2562
+ }
2563
+ get minimumWidth() {
2564
+ return this.gridview.minimumWidth;
2565
+ }
2566
+ get maximumWidth() {
2567
+ return this.gridview.maximumWidth;
2568
+ }
2569
+ get activeGroup() {
2570
+ return this._activeGroup;
2571
+ }
2572
+ get locked() {
2573
+ return this.gridview.locked;
2574
+ }
2575
+ set locked(value) {
2576
+ this.gridview.locked = value;
2577
+ }
2578
+ constructor(options) {
2579
+ super(document.createElement('div'), options.disableAutoResizing);
2580
+ this._id = nextLayoutId$1.next();
2581
+ this._groups = new Map();
2582
+ this._onDidLayoutChange = new Emitter();
2583
+ this.onDidLayoutChange = this._onDidLayoutChange.event;
2584
+ this._onDidRemove = new Emitter();
2585
+ this.onDidRemove = this._onDidRemove.event;
2586
+ this._onDidAdd = new Emitter();
2587
+ this.onDidAdd = this._onDidAdd.event;
2588
+ this._onDidActiveChange = new Emitter();
2589
+ this.onDidActiveChange = this._onDidActiveChange.event;
2590
+ this._bufferOnDidLayoutChange = new TickDelayedEvent();
2591
+ this.element.style.height = '100%';
2592
+ this.element.style.width = '100%';
2593
+ options.parentElement.appendChild(this.element);
2594
+ this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation);
2595
+ this.gridview.locked = !!options.locked;
2596
+ this.element.appendChild(this.gridview.element);
2597
+ this.layout(0, 0, true); // set some elements height/widths
2598
+ this.addDisposables(Disposable.from(() => {
2599
+ var _a;
2600
+ (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element);
2601
+ }), this.gridview.onDidChange(() => {
2602
+ this._bufferOnDidLayoutChange.fire();
2603
+ }), exports.DockviewEvent.any(this.onDidAdd, this.onDidRemove, this.onDidActiveChange)(() => {
2604
+ this._bufferOnDidLayoutChange.fire();
2605
+ }), this._bufferOnDidLayoutChange.onEvent(() => {
2606
+ this._onDidLayoutChange.fire();
2607
+ }), this._bufferOnDidLayoutChange);
2608
+ }
2609
+ setVisible(panel, visible) {
2610
+ this.gridview.setViewVisible(getGridLocation(panel.element), visible);
2611
+ this._onDidLayoutChange.fire();
2612
+ }
2613
+ isVisible(panel) {
2614
+ return this.gridview.isViewVisible(getGridLocation(panel.element));
2615
+ }
2616
+ maximizeGroup(panel) {
2617
+ this.gridview.maximizeView(panel);
2618
+ this.doSetGroupActive(panel);
2619
+ }
2620
+ isMaximizedGroup(panel) {
2621
+ return this.gridview.maximizedView() === panel;
2622
+ }
2623
+ exitMaximizedGroup() {
2624
+ this.gridview.exitMaximizedView();
2625
+ }
2626
+ hasMaximizedGroup() {
2627
+ return this.gridview.hasMaximizedView();
2628
+ }
2629
+ get onDidMaximizedGroupChange() {
2630
+ return this.gridview.onDidMaximizedNodeChange;
2631
+ }
2632
+ doAddGroup(group, location = [0], size) {
2633
+ this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
2634
+ this._onDidAdd.fire(group);
2635
+ }
2636
+ doRemoveGroup(group, options) {
2637
+ if (!this._groups.has(group.id)) {
2638
+ throw new Error('invalid operation');
2639
+ }
2640
+ const item = this._groups.get(group.id);
2641
+ const view = this.gridview.remove(group, exports.Sizing.Distribute);
2642
+ if (item && !(options === null || options === void 0 ? void 0 : options.skipDispose)) {
2643
+ item.disposable.dispose();
2644
+ item.value.dispose();
2645
+ this._groups.delete(group.id);
2646
+ this._onDidRemove.fire(group);
2647
+ }
2648
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
2649
+ const groups = Array.from(this._groups.values());
2650
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
2651
+ }
2652
+ return view;
2653
+ }
2654
+ getPanel(id) {
2655
+ var _a;
2656
+ return (_a = this._groups.get(id)) === null || _a === void 0 ? void 0 : _a.value;
2657
+ }
2658
+ doSetGroupActive(group) {
2659
+ if (this._activeGroup === group) {
2660
+ return;
2661
+ }
2662
+ if (this._activeGroup) {
2663
+ this._activeGroup.setActive(false);
2664
+ }
2665
+ if (group) {
2666
+ group.setActive(true);
2667
+ }
2668
+ this._activeGroup = group;
2669
+ this._onDidActiveChange.fire(group);
2670
+ }
2671
+ removeGroup(group) {
2672
+ this.doRemoveGroup(group);
2673
+ }
2674
+ moveToNext(options) {
2675
+ var _a;
2676
+ if (!options) {
2677
+ options = {};
2678
+ }
2679
+ if (!options.group) {
2680
+ if (!this.activeGroup) {
2681
+ return;
2682
+ }
2683
+ options.group = this.activeGroup;
2684
+ }
2685
+ const location = getGridLocation(options.group.element);
2686
+ const next = (_a = this.gridview.next(location)) === null || _a === void 0 ? void 0 : _a.view;
2687
+ this.doSetGroupActive(next);
2688
+ }
2689
+ moveToPrevious(options) {
2690
+ var _a;
2691
+ if (!options) {
2692
+ options = {};
2693
+ }
2694
+ if (!options.group) {
2695
+ if (!this.activeGroup) {
2696
+ return;
2697
+ }
2698
+ options.group = this.activeGroup;
2699
+ }
2700
+ const location = getGridLocation(options.group.element);
2701
+ const next = (_a = this.gridview.previous(location)) === null || _a === void 0 ? void 0 : _a.view;
2702
+ this.doSetGroupActive(next);
2703
+ }
2704
+ layout(width, height, forceResize) {
2705
+ const different = forceResize !== null && forceResize !== void 0 ? forceResize : (width !== this.width || height !== this.height);
2706
+ if (!different) {
2707
+ return;
2708
+ }
2709
+ this.gridview.element.style.height = `${height}px`;
2710
+ this.gridview.element.style.width = `${width}px`;
2711
+ this.gridview.layout(width, height);
2712
+ }
2713
+ dispose() {
2714
+ this._onDidActiveChange.dispose();
2715
+ this._onDidAdd.dispose();
2716
+ this._onDidRemove.dispose();
2717
+ this._onDidLayoutChange.dispose();
2718
+ for (const group of this.groups) {
2719
+ group.dispose();
2720
+ }
2721
+ this.gridview.dispose();
2722
+ super.dispose();
2723
+ }
2724
+ }
2725
+
2471
2726
  class SplitviewApi {
2472
2727
  /**
2473
2728
  * The minimum size the component can reach where size is measured in the direction of orientation provided.
@@ -3010,6 +3265,9 @@ class DockviewApi {
3010
3265
  get onWillDragPanel() {
3011
3266
  return this.component.onWillDragPanel;
3012
3267
  }
3268
+ get onUnhandledDragOverEvent() {
3269
+ return this.component.onUnhandledDragOverEvent;
3270
+ }
3013
3271
  /**
3014
3272
  * All panel objects.
3015
3273
  */
@@ -3147,6 +3405,67 @@ class DockviewApi {
3147
3405
  }
3148
3406
  }
3149
3407
 
3408
+ class DragHandler extends CompositeDisposable {
3409
+ constructor(el) {
3410
+ super();
3411
+ this.el = el;
3412
+ this.dataDisposable = new MutableDisposable();
3413
+ this.pointerEventsDisposable = new MutableDisposable();
3414
+ this._onDragStart = new Emitter();
3415
+ this.onDragStart = this._onDragStart.event;
3416
+ this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
3417
+ this.configure();
3418
+ }
3419
+ isCancelled(_event) {
3420
+ return false;
3421
+ }
3422
+ configure() {
3423
+ this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
3424
+ if (event.defaultPrevented || this.isCancelled(event)) {
3425
+ event.preventDefault();
3426
+ return;
3427
+ }
3428
+ const iframes = [
3429
+ ...getElementsByTagName('iframe'),
3430
+ ...getElementsByTagName('webview'),
3431
+ ];
3432
+ this.pointerEventsDisposable.value = {
3433
+ dispose: () => {
3434
+ for (const iframe of iframes) {
3435
+ iframe.style.pointerEvents = 'auto';
3436
+ }
3437
+ },
3438
+ };
3439
+ for (const iframe of iframes) {
3440
+ iframe.style.pointerEvents = 'none';
3441
+ }
3442
+ this.el.classList.add('dv-dragged');
3443
+ setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
3444
+ this.dataDisposable.value = this.getData(event);
3445
+ this._onDragStart.fire(event);
3446
+ if (event.dataTransfer) {
3447
+ event.dataTransfer.effectAllowed = 'move';
3448
+ const hasData = event.dataTransfer.items.length > 0;
3449
+ if (!hasData) {
3450
+ /**
3451
+ * Although this is not used by dockview many third party dnd libraries will check
3452
+ * dataTransfer.types to determine valid drag events.
3453
+ *
3454
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
3455
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
3456
+ * dnd logic. You can see the code at
3457
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3458
+ */
3459
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
3460
+ }
3461
+ }
3462
+ }), addDisposableListener(this.el, 'dragend', () => {
3463
+ this.pointerEventsDisposable.dispose();
3464
+ this.dataDisposable.dispose();
3465
+ }));
3466
+ }
3467
+ }
3468
+
3150
3469
  class DragAndDropObserver extends CompositeDisposable {
3151
3470
  constructor(element, callbacks) {
3152
3471
  super();
@@ -3291,6 +3610,10 @@ class Droptarget extends CompositeDisposable {
3291
3610
  this.removeDropTarget();
3292
3611
  return;
3293
3612
  }
3613
+ if (!this.options.canDisplayOverlay(e, quadrant)) {
3614
+ this.removeDropTarget();
3615
+ return;
3616
+ }
3294
3617
  const willShowOverlayEvent = new WillShowOverlayEvent({
3295
3618
  nativeEvent: e,
3296
3619
  position: quadrant,
@@ -3304,16 +3627,6 @@ class Droptarget extends CompositeDisposable {
3304
3627
  this.removeDropTarget();
3305
3628
  return;
3306
3629
  }
3307
- if (typeof this.options.canDisplayOverlay === 'boolean') {
3308
- if (!this.options.canDisplayOverlay) {
3309
- this.removeDropTarget();
3310
- return;
3311
- }
3312
- }
3313
- else if (!this.options.canDisplayOverlay(e, quadrant)) {
3314
- this.removeDropTarget();
3315
- return;
3316
- }
3317
3630
  this.markAsUsed(e);
3318
3631
  if (!this.targetElement) {
3319
3632
  this.targetElement = document.createElement('div');
@@ -3504,1997 +3817,1758 @@ function calculateQuadrantAsPixels(overlayType, x, y, width, height, threshold)
3504
3817
  return 'center';
3505
3818
  }
3506
3819
 
3507
- class ContentContainer extends CompositeDisposable {
3508
- get element() {
3509
- return this._element;
3510
- }
3511
- constructor(accessor, group) {
3820
+ class WillFocusEvent extends DockviewEvent {
3821
+ constructor() {
3512
3822
  super();
3513
- this.accessor = accessor;
3514
- this.group = group;
3515
- this.disposable = new MutableDisposable();
3516
- this._onDidFocus = new Emitter();
3517
- this.onDidFocus = this._onDidFocus.event;
3518
- this._onDidBlur = new Emitter();
3519
- this.onDidBlur = this._onDidBlur.event;
3520
- this._element = document.createElement('div');
3521
- this._element.className = 'content-container';
3522
- this._element.tabIndex = -1;
3523
- this.addDisposables(this._onDidFocus, this._onDidBlur);
3524
- this.dropTarget = new Droptarget(this.element, {
3525
- acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3526
- canDisplayOverlay: (event, position) => {
3527
- if (this.group.locked === 'no-drop-target' ||
3528
- (this.group.locked && position === 'center')) {
3529
- return false;
3530
- }
3531
- const data = getPanelData();
3532
- if (!data &&
3533
- event.shiftKey &&
3534
- this.group.location.type !== 'floating') {
3535
- return false;
3536
- }
3537
- if (data && data.viewId === this.accessor.id) {
3538
- if (data.groupId === this.group.id) {
3539
- if (position === 'center') {
3540
- // don't allow to drop on self for center position
3541
- return false;
3542
- }
3543
- if (data.panelId === null) {
3544
- // don't allow group move to drop anywhere on self
3545
- return false;
3546
- }
3547
- }
3548
- const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
3549
- data.groupId === this.group.id;
3550
- return !groupHasOnePanelAndIsActiveDragElement;
3551
- }
3552
- return this.group.canDisplayOverlay(event, position, 'content');
3553
- },
3554
- });
3555
- this.addDisposables(this.dropTarget);
3556
3823
  }
3557
- show() {
3558
- this.element.style.display = '';
3824
+ }
3825
+ /**
3826
+ * A core api implementation that should be used across all panel-like objects
3827
+ */
3828
+ class PanelApiImpl extends CompositeDisposable {
3829
+ get isFocused() {
3830
+ return this._isFocused;
3559
3831
  }
3560
- hide() {
3561
- this.element.style.display = 'none';
3832
+ get isActive() {
3833
+ return this._isActive;
3562
3834
  }
3563
- renderPanel(panel, options = { asActive: true }) {
3564
- const doRender = options.asActive ||
3565
- (this.panel && this.group.isPanelActive(this.panel));
3566
- if (this.panel &&
3567
- this.panel.view.content.element.parentElement === this._element) {
3568
- /**
3569
- * If the currently attached panel is mounted directly to the content then remove it
3570
- */
3571
- this._element.removeChild(this.panel.view.content.element);
3572
- }
3573
- this.panel = panel;
3574
- let container;
3575
- switch (panel.api.renderer) {
3576
- case 'onlyWhenVisibile':
3577
- this.group.renderContainer.detatch(panel);
3578
- if (this.panel) {
3579
- if (doRender) {
3580
- this._element.appendChild(this.panel.view.content.element);
3581
- }
3582
- }
3583
- container = this._element;
3584
- break;
3585
- case 'always':
3586
- if (panel.view.content.element.parentElement === this._element) {
3587
- this._element.removeChild(panel.view.content.element);
3588
- }
3589
- container = this.group.renderContainer.attach({
3590
- panel,
3591
- referenceContainer: this,
3592
- });
3593
- break;
3594
- }
3595
- if (doRender) {
3596
- const _onDidFocus = panel.view.content.onDidFocus;
3597
- const _onDidBlur = panel.view.content.onDidBlur;
3598
- const focusTracker = trackFocus(container);
3599
- const disposable = new CompositeDisposable();
3600
- disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
3601
- if (_onDidFocus) {
3602
- disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire()));
3603
- }
3604
- if (_onDidBlur) {
3605
- disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
3606
- }
3607
- this.disposable.value = disposable;
3608
- }
3835
+ get isVisible() {
3836
+ return this._isVisible;
3609
3837
  }
3610
- openPanel(panel) {
3611
- if (this.panel === panel) {
3612
- return;
3613
- }
3614
- this.renderPanel(panel);
3838
+ get width() {
3839
+ return this._width;
3615
3840
  }
3616
- layout(_width, _height) {
3617
- // noop
3841
+ get height() {
3842
+ return this._height;
3618
3843
  }
3619
- closePanel() {
3620
- var _a;
3621
- if (this.panel) {
3622
- if (this.panel.api.renderer === 'onlyWhenVisibile') {
3623
- (_a = this.panel.view.content.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.panel.view.content.element);
3624
- }
3625
- }
3626
- this.panel = undefined;
3844
+ constructor(id, component) {
3845
+ super();
3846
+ this.id = id;
3847
+ this.component = component;
3848
+ this._isFocused = false;
3849
+ this._isActive = false;
3850
+ this._isVisible = true;
3851
+ this._width = 0;
3852
+ this._height = 0;
3853
+ this._parameters = {};
3854
+ this.panelUpdatesDisposable = new MutableDisposable();
3855
+ this._onDidDimensionChange = new Emitter();
3856
+ this.onDidDimensionsChange = this._onDidDimensionChange.event;
3857
+ this._onDidChangeFocus = new Emitter();
3858
+ this.onDidFocusChange = this._onDidChangeFocus.event;
3859
+ //
3860
+ this._onWillFocus = new Emitter();
3861
+ this.onWillFocus = this._onWillFocus.event;
3862
+ //
3863
+ this._onDidVisibilityChange = new Emitter();
3864
+ this.onDidVisibilityChange = this._onDidVisibilityChange.event;
3865
+ this._onWillVisibilityChange = new Emitter();
3866
+ this.onWillVisibilityChange = this._onWillVisibilityChange.event;
3867
+ this._onDidActiveChange = new Emitter();
3868
+ this.onDidActiveChange = this._onDidActiveChange.event;
3869
+ this._onActiveChange = new Emitter();
3870
+ this.onActiveChange = this._onActiveChange.event;
3871
+ this._onDidParametersChange = new Emitter();
3872
+ this.onDidParametersChange = this._onDidParametersChange.event;
3873
+ this.addDisposables(this.onDidFocusChange((event) => {
3874
+ this._isFocused = event.isFocused;
3875
+ }), this.onDidActiveChange((event) => {
3876
+ this._isActive = event.isActive;
3877
+ }), this.onDidVisibilityChange((event) => {
3878
+ this._isVisible = event.isVisible;
3879
+ }), this.onDidDimensionsChange((event) => {
3880
+ this._width = event.width;
3881
+ this._height = event.height;
3882
+ }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onWillFocus, this._onActiveChange, this._onWillFocus, this._onWillVisibilityChange, this._onDidParametersChange);
3627
3883
  }
3628
- dispose() {
3629
- this.disposable.dispose();
3630
- super.dispose();
3884
+ getParameters() {
3885
+ return this._parameters;
3886
+ }
3887
+ initialize(panel) {
3888
+ this.panelUpdatesDisposable.value = this._onDidParametersChange.event((parameters) => {
3889
+ this._parameters = parameters;
3890
+ panel.update({
3891
+ params: parameters,
3892
+ });
3893
+ });
3894
+ }
3895
+ setVisible(isVisible) {
3896
+ this._onWillVisibilityChange.fire({ isVisible });
3897
+ }
3898
+ setActive() {
3899
+ this._onActiveChange.fire();
3900
+ }
3901
+ updateParameters(parameters) {
3902
+ this._onDidParametersChange.fire(parameters);
3631
3903
  }
3632
3904
  }
3633
3905
 
3634
- class DragHandler extends CompositeDisposable {
3635
- constructor(el) {
3636
- super();
3637
- this.el = el;
3638
- this.dataDisposable = new MutableDisposable();
3639
- this.pointerEventsDisposable = new MutableDisposable();
3640
- this._onDragStart = new Emitter();
3641
- this.onDragStart = this._onDragStart.event;
3642
- this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
3643
- this.configure();
3906
+ class SplitviewPanelApiImpl extends PanelApiImpl {
3907
+ //
3908
+ constructor(id, component) {
3909
+ super(id, component);
3910
+ this._onDidConstraintsChangeInternal = new Emitter();
3911
+ this.onDidConstraintsChangeInternal = this._onDidConstraintsChangeInternal.event;
3912
+ //
3913
+ this._onDidConstraintsChange = new Emitter({
3914
+ replay: true,
3915
+ });
3916
+ this.onDidConstraintsChange = this._onDidConstraintsChange.event;
3917
+ //
3918
+ this._onDidSizeChange = new Emitter();
3919
+ this.onDidSizeChange = this._onDidSizeChange.event;
3920
+ this.addDisposables(this._onDidConstraintsChangeInternal, this._onDidConstraintsChange, this._onDidSizeChange);
3644
3921
  }
3645
- isCancelled(_event) {
3646
- return false;
3922
+ setConstraints(value) {
3923
+ this._onDidConstraintsChangeInternal.fire(value);
3647
3924
  }
3648
- configure() {
3649
- this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
3650
- if (event.defaultPrevented || this.isCancelled(event)) {
3651
- event.preventDefault();
3652
- return;
3653
- }
3654
- const iframes = [
3655
- ...getElementsByTagName('iframe'),
3656
- ...getElementsByTagName('webview'),
3657
- ];
3658
- this.pointerEventsDisposable.value = {
3659
- dispose: () => {
3660
- for (const iframe of iframes) {
3661
- iframe.style.pointerEvents = 'auto';
3662
- }
3663
- },
3664
- };
3665
- for (const iframe of iframes) {
3666
- iframe.style.pointerEvents = 'none';
3667
- }
3668
- this.el.classList.add('dv-dragged');
3669
- setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
3670
- this.dataDisposable.value = this.getData(event);
3671
- this._onDragStart.fire(event);
3672
- if (event.dataTransfer) {
3673
- event.dataTransfer.effectAllowed = 'move';
3674
- const hasData = event.dataTransfer.items.length > 0;
3675
- if (!hasData) {
3676
- /**
3677
- * Although this is not used by dockview many third party dnd libraries will check
3678
- * dataTransfer.types to determine valid drag events.
3679
- *
3680
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
3681
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
3682
- * dnd logic. You can see the code at
3683
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3684
- */
3685
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
3686
- }
3687
- }
3688
- }), addDisposableListener(this.el, 'dragend', () => {
3689
- this.pointerEventsDisposable.dispose();
3690
- this.dataDisposable.dispose();
3691
- }));
3925
+ setSize(event) {
3926
+ this._onDidSizeChange.fire(event);
3692
3927
  }
3693
3928
  }
3694
3929
 
3695
- class TabDragHandler extends DragHandler {
3696
- constructor(element, accessor, group, panel) {
3697
- super(element);
3698
- this.accessor = accessor;
3699
- this.group = group;
3700
- this.panel = panel;
3701
- this.panelTransfer = LocalSelectionTransfer.getInstance();
3930
+ class PaneviewPanelApiImpl extends SplitviewPanelApiImpl {
3931
+ set pane(pane) {
3932
+ this._pane = pane;
3702
3933
  }
3703
- getData(event) {
3704
- this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
3705
- return {
3706
- dispose: () => {
3707
- this.panelTransfer.clearData(PanelTransfer.prototype);
3708
- },
3709
- };
3934
+ constructor(id, component) {
3935
+ super(id, component);
3936
+ this._onDidExpansionChange = new Emitter({
3937
+ replay: true,
3938
+ });
3939
+ this.onDidExpansionChange = this._onDidExpansionChange.event;
3940
+ this._onMouseEnter = new Emitter({});
3941
+ this.onMouseEnter = this._onMouseEnter.event;
3942
+ this._onMouseLeave = new Emitter({});
3943
+ this.onMouseLeave = this._onMouseLeave.event;
3944
+ this.addDisposables(this._onDidExpansionChange, this._onMouseEnter, this._onMouseLeave);
3945
+ }
3946
+ setExpanded(isExpanded) {
3947
+ var _a;
3948
+ (_a = this._pane) === null || _a === void 0 ? void 0 : _a.setExpanded(isExpanded);
3949
+ }
3950
+ get isExpanded() {
3951
+ var _a;
3952
+ return !!((_a = this._pane) === null || _a === void 0 ? void 0 : _a.isExpanded());
3710
3953
  }
3711
3954
  }
3712
- class Tab extends CompositeDisposable {
3955
+
3956
+ class BasePanelView extends CompositeDisposable {
3713
3957
  get element() {
3714
3958
  return this._element;
3715
3959
  }
3716
- constructor(panel, accessor, group) {
3960
+ get width() {
3961
+ return this._width;
3962
+ }
3963
+ get height() {
3964
+ return this._height;
3965
+ }
3966
+ get params() {
3967
+ var _a;
3968
+ return (_a = this._params) === null || _a === void 0 ? void 0 : _a.params;
3969
+ }
3970
+ constructor(id, component, api) {
3717
3971
  super();
3718
- this.panel = panel;
3719
- this.accessor = accessor;
3720
- this.group = group;
3721
- this.content = undefined;
3722
- this._onChanged = new Emitter();
3723
- this.onChanged = this._onChanged.event;
3724
- this._onDropped = new Emitter();
3725
- this.onDrop = this._onDropped.event;
3726
- this._onDragStart = new Emitter();
3727
- this.onDragStart = this._onDragStart.event;
3972
+ this.id = id;
3973
+ this.component = component;
3974
+ this.api = api;
3975
+ this._height = 0;
3976
+ this._width = 0;
3728
3977
  this._element = document.createElement('div');
3729
- this._element.className = 'tab';
3730
- this._element.tabIndex = 0;
3731
- this._element.draggable = true;
3732
- toggleClass(this.element, 'inactive-tab', true);
3733
- const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3734
- this.dropTarget = new Droptarget(this._element, {
3735
- acceptedTargetZones: ['center'],
3736
- canDisplayOverlay: (event, position) => {
3737
- if (this.group.locked) {
3738
- return false;
3739
- }
3740
- const data = getPanelData();
3741
- if (data && this.accessor.id === data.viewId) {
3742
- if (data.panelId === null &&
3743
- data.groupId === this.group.id) {
3744
- // don't allow group move to drop on self
3745
- return false;
3746
- }
3747
- return this.panel.id !== data.panelId;
3748
- }
3749
- return this.group.model.canDisplayOverlay(event, position, 'tab');
3750
- },
3751
- });
3752
- this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
3753
- this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3754
- this._onDragStart.fire(event);
3755
- }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3756
- if (event.defaultPrevented) {
3757
- return;
3978
+ this._element.tabIndex = -1;
3979
+ this._element.style.outline = 'none';
3980
+ this._element.style.height = '100%';
3981
+ this._element.style.width = '100%';
3982
+ this._element.style.overflow = 'hidden';
3983
+ const focusTracker = trackFocus(this._element);
3984
+ this.addDisposables(this.api, focusTracker.onDidFocus(() => {
3985
+ this.api._onDidChangeFocus.fire({ isFocused: true });
3986
+ }), focusTracker.onDidBlur(() => {
3987
+ this.api._onDidChangeFocus.fire({ isFocused: false });
3988
+ }), focusTracker);
3989
+ }
3990
+ focus() {
3991
+ const event = new WillFocusEvent();
3992
+ this.api._onWillFocus.fire(event);
3993
+ if (event.defaultPrevented) {
3994
+ return;
3995
+ }
3996
+ this._element.focus();
3997
+ }
3998
+ layout(width, height) {
3999
+ this._width = width;
4000
+ this._height = height;
4001
+ this.api._onDidDimensionChange.fire({ width, height });
4002
+ if (this.part) {
4003
+ if (this._params) {
4004
+ this.part.update(this._params.params);
3758
4005
  }
3759
- this._onChanged.fire(event);
3760
- }), this.dropTarget.onDrop((event) => {
3761
- this._onDropped.fire(event);
3762
- }), this.dropTarget);
4006
+ }
3763
4007
  }
3764
- setActive(isActive) {
3765
- toggleClass(this.element, 'active-tab', isActive);
3766
- toggleClass(this.element, 'inactive-tab', !isActive);
4008
+ init(parameters) {
4009
+ this._params = parameters;
4010
+ this.part = this.getComponent();
3767
4011
  }
3768
- setContent(part) {
3769
- if (this.content) {
3770
- this._element.removeChild(this.content.element);
4012
+ update(event) {
4013
+ var _a, _b;
4014
+ // merge the new parameters with the existing parameters
4015
+ this._params = Object.assign(Object.assign({}, this._params), { params: Object.assign(Object.assign({}, (_a = this._params) === null || _a === void 0 ? void 0 : _a.params), event.params) });
4016
+ /**
4017
+ * delete new keys that have a value of undefined,
4018
+ * allow values of null
4019
+ */
4020
+ for (const key of Object.keys(event.params)) {
4021
+ if (event.params[key] === undefined) {
4022
+ delete this._params.params[key];
4023
+ }
3771
4024
  }
3772
- this.content = part;
3773
- this._element.appendChild(this.content.element);
4025
+ // update the view with the updated props
4026
+ (_b = this.part) === null || _b === void 0 ? void 0 : _b.update({ params: this._params.params });
4027
+ }
4028
+ toJSON() {
4029
+ var _a, _b;
4030
+ const params = (_b = (_a = this._params) === null || _a === void 0 ? void 0 : _a.params) !== null && _b !== void 0 ? _b : {};
4031
+ return {
4032
+ id: this.id,
4033
+ component: this.component,
4034
+ params: Object.keys(params).length > 0 ? params : undefined,
4035
+ };
3774
4036
  }
3775
4037
  dispose() {
4038
+ var _a;
4039
+ this.api.dispose();
4040
+ (_a = this.part) === null || _a === void 0 ? void 0 : _a.dispose();
3776
4041
  super.dispose();
3777
4042
  }
3778
4043
  }
3779
4044
 
3780
- function addGhostImage(dataTransfer, ghostElement) {
3781
- // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
3782
- addClasses(ghostElement, 'dv-dragged');
3783
- document.body.appendChild(ghostElement);
3784
- dataTransfer.setDragImage(ghostElement, 0, 0);
3785
- setTimeout(() => {
3786
- removeClasses(ghostElement, 'dv-dragged');
3787
- ghostElement.remove();
3788
- }, 0);
3789
- }
3790
-
3791
- class GroupDragHandler extends DragHandler {
3792
- constructor(element, accessor, group) {
3793
- super(element);
3794
- this.accessor = accessor;
3795
- this.group = group;
3796
- this.panelTransfer = LocalSelectionTransfer.getInstance();
3797
- this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
3798
- if (e.shiftKey) {
3799
- /**
3800
- * You cannot call e.preventDefault() because that will prevent drag events from firing
3801
- * but we also need to stop any group overlay drag events from occuring
3802
- * Use a custom event marker that can be checked by the overlay drag events
3803
- */
3804
- quasiPreventDefault(e);
3805
- }
3806
- }, true));
4045
+ class PaneviewPanel extends BasePanelView {
4046
+ set orientation(value) {
4047
+ this._orientation = value;
3807
4048
  }
3808
- isCancelled(_event) {
3809
- if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
3810
- return true;
3811
- }
3812
- return false;
4049
+ get orientation() {
4050
+ return this._orientation;
3813
4051
  }
3814
- getData(dragEvent) {
3815
- const dataTransfer = dragEvent.dataTransfer;
3816
- this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3817
- const style = window.getComputedStyle(this.el);
3818
- const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3819
- const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
3820
- if (dataTransfer) {
3821
- const ghostElement = document.createElement('div');
3822
- ghostElement.style.backgroundColor = bgColor;
3823
- ghostElement.style.color = color;
3824
- ghostElement.style.padding = '2px 8px';
3825
- ghostElement.style.height = '24px';
3826
- ghostElement.style.fontSize = '11px';
3827
- ghostElement.style.lineHeight = '20px';
3828
- ghostElement.style.borderRadius = '12px';
3829
- ghostElement.style.position = 'absolute';
3830
- ghostElement.textContent = `Multiple Panels (${this.group.size})`;
3831
- addGhostImage(dataTransfer, ghostElement);
3832
- }
3833
- return {
3834
- dispose: () => {
3835
- this.panelTransfer.clearData(PanelTransfer.prototype);
3836
- },
3837
- };
4052
+ get minimumSize() {
4053
+ const headerSize = this.headerSize;
4054
+ const expanded = this.isExpanded();
4055
+ const minimumBodySize = expanded ? this._minimumBodySize : 0;
4056
+ return headerSize + minimumBodySize;
3838
4057
  }
3839
- }
3840
-
3841
- class VoidContainer extends CompositeDisposable {
3842
- get element() {
3843
- return this._element;
4058
+ get maximumSize() {
4059
+ const headerSize = this.headerSize;
4060
+ const expanded = this.isExpanded();
4061
+ const maximumBodySize = expanded ? this._maximumBodySize : 0;
4062
+ return headerSize + maximumBodySize;
3844
4063
  }
3845
- constructor(accessor, group) {
3846
- super();
3847
- this.accessor = accessor;
3848
- this.group = group;
3849
- this._onDrop = new Emitter();
3850
- this.onDrop = this._onDrop.event;
3851
- this._onDragStart = new Emitter();
3852
- this.onDragStart = this._onDragStart.event;
3853
- this._element = document.createElement('div');
3854
- this._element.className = 'void-container';
3855
- this._element.tabIndex = 0;
3856
- this._element.draggable = true;
3857
- this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3858
- this.accessor.doSetGroupActive(this.group);
3859
- }));
3860
- const handler = new GroupDragHandler(this._element, accessor, group);
3861
- this.dropTraget = new Droptarget(this._element, {
3862
- acceptedTargetZones: ['center'],
3863
- canDisplayOverlay: (event, position) => {
3864
- var _a;
3865
- const data = getPanelData();
3866
- if (data && this.accessor.id === data.viewId) {
3867
- if (data.panelId === null &&
3868
- data.groupId === this.group.id) {
3869
- // don't allow group move to drop on self
3870
- return false;
3871
- }
3872
- // don't show the overlay if the tab being dragged is the last panel of this group
3873
- return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
3874
- }
3875
- return group.model.canDisplayOverlay(event, position, 'header_space');
3876
- },
3877
- });
3878
- this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
3879
- this.addDisposables(handler, handler.onDragStart((event) => {
3880
- this._onDragStart.fire(event);
3881
- }), this.dropTraget.onDrop((event) => {
3882
- this._onDrop.fire(event);
3883
- }), this.dropTraget);
4064
+ get size() {
4065
+ return this._size;
3884
4066
  }
3885
- }
3886
-
3887
- class TabsContainer extends CompositeDisposable {
3888
- get panels() {
3889
- return this.tabs.map((_) => _.value.panel.id);
4067
+ get orthogonalSize() {
4068
+ return this._orthogonalSize;
3890
4069
  }
3891
- get size() {
3892
- return this.tabs.length;
4070
+ set orthogonalSize(size) {
4071
+ this._orthogonalSize = size;
3893
4072
  }
3894
- get hidden() {
3895
- return this._hidden;
4073
+ get minimumBodySize() {
4074
+ return this._minimumBodySize;
3896
4075
  }
3897
- set hidden(value) {
3898
- this._hidden = value;
3899
- this.element.style.display = value ? 'none' : '';
4076
+ set minimumBodySize(value) {
4077
+ this._minimumBodySize = typeof value === 'number' ? value : 0;
3900
4078
  }
3901
- show() {
3902
- if (!this.hidden) {
3903
- this.element.style.display = '';
3904
- }
4079
+ get maximumBodySize() {
4080
+ return this._maximumBodySize;
3905
4081
  }
3906
- hide() {
3907
- this._element.style.display = 'none';
4082
+ set maximumBodySize(value) {
4083
+ this._maximumBodySize =
4084
+ typeof value === 'number' ? value : Number.POSITIVE_INFINITY;
3908
4085
  }
3909
- setRightActionsElement(element) {
3910
- if (this.rightActions === element) {
3911
- return;
3912
- }
3913
- if (this.rightActions) {
3914
- this.rightActions.remove();
3915
- this.rightActions = undefined;
3916
- }
3917
- if (element) {
3918
- this.rightActionsContainer.appendChild(element);
3919
- this.rightActions = element;
3920
- }
4086
+ get headerVisible() {
4087
+ return this._headerVisible;
3921
4088
  }
3922
- setLeftActionsElement(element) {
3923
- if (this.leftActions === element) {
4089
+ set headerVisible(value) {
4090
+ this._headerVisible = value;
4091
+ this.header.style.display = value ? '' : 'none';
4092
+ }
4093
+ constructor(id, component, headerComponent, orientation, isExpanded, isHeaderVisible) {
4094
+ super(id, component, new PaneviewPanelApiImpl(id, component));
4095
+ this.headerComponent = headerComponent;
4096
+ this._onDidChangeExpansionState = new Emitter({ replay: true });
4097
+ this.onDidChangeExpansionState = this._onDidChangeExpansionState.event;
4098
+ this._onDidChange = new Emitter();
4099
+ this.onDidChange = this._onDidChange.event;
4100
+ this.headerSize = 22;
4101
+ this._orthogonalSize = 0;
4102
+ this._size = 0;
4103
+ this._minimumBodySize = 100;
4104
+ this._maximumBodySize = Number.POSITIVE_INFINITY;
4105
+ this._isExpanded = false;
4106
+ this.expandedSize = 0;
4107
+ this.api.pane = this; // TODO cannot use 'this' before 'super'
4108
+ this.api.initialize(this);
4109
+ this._isExpanded = isExpanded;
4110
+ this._headerVisible = isHeaderVisible;
4111
+ this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
4112
+ this._orientation = orientation;
4113
+ this.element.classList.add('pane');
4114
+ this.addDisposables(this.api.onWillVisibilityChange((event) => {
4115
+ const { isVisible } = event;
4116
+ const { accessor } = this._params;
4117
+ accessor.setVisible(this, isVisible);
4118
+ }), this.api.onDidSizeChange((event) => {
4119
+ this._onDidChange.fire({ size: event.size });
4120
+ }), addDisposableListener(this.element, 'mouseenter', (ev) => {
4121
+ this.api._onMouseEnter.fire(ev);
4122
+ }), addDisposableListener(this.element, 'mouseleave', (ev) => {
4123
+ this.api._onMouseLeave.fire(ev);
4124
+ }));
4125
+ this.addDisposables(this._onDidChangeExpansionState, this.onDidChangeExpansionState((isPanelExpanded) => {
4126
+ this.api._onDidExpansionChange.fire({
4127
+ isExpanded: isPanelExpanded,
4128
+ });
4129
+ }), this.api.onDidFocusChange((e) => {
4130
+ if (!this.header) {
4131
+ return;
4132
+ }
4133
+ if (e.isFocused) {
4134
+ addClasses(this.header, 'focused');
4135
+ }
4136
+ else {
4137
+ removeClasses(this.header, 'focused');
4138
+ }
4139
+ }));
4140
+ this.renderOnce();
4141
+ }
4142
+ setVisible(isVisible) {
4143
+ this.api._onDidVisibilityChange.fire({ isVisible });
4144
+ }
4145
+ setActive(isActive) {
4146
+ this.api._onDidActiveChange.fire({ isActive });
4147
+ }
4148
+ isExpanded() {
4149
+ return this._isExpanded;
4150
+ }
4151
+ setExpanded(expanded) {
4152
+ if (this._isExpanded === expanded) {
3924
4153
  return;
3925
4154
  }
3926
- if (this.leftActions) {
3927
- this.leftActions.remove();
3928
- this.leftActions = undefined;
4155
+ this._isExpanded = expanded;
4156
+ if (expanded) {
4157
+ if (this.animationTimer) {
4158
+ clearTimeout(this.animationTimer);
4159
+ }
4160
+ if (this.body) {
4161
+ this.element.appendChild(this.body);
4162
+ }
3929
4163
  }
3930
- if (element) {
3931
- this.leftActionsContainer.appendChild(element);
3932
- this.leftActions = element;
4164
+ else {
4165
+ this.animationTimer = setTimeout(() => {
4166
+ var _a;
4167
+ (_a = this.body) === null || _a === void 0 ? void 0 : _a.remove();
4168
+ }, 200);
3933
4169
  }
4170
+ this._onDidChange.fire(expanded ? { size: this.width } : {});
4171
+ this._onDidChangeExpansionState.fire(expanded);
3934
4172
  }
3935
- setPrefixActionsElement(element) {
3936
- if (this.preActions === element) {
3937
- return;
4173
+ layout(size, orthogonalSize) {
4174
+ this._size = size;
4175
+ this._orthogonalSize = orthogonalSize;
4176
+ const [width, height] = this.orientation === exports.Orientation.HORIZONTAL
4177
+ ? [size, orthogonalSize]
4178
+ : [orthogonalSize, size];
4179
+ if (this.isExpanded()) {
4180
+ this.expandedSize = width;
3938
4181
  }
3939
- if (this.preActions) {
3940
- this.preActions.remove();
3941
- this.preActions = undefined;
4182
+ super.layout(width, height);
4183
+ }
4184
+ init(parameters) {
4185
+ var _a, _b;
4186
+ super.init(parameters);
4187
+ if (typeof parameters.minimumBodySize === 'number') {
4188
+ this.minimumBodySize = parameters.minimumBodySize;
3942
4189
  }
3943
- if (element) {
3944
- this.preActionsContainer.appendChild(element);
3945
- this.preActions = element;
4190
+ if (typeof parameters.maximumBodySize === 'number') {
4191
+ this.maximumBodySize = parameters.maximumBodySize;
3946
4192
  }
3947
- }
3948
- get element() {
3949
- return this._element;
3950
- }
3951
- isActive(tab) {
3952
- return (this.selectedIndex > -1 &&
3953
- this.tabs[this.selectedIndex].value === tab);
3954
- }
3955
- indexOf(id) {
3956
- return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3957
- }
3958
- constructor(accessor, group) {
3959
- super();
3960
- this.accessor = accessor;
3961
- this.group = group;
3962
- this.tabs = [];
3963
- this.selectedIndex = -1;
3964
- this._hidden = false;
3965
- this._onDrop = new Emitter();
3966
- this.onDrop = this._onDrop.event;
3967
- this._onTabDragStart = new Emitter();
3968
- this.onTabDragStart = this._onTabDragStart.event;
3969
- this._onGroupDragStart = new Emitter();
3970
- this.onGroupDragStart = this._onGroupDragStart.event;
3971
- this._onWillShowOverlay = new Emitter();
3972
- this.onWillShowOverlay = this._onWillShowOverlay.event;
3973
- this._element = document.createElement('div');
3974
- this._element.className = 'tabs-and-actions-container';
3975
- toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
3976
- this.rightActionsContainer = document.createElement('div');
3977
- this.rightActionsContainer.className = 'right-actions-container';
3978
- this.leftActionsContainer = document.createElement('div');
3979
- this.leftActionsContainer.className = 'left-actions-container';
3980
- this.preActionsContainer = document.createElement('div');
3981
- this.preActionsContainer.className = 'pre-actions-container';
3982
- this.tabContainer = document.createElement('div');
3983
- this.tabContainer.className = 'tabs-container';
3984
- this.voidContainer = new VoidContainer(this.accessor, this.group);
3985
- this._element.appendChild(this.preActionsContainer);
3986
- this._element.appendChild(this.tabContainer);
3987
- this._element.appendChild(this.leftActionsContainer);
3988
- this._element.appendChild(this.voidContainer.element);
3989
- this._element.appendChild(this.rightActionsContainer);
3990
- this.addDisposables(this.accessor.onDidAddPanel((e) => {
3991
- if (e.api.group === this.group) {
3992
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3993
- }
3994
- }), this.accessor.onDidRemovePanel((e) => {
3995
- if (e.api.group === this.group) {
3996
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3997
- }
3998
- }), this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
3999
- this._onGroupDragStart.fire({
4000
- nativeEvent: event,
4001
- group: this.group,
4002
- });
4003
- }), this.voidContainer.onDrop((event) => {
4004
- this._onDrop.fire({
4005
- event: event.nativeEvent,
4006
- index: this.tabs.length,
4007
- });
4008
- }), this.voidContainer.onWillShowOverlay((event) => {
4009
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4010
- kind: 'header_space',
4011
- }));
4012
- }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
4013
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
4014
- if (isFloatingGroupsEnabled &&
4015
- event.shiftKey &&
4016
- this.group.api.location.type !== 'floating') {
4017
- event.preventDefault();
4018
- const { top, left } = this.element.getBoundingClientRect();
4019
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
4020
- this.accessor.addFloatingGroup(this.group, {
4021
- x: left - rootLeft + 20,
4022
- y: top - rootTop + 20,
4023
- }, { inDragMode: true });
4024
- }
4025
- }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
4026
- if (event.defaultPrevented) {
4027
- return;
4028
- }
4029
- const isLeftClick = event.button === 0;
4030
- if (isLeftClick) {
4031
- this.accessor.doSetGroupActive(this.group);
4032
- }
4033
- }));
4034
- }
4035
- setActive(_isGroupActive) {
4036
- // noop
4037
- }
4038
- addTab(tab, index = this.tabs.length) {
4039
- if (index < 0 || index > this.tabs.length) {
4040
- throw new Error('invalid location');
4041
- }
4042
- this.tabContainer.insertBefore(tab.value.element, this.tabContainer.children[index]);
4043
- this.tabs = [
4044
- ...this.tabs.slice(0, index),
4045
- tab,
4046
- ...this.tabs.slice(index),
4047
- ];
4048
- if (this.selectedIndex < 0) {
4049
- this.selectedIndex = index;
4050
- }
4051
- }
4052
- delete(id) {
4053
- const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
4054
- const tabToRemove = this.tabs.splice(index, 1)[0];
4055
- const { value, disposable } = tabToRemove;
4056
- disposable.dispose();
4057
- value.dispose();
4058
- value.element.remove();
4059
- }
4060
- setActivePanel(panel) {
4061
- this.tabs.forEach((tab) => {
4062
- const isActivePanel = panel.id === tab.value.panel.id;
4063
- tab.value.setActive(isActivePanel);
4064
- });
4065
- }
4066
- openPanel(panel, index = this.tabs.length) {
4067
- var _a;
4068
- if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
4069
- return;
4070
- }
4071
- const tab = new Tab(panel, this.accessor, this.group);
4072
- if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
4073
- throw new Error('invalid header component');
4074
- }
4075
- tab.setContent(panel.view.tab);
4076
- const disposable = new CompositeDisposable(tab.onDragStart((event) => {
4077
- this._onTabDragStart.fire({ nativeEvent: event, panel });
4078
- }), tab.onChanged((event) => {
4079
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
4080
- const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
4081
- this.size === 1;
4082
- if (isFloatingGroupsEnabled &&
4083
- !isFloatingWithOnePanel &&
4084
- event.shiftKey) {
4085
- event.preventDefault();
4086
- const panel = this.accessor.getGroupPanel(tab.panel.id);
4087
- const { top, left } = tab.element.getBoundingClientRect();
4088
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
4089
- this.accessor.addFloatingGroup(panel, {
4090
- x: left - rootLeft,
4091
- y: top - rootTop,
4092
- }, { inDragMode: true });
4093
- return;
4094
- }
4095
- const isLeftClick = event.button === 0;
4096
- if (!isLeftClick || event.defaultPrevented) {
4097
- return;
4098
- }
4099
- if (this.group.activePanel !== panel) {
4100
- this.group.model.openPanel(panel);
4101
- }
4102
- }), tab.onDrop((event) => {
4103
- this._onDrop.fire({
4104
- event: event.nativeEvent,
4105
- index: this.tabs.findIndex((x) => x.value === tab),
4106
- });
4107
- }), tab.onWillShowOverlay((event) => {
4108
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, { kind: 'tab' }));
4109
- }));
4110
- const value = { value: tab, disposable };
4111
- this.addTab(value, index);
4112
- }
4113
- closePanel(panel) {
4114
- this.delete(panel.id);
4115
- }
4116
- dispose() {
4117
- super.dispose();
4118
- for (const { value, disposable } of this.tabs) {
4119
- disposable.dispose();
4120
- value.dispose();
4193
+ this.bodyPart = this.getBodyComponent();
4194
+ this.headerPart = this.getHeaderComponent();
4195
+ this.bodyPart.init(Object.assign(Object.assign({}, parameters), { api: this.api }));
4196
+ this.headerPart.init(Object.assign(Object.assign({}, parameters), { api: this.api }));
4197
+ (_a = this.body) === null || _a === void 0 ? void 0 : _a.append(this.bodyPart.element);
4198
+ (_b = this.header) === null || _b === void 0 ? void 0 : _b.append(this.headerPart.element);
4199
+ if (typeof parameters.isExpanded === 'boolean') {
4200
+ this.setExpanded(parameters.isExpanded);
4121
4201
  }
4122
- this.tabs = [];
4123
- }
4124
- }
4125
-
4126
- class DockviewDidDropEvent extends DockviewEvent {
4127
- get nativeEvent() {
4128
- return this.options.nativeEvent;
4129
- }
4130
- get position() {
4131
- return this.options.position;
4132
- }
4133
- get panel() {
4134
- return this.options.panel;
4135
- }
4136
- get group() {
4137
- return this.options.group;
4138
- }
4139
- get api() {
4140
- return this.options.api;
4141
- }
4142
- constructor(options) {
4143
- super();
4144
- this.options = options;
4145
- }
4146
- getData() {
4147
- return this.options.getData();
4148
- }
4149
- }
4150
- class DockviewWillDropEvent extends DockviewDidDropEvent {
4151
- get kind() {
4152
- return this._kind;
4153
- }
4154
- constructor(options) {
4155
- super(options);
4156
- this._kind = options.kind;
4157
- }
4158
- }
4159
- class WillShowOverlayLocationEvent {
4160
- get kind() {
4161
- return this._kind;
4162
- }
4163
- get nativeEvent() {
4164
- return this.event.nativeEvent;
4165
- }
4166
- get position() {
4167
- return this.event.position;
4168
- }
4169
- get defaultPrevented() {
4170
- return this.event.defaultPrevented;
4171
- }
4172
- preventDefault() {
4173
- this.event.preventDefault();
4174
- }
4175
- constructor(event, options) {
4176
- this.event = event;
4177
- this._kind = options.kind;
4178
- }
4179
- }
4180
- class DockviewGroupPanelModel extends CompositeDisposable {
4181
- get element() {
4182
- throw new Error('not supported');
4183
- }
4184
- get activePanel() {
4185
- return this._activePanel;
4186
- }
4187
- get locked() {
4188
- return this._locked;
4189
- }
4190
- set locked(value) {
4191
- this._locked = value;
4192
- toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
4193
- }
4194
- get isActive() {
4195
- return this._isGroupActive;
4196
4202
  }
4197
- get panels() {
4198
- return this._panels;
4199
- }
4200
- get size() {
4201
- return this._panels.length;
4202
- }
4203
- get isEmpty() {
4204
- return this._panels.length === 0;
4205
- }
4206
- get hasWatermark() {
4207
- return !!(this.watermark && this.container.contains(this.watermark.element));
4208
- }
4209
- get header() {
4210
- return this.tabsContainer;
4211
- }
4212
- get isContentFocused() {
4213
- if (!document.activeElement) {
4214
- return false;
4215
- }
4216
- return isAncestor(document.activeElement, this.contentContainer.element);
4203
+ toJSON() {
4204
+ const params = this._params;
4205
+ return Object.assign(Object.assign({}, super.toJSON()), { headerComponent: this.headerComponent, title: params.title });
4217
4206
  }
4218
- get location() {
4219
- return this._location;
4207
+ renderOnce() {
4208
+ this.header = document.createElement('div');
4209
+ this.header.tabIndex = 0;
4210
+ this.header.className = 'pane-header';
4211
+ this.header.style.height = `${this.headerSize}px`;
4212
+ this.header.style.lineHeight = `${this.headerSize}px`;
4213
+ this.header.style.minHeight = `${this.headerSize}px`;
4214
+ this.header.style.maxHeight = `${this.headerSize}px`;
4215
+ this.element.appendChild(this.header);
4216
+ this.body = document.createElement('div');
4217
+ this.body.className = 'pane-body';
4218
+ this.element.appendChild(this.body);
4220
4219
  }
4221
- set location(value) {
4222
- this._location = value;
4223
- toggleClass(this.container, 'dv-groupview-floating', false);
4224
- toggleClass(this.container, 'dv-groupview-popout', false);
4225
- switch (value.type) {
4226
- case 'grid':
4227
- this.contentContainer.dropTarget.setTargetZones([
4228
- 'top',
4229
- 'bottom',
4230
- 'left',
4231
- 'right',
4232
- 'center',
4233
- ]);
4234
- break;
4235
- case 'floating':
4236
- this.contentContainer.dropTarget.setTargetZones(['center']);
4237
- this.contentContainer.dropTarget.setTargetZones(value
4238
- ? ['center']
4239
- : ['top', 'bottom', 'left', 'right', 'center']);
4240
- toggleClass(this.container, 'dv-groupview-floating', true);
4241
- break;
4242
- case 'popout':
4243
- this.contentContainer.dropTarget.setTargetZones(['center']);
4244
- toggleClass(this.container, 'dv-groupview-popout', true);
4245
- break;
4246
- }
4247
- this.groupPanel.api._onDidLocationChange.fire({
4248
- location: this.location,
4249
- });
4220
+ // TODO slightly hacky by-pass of the component to create a body and header component
4221
+ getComponent() {
4222
+ return {
4223
+ update: (params) => {
4224
+ var _a, _b;
4225
+ (_a = this.bodyPart) === null || _a === void 0 ? void 0 : _a.update({ params });
4226
+ (_b = this.headerPart) === null || _b === void 0 ? void 0 : _b.update({ params });
4227
+ },
4228
+ dispose: () => {
4229
+ var _a, _b;
4230
+ (_a = this.bodyPart) === null || _a === void 0 ? void 0 : _a.dispose();
4231
+ (_b = this.headerPart) === null || _b === void 0 ? void 0 : _b.dispose();
4232
+ },
4233
+ };
4250
4234
  }
4251
- constructor(container, accessor, id, options, groupPanel) {
4252
- var _a;
4253
- super();
4254
- this.container = container;
4235
+ }
4236
+
4237
+ class DraggablePaneviewPanel extends PaneviewPanel {
4238
+ constructor(accessor, id, component, headerComponent, orientation, isExpanded, disableDnd) {
4239
+ super(id, component, headerComponent, orientation, isExpanded, true);
4255
4240
  this.accessor = accessor;
4256
- this.id = id;
4257
- this.options = options;
4258
- this.groupPanel = groupPanel;
4259
- this._isGroupActive = false;
4260
- this._locked = false;
4261
- this._location = { type: 'grid' };
4262
- this.mostRecentlyUsed = [];
4263
- this._onDidChange = new Emitter();
4264
- this.onDidChange = this._onDidChange.event;
4265
- this._width = 0;
4266
- this._height = 0;
4267
- this._panels = [];
4268
- this._panelDisposables = new Map();
4269
- this._onMove = new Emitter();
4270
- this.onMove = this._onMove.event;
4271
4241
  this._onDidDrop = new Emitter();
4272
4242
  this.onDidDrop = this._onDidDrop.event;
4273
- this._onWillDrop = new Emitter();
4274
- this.onWillDrop = this._onWillDrop.event;
4275
- this._onWillShowOverlay = new Emitter();
4276
- this.onWillShowOverlay = this._onWillShowOverlay.event;
4277
- this._onTabDragStart = new Emitter();
4278
- this.onTabDragStart = this._onTabDragStart.event;
4279
- this._onGroupDragStart = new Emitter();
4280
- this.onGroupDragStart = this._onGroupDragStart.event;
4281
- this._onDidAddPanel = new Emitter();
4282
- this.onDidAddPanel = this._onDidAddPanel.event;
4283
- this._onDidPanelTitleChange = new Emitter();
4284
- this.onDidPanelTitleChange = this._onDidPanelTitleChange.event;
4285
- this._onDidPanelParametersChange = new Emitter();
4286
- this.onDidPanelParametersChange = this._onDidPanelParametersChange.event;
4287
- this._onDidRemovePanel = new Emitter();
4288
- this.onDidRemovePanel = this._onDidRemovePanel.event;
4289
- this._onDidActivePanelChange = new Emitter();
4290
- this.onDidActivePanelChange = this._onDidActivePanelChange.event;
4291
- this._overwriteRenderContainer = null;
4292
- toggleClass(this.container, 'groupview', true);
4293
- this._api = new DockviewApi(this.accessor);
4294
- this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
4295
- this.contentContainer = new ContentContainer(this.accessor, this);
4296
- container.append(this.tabsContainer.element, this.contentContainer.element);
4297
- this.header.hidden = !!options.hideHeader;
4298
- this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
4299
- this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
4300
- this._onTabDragStart.fire(event);
4301
- }), this.tabsContainer.onGroupDragStart((event) => {
4302
- this._onGroupDragStart.fire(event);
4303
- }), this.tabsContainer.onDrop((event) => {
4304
- this.handleDropEvent('header', event.event, 'center', event.index);
4305
- }), this.contentContainer.onDidFocus(() => {
4306
- this.accessor.doSetGroupActive(this.groupPanel);
4307
- }), this.contentContainer.onDidBlur(() => {
4308
- // noop
4309
- }), this.contentContainer.dropTarget.onDrop((event) => {
4310
- this.handleDropEvent('content', event.nativeEvent, event.position);
4311
- }), this.tabsContainer.onWillShowOverlay((event) => {
4312
- this._onWillShowOverlay.fire(event);
4313
- }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
4314
- this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4315
- kind: 'content',
4316
- }));
4317
- }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4318
- }
4319
- focusContent() {
4320
- this.contentContainer.element.focus();
4243
+ if (!disableDnd) {
4244
+ this.initDragFeatures();
4245
+ }
4321
4246
  }
4322
- set renderContainer(value) {
4323
- this.panels.forEach((panel) => {
4324
- this.renderContainer.detatch(panel);
4325
- });
4326
- this._overwriteRenderContainer = value;
4327
- this.panels.forEach((panel) => {
4328
- this.rerender(panel);
4247
+ initDragFeatures() {
4248
+ if (!this.header) {
4249
+ return;
4250
+ }
4251
+ const id = this.id;
4252
+ const accessorId = this.accessor.id;
4253
+ this.header.draggable = true;
4254
+ this.handler = new (class PaneDragHandler extends DragHandler {
4255
+ getData() {
4256
+ LocalSelectionTransfer.getInstance().setData([new PaneTransfer(accessorId, id)], PaneTransfer.prototype);
4257
+ return {
4258
+ dispose: () => {
4259
+ LocalSelectionTransfer.getInstance().clearData(PaneTransfer.prototype);
4260
+ },
4261
+ };
4262
+ }
4263
+ })(this.header);
4264
+ this.target = new Droptarget(this.element, {
4265
+ acceptedTargetZones: ['top', 'bottom'],
4266
+ overlayModel: {
4267
+ activationSize: { type: 'percentage', value: 50 },
4268
+ },
4269
+ canDisplayOverlay: (event) => {
4270
+ const data = getPaneData();
4271
+ if (data) {
4272
+ if (data.paneId !== this.id &&
4273
+ data.viewId === this.accessor.id) {
4274
+ return true;
4275
+ }
4276
+ }
4277
+ if (this.accessor.options.showDndOverlay) {
4278
+ return this.accessor.options.showDndOverlay({
4279
+ nativeEvent: event,
4280
+ getData: getPaneData,
4281
+ panel: this,
4282
+ });
4283
+ }
4284
+ return false;
4285
+ },
4329
4286
  });
4287
+ this.addDisposables(this._onDidDrop, this.handler, this.target, this.target.onDrop((event) => {
4288
+ this.onDrop(event);
4289
+ }));
4330
4290
  }
4331
- get renderContainer() {
4332
- var _a;
4333
- return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
4334
- }
4335
- initialize() {
4336
- if (this.options.panels) {
4337
- this.options.panels.forEach((panel) => {
4338
- this.doAddPanel(panel);
4339
- });
4340
- }
4341
- if (this.options.activePanel) {
4342
- this.openPanel(this.options.activePanel);
4291
+ onDrop(event) {
4292
+ const data = getPaneData();
4293
+ if (!data || data.viewId !== this.accessor.id) {
4294
+ // if there is no local drag event for this panel
4295
+ // or if the drag event was creating by another Paneview instance
4296
+ this._onDidDrop.fire(Object.assign(Object.assign({}, event), { panel: this, api: new PaneviewApi(this.accessor), getData: getPaneData }));
4297
+ return;
4343
4298
  }
4344
- // must be run after the constructor otherwise this.parent may not be
4345
- // correctly initialized
4346
- this.setActive(this.isActive, true);
4347
- this.updateContainer();
4348
- if (this.accessor.options.createRightHeaderActionsElement) {
4349
- this._rightHeaderActions =
4350
- this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
4351
- this.addDisposables(this._rightHeaderActions);
4352
- this._rightHeaderActions.init({
4353
- containerApi: this._api,
4354
- api: this.groupPanel.api,
4355
- });
4356
- this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
4299
+ const containerApi = this._params
4300
+ .containerApi;
4301
+ const panelId = data.paneId;
4302
+ const existingPanel = containerApi.getPanel(panelId);
4303
+ if (!existingPanel) {
4304
+ // if the panel doesn't exist
4305
+ this._onDidDrop.fire(Object.assign(Object.assign({}, event), { panel: this, getData: getPaneData, api: new PaneviewApi(this.accessor) }));
4306
+ return;
4357
4307
  }
4358
- if (this.accessor.options.createLeftHeaderActionsElement) {
4359
- this._leftHeaderActions =
4360
- this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
4361
- this.addDisposables(this._leftHeaderActions);
4362
- this._leftHeaderActions.init({
4363
- containerApi: this._api,
4364
- api: this.groupPanel.api,
4365
- });
4366
- this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
4308
+ const allPanels = containerApi.panels;
4309
+ const fromIndex = allPanels.indexOf(existingPanel);
4310
+ let toIndex = containerApi.panels.indexOf(this);
4311
+ if (event.position === 'left' || event.position === 'top') {
4312
+ toIndex = Math.max(0, toIndex - 1);
4367
4313
  }
4368
- if (this.accessor.options.createPrefixHeaderActionsElement) {
4369
- this._prefixHeaderActions =
4370
- this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
4371
- this.addDisposables(this._prefixHeaderActions);
4372
- this._prefixHeaderActions.init({
4373
- containerApi: this._api,
4374
- api: this.groupPanel.api,
4375
- });
4376
- this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
4314
+ if (event.position === 'right' || event.position === 'bottom') {
4315
+ if (fromIndex > toIndex) {
4316
+ toIndex++;
4317
+ }
4318
+ toIndex = Math.min(allPanels.length - 1, toIndex);
4377
4319
  }
4320
+ containerApi.movePanel(fromIndex, toIndex);
4378
4321
  }
4379
- rerender(panel) {
4380
- this.contentContainer.renderPanel(panel, { asActive: false });
4381
- }
4382
- indexOf(panel) {
4383
- return this.tabsContainer.indexOf(panel.id);
4322
+ }
4323
+
4324
+ class ContentContainer extends CompositeDisposable {
4325
+ get element() {
4326
+ return this._element;
4384
4327
  }
4385
- toJSON() {
4386
- var _a;
4387
- const result = {
4388
- views: this.tabsContainer.panels,
4389
- activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
4390
- id: this.id,
4391
- };
4392
- if (this.locked !== false) {
4393
- result.locked = this.locked;
4394
- }
4395
- if (this.header.hidden) {
4396
- result.hideHeader = true;
4397
- }
4398
- return result;
4328
+ constructor(accessor, group) {
4329
+ super();
4330
+ this.accessor = accessor;
4331
+ this.group = group;
4332
+ this.disposable = new MutableDisposable();
4333
+ this._onDidFocus = new Emitter();
4334
+ this.onDidFocus = this._onDidFocus.event;
4335
+ this._onDidBlur = new Emitter();
4336
+ this.onDidBlur = this._onDidBlur.event;
4337
+ this._element = document.createElement('div');
4338
+ this._element.className = 'content-container';
4339
+ this._element.tabIndex = -1;
4340
+ this.addDisposables(this._onDidFocus, this._onDidBlur);
4341
+ this.dropTarget = new Droptarget(this.element, {
4342
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
4343
+ canDisplayOverlay: (event, position) => {
4344
+ if (this.group.locked === 'no-drop-target' ||
4345
+ (this.group.locked && position === 'center')) {
4346
+ return false;
4347
+ }
4348
+ const data = getPanelData();
4349
+ if (!data &&
4350
+ event.shiftKey &&
4351
+ this.group.location.type !== 'floating') {
4352
+ return false;
4353
+ }
4354
+ if (data && data.viewId === this.accessor.id) {
4355
+ if (data.groupId === this.group.id) {
4356
+ if (position === 'center') {
4357
+ // don't allow to drop on self for center position
4358
+ return false;
4359
+ }
4360
+ if (data.panelId === null) {
4361
+ // don't allow group move to drop anywhere on self
4362
+ return false;
4363
+ }
4364
+ }
4365
+ const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
4366
+ data.groupId === this.group.id;
4367
+ return !groupHasOnePanelAndIsActiveDragElement;
4368
+ }
4369
+ return this.group.canDisplayOverlay(event, position, 'content');
4370
+ },
4371
+ });
4372
+ this.addDisposables(this.dropTarget);
4399
4373
  }
4400
- moveToNext(options) {
4401
- if (!options) {
4402
- options = {};
4403
- }
4404
- if (!options.panel) {
4405
- options.panel = this.activePanel;
4406
- }
4407
- const index = options.panel ? this.panels.indexOf(options.panel) : -1;
4408
- let normalizedIndex;
4409
- if (index < this.panels.length - 1) {
4410
- normalizedIndex = index + 1;
4374
+ show() {
4375
+ this.element.style.display = '';
4376
+ }
4377
+ hide() {
4378
+ this.element.style.display = 'none';
4379
+ }
4380
+ renderPanel(panel, options = { asActive: true }) {
4381
+ const doRender = options.asActive ||
4382
+ (this.panel && this.group.isPanelActive(this.panel));
4383
+ if (this.panel &&
4384
+ this.panel.view.content.element.parentElement === this._element) {
4385
+ /**
4386
+ * If the currently attached panel is mounted directly to the content then remove it
4387
+ */
4388
+ this._element.removeChild(this.panel.view.content.element);
4411
4389
  }
4412
- else if (!options.suppressRoll) {
4413
- normalizedIndex = 0;
4390
+ this.panel = panel;
4391
+ let container;
4392
+ switch (panel.api.renderer) {
4393
+ case 'onlyWhenVisible':
4394
+ this.group.renderContainer.detatch(panel);
4395
+ if (this.panel) {
4396
+ if (doRender) {
4397
+ this._element.appendChild(this.panel.view.content.element);
4398
+ }
4399
+ }
4400
+ container = this._element;
4401
+ break;
4402
+ case 'always':
4403
+ if (panel.view.content.element.parentElement === this._element) {
4404
+ this._element.removeChild(panel.view.content.element);
4405
+ }
4406
+ container = this.group.renderContainer.attach({
4407
+ panel,
4408
+ referenceContainer: this,
4409
+ });
4410
+ break;
4414
4411
  }
4415
- else {
4416
- return;
4412
+ if (doRender) {
4413
+ const focusTracker = trackFocus(container);
4414
+ const disposable = new CompositeDisposable();
4415
+ disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
4416
+ this.disposable.value = disposable;
4417
4417
  }
4418
- this.openPanel(this.panels[normalizedIndex]);
4419
4418
  }
4420
- moveToPrevious(options) {
4421
- if (!options) {
4422
- options = {};
4423
- }
4424
- if (!options.panel) {
4425
- options.panel = this.activePanel;
4426
- }
4427
- if (!options.panel) {
4419
+ openPanel(panel) {
4420
+ if (this.panel === panel) {
4428
4421
  return;
4429
4422
  }
4430
- const index = this.panels.indexOf(options.panel);
4431
- let normalizedIndex;
4432
- if (index > 0) {
4433
- normalizedIndex = index - 1;
4434
- }
4435
- else if (!options.suppressRoll) {
4436
- normalizedIndex = this.panels.length - 1;
4437
- }
4438
- else {
4439
- return;
4423
+ this.renderPanel(panel);
4424
+ }
4425
+ layout(_width, _height) {
4426
+ // noop
4427
+ }
4428
+ closePanel() {
4429
+ var _a;
4430
+ if (this.panel) {
4431
+ if (this.panel.api.renderer === 'onlyWhenVisible') {
4432
+ (_a = this.panel.view.content.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.panel.view.content.element);
4433
+ }
4440
4434
  }
4441
- this.openPanel(this.panels[normalizedIndex]);
4435
+ this.panel = undefined;
4442
4436
  }
4443
- containsPanel(panel) {
4444
- return this.panels.includes(panel);
4437
+ dispose() {
4438
+ this.disposable.dispose();
4439
+ super.dispose();
4445
4440
  }
4446
- init(_params) {
4447
- //noop
4441
+ }
4442
+
4443
+ class TabDragHandler extends DragHandler {
4444
+ constructor(element, accessor, group, panel) {
4445
+ super(element);
4446
+ this.accessor = accessor;
4447
+ this.group = group;
4448
+ this.panel = panel;
4449
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
4448
4450
  }
4449
- update(_params) {
4450
- //noop
4451
+ getData(event) {
4452
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
4453
+ return {
4454
+ dispose: () => {
4455
+ this.panelTransfer.clearData(PanelTransfer.prototype);
4456
+ },
4457
+ };
4451
4458
  }
4452
- focus() {
4453
- var _a;
4454
- (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus();
4459
+ }
4460
+ class Tab extends CompositeDisposable {
4461
+ get element() {
4462
+ return this._element;
4455
4463
  }
4456
- openPanel(panel, options = {}) {
4457
- /**
4458
- * set the panel group
4459
- * add the panel
4460
- * check if group active
4461
- * check if panel active
4462
- */
4463
- if (typeof options.index !== 'number' ||
4464
- options.index > this.panels.length) {
4465
- options.index = this.panels.length;
4466
- }
4467
- const skipSetActive = !!options.skipSetActive;
4468
- // ensure the group is updated before we fire any events
4469
- panel.updateParentGroup(this.groupPanel, {
4470
- skipSetActive: options.skipSetActive,
4471
- });
4472
- this.doAddPanel(panel, options.index, {
4473
- skipSetActive: skipSetActive,
4464
+ constructor(panel, accessor, group) {
4465
+ super();
4466
+ this.panel = panel;
4467
+ this.accessor = accessor;
4468
+ this.group = group;
4469
+ this.content = undefined;
4470
+ this._onChanged = new Emitter();
4471
+ this.onChanged = this._onChanged.event;
4472
+ this._onDropped = new Emitter();
4473
+ this.onDrop = this._onDropped.event;
4474
+ this._onDragStart = new Emitter();
4475
+ this.onDragStart = this._onDragStart.event;
4476
+ this._element = document.createElement('div');
4477
+ this._element.className = 'tab';
4478
+ this._element.tabIndex = 0;
4479
+ this._element.draggable = true;
4480
+ toggleClass(this.element, 'inactive-tab', true);
4481
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
4482
+ this.dropTarget = new Droptarget(this._element, {
4483
+ acceptedTargetZones: ['center'],
4484
+ canDisplayOverlay: (event, position) => {
4485
+ if (this.group.locked) {
4486
+ return false;
4487
+ }
4488
+ const data = getPanelData();
4489
+ if (data && this.accessor.id === data.viewId) {
4490
+ if (data.panelId === null &&
4491
+ data.groupId === this.group.id) {
4492
+ // don't allow group move to drop on self
4493
+ return false;
4494
+ }
4495
+ return this.panel.id !== data.panelId;
4496
+ }
4497
+ return this.group.model.canDisplayOverlay(event, position, 'tab');
4498
+ },
4474
4499
  });
4475
- if (this._activePanel === panel) {
4476
- this.contentContainer.renderPanel(panel, { asActive: true });
4477
- return;
4478
- }
4479
- if (!skipSetActive) {
4480
- this.doSetActivePanel(panel);
4481
- }
4482
- if (!options.skipSetGroupActive) {
4483
- this.accessor.doSetGroupActive(this.groupPanel);
4484
- }
4485
- if (!options.skipSetActive) {
4486
- this.updateContainer();
4487
- }
4500
+ this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
4501
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
4502
+ this._onDragStart.fire(event);
4503
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
4504
+ if (event.defaultPrevented) {
4505
+ return;
4506
+ }
4507
+ this._onChanged.fire(event);
4508
+ }), this.dropTarget.onDrop((event) => {
4509
+ this._onDropped.fire(event);
4510
+ }), this.dropTarget);
4488
4511
  }
4489
- removePanel(groupItemOrId, options = {
4490
- skipSetActive: false,
4491
- }) {
4492
- const id = typeof groupItemOrId === 'string'
4493
- ? groupItemOrId
4494
- : groupItemOrId.id;
4495
- const panelToRemove = this._panels.find((panel) => panel.id === id);
4496
- if (!panelToRemove) {
4497
- throw new Error('invalid operation');
4512
+ setActive(isActive) {
4513
+ toggleClass(this.element, 'active-tab', isActive);
4514
+ toggleClass(this.element, 'inactive-tab', !isActive);
4515
+ }
4516
+ setContent(part) {
4517
+ if (this.content) {
4518
+ this._element.removeChild(this.content.element);
4498
4519
  }
4499
- return this._removePanel(panelToRemove, options);
4520
+ this.content = part;
4521
+ this._element.appendChild(this.content.element);
4500
4522
  }
4501
- closeAllPanels() {
4502
- if (this.panels.length > 0) {
4503
- // take a copy since we will be edting the array as we iterate through
4504
- const arrPanelCpy = [...this.panels];
4505
- for (const panel of arrPanelCpy) {
4506
- this.doClose(panel);
4523
+ dispose() {
4524
+ super.dispose();
4525
+ }
4526
+ }
4527
+
4528
+ function addGhostImage(dataTransfer, ghostElement) {
4529
+ // class dockview provides to force ghost image to be drawn on a different layer and prevent weird rendering issues
4530
+ addClasses(ghostElement, 'dv-dragged');
4531
+ document.body.appendChild(ghostElement);
4532
+ dataTransfer.setDragImage(ghostElement, 0, 0);
4533
+ setTimeout(() => {
4534
+ removeClasses(ghostElement, 'dv-dragged');
4535
+ ghostElement.remove();
4536
+ }, 0);
4537
+ }
4538
+
4539
+ class GroupDragHandler extends DragHandler {
4540
+ constructor(element, accessor, group) {
4541
+ super(element);
4542
+ this.accessor = accessor;
4543
+ this.group = group;
4544
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
4545
+ this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
4546
+ if (e.shiftKey) {
4547
+ /**
4548
+ * You cannot call e.preventDefault() because that will prevent drag events from firing
4549
+ * but we also need to stop any group overlay drag events from occuring
4550
+ * Use a custom event marker that can be checked by the overlay drag events
4551
+ */
4552
+ quasiPreventDefault(e);
4507
4553
  }
4508
- }
4509
- else {
4510
- this.accessor.removeGroup(this.groupPanel);
4511
- }
4512
- }
4513
- closePanel(panel) {
4514
- this.doClose(panel);
4515
- }
4516
- doClose(panel) {
4517
- this.accessor.removePanel(panel);
4518
- }
4519
- isPanelActive(panel) {
4520
- return this._activePanel === panel;
4521
- }
4522
- updateActions(element) {
4523
- this.tabsContainer.setRightActionsElement(element);
4554
+ }, true));
4524
4555
  }
4525
- setActive(isGroupActive, force = false) {
4526
- if (!force && this.isActive === isGroupActive) {
4527
- return;
4528
- }
4529
- this._isGroupActive = isGroupActive;
4530
- toggleClass(this.container, 'active-group', isGroupActive);
4531
- toggleClass(this.container, 'inactive-group', !isGroupActive);
4532
- this.tabsContainer.setActive(this.isActive);
4533
- if (!this._activePanel && this.panels.length > 0) {
4534
- this.doSetActivePanel(this.panels[0]);
4556
+ isCancelled(_event) {
4557
+ if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
4558
+ return true;
4535
4559
  }
4536
- this.updateContainer();
4560
+ return false;
4537
4561
  }
4538
- layout(width, height) {
4539
- var _a;
4540
- this._width = width;
4541
- this._height = height;
4542
- this.contentContainer.layout(this._width, this._height);
4543
- if ((_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.layout) {
4544
- this._activePanel.layout(this._width, this._height);
4562
+ getData(dragEvent) {
4563
+ const dataTransfer = dragEvent.dataTransfer;
4564
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
4565
+ const style = window.getComputedStyle(this.el);
4566
+ const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
4567
+ const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
4568
+ if (dataTransfer) {
4569
+ const ghostElement = document.createElement('div');
4570
+ ghostElement.style.backgroundColor = bgColor;
4571
+ ghostElement.style.color = color;
4572
+ ghostElement.style.padding = '2px 8px';
4573
+ ghostElement.style.height = '24px';
4574
+ ghostElement.style.fontSize = '11px';
4575
+ ghostElement.style.lineHeight = '20px';
4576
+ ghostElement.style.borderRadius = '12px';
4577
+ ghostElement.style.position = 'absolute';
4578
+ ghostElement.textContent = `Multiple Panels (${this.group.size})`;
4579
+ addGhostImage(dataTransfer, ghostElement);
4545
4580
  }
4581
+ return {
4582
+ dispose: () => {
4583
+ this.panelTransfer.clearData(PanelTransfer.prototype);
4584
+ },
4585
+ };
4546
4586
  }
4547
- _removePanel(panel, options) {
4548
- const isActivePanel = this._activePanel === panel;
4549
- this.doRemovePanel(panel);
4550
- if (isActivePanel && this.panels.length > 0) {
4551
- const nextPanel = this.mostRecentlyUsed[0];
4552
- this.openPanel(nextPanel, {
4553
- skipSetActive: options.skipSetActive,
4554
- skipSetGroupActive: options.skipSetActiveGroup,
4555
- });
4556
- }
4557
- if (this._activePanel && this.panels.length === 0) {
4558
- this.doSetActivePanel(undefined);
4559
- }
4560
- if (!options.skipSetActive) {
4561
- this.updateContainer();
4562
- }
4563
- return panel;
4587
+ }
4588
+
4589
+ class VoidContainer extends CompositeDisposable {
4590
+ get element() {
4591
+ return this._element;
4564
4592
  }
4565
- doRemovePanel(panel) {
4566
- const index = this.panels.indexOf(panel);
4567
- if (this._activePanel === panel) {
4568
- this.contentContainer.closePanel();
4569
- }
4570
- this.tabsContainer.delete(panel.id);
4571
- this._panels.splice(index, 1);
4572
- if (this.mostRecentlyUsed.includes(panel)) {
4573
- this.mostRecentlyUsed.splice(this.mostRecentlyUsed.indexOf(panel), 1);
4574
- }
4575
- const disposable = this._panelDisposables.get(panel.id);
4576
- if (disposable) {
4577
- disposable.dispose();
4578
- this._panelDisposables.delete(panel.id);
4579
- }
4580
- this._onDidRemovePanel.fire({ panel });
4593
+ constructor(accessor, group) {
4594
+ super();
4595
+ this.accessor = accessor;
4596
+ this.group = group;
4597
+ this._onDrop = new Emitter();
4598
+ this.onDrop = this._onDrop.event;
4599
+ this._onDragStart = new Emitter();
4600
+ this.onDragStart = this._onDragStart.event;
4601
+ this._element = document.createElement('div');
4602
+ this._element.className = 'void-container';
4603
+ this._element.tabIndex = 0;
4604
+ this._element.draggable = true;
4605
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
4606
+ this.accessor.doSetGroupActive(this.group);
4607
+ }));
4608
+ const handler = new GroupDragHandler(this._element, accessor, group);
4609
+ this.dropTraget = new Droptarget(this._element, {
4610
+ acceptedTargetZones: ['center'],
4611
+ canDisplayOverlay: (event, position) => {
4612
+ var _a;
4613
+ const data = getPanelData();
4614
+ if (data && this.accessor.id === data.viewId) {
4615
+ if (data.panelId === null &&
4616
+ data.groupId === this.group.id) {
4617
+ // don't allow group move to drop on self
4618
+ return false;
4619
+ }
4620
+ // don't show the overlay if the tab being dragged is the last panel of this group
4621
+ return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
4622
+ }
4623
+ return group.model.canDisplayOverlay(event, position, 'header_space');
4624
+ },
4625
+ });
4626
+ this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
4627
+ this.addDisposables(handler, handler.onDragStart((event) => {
4628
+ this._onDragStart.fire(event);
4629
+ }), this.dropTraget.onDrop((event) => {
4630
+ this._onDrop.fire(event);
4631
+ }), this.dropTraget);
4581
4632
  }
4582
- doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
4583
- const existingPanel = this._panels.indexOf(panel);
4584
- const hasExistingPanel = existingPanel > -1;
4585
- this.tabsContainer.show();
4586
- this.contentContainer.show();
4587
- this.tabsContainer.openPanel(panel, index);
4588
- if (!options.skipSetActive) {
4589
- this.contentContainer.openPanel(panel);
4590
- }
4591
- if (hasExistingPanel) {
4592
- // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
4593
- return;
4594
- }
4595
- this.updateMru(panel);
4596
- this.panels.splice(index, 0, panel);
4597
- this._panelDisposables.set(panel.id, new CompositeDisposable(panel.api.onDidTitleChange((event) => this._onDidPanelTitleChange.fire(event)), panel.api.onDidParametersChange((event) => this._onDidPanelParametersChange.fire(event))));
4598
- this._onDidAddPanel.fire({ panel });
4633
+ }
4634
+
4635
+ class TabsContainer extends CompositeDisposable {
4636
+ get panels() {
4637
+ return this.tabs.map((_) => _.value.panel.id);
4599
4638
  }
4600
- doSetActivePanel(panel) {
4601
- if (this._activePanel === panel) {
4602
- return;
4603
- }
4604
- this._activePanel = panel;
4605
- if (panel) {
4606
- this.tabsContainer.setActivePanel(panel);
4607
- panel.layout(this._width, this._height);
4608
- this.updateMru(panel);
4609
- this._onDidActivePanelChange.fire({
4610
- panel,
4611
- });
4612
- }
4639
+ get size() {
4640
+ return this.tabs.length;
4613
4641
  }
4614
- updateMru(panel) {
4615
- if (this.mostRecentlyUsed.includes(panel)) {
4616
- this.mostRecentlyUsed.splice(this.mostRecentlyUsed.indexOf(panel), 1);
4617
- }
4618
- this.mostRecentlyUsed = [panel, ...this.mostRecentlyUsed];
4642
+ get hidden() {
4643
+ return this._hidden;
4619
4644
  }
4620
- updateContainer() {
4621
- var _a, _b;
4622
- toggleClass(this.container, 'empty', this.isEmpty);
4623
- this.panels.forEach((panel) => panel.runEvents());
4624
- if (this.isEmpty && !this.watermark) {
4625
- const watermark = this.accessor.createWatermarkComponent();
4626
- watermark.init({
4627
- containerApi: this._api,
4628
- group: this.groupPanel,
4629
- });
4630
- this.watermark = watermark;
4631
- addDisposableListener(this.watermark.element, 'click', () => {
4632
- if (!this.isActive) {
4633
- this.accessor.doSetGroupActive(this.groupPanel);
4634
- }
4635
- });
4636
- this.tabsContainer.hide();
4637
- this.contentContainer.element.appendChild(this.watermark.element);
4638
- this.watermark.updateParentGroup(this.groupPanel, true);
4639
- }
4640
- if (!this.isEmpty && this.watermark) {
4641
- this.watermark.element.remove();
4642
- (_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
4643
- this.watermark = undefined;
4644
- this.tabsContainer.show();
4645
- }
4645
+ set hidden(value) {
4646
+ this._hidden = value;
4647
+ this.element.style.display = value ? 'none' : '';
4646
4648
  }
4647
- canDisplayOverlay(event, position, target) {
4648
- // custom overlay handler
4649
- if (this.accessor.options.showDndOverlay) {
4650
- return this.accessor.options.showDndOverlay({
4651
- nativeEvent: event,
4652
- target,
4653
- group: this.accessor.getPanel(this.id),
4654
- position,
4655
- getData: getPanelData,
4656
- });
4649
+ show() {
4650
+ if (!this.hidden) {
4651
+ this.element.style.display = '';
4657
4652
  }
4658
- return false;
4659
4653
  }
4660
- handleDropEvent(type, event, position, index) {
4661
- if (this.locked === 'no-drop-target') {
4654
+ hide() {
4655
+ this._element.style.display = 'none';
4656
+ }
4657
+ setRightActionsElement(element) {
4658
+ if (this.rightActions === element) {
4662
4659
  return;
4663
4660
  }
4664
- function getKind() {
4665
- switch (type) {
4666
- case 'header':
4667
- return typeof index === 'number' ? 'tab' : 'header_space';
4668
- case 'content':
4669
- return 'content';
4670
- }
4661
+ if (this.rightActions) {
4662
+ this.rightActions.remove();
4663
+ this.rightActions = undefined;
4671
4664
  }
4672
- const panel = typeof index === 'number' ? this.panels[index] : undefined;
4673
- const willDropEvent = new DockviewWillDropEvent({
4674
- nativeEvent: event,
4675
- position,
4676
- panel,
4677
- getData: () => getPanelData(),
4678
- kind: getKind(),
4679
- group: this.groupPanel,
4680
- api: this._api,
4681
- });
4682
- this._onWillDrop.fire(willDropEvent);
4683
- if (willDropEvent.defaultPrevented) {
4665
+ if (element) {
4666
+ this.rightActionsContainer.appendChild(element);
4667
+ this.rightActions = element;
4668
+ }
4669
+ }
4670
+ setLeftActionsElement(element) {
4671
+ if (this.leftActions === element) {
4684
4672
  return;
4685
4673
  }
4686
- const data = getPanelData();
4687
- if (data && data.viewId === this.accessor.id) {
4688
- if (data.panelId === null) {
4689
- // this is a group move dnd event
4690
- const { groupId } = data;
4691
- this._onMove.fire({
4692
- target: position,
4693
- groupId: groupId,
4694
- index,
4695
- });
4696
- return;
4697
- }
4698
- const fromSameGroup = this.tabsContainer.indexOf(data.panelId) !== -1;
4699
- if (fromSameGroup && this.tabsContainer.size === 1) {
4700
- return;
4701
- }
4702
- const { groupId, panelId } = data;
4703
- const isSameGroup = this.id === groupId;
4704
- if (isSameGroup && !position) {
4705
- const oldIndex = this.tabsContainer.indexOf(panelId);
4706
- if (oldIndex === index) {
4707
- return;
4708
- }
4709
- }
4710
- this._onMove.fire({
4711
- target: position,
4712
- groupId: data.groupId,
4713
- itemId: data.panelId,
4714
- index,
4715
- });
4674
+ if (this.leftActions) {
4675
+ this.leftActions.remove();
4676
+ this.leftActions = undefined;
4716
4677
  }
4717
- else {
4718
- this._onDidDrop.fire(new DockviewDidDropEvent({
4719
- nativeEvent: event,
4720
- position,
4721
- panel,
4722
- getData: () => getPanelData(),
4723
- group: this.groupPanel,
4724
- api: this._api,
4725
- }));
4678
+ if (element) {
4679
+ this.leftActionsContainer.appendChild(element);
4680
+ this.leftActions = element;
4726
4681
  }
4727
4682
  }
4728
- dispose() {
4729
- var _a, _b, _c;
4730
- super.dispose();
4731
- (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
4732
- (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
4733
- this.watermark = undefined;
4734
- for (const panel of this.panels) {
4735
- panel.dispose();
4683
+ setPrefixActionsElement(element) {
4684
+ if (this.preActions === element) {
4685
+ return;
4686
+ }
4687
+ if (this.preActions) {
4688
+ this.preActions.remove();
4689
+ this.preActions = undefined;
4690
+ }
4691
+ if (element) {
4692
+ this.preActionsContainer.appendChild(element);
4693
+ this.preActions = element;
4736
4694
  }
4737
- this.tabsContainer.dispose();
4738
- this.contentContainer.dispose();
4739
4695
  }
4740
- }
4741
-
4742
- class Resizable extends CompositeDisposable {
4743
4696
  get element() {
4744
4697
  return this._element;
4745
4698
  }
4746
- get disableResizing() {
4747
- return this._disableResizing;
4699
+ isActive(tab) {
4700
+ return (this.selectedIndex > -1 &&
4701
+ this.tabs[this.selectedIndex].value === tab);
4748
4702
  }
4749
- set disableResizing(value) {
4750
- this._disableResizing = value;
4703
+ indexOf(id) {
4704
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
4751
4705
  }
4752
- constructor(parentElement, disableResizing = false) {
4706
+ constructor(accessor, group) {
4753
4707
  super();
4754
- this._disableResizing = disableResizing;
4755
- this._element = parentElement;
4756
- this.addDisposables(watchElementResize(this._element, (entry) => {
4757
- if (this.isDisposed) {
4758
- /**
4759
- * resize is delayed through requestAnimationFrame so there is a small chance
4760
- * the component has already been disposed of
4761
- */
4762
- return;
4708
+ this.accessor = accessor;
4709
+ this.group = group;
4710
+ this.tabs = [];
4711
+ this.selectedIndex = -1;
4712
+ this._hidden = false;
4713
+ this._onDrop = new Emitter();
4714
+ this.onDrop = this._onDrop.event;
4715
+ this._onTabDragStart = new Emitter();
4716
+ this.onTabDragStart = this._onTabDragStart.event;
4717
+ this._onGroupDragStart = new Emitter();
4718
+ this.onGroupDragStart = this._onGroupDragStart.event;
4719
+ this._onWillShowOverlay = new Emitter();
4720
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
4721
+ this._element = document.createElement('div');
4722
+ this._element.className = 'tabs-and-actions-container';
4723
+ toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
4724
+ this.rightActionsContainer = document.createElement('div');
4725
+ this.rightActionsContainer.className = 'right-actions-container';
4726
+ this.leftActionsContainer = document.createElement('div');
4727
+ this.leftActionsContainer.className = 'left-actions-container';
4728
+ this.preActionsContainer = document.createElement('div');
4729
+ this.preActionsContainer.className = 'pre-actions-container';
4730
+ this.tabContainer = document.createElement('div');
4731
+ this.tabContainer.className = 'tabs-container';
4732
+ this.voidContainer = new VoidContainer(this.accessor, this.group);
4733
+ this._element.appendChild(this.preActionsContainer);
4734
+ this._element.appendChild(this.tabContainer);
4735
+ this._element.appendChild(this.leftActionsContainer);
4736
+ this._element.appendChild(this.voidContainer.element);
4737
+ this._element.appendChild(this.rightActionsContainer);
4738
+ this.addDisposables(this.accessor.onDidAddPanel((e) => {
4739
+ if (e.api.group === this.group) {
4740
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
4763
4741
  }
4764
- if (this.disableResizing) {
4742
+ }), this.accessor.onDidRemovePanel((e) => {
4743
+ if (e.api.group === this.group) {
4744
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
4745
+ }
4746
+ }), this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
4747
+ this._onGroupDragStart.fire({
4748
+ nativeEvent: event,
4749
+ group: this.group,
4750
+ });
4751
+ }), this.voidContainer.onDrop((event) => {
4752
+ this._onDrop.fire({
4753
+ event: event.nativeEvent,
4754
+ index: this.tabs.length,
4755
+ });
4756
+ }), this.voidContainer.onWillShowOverlay((event) => {
4757
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4758
+ kind: 'header_space',
4759
+ panel: this.group.activePanel,
4760
+ api: this.accessor.api,
4761
+ group: this.group,
4762
+ getData: getPanelData,
4763
+ }));
4764
+ }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
4765
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
4766
+ if (isFloatingGroupsEnabled &&
4767
+ event.shiftKey &&
4768
+ this.group.api.location.type !== 'floating') {
4769
+ event.preventDefault();
4770
+ const { top, left } = this.element.getBoundingClientRect();
4771
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
4772
+ this.accessor.addFloatingGroup(this.group, {
4773
+ x: left - rootLeft + 20,
4774
+ y: top - rootTop + 20,
4775
+ }, { inDragMode: true });
4776
+ }
4777
+ }), addDisposableListener(this.tabContainer, 'mousedown', (event) => {
4778
+ if (event.defaultPrevented) {
4765
4779
  return;
4766
4780
  }
4767
- if (!this._element.offsetParent) {
4768
- /**
4769
- * offsetParent === null is equivalent to display: none being set on the element or one
4770
- * of it's parents. In the display: none case the size will become (0, 0) which we do
4771
- * not want to propagate.
4772
- *
4773
- * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
4774
- *
4775
- * You could use checkVisibility() but at the time of writing it's not supported across
4776
- * all Browsers
4777
- *
4778
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility
4779
- */
4781
+ const isLeftClick = event.button === 0;
4782
+ if (isLeftClick) {
4783
+ this.accessor.doSetGroupActive(this.group);
4784
+ }
4785
+ }));
4786
+ }
4787
+ setActive(_isGroupActive) {
4788
+ // noop
4789
+ }
4790
+ addTab(tab, index = this.tabs.length) {
4791
+ if (index < 0 || index > this.tabs.length) {
4792
+ throw new Error('invalid location');
4793
+ }
4794
+ this.tabContainer.insertBefore(tab.value.element, this.tabContainer.children[index]);
4795
+ this.tabs = [
4796
+ ...this.tabs.slice(0, index),
4797
+ tab,
4798
+ ...this.tabs.slice(index),
4799
+ ];
4800
+ if (this.selectedIndex < 0) {
4801
+ this.selectedIndex = index;
4802
+ }
4803
+ }
4804
+ delete(id) {
4805
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
4806
+ const tabToRemove = this.tabs.splice(index, 1)[0];
4807
+ const { value, disposable } = tabToRemove;
4808
+ disposable.dispose();
4809
+ value.dispose();
4810
+ value.element.remove();
4811
+ }
4812
+ setActivePanel(panel) {
4813
+ this.tabs.forEach((tab) => {
4814
+ const isActivePanel = panel.id === tab.value.panel.id;
4815
+ tab.value.setActive(isActivePanel);
4816
+ });
4817
+ }
4818
+ openPanel(panel, index = this.tabs.length) {
4819
+ var _a;
4820
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
4821
+ return;
4822
+ }
4823
+ const tab = new Tab(panel, this.accessor, this.group);
4824
+ if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
4825
+ throw new Error('invalid header component');
4826
+ }
4827
+ tab.setContent(panel.view.tab);
4828
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
4829
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
4830
+ }), tab.onChanged((event) => {
4831
+ const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
4832
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
4833
+ this.size === 1;
4834
+ if (isFloatingGroupsEnabled &&
4835
+ !isFloatingWithOnePanel &&
4836
+ event.shiftKey) {
4837
+ event.preventDefault();
4838
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
4839
+ const { top, left } = tab.element.getBoundingClientRect();
4840
+ const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
4841
+ this.accessor.addFloatingGroup(panel, {
4842
+ x: left - rootLeft,
4843
+ y: top - rootTop,
4844
+ }, { inDragMode: true });
4780
4845
  return;
4781
4846
  }
4782
- if (!isInDocument(this._element)) {
4783
- /**
4784
- * since the event is dispatched through requestAnimationFrame there is a small chance
4785
- * the component is no longer attached to the DOM, if that is the case the dimensions
4786
- * are mostly likely all zero and meaningless. we should skip this case.
4787
- */
4847
+ const isLeftClick = event.button === 0;
4848
+ if (!isLeftClick || event.defaultPrevented) {
4788
4849
  return;
4789
4850
  }
4790
- const { width, height } = entry.contentRect;
4791
- this.layout(width, height);
4851
+ if (this.group.activePanel !== panel) {
4852
+ this.group.model.openPanel(panel);
4853
+ }
4854
+ }), tab.onDrop((event) => {
4855
+ this._onDrop.fire({
4856
+ event: event.nativeEvent,
4857
+ index: this.tabs.findIndex((x) => x.value === tab),
4858
+ });
4859
+ }), tab.onWillShowOverlay((event) => {
4860
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4861
+ kind: 'tab',
4862
+ panel: this.group.activePanel,
4863
+ api: this.accessor.api,
4864
+ group: this.group,
4865
+ getData: getPanelData,
4866
+ }));
4792
4867
  }));
4868
+ const value = { value: tab, disposable };
4869
+ this.addTab(value, index);
4793
4870
  }
4794
- }
4795
-
4796
- const nextLayoutId$1 = sequentialNumberGenerator();
4797
- function toTarget(direction) {
4798
- switch (direction) {
4799
- case 'left':
4800
- return 'left';
4801
- case 'right':
4802
- return 'right';
4803
- case 'above':
4804
- return 'top';
4805
- case 'below':
4806
- return 'bottom';
4807
- case 'within':
4808
- default:
4809
- return 'center';
4871
+ closePanel(panel) {
4872
+ this.delete(panel.id);
4873
+ }
4874
+ dispose() {
4875
+ super.dispose();
4876
+ for (const { value, disposable } of this.tabs) {
4877
+ disposable.dispose();
4878
+ value.dispose();
4879
+ }
4880
+ this.tabs = [];
4810
4881
  }
4811
4882
  }
4812
- class BaseGrid extends Resizable {
4813
- get id() {
4814
- return this._id;
4883
+
4884
+ class DockviewUnhandledDragOverEvent {
4885
+ get isAccepted() {
4886
+ return this._isAccepted;
4815
4887
  }
4816
- get size() {
4817
- return this._groups.size;
4888
+ constructor(nativeEvent, target, position, getData, group) {
4889
+ this.nativeEvent = nativeEvent;
4890
+ this.target = target;
4891
+ this.position = position;
4892
+ this.getData = getData;
4893
+ this.group = group;
4894
+ this._isAccepted = false;
4818
4895
  }
4819
- get groups() {
4820
- return Array.from(this._groups.values()).map((_) => _.value);
4896
+ accept() {
4897
+ this._isAccepted = true;
4821
4898
  }
4822
- get width() {
4823
- return this.gridview.width;
4899
+ }
4900
+ const PROPERTY_KEYS = (() => {
4901
+ /**
4902
+ * by readong the keys from an empty value object TypeScript will error
4903
+ * when we add or remove new properties to `DockviewOptions`
4904
+ */
4905
+ const properties = {
4906
+ disableAutoResizing: undefined,
4907
+ hideBorders: undefined,
4908
+ singleTabMode: undefined,
4909
+ disableFloatingGroups: undefined,
4910
+ floatingGroupBounds: undefined,
4911
+ popoutUrl: undefined,
4912
+ defaultRenderer: undefined,
4913
+ debug: undefined,
4914
+ rootOverlayModel: undefined,
4915
+ locked: undefined,
4916
+ disableDnd: undefined,
4917
+ };
4918
+ return Object.keys(properties);
4919
+ })();
4920
+ function isPanelOptionsWithPanel(data) {
4921
+ if (data.referencePanel) {
4922
+ return true;
4824
4923
  }
4825
- get height() {
4826
- return this.gridview.height;
4924
+ return false;
4925
+ }
4926
+ function isPanelOptionsWithGroup(data) {
4927
+ if (data.referenceGroup) {
4928
+ return true;
4827
4929
  }
4828
- get minimumHeight() {
4829
- return this.gridview.minimumHeight;
4930
+ return false;
4931
+ }
4932
+ function isGroupOptionsWithPanel(data) {
4933
+ if (data.referencePanel) {
4934
+ return true;
4830
4935
  }
4831
- get maximumHeight() {
4832
- return this.gridview.maximumHeight;
4936
+ return false;
4937
+ }
4938
+ function isGroupOptionsWithGroup(data) {
4939
+ if (data.referenceGroup) {
4940
+ return true;
4833
4941
  }
4834
- get minimumWidth() {
4835
- return this.gridview.minimumWidth;
4942
+ return false;
4943
+ }
4944
+
4945
+ class DockviewDidDropEvent extends DockviewEvent {
4946
+ get nativeEvent() {
4947
+ return this.options.nativeEvent;
4836
4948
  }
4837
- get maximumWidth() {
4838
- return this.gridview.maximumWidth;
4949
+ get position() {
4950
+ return this.options.position;
4839
4951
  }
4840
- get activeGroup() {
4841
- return this._activeGroup;
4952
+ get panel() {
4953
+ return this.options.panel;
4842
4954
  }
4843
- get locked() {
4844
- return this.gridview.locked;
4955
+ get group() {
4956
+ return this.options.group;
4845
4957
  }
4846
- set locked(value) {
4847
- this.gridview.locked = value;
4958
+ get api() {
4959
+ return this.options.api;
4848
4960
  }
4849
4961
  constructor(options) {
4850
- super(document.createElement('div'), options.disableAutoResizing);
4851
- this._id = nextLayoutId$1.next();
4852
- this._groups = new Map();
4853
- this._onDidLayoutChange = new Emitter();
4854
- this.onDidLayoutChange = this._onDidLayoutChange.event;
4855
- this._onDidRemove = new Emitter();
4856
- this.onDidRemove = this._onDidRemove.event;
4857
- this._onDidAdd = new Emitter();
4858
- this.onDidAdd = this._onDidAdd.event;
4859
- this._onDidActiveChange = new Emitter();
4860
- this.onDidActiveChange = this._onDidActiveChange.event;
4861
- this._bufferOnDidLayoutChange = new TickDelayedEvent();
4862
- this.element.style.height = '100%';
4863
- this.element.style.width = '100%';
4864
- options.parentElement.appendChild(this.element);
4865
- this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation);
4866
- this.gridview.locked = !!options.locked;
4867
- this.element.appendChild(this.gridview.element);
4868
- this.layout(0, 0, true); // set some elements height/widths
4869
- this.addDisposables(Disposable.from(() => {
4870
- var _a;
4871
- (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element);
4872
- }), this.gridview.onDidChange(() => {
4873
- this._bufferOnDidLayoutChange.fire();
4874
- }), exports.DockviewEvent.any(this.onDidAdd, this.onDidRemove, this.onDidActiveChange)(() => {
4875
- this._bufferOnDidLayoutChange.fire();
4876
- }), this._bufferOnDidLayoutChange.onEvent(() => {
4877
- this._onDidLayoutChange.fire();
4878
- }), this._bufferOnDidLayoutChange);
4879
- }
4880
- setVisible(panel, visible) {
4881
- this.gridview.setViewVisible(getGridLocation(panel.element), visible);
4882
- this._onDidLayoutChange.fire();
4883
- }
4884
- isVisible(panel) {
4885
- return this.gridview.isViewVisible(getGridLocation(panel.element));
4886
- }
4887
- maximizeGroup(panel) {
4888
- this.gridview.maximizeView(panel);
4889
- this.doSetGroupActive(panel);
4890
- }
4891
- isMaximizedGroup(panel) {
4892
- return this.gridview.maximizedView() === panel;
4893
- }
4894
- exitMaximizedGroup() {
4895
- this.gridview.exitMaximizedView();
4896
- }
4897
- hasMaximizedGroup() {
4898
- return this.gridview.hasMaximizedView();
4899
- }
4900
- get onDidMaximizedGroupChange() {
4901
- return this.gridview.onDidMaximizedNodeChange;
4902
- }
4903
- doAddGroup(group, location = [0], size) {
4904
- this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4905
- this._onDidAdd.fire(group);
4906
- }
4907
- doRemoveGroup(group, options) {
4908
- if (!this._groups.has(group.id)) {
4909
- throw new Error('invalid operation');
4910
- }
4911
- const item = this._groups.get(group.id);
4912
- const view = this.gridview.remove(group, exports.Sizing.Distribute);
4913
- if (item && !(options === null || options === void 0 ? void 0 : options.skipDispose)) {
4914
- item.disposable.dispose();
4915
- item.value.dispose();
4916
- this._groups.delete(group.id);
4917
- this._onDidRemove.fire(group);
4918
- }
4919
- if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
4920
- const groups = Array.from(this._groups.values());
4921
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
4922
- }
4923
- return view;
4962
+ super();
4963
+ this.options = options;
4924
4964
  }
4925
- getPanel(id) {
4926
- var _a;
4927
- return (_a = this._groups.get(id)) === null || _a === void 0 ? void 0 : _a.value;
4965
+ getData() {
4966
+ return this.options.getData();
4928
4967
  }
4929
- doSetGroupActive(group) {
4930
- if (this._activeGroup === group) {
4931
- return;
4932
- }
4933
- if (this._activeGroup) {
4934
- this._activeGroup.setActive(false);
4935
- }
4936
- if (group) {
4937
- group.setActive(true);
4938
- }
4939
- this._activeGroup = group;
4940
- this._onDidActiveChange.fire(group);
4968
+ }
4969
+ class DockviewWillDropEvent extends DockviewDidDropEvent {
4970
+ get kind() {
4971
+ return this._kind;
4941
4972
  }
4942
- removeGroup(group) {
4943
- this.doRemoveGroup(group);
4973
+ constructor(options) {
4974
+ super(options);
4975
+ this._kind = options.kind;
4944
4976
  }
4945
- moveToNext(options) {
4946
- var _a;
4947
- if (!options) {
4948
- options = {};
4949
- }
4950
- if (!options.group) {
4951
- if (!this.activeGroup) {
4952
- return;
4953
- }
4954
- options.group = this.activeGroup;
4955
- }
4956
- const location = getGridLocation(options.group.element);
4957
- const next = (_a = this.gridview.next(location)) === null || _a === void 0 ? void 0 : _a.view;
4958
- this.doSetGroupActive(next);
4977
+ }
4978
+ class WillShowOverlayLocationEvent {
4979
+ get kind() {
4980
+ return this.options.kind;
4959
4981
  }
4960
- moveToPrevious(options) {
4961
- var _a;
4962
- if (!options) {
4963
- options = {};
4964
- }
4965
- if (!options.group) {
4966
- if (!this.activeGroup) {
4967
- return;
4968
- }
4969
- options.group = this.activeGroup;
4970
- }
4971
- const location = getGridLocation(options.group.element);
4972
- const next = (_a = this.gridview.previous(location)) === null || _a === void 0 ? void 0 : _a.view;
4973
- this.doSetGroupActive(next);
4982
+ get nativeEvent() {
4983
+ return this.event.nativeEvent;
4974
4984
  }
4975
- layout(width, height, forceResize) {
4976
- const different = forceResize !== null && forceResize !== void 0 ? forceResize : (width !== this.width || height !== this.height);
4977
- if (!different) {
4978
- return;
4979
- }
4980
- this.gridview.element.style.height = `${height}px`;
4981
- this.gridview.element.style.width = `${width}px`;
4982
- this.gridview.layout(width, height);
4985
+ get position() {
4986
+ return this.event.position;
4983
4987
  }
4984
- dispose() {
4985
- this._onDidActiveChange.dispose();
4986
- this._onDidAdd.dispose();
4987
- this._onDidRemove.dispose();
4988
- this._onDidLayoutChange.dispose();
4989
- for (const group of this.groups) {
4990
- group.dispose();
4991
- }
4992
- this.gridview.dispose();
4993
- super.dispose();
4988
+ get defaultPrevented() {
4989
+ return this.event.defaultPrevented;
4994
4990
  }
4995
- }
4996
-
4997
- class WillFocusEvent extends DockviewEvent {
4998
- constructor() {
4999
- super();
4991
+ get panel() {
4992
+ return this.options.panel;
5000
4993
  }
5001
- }
5002
- /**
5003
- * A core api implementation that should be used across all panel-like objects
5004
- */
5005
- class PanelApiImpl extends CompositeDisposable {
5006
- get isFocused() {
5007
- return this._isFocused;
4994
+ get api() {
4995
+ return this.options.api;
5008
4996
  }
5009
- get isActive() {
5010
- return this._isActive;
4997
+ get group() {
4998
+ return this.options.group;
5011
4999
  }
5012
- get isVisible() {
5013
- return this._isVisible;
5000
+ preventDefault() {
5001
+ this.event.preventDefault();
5014
5002
  }
5015
- get width() {
5016
- return this._width;
5003
+ getData() {
5004
+ return this.options.getData();
5017
5005
  }
5018
- get height() {
5019
- return this._height;
5006
+ constructor(event, options) {
5007
+ this.event = event;
5008
+ this.options = options;
5020
5009
  }
5021
- constructor(id, component) {
5022
- super();
5023
- this.id = id;
5024
- this.component = component;
5025
- this._isFocused = false;
5026
- this._isActive = false;
5027
- this._isVisible = true;
5028
- this._width = 0;
5029
- this._height = 0;
5030
- this._parameters = {};
5031
- this.panelUpdatesDisposable = new MutableDisposable();
5032
- this._onDidDimensionChange = new Emitter();
5033
- this.onDidDimensionsChange = this._onDidDimensionChange.event;
5034
- this._onDidChangeFocus = new Emitter();
5035
- this.onDidFocusChange = this._onDidChangeFocus.event;
5036
- //
5037
- this._onWillFocus = new Emitter();
5038
- this.onWillFocus = this._onWillFocus.event;
5039
- //
5040
- this._onDidVisibilityChange = new Emitter();
5041
- this.onDidVisibilityChange = this._onDidVisibilityChange.event;
5042
- this._onWillVisibilityChange = new Emitter();
5043
- this.onWillVisibilityChange = this._onWillVisibilityChange.event;
5044
- this._onDidActiveChange = new Emitter();
5045
- this.onDidActiveChange = this._onDidActiveChange.event;
5046
- this._onActiveChange = new Emitter();
5047
- this.onActiveChange = this._onActiveChange.event;
5048
- this._onDidParametersChange = new Emitter();
5049
- this.onDidParametersChange = this._onDidParametersChange.event;
5050
- this.addDisposables(this.onDidFocusChange((event) => {
5051
- this._isFocused = event.isFocused;
5052
- }), this.onDidActiveChange((event) => {
5053
- this._isActive = event.isActive;
5054
- }), this.onDidVisibilityChange((event) => {
5055
- this._isVisible = event.isVisible;
5056
- }), this.onDidDimensionsChange((event) => {
5057
- this._width = event.width;
5058
- this._height = event.height;
5059
- }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onWillFocus, this._onActiveChange, this._onWillFocus, this._onWillVisibilityChange, this._onDidParametersChange);
5010
+ }
5011
+ class DockviewGroupPanelModel extends CompositeDisposable {
5012
+ get element() {
5013
+ throw new Error('not supported');
5060
5014
  }
5061
- getParameters() {
5062
- return this._parameters;
5015
+ get activePanel() {
5016
+ return this._activePanel;
5063
5017
  }
5064
- initialize(panel) {
5065
- this.panelUpdatesDisposable.value = this._onDidParametersChange.event((parameters) => {
5066
- this._parameters = parameters;
5067
- panel.update({
5068
- params: parameters,
5069
- });
5070
- });
5018
+ get locked() {
5019
+ return this._locked;
5071
5020
  }
5072
- setVisible(isVisible) {
5073
- this._onWillVisibilityChange.fire({ isVisible });
5021
+ set locked(value) {
5022
+ this._locked = value;
5023
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
5074
5024
  }
5075
- setActive() {
5076
- this._onActiveChange.fire();
5025
+ get isActive() {
5026
+ return this._isGroupActive;
5077
5027
  }
5078
- updateParameters(parameters) {
5079
- this._onDidParametersChange.fire(parameters);
5028
+ get panels() {
5029
+ return this._panels;
5080
5030
  }
5081
- }
5082
-
5083
- class SplitviewPanelApiImpl extends PanelApiImpl {
5084
- //
5085
- constructor(id, component) {
5086
- super(id, component);
5087
- this._onDidConstraintsChangeInternal = new Emitter();
5088
- this.onDidConstraintsChangeInternal = this._onDidConstraintsChangeInternal.event;
5089
- //
5090
- this._onDidConstraintsChange = new Emitter({
5091
- replay: true,
5092
- });
5093
- this.onDidConstraintsChange = this._onDidConstraintsChange.event;
5094
- //
5095
- this._onDidSizeChange = new Emitter();
5096
- this.onDidSizeChange = this._onDidSizeChange.event;
5097
- this.addDisposables(this._onDidConstraintsChangeInternal, this._onDidConstraintsChange, this._onDidSizeChange);
5031
+ get size() {
5032
+ return this._panels.length;
5098
5033
  }
5099
- setConstraints(value) {
5100
- this._onDidConstraintsChangeInternal.fire(value);
5034
+ get isEmpty() {
5035
+ return this._panels.length === 0;
5101
5036
  }
5102
- setSize(event) {
5103
- this._onDidSizeChange.fire(event);
5037
+ get hasWatermark() {
5038
+ return !!(this.watermark && this.container.contains(this.watermark.element));
5104
5039
  }
5105
- }
5106
-
5107
- class PaneviewPanelApiImpl extends SplitviewPanelApiImpl {
5108
- set pane(pane) {
5109
- this._pane = pane;
5040
+ get header() {
5041
+ return this.tabsContainer;
5110
5042
  }
5111
- constructor(id, component) {
5112
- super(id, component);
5113
- this._onDidExpansionChange = new Emitter({
5114
- replay: true,
5115
- });
5116
- this.onDidExpansionChange = this._onDidExpansionChange.event;
5117
- this._onMouseEnter = new Emitter({});
5118
- this.onMouseEnter = this._onMouseEnter.event;
5119
- this._onMouseLeave = new Emitter({});
5120
- this.onMouseLeave = this._onMouseLeave.event;
5121
- this.addDisposables(this._onDidExpansionChange, this._onMouseEnter, this._onMouseLeave);
5043
+ get isContentFocused() {
5044
+ if (!document.activeElement) {
5045
+ return false;
5046
+ }
5047
+ return isAncestor(document.activeElement, this.contentContainer.element);
5122
5048
  }
5123
- setExpanded(isExpanded) {
5124
- var _a;
5125
- (_a = this._pane) === null || _a === void 0 ? void 0 : _a.setExpanded(isExpanded);
5049
+ get location() {
5050
+ return this._location;
5126
5051
  }
5127
- get isExpanded() {
5128
- var _a;
5129
- return !!((_a = this._pane) === null || _a === void 0 ? void 0 : _a.isExpanded());
5052
+ set location(value) {
5053
+ this._location = value;
5054
+ toggleClass(this.container, 'dv-groupview-floating', false);
5055
+ toggleClass(this.container, 'dv-groupview-popout', false);
5056
+ switch (value.type) {
5057
+ case 'grid':
5058
+ this.contentContainer.dropTarget.setTargetZones([
5059
+ 'top',
5060
+ 'bottom',
5061
+ 'left',
5062
+ 'right',
5063
+ 'center',
5064
+ ]);
5065
+ break;
5066
+ case 'floating':
5067
+ this.contentContainer.dropTarget.setTargetZones(['center']);
5068
+ this.contentContainer.dropTarget.setTargetZones(value
5069
+ ? ['center']
5070
+ : ['top', 'bottom', 'left', 'right', 'center']);
5071
+ toggleClass(this.container, 'dv-groupview-floating', true);
5072
+ break;
5073
+ case 'popout':
5074
+ this.contentContainer.dropTarget.setTargetZones(['center']);
5075
+ toggleClass(this.container, 'dv-groupview-popout', true);
5076
+ break;
5077
+ }
5078
+ this.groupPanel.api._onDidLocationChange.fire({
5079
+ location: this.location,
5080
+ });
5130
5081
  }
5131
- }
5132
-
5133
- class BasePanelView extends CompositeDisposable {
5134
- get element() {
5135
- return this._element;
5082
+ constructor(container, accessor, id, options, groupPanel) {
5083
+ var _a;
5084
+ super();
5085
+ this.container = container;
5086
+ this.accessor = accessor;
5087
+ this.id = id;
5088
+ this.options = options;
5089
+ this.groupPanel = groupPanel;
5090
+ this._isGroupActive = false;
5091
+ this._locked = false;
5092
+ this._location = { type: 'grid' };
5093
+ this.mostRecentlyUsed = [];
5094
+ this._onDidChange = new Emitter();
5095
+ this.onDidChange = this._onDidChange.event;
5096
+ this._width = 0;
5097
+ this._height = 0;
5098
+ this._panels = [];
5099
+ this._panelDisposables = new Map();
5100
+ this._onMove = new Emitter();
5101
+ this.onMove = this._onMove.event;
5102
+ this._onDidDrop = new Emitter();
5103
+ this.onDidDrop = this._onDidDrop.event;
5104
+ this._onWillDrop = new Emitter();
5105
+ this.onWillDrop = this._onWillDrop.event;
5106
+ this._onWillShowOverlay = new Emitter();
5107
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
5108
+ this._onTabDragStart = new Emitter();
5109
+ this.onTabDragStart = this._onTabDragStart.event;
5110
+ this._onGroupDragStart = new Emitter();
5111
+ this.onGroupDragStart = this._onGroupDragStart.event;
5112
+ this._onDidAddPanel = new Emitter();
5113
+ this.onDidAddPanel = this._onDidAddPanel.event;
5114
+ this._onDidPanelTitleChange = new Emitter();
5115
+ this.onDidPanelTitleChange = this._onDidPanelTitleChange.event;
5116
+ this._onDidPanelParametersChange = new Emitter();
5117
+ this.onDidPanelParametersChange = this._onDidPanelParametersChange.event;
5118
+ this._onDidRemovePanel = new Emitter();
5119
+ this.onDidRemovePanel = this._onDidRemovePanel.event;
5120
+ this._onDidActivePanelChange = new Emitter();
5121
+ this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5122
+ this._onUnhandledDragOverEvent = new Emitter();
5123
+ this.onUnhandledDragOverEvent = this._onUnhandledDragOverEvent.event;
5124
+ this._overwriteRenderContainer = null;
5125
+ toggleClass(this.container, 'groupview', true);
5126
+ this._api = new DockviewApi(this.accessor);
5127
+ this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
5128
+ this.contentContainer = new ContentContainer(this.accessor, this);
5129
+ container.append(this.tabsContainer.element, this.contentContainer.element);
5130
+ this.header.hidden = !!options.hideHeader;
5131
+ this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
5132
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
5133
+ this._onTabDragStart.fire(event);
5134
+ }), this.tabsContainer.onGroupDragStart((event) => {
5135
+ this._onGroupDragStart.fire(event);
5136
+ }), this.tabsContainer.onDrop((event) => {
5137
+ this.handleDropEvent('header', event.event, 'center', event.index);
5138
+ }), this.contentContainer.onDidFocus(() => {
5139
+ this.accessor.doSetGroupActive(this.groupPanel);
5140
+ }), this.contentContainer.onDidBlur(() => {
5141
+ // noop
5142
+ }), this.contentContainer.dropTarget.onDrop((event) => {
5143
+ this.handleDropEvent('content', event.nativeEvent, event.position);
5144
+ }), this.tabsContainer.onWillShowOverlay((event) => {
5145
+ this._onWillShowOverlay.fire(event);
5146
+ }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
5147
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
5148
+ kind: 'content',
5149
+ panel: this.activePanel,
5150
+ api: this._api,
5151
+ group: this.groupPanel,
5152
+ getData: getPanelData,
5153
+ }));
5154
+ }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOverEvent);
5136
5155
  }
5137
- get width() {
5138
- return this._width;
5156
+ focusContent() {
5157
+ this.contentContainer.element.focus();
5139
5158
  }
5140
- get height() {
5141
- return this._height;
5159
+ set renderContainer(value) {
5160
+ this.panels.forEach((panel) => {
5161
+ this.renderContainer.detatch(panel);
5162
+ });
5163
+ this._overwriteRenderContainer = value;
5164
+ this.panels.forEach((panel) => {
5165
+ this.rerender(panel);
5166
+ });
5142
5167
  }
5143
- get params() {
5168
+ get renderContainer() {
5144
5169
  var _a;
5145
- return (_a = this._params) === null || _a === void 0 ? void 0 : _a.params;
5146
- }
5147
- constructor(id, component, api) {
5148
- super();
5149
- this.id = id;
5150
- this.component = component;
5151
- this.api = api;
5152
- this._height = 0;
5153
- this._width = 0;
5154
- this._element = document.createElement('div');
5155
- this._element.tabIndex = -1;
5156
- this._element.style.outline = 'none';
5157
- this._element.style.height = '100%';
5158
- this._element.style.width = '100%';
5159
- this._element.style.overflow = 'hidden';
5160
- const focusTracker = trackFocus(this._element);
5161
- this.addDisposables(this.api, focusTracker.onDidFocus(() => {
5162
- this.api._onDidChangeFocus.fire({ isFocused: true });
5163
- }), focusTracker.onDidBlur(() => {
5164
- this.api._onDidChangeFocus.fire({ isFocused: false });
5165
- }), focusTracker);
5170
+ return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
5166
5171
  }
5167
- focus() {
5168
- const event = new WillFocusEvent();
5169
- this.api._onWillFocus.fire(event);
5170
- if (event.defaultPrevented) {
5171
- return;
5172
+ initialize() {
5173
+ if (this.options.panels) {
5174
+ this.options.panels.forEach((panel) => {
5175
+ this.doAddPanel(panel);
5176
+ });
5172
5177
  }
5173
- this._element.focus();
5174
- }
5175
- layout(width, height) {
5176
- this._width = width;
5177
- this._height = height;
5178
- this.api._onDidDimensionChange.fire({ width, height });
5179
- if (this.part) {
5180
- if (this._params) {
5181
- this.part.update(this._params.params);
5182
- }
5178
+ if (this.options.activePanel) {
5179
+ this.openPanel(this.options.activePanel);
5180
+ }
5181
+ // must be run after the constructor otherwise this.parent may not be
5182
+ // correctly initialized
5183
+ this.setActive(this.isActive, true);
5184
+ this.updateContainer();
5185
+ if (this.accessor.options.createRightHeaderActionComponent) {
5186
+ this._rightHeaderActions =
5187
+ this.accessor.options.createRightHeaderActionComponent(this.groupPanel);
5188
+ this.addDisposables(this._rightHeaderActions);
5189
+ this._rightHeaderActions.init({
5190
+ containerApi: this._api,
5191
+ api: this.groupPanel.api,
5192
+ group: this.groupPanel,
5193
+ });
5194
+ this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
5195
+ }
5196
+ if (this.accessor.options.createLeftHeaderActionComponent) {
5197
+ this._leftHeaderActions =
5198
+ this.accessor.options.createLeftHeaderActionComponent(this.groupPanel);
5199
+ this.addDisposables(this._leftHeaderActions);
5200
+ this._leftHeaderActions.init({
5201
+ containerApi: this._api,
5202
+ api: this.groupPanel.api,
5203
+ group: this.groupPanel,
5204
+ });
5205
+ this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
5206
+ }
5207
+ if (this.accessor.options.createPrefixHeaderActionComponent) {
5208
+ this._prefixHeaderActions =
5209
+ this.accessor.options.createPrefixHeaderActionComponent(this.groupPanel);
5210
+ this.addDisposables(this._prefixHeaderActions);
5211
+ this._prefixHeaderActions.init({
5212
+ containerApi: this._api,
5213
+ api: this.groupPanel.api,
5214
+ group: this.groupPanel,
5215
+ });
5216
+ this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
5183
5217
  }
5184
5218
  }
5185
- init(parameters) {
5186
- this._params = parameters;
5187
- this.part = this.getComponent();
5219
+ rerender(panel) {
5220
+ this.contentContainer.renderPanel(panel, { asActive: false });
5188
5221
  }
5189
- update(event) {
5190
- var _a, _b;
5191
- // merge the new parameters with the existing parameters
5192
- this._params = Object.assign(Object.assign({}, this._params), { params: Object.assign(Object.assign({}, (_a = this._params) === null || _a === void 0 ? void 0 : _a.params), event.params) });
5193
- /**
5194
- * delete new keys that have a value of undefined,
5195
- * allow values of null
5196
- */
5197
- for (const key of Object.keys(event.params)) {
5198
- if (event.params[key] === undefined) {
5199
- delete this._params.params[key];
5200
- }
5201
- }
5202
- // update the view with the updated props
5203
- (_b = this.part) === null || _b === void 0 ? void 0 : _b.update({ params: this._params.params });
5222
+ indexOf(panel) {
5223
+ return this.tabsContainer.indexOf(panel.id);
5204
5224
  }
5205
5225
  toJSON() {
5206
- var _a, _b;
5207
- const params = (_b = (_a = this._params) === null || _a === void 0 ? void 0 : _a.params) !== null && _b !== void 0 ? _b : {};
5208
- return {
5226
+ var _a;
5227
+ const result = {
5228
+ views: this.tabsContainer.panels,
5229
+ activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
5209
5230
  id: this.id,
5210
- component: this.component,
5211
- params: Object.keys(params).length > 0 ? params : undefined,
5212
5231
  };
5232
+ if (this.locked !== false) {
5233
+ result.locked = this.locked;
5234
+ }
5235
+ if (this.header.hidden) {
5236
+ result.hideHeader = true;
5237
+ }
5238
+ return result;
5213
5239
  }
5214
- dispose() {
5215
- var _a;
5216
- this.api.dispose();
5217
- (_a = this.part) === null || _a === void 0 ? void 0 : _a.dispose();
5218
- super.dispose();
5219
- }
5220
- }
5221
-
5222
- class PaneviewPanel extends BasePanelView {
5223
- set orientation(value) {
5224
- this._orientation = value;
5225
- }
5226
- get orientation() {
5227
- return this._orientation;
5228
- }
5229
- get minimumSize() {
5230
- const headerSize = this.headerSize;
5231
- const expanded = this.isExpanded();
5232
- const minimumBodySize = expanded ? this._minimumBodySize : 0;
5233
- return headerSize + minimumBodySize;
5234
- }
5235
- get maximumSize() {
5236
- const headerSize = this.headerSize;
5237
- const expanded = this.isExpanded();
5238
- const maximumBodySize = expanded ? this._maximumBodySize : 0;
5239
- return headerSize + maximumBodySize;
5240
- }
5241
- get size() {
5242
- return this._size;
5243
- }
5244
- get orthogonalSize() {
5245
- return this._orthogonalSize;
5240
+ moveToNext(options) {
5241
+ if (!options) {
5242
+ options = {};
5243
+ }
5244
+ if (!options.panel) {
5245
+ options.panel = this.activePanel;
5246
+ }
5247
+ const index = options.panel ? this.panels.indexOf(options.panel) : -1;
5248
+ let normalizedIndex;
5249
+ if (index < this.panels.length - 1) {
5250
+ normalizedIndex = index + 1;
5251
+ }
5252
+ else if (!options.suppressRoll) {
5253
+ normalizedIndex = 0;
5254
+ }
5255
+ else {
5256
+ return;
5257
+ }
5258
+ this.openPanel(this.panels[normalizedIndex]);
5246
5259
  }
5247
- set orthogonalSize(size) {
5248
- this._orthogonalSize = size;
5260
+ moveToPrevious(options) {
5261
+ if (!options) {
5262
+ options = {};
5263
+ }
5264
+ if (!options.panel) {
5265
+ options.panel = this.activePanel;
5266
+ }
5267
+ if (!options.panel) {
5268
+ return;
5269
+ }
5270
+ const index = this.panels.indexOf(options.panel);
5271
+ let normalizedIndex;
5272
+ if (index > 0) {
5273
+ normalizedIndex = index - 1;
5274
+ }
5275
+ else if (!options.suppressRoll) {
5276
+ normalizedIndex = this.panels.length - 1;
5277
+ }
5278
+ else {
5279
+ return;
5280
+ }
5281
+ this.openPanel(this.panels[normalizedIndex]);
5249
5282
  }
5250
- get minimumBodySize() {
5251
- return this._minimumBodySize;
5283
+ containsPanel(panel) {
5284
+ return this.panels.includes(panel);
5252
5285
  }
5253
- set minimumBodySize(value) {
5254
- this._minimumBodySize = typeof value === 'number' ? value : 0;
5286
+ init(_params) {
5287
+ //noop
5255
5288
  }
5256
- get maximumBodySize() {
5257
- return this._maximumBodySize;
5289
+ update(_params) {
5290
+ //noop
5258
5291
  }
5259
- set maximumBodySize(value) {
5260
- this._maximumBodySize =
5261
- typeof value === 'number' ? value : Number.POSITIVE_INFINITY;
5292
+ focus() {
5293
+ var _a;
5294
+ (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus();
5262
5295
  }
5263
- get headerVisible() {
5264
- return this._headerVisible;
5296
+ openPanel(panel, options = {}) {
5297
+ /**
5298
+ * set the panel group
5299
+ * add the panel
5300
+ * check if group active
5301
+ * check if panel active
5302
+ */
5303
+ if (typeof options.index !== 'number' ||
5304
+ options.index > this.panels.length) {
5305
+ options.index = this.panels.length;
5306
+ }
5307
+ const skipSetActive = !!options.skipSetActive;
5308
+ // ensure the group is updated before we fire any events
5309
+ panel.updateParentGroup(this.groupPanel, {
5310
+ skipSetActive: options.skipSetActive,
5311
+ });
5312
+ this.doAddPanel(panel, options.index, {
5313
+ skipSetActive: skipSetActive,
5314
+ });
5315
+ if (this._activePanel === panel) {
5316
+ this.contentContainer.renderPanel(panel, { asActive: true });
5317
+ return;
5318
+ }
5319
+ if (!skipSetActive) {
5320
+ this.doSetActivePanel(panel);
5321
+ }
5322
+ if (!options.skipSetGroupActive) {
5323
+ this.accessor.doSetGroupActive(this.groupPanel);
5324
+ }
5325
+ if (!options.skipSetActive) {
5326
+ this.updateContainer();
5327
+ }
5265
5328
  }
5266
- set headerVisible(value) {
5267
- this._headerVisible = value;
5268
- this.header.style.display = value ? '' : 'none';
5329
+ removePanel(groupItemOrId, options = {
5330
+ skipSetActive: false,
5331
+ }) {
5332
+ const id = typeof groupItemOrId === 'string'
5333
+ ? groupItemOrId
5334
+ : groupItemOrId.id;
5335
+ const panelToRemove = this._panels.find((panel) => panel.id === id);
5336
+ if (!panelToRemove) {
5337
+ throw new Error('invalid operation');
5338
+ }
5339
+ return this._removePanel(panelToRemove, options);
5269
5340
  }
5270
- constructor(id, component, headerComponent, orientation, isExpanded, isHeaderVisible) {
5271
- super(id, component, new PaneviewPanelApiImpl(id, component));
5272
- this.headerComponent = headerComponent;
5273
- this._onDidChangeExpansionState = new Emitter({ replay: true });
5274
- this.onDidChangeExpansionState = this._onDidChangeExpansionState.event;
5275
- this._onDidChange = new Emitter();
5276
- this.onDidChange = this._onDidChange.event;
5277
- this.headerSize = 22;
5278
- this._orthogonalSize = 0;
5279
- this._size = 0;
5280
- this._minimumBodySize = 100;
5281
- this._maximumBodySize = Number.POSITIVE_INFINITY;
5282
- this._isExpanded = false;
5283
- this.expandedSize = 0;
5284
- this.api.pane = this; // TODO cannot use 'this' before 'super'
5285
- this.api.initialize(this);
5286
- this._isExpanded = isExpanded;
5287
- this._headerVisible = isHeaderVisible;
5288
- this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
5289
- this._orientation = orientation;
5290
- this.element.classList.add('pane');
5291
- this.addDisposables(this.api.onWillVisibilityChange((event) => {
5292
- const { isVisible } = event;
5293
- const { accessor } = this._params;
5294
- accessor.setVisible(this, isVisible);
5295
- }), this.api.onDidSizeChange((event) => {
5296
- this._onDidChange.fire({ size: event.size });
5297
- }), addDisposableListener(this.element, 'mouseenter', (ev) => {
5298
- this.api._onMouseEnter.fire(ev);
5299
- }), addDisposableListener(this.element, 'mouseleave', (ev) => {
5300
- this.api._onMouseLeave.fire(ev);
5301
- }));
5302
- this.addDisposables(this._onDidChangeExpansionState, this.onDidChangeExpansionState((isPanelExpanded) => {
5303
- this.api._onDidExpansionChange.fire({
5304
- isExpanded: isPanelExpanded,
5305
- });
5306
- }), this.api.onDidFocusChange((e) => {
5307
- if (!this.header) {
5308
- return;
5309
- }
5310
- if (e.isFocused) {
5311
- addClasses(this.header, 'focused');
5312
- }
5313
- else {
5314
- removeClasses(this.header, 'focused');
5341
+ closeAllPanels() {
5342
+ if (this.panels.length > 0) {
5343
+ // take a copy since we will be edting the array as we iterate through
5344
+ const arrPanelCpy = [...this.panels];
5345
+ for (const panel of arrPanelCpy) {
5346
+ this.doClose(panel);
5315
5347
  }
5316
- }));
5317
- this.renderOnce();
5348
+ }
5349
+ else {
5350
+ this.accessor.removeGroup(this.groupPanel);
5351
+ }
5318
5352
  }
5319
- setVisible(isVisible) {
5320
- this.api._onDidVisibilityChange.fire({ isVisible });
5353
+ closePanel(panel) {
5354
+ this.doClose(panel);
5321
5355
  }
5322
- setActive(isActive) {
5323
- this.api._onDidActiveChange.fire({ isActive });
5356
+ doClose(panel) {
5357
+ this.accessor.removePanel(panel);
5324
5358
  }
5325
- isExpanded() {
5326
- return this._isExpanded;
5359
+ isPanelActive(panel) {
5360
+ return this._activePanel === panel;
5327
5361
  }
5328
- setExpanded(expanded) {
5329
- if (this._isExpanded === expanded) {
5362
+ updateActions(element) {
5363
+ this.tabsContainer.setRightActionsElement(element);
5364
+ }
5365
+ setActive(isGroupActive, force = false) {
5366
+ if (!force && this.isActive === isGroupActive) {
5330
5367
  return;
5331
5368
  }
5332
- this._isExpanded = expanded;
5333
- if (expanded) {
5334
- if (this.animationTimer) {
5335
- clearTimeout(this.animationTimer);
5336
- }
5337
- if (this.body) {
5338
- this.element.appendChild(this.body);
5339
- }
5369
+ this._isGroupActive = isGroupActive;
5370
+ toggleClass(this.container, 'active-group', isGroupActive);
5371
+ toggleClass(this.container, 'inactive-group', !isGroupActive);
5372
+ this.tabsContainer.setActive(this.isActive);
5373
+ if (!this._activePanel && this.panels.length > 0) {
5374
+ this.doSetActivePanel(this.panels[0]);
5340
5375
  }
5341
- else {
5342
- this.animationTimer = setTimeout(() => {
5343
- var _a;
5344
- (_a = this.body) === null || _a === void 0 ? void 0 : _a.remove();
5345
- }, 200);
5376
+ this.updateContainer();
5377
+ }
5378
+ layout(width, height) {
5379
+ var _a;
5380
+ this._width = width;
5381
+ this._height = height;
5382
+ this.contentContainer.layout(this._width, this._height);
5383
+ if ((_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.layout) {
5384
+ this._activePanel.layout(this._width, this._height);
5346
5385
  }
5347
- this._onDidChange.fire(expanded ? { size: this.width } : {});
5348
- this._onDidChangeExpansionState.fire(expanded);
5349
5386
  }
5350
- layout(size, orthogonalSize) {
5351
- this._size = size;
5352
- this._orthogonalSize = orthogonalSize;
5353
- const [width, height] = this.orientation === exports.Orientation.HORIZONTAL
5354
- ? [size, orthogonalSize]
5355
- : [orthogonalSize, size];
5356
- if (this.isExpanded()) {
5357
- this.expandedSize = width;
5387
+ _removePanel(panel, options) {
5388
+ const isActivePanel = this._activePanel === panel;
5389
+ this.doRemovePanel(panel);
5390
+ if (isActivePanel && this.panels.length > 0) {
5391
+ const nextPanel = this.mostRecentlyUsed[0];
5392
+ this.openPanel(nextPanel, {
5393
+ skipSetActive: options.skipSetActive,
5394
+ skipSetGroupActive: options.skipSetActiveGroup,
5395
+ });
5358
5396
  }
5359
- super.layout(width, height);
5397
+ if (this._activePanel && this.panels.length === 0) {
5398
+ this.doSetActivePanel(undefined);
5399
+ }
5400
+ if (!options.skipSetActive) {
5401
+ this.updateContainer();
5402
+ }
5403
+ return panel;
5360
5404
  }
5361
- init(parameters) {
5362
- var _a, _b;
5363
- super.init(parameters);
5364
- if (typeof parameters.minimumBodySize === 'number') {
5365
- this.minimumBodySize = parameters.minimumBodySize;
5405
+ doRemovePanel(panel) {
5406
+ const index = this.panels.indexOf(panel);
5407
+ if (this._activePanel === panel) {
5408
+ this.contentContainer.closePanel();
5366
5409
  }
5367
- if (typeof parameters.maximumBodySize === 'number') {
5368
- this.maximumBodySize = parameters.maximumBodySize;
5410
+ this.tabsContainer.delete(panel.id);
5411
+ this._panels.splice(index, 1);
5412
+ if (this.mostRecentlyUsed.includes(panel)) {
5413
+ const index = this.mostRecentlyUsed.indexOf(panel);
5414
+ this.mostRecentlyUsed.splice(index, 1);
5369
5415
  }
5370
- this.bodyPart = this.getBodyComponent();
5371
- this.headerPart = this.getHeaderComponent();
5372
- this.bodyPart.init(Object.assign(Object.assign({}, parameters), { api: this.api }));
5373
- this.headerPart.init(Object.assign(Object.assign({}, parameters), { api: this.api }));
5374
- (_a = this.body) === null || _a === void 0 ? void 0 : _a.append(this.bodyPart.element);
5375
- (_b = this.header) === null || _b === void 0 ? void 0 : _b.append(this.headerPart.element);
5376
- if (typeof parameters.isExpanded === 'boolean') {
5377
- this.setExpanded(parameters.isExpanded);
5416
+ const disposable = this._panelDisposables.get(panel.id);
5417
+ if (disposable) {
5418
+ disposable.dispose();
5419
+ this._panelDisposables.delete(panel.id);
5378
5420
  }
5421
+ this._onDidRemovePanel.fire({ panel });
5379
5422
  }
5380
- toJSON() {
5381
- const params = this._params;
5382
- return Object.assign(Object.assign({}, super.toJSON()), { headerComponent: this.headerComponent, title: params.title });
5423
+ doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
5424
+ const existingPanel = this._panels.indexOf(panel);
5425
+ const hasExistingPanel = existingPanel > -1;
5426
+ this.tabsContainer.show();
5427
+ this.contentContainer.show();
5428
+ this.tabsContainer.openPanel(panel, index);
5429
+ if (!options.skipSetActive) {
5430
+ this.contentContainer.openPanel(panel);
5431
+ }
5432
+ if (hasExistingPanel) {
5433
+ // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
5434
+ return;
5435
+ }
5436
+ this.updateMru(panel);
5437
+ this.panels.splice(index, 0, panel);
5438
+ this._panelDisposables.set(panel.id, new CompositeDisposable(panel.api.onDidTitleChange((event) => this._onDidPanelTitleChange.fire(event)), panel.api.onDidParametersChange((event) => this._onDidPanelParametersChange.fire(event))));
5439
+ this._onDidAddPanel.fire({ panel });
5383
5440
  }
5384
- renderOnce() {
5385
- this.header = document.createElement('div');
5386
- this.header.tabIndex = 0;
5387
- this.header.className = 'pane-header';
5388
- this.header.style.height = `${this.headerSize}px`;
5389
- this.header.style.lineHeight = `${this.headerSize}px`;
5390
- this.header.style.minHeight = `${this.headerSize}px`;
5391
- this.header.style.maxHeight = `${this.headerSize}px`;
5392
- this.element.appendChild(this.header);
5393
- this.body = document.createElement('div');
5394
- this.body.className = 'pane-body';
5395
- this.element.appendChild(this.body);
5441
+ doSetActivePanel(panel) {
5442
+ if (this._activePanel === panel) {
5443
+ return;
5444
+ }
5445
+ this._activePanel = panel;
5446
+ if (panel) {
5447
+ this.tabsContainer.setActivePanel(panel);
5448
+ panel.layout(this._width, this._height);
5449
+ this.updateMru(panel);
5450
+ this._onDidActivePanelChange.fire({
5451
+ panel,
5452
+ });
5453
+ }
5396
5454
  }
5397
- // TODO slightly hacky by-pass of the component to create a body and header component
5398
- getComponent() {
5399
- return {
5400
- update: (params) => {
5401
- var _a, _b;
5402
- (_a = this.bodyPart) === null || _a === void 0 ? void 0 : _a.update({ params });
5403
- (_b = this.headerPart) === null || _b === void 0 ? void 0 : _b.update({ params });
5404
- },
5405
- dispose: () => {
5406
- var _a, _b;
5407
- (_a = this.bodyPart) === null || _a === void 0 ? void 0 : _a.dispose();
5408
- (_b = this.headerPart) === null || _b === void 0 ? void 0 : _b.dispose();
5409
- },
5410
- };
5455
+ updateMru(panel) {
5456
+ if (this.mostRecentlyUsed.includes(panel)) {
5457
+ this.mostRecentlyUsed.splice(this.mostRecentlyUsed.indexOf(panel), 1);
5458
+ }
5459
+ this.mostRecentlyUsed = [panel, ...this.mostRecentlyUsed];
5411
5460
  }
5412
- }
5413
-
5414
- class DraggablePaneviewPanel extends PaneviewPanel {
5415
- constructor(accessor, id, component, headerComponent, orientation, isExpanded, disableDnd) {
5416
- super(id, component, headerComponent, orientation, isExpanded, true);
5417
- this.accessor = accessor;
5418
- this._onDidDrop = new Emitter();
5419
- this.onDidDrop = this._onDidDrop.event;
5420
- if (!disableDnd) {
5421
- this.initDragFeatures();
5461
+ updateContainer() {
5462
+ var _a, _b;
5463
+ toggleClass(this.container, 'empty', this.isEmpty);
5464
+ this.panels.forEach((panel) => panel.runEvents());
5465
+ if (this.isEmpty && !this.watermark) {
5466
+ const watermark = this.accessor.createWatermarkComponent();
5467
+ watermark.init({
5468
+ containerApi: this._api,
5469
+ group: this.groupPanel,
5470
+ });
5471
+ this.watermark = watermark;
5472
+ addDisposableListener(this.watermark.element, 'click', () => {
5473
+ if (!this.isActive) {
5474
+ this.accessor.doSetGroupActive(this.groupPanel);
5475
+ }
5476
+ });
5477
+ this.tabsContainer.hide();
5478
+ this.contentContainer.element.appendChild(this.watermark.element);
5479
+ this.watermark.updateParentGroup(this.groupPanel, true);
5480
+ }
5481
+ if (!this.isEmpty && this.watermark) {
5482
+ this.watermark.element.remove();
5483
+ (_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
5484
+ this.watermark = undefined;
5485
+ this.tabsContainer.show();
5422
5486
  }
5423
5487
  }
5424
- initDragFeatures() {
5425
- if (!this.header) {
5488
+ canDisplayOverlay(event, position, target) {
5489
+ const firedEvent = new DockviewUnhandledDragOverEvent(event, target, position, getPanelData, this.accessor.getPanel(this.id));
5490
+ this._onUnhandledDragOverEvent.fire(firedEvent);
5491
+ return firedEvent.isAccepted;
5492
+ }
5493
+ handleDropEvent(type, event, position, index) {
5494
+ if (this.locked === 'no-drop-target') {
5426
5495
  return;
5427
5496
  }
5428
- const id = this.id;
5429
- const accessorId = this.accessor.id;
5430
- this.header.draggable = true;
5431
- this.handler = new (class PaneDragHandler extends DragHandler {
5432
- getData() {
5433
- LocalSelectionTransfer.getInstance().setData([new PaneTransfer(accessorId, id)], PaneTransfer.prototype);
5434
- return {
5435
- dispose: () => {
5436
- LocalSelectionTransfer.getInstance().clearData(PaneTransfer.prototype);
5437
- },
5438
- };
5497
+ function getKind() {
5498
+ switch (type) {
5499
+ case 'header':
5500
+ return typeof index === 'number' ? 'tab' : 'header_space';
5501
+ case 'content':
5502
+ return 'content';
5439
5503
  }
5440
- })(this.header);
5441
- this.target = new Droptarget(this.element, {
5442
- acceptedTargetZones: ['top', 'bottom'],
5443
- overlayModel: {
5444
- activationSize: { type: 'percentage', value: 50 },
5445
- },
5446
- canDisplayOverlay: (event) => {
5447
- const data = getPaneData();
5448
- if (data) {
5449
- if (data.paneId !== this.id &&
5450
- data.viewId === this.accessor.id) {
5451
- return true;
5452
- }
5453
- }
5454
- if (this.accessor.options.showDndOverlay) {
5455
- return this.accessor.options.showDndOverlay({
5456
- nativeEvent: event,
5457
- getData: getPaneData,
5458
- panel: this,
5459
- });
5460
- }
5461
- return false;
5462
- },
5504
+ }
5505
+ const panel = typeof index === 'number' ? this.panels[index] : undefined;
5506
+ const willDropEvent = new DockviewWillDropEvent({
5507
+ nativeEvent: event,
5508
+ position,
5509
+ panel,
5510
+ getData: () => getPanelData(),
5511
+ kind: getKind(),
5512
+ group: this.groupPanel,
5513
+ api: this._api,
5463
5514
  });
5464
- this.addDisposables(this._onDidDrop, this.handler, this.target, this.target.onDrop((event) => {
5465
- this.onDrop(event);
5466
- }));
5467
- }
5468
- onDrop(event) {
5469
- const data = getPaneData();
5470
- if (!data || data.viewId !== this.accessor.id) {
5471
- // if there is no local drag event for this panel
5472
- // or if the drag event was creating by another Paneview instance
5473
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { panel: this, api: new PaneviewApi(this.accessor), getData: getPaneData }));
5515
+ this._onWillDrop.fire(willDropEvent);
5516
+ if (willDropEvent.defaultPrevented) {
5474
5517
  return;
5475
5518
  }
5476
- const containerApi = this._params
5477
- .containerApi;
5478
- const panelId = data.paneId;
5479
- const existingPanel = containerApi.getPanel(panelId);
5480
- if (!existingPanel) {
5481
- // if the panel doesn't exist
5482
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { panel: this, getData: getPaneData, api: new PaneviewApi(this.accessor) }));
5483
- return;
5519
+ const data = getPanelData();
5520
+ if (data && data.viewId === this.accessor.id) {
5521
+ if (data.panelId === null) {
5522
+ // this is a group move dnd event
5523
+ const { groupId } = data;
5524
+ this._onMove.fire({
5525
+ target: position,
5526
+ groupId: groupId,
5527
+ index,
5528
+ });
5529
+ return;
5530
+ }
5531
+ const fromSameGroup = this.tabsContainer.indexOf(data.panelId) !== -1;
5532
+ if (fromSameGroup && this.tabsContainer.size === 1) {
5533
+ return;
5534
+ }
5535
+ const { groupId, panelId } = data;
5536
+ const isSameGroup = this.id === groupId;
5537
+ if (isSameGroup && !position) {
5538
+ const oldIndex = this.tabsContainer.indexOf(panelId);
5539
+ if (oldIndex === index) {
5540
+ return;
5541
+ }
5542
+ }
5543
+ this._onMove.fire({
5544
+ target: position,
5545
+ groupId: data.groupId,
5546
+ itemId: data.panelId,
5547
+ index,
5548
+ });
5484
5549
  }
5485
- const allPanels = containerApi.panels;
5486
- const fromIndex = allPanels.indexOf(existingPanel);
5487
- let toIndex = containerApi.panels.indexOf(this);
5488
- if (event.position === 'left' || event.position === 'top') {
5489
- toIndex = Math.max(0, toIndex - 1);
5550
+ else {
5551
+ this._onDidDrop.fire(new DockviewDidDropEvent({
5552
+ nativeEvent: event,
5553
+ position,
5554
+ panel,
5555
+ getData: () => getPanelData(),
5556
+ group: this.groupPanel,
5557
+ api: this._api,
5558
+ }));
5490
5559
  }
5491
- if (event.position === 'right' || event.position === 'bottom') {
5492
- if (fromIndex > toIndex) {
5493
- toIndex++;
5494
- }
5495
- toIndex = Math.min(allPanels.length - 1, toIndex);
5560
+ }
5561
+ dispose() {
5562
+ var _a, _b, _c;
5563
+ super.dispose();
5564
+ (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
5565
+ (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
5566
+ this.watermark = undefined;
5567
+ for (const panel of this.panels) {
5568
+ panel.dispose();
5496
5569
  }
5497
- containerApi.movePanel(fromIndex, toIndex);
5570
+ this.tabsContainer.dispose();
5571
+ this.contentContainer.dispose();
5498
5572
  }
5499
5573
  }
5500
5574
 
@@ -5681,9 +5755,12 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5681
5755
  constructor(id, accessor) {
5682
5756
  super(id, '__dockviewgroup__');
5683
5757
  this.accessor = accessor;
5758
+ this._mutableDisposable = new MutableDisposable();
5684
5759
  this._onDidLocationChange = new Emitter();
5685
5760
  this.onDidLocationChange = this._onDidLocationChange.event;
5686
- this.addDisposables(this._onDidLocationChange);
5761
+ this._onDidActivePanelChange = new Emitter();
5762
+ this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5763
+ this.addDisposables(this._onDidLocationChange, this._onDidActivePanelChange, this._mutableDisposable);
5687
5764
  }
5688
5765
  close() {
5689
5766
  if (!this._group) {
@@ -5741,6 +5818,19 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5741
5818
  }
5742
5819
  initialize(group) {
5743
5820
  this._group = group;
5821
+ /**
5822
+ * TODO: Annoying initialization order caveat
5823
+ *
5824
+ * Due to the order on initialization we know that the model isn't defined until later in the same stack-frame of setup.
5825
+ * By queuing a microtask we can ensure the setup is completed within the same stack-frame, but after everything else has
5826
+ * finished ensuring the `model` is defined.
5827
+ */
5828
+ queueMicrotask(() => {
5829
+ this._mutableDisposable.value =
5830
+ this._group.model.onDidActivePanelChange((event) => {
5831
+ this._onDidActivePanelChange.fire(event);
5832
+ });
5833
+ });
5744
5834
  }
5745
5835
  }
5746
5836
 
@@ -5801,31 +5891,6 @@ class DockviewGroupPanel extends GridviewPanel {
5801
5891
  }
5802
5892
  }
5803
5893
 
5804
- function isPanelOptionsWithPanel(data) {
5805
- if (data.referencePanel) {
5806
- return true;
5807
- }
5808
- return false;
5809
- }
5810
- function isPanelOptionsWithGroup(data) {
5811
- if (data.referenceGroup) {
5812
- return true;
5813
- }
5814
- return false;
5815
- }
5816
- function isGroupOptionsWithPanel(data) {
5817
- if (data.referencePanel) {
5818
- return true;
5819
- }
5820
- return false;
5821
- }
5822
- function isGroupOptionsWithGroup(data) {
5823
- if (data.referenceGroup) {
5824
- return true;
5825
- }
5826
- return false;
5827
- }
5828
-
5829
5894
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5830
5895
  get location() {
5831
5896
  return this.group.api.location;
@@ -6193,7 +6258,7 @@ class DockviewPanelModel {
6193
6258
  this._tab = this.createTabComponent(this.id, tabComponent);
6194
6259
  }
6195
6260
  init(params) {
6196
- this.content.init(Object.assign(Object.assign({}, params), { tab: this.tab }));
6261
+ this.content.init(params);
6197
6262
  this.tab.init(params);
6198
6263
  }
6199
6264
  updateParentGroup(_group, _isPanelVisible) {
@@ -6214,20 +6279,29 @@ class DockviewPanelModel {
6214
6279
  (_d = (_c = this.tab).dispose) === null || _d === void 0 ? void 0 : _d.call(_c);
6215
6280
  }
6216
6281
  createContentComponent(id, componentName) {
6217
- var _a, _b;
6218
- return createComponent(id, componentName, (_a = this.accessor.options.components) !== null && _a !== void 0 ? _a : {}, this.accessor.options.frameworkComponents, (_b = this.accessor.options.frameworkComponentFactory) === null || _b === void 0 ? void 0 : _b.content);
6282
+ return this.accessor.options.createComponent({
6283
+ id,
6284
+ name: componentName,
6285
+ });
6219
6286
  }
6220
6287
  createTabComponent(id, componentName) {
6221
- var _a, _b;
6222
- if (componentName) {
6223
- return createComponent(id, componentName, this.accessor.options.tabComponents, this.accessor.options.frameworkTabComponents, (_a = this.accessor.options.frameworkComponentFactory) === null || _a === void 0 ? void 0 : _a.tab, () => new DefaultTab());
6224
- }
6225
- else if (this.accessor.options.defaultTabComponent) {
6226
- return createComponent(id, this.accessor.options.defaultTabComponent, this.accessor.options.tabComponents, this.accessor.options.frameworkTabComponents, (_b = this.accessor.options.frameworkComponentFactory) === null || _b === void 0 ? void 0 : _b.tab, () => new DefaultTab());
6227
- }
6228
- else {
6229
- return new DefaultTab();
6288
+ const name = componentName !== null && componentName !== void 0 ? componentName : this.accessor.options.defaultTabComponent;
6289
+ if (name) {
6290
+ if (this.accessor.options.createTabComponent) {
6291
+ const component = this.accessor.options.createTabComponent({
6292
+ id,
6293
+ name,
6294
+ });
6295
+ if (component) {
6296
+ return component;
6297
+ }
6298
+ else {
6299
+ return new DefaultTab();
6300
+ }
6301
+ }
6302
+ console.warn(`dockview: tabComponent '${componentName}' was not found. falling back to the default tab.`);
6230
6303
  }
6304
+ return new DefaultTab();
6231
6305
  }
6232
6306
  }
6233
6307
 
@@ -6981,14 +7055,19 @@ class DockviewComponent extends BaseGrid {
6981
7055
  }
6982
7056
  get renderer() {
6983
7057
  var _a;
6984
- return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisibile';
7058
+ return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisible';
7059
+ }
7060
+ get api() {
7061
+ return this._api;
6985
7062
  }
6986
7063
  constructor(options) {
6987
- var _a, _b;
7064
+ var _a;
6988
7065
  super({
6989
7066
  proportionalLayout: true,
6990
- orientation: (_a = options.orientation) !== null && _a !== void 0 ? _a : exports.Orientation.HORIZONTAL,
6991
- styles: options.styles,
7067
+ orientation: exports.Orientation.HORIZONTAL,
7068
+ styles: options.hideBorders
7069
+ ? { separatorBorder: 'transparent' }
7070
+ : undefined,
6992
7071
  parentElement: options.parentElement,
6993
7072
  disableAutoResizing: options.disableAutoResizing,
6994
7073
  locked: options.locked,
@@ -7006,6 +7085,8 @@ class DockviewComponent extends BaseGrid {
7006
7085
  this.onWillDrop = this._onWillDrop.event;
7007
7086
  this._onWillShowOverlay = new Emitter();
7008
7087
  this.onWillShowOverlay = this._onWillShowOverlay.event;
7088
+ this._onUnhandledDragOverEvent = new Emitter();
7089
+ this.onUnhandledDragOverEvent = this._onUnhandledDragOverEvent.event;
7009
7090
  this._onDidRemovePanel = new Emitter();
7010
7091
  this.onDidRemovePanel = this._onDidRemovePanel.event;
7011
7092
  this._onDidAddPanel = new Emitter();
@@ -7031,7 +7112,7 @@ class DockviewComponent extends BaseGrid {
7031
7112
  this.overlayRenderContainer = new OverlayRenderContainer(gready);
7032
7113
  toggleClass(this.gridview.element, 'dv-dockview', true);
7033
7114
  toggleClass(this.element, 'dv-debug', !!options.debug);
7034
- this.addDisposables(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.onDidAdd((event) => {
7115
+ this.addDisposables(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.onDidAdd((event) => {
7035
7116
  if (!this._moving) {
7036
7117
  this._onDidAddGroup.fire(event);
7037
7118
  }
@@ -7058,22 +7139,6 @@ class DockviewComponent extends BaseGrid {
7058
7139
  }
7059
7140
  }));
7060
7141
  this._options = options;
7061
- if (!this.options.components) {
7062
- this.options.components = {};
7063
- }
7064
- if (!this.options.frameworkComponents) {
7065
- this.options.frameworkComponents = {};
7066
- }
7067
- if (!this.options.frameworkTabComponents) {
7068
- this.options.frameworkTabComponents = {};
7069
- }
7070
- if (!this.options.tabComponents) {
7071
- this.options.tabComponents = {};
7072
- }
7073
- if (!this.options.watermarkComponent &&
7074
- !this.options.watermarkFrameworkComponent) {
7075
- this.options.watermarkComponent = Watermark;
7076
- }
7077
7142
  this._rootDropTarget = new Droptarget(this.element, {
7078
7143
  canDisplayOverlay: (event, position) => {
7079
7144
  const data = getPanelData();
@@ -7088,26 +7153,20 @@ class DockviewComponent extends BaseGrid {
7088
7153
  }
7089
7154
  return true;
7090
7155
  }
7091
- if (this.options.showDndOverlay) {
7092
- if (position === 'center' && this.gridview.length !== 0) {
7093
- /**
7094
- * for external events only show the four-corner drag overlays, disable
7095
- * the center position so that external drag events can fall through to the group
7096
- * and panel drop target handlers
7097
- */
7098
- return false;
7099
- }
7100
- return this.options.showDndOverlay({
7101
- nativeEvent: event,
7102
- position: position,
7103
- target: 'edge',
7104
- getData: getPanelData,
7105
- });
7156
+ if (position === 'center' && this.gridview.length !== 0) {
7157
+ /**
7158
+ * for external events only show the four-corner drag overlays, disable
7159
+ * the center position so that external drag events can fall through to the group
7160
+ * and panel drop target handlers
7161
+ */
7162
+ return false;
7106
7163
  }
7107
- return false;
7164
+ const firedEvent = new DockviewUnhandledDragOverEvent(event, 'edge', position, getPanelData);
7165
+ this._onUnhandledDragOverEvent.fire(firedEvent);
7166
+ return firedEvent.isAccepted;
7108
7167
  },
7109
7168
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
7110
- overlayModel: (_b = this.options.rootOverlayModel) !== null && _b !== void 0 ? _b : DEFAULT_ROOT_OVERLAY_MODEL,
7169
+ overlayModel: (_a = this.options.rootOverlayModel) !== null && _a !== void 0 ? _a : DEFAULT_ROOT_OVERLAY_MODEL,
7111
7170
  });
7112
7171
  this.addDisposables(this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
7113
7172
  if (this.gridview.length > 0 && event.position === 'center') {
@@ -7116,6 +7175,10 @@ class DockviewComponent extends BaseGrid {
7116
7175
  }
7117
7176
  this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
7118
7177
  kind: 'edge',
7178
+ panel: undefined,
7179
+ api: this._api,
7180
+ group: undefined,
7181
+ getData: getPanelData,
7119
7182
  }));
7120
7183
  }), this._rootDropTarget.onDrop((event) => {
7121
7184
  var _a;
@@ -7327,7 +7390,7 @@ class DockviewComponent extends BaseGrid {
7327
7390
  skipDispose: true,
7328
7391
  skipSetActiveGroup: true,
7329
7392
  }));
7330
- group.model.openPanel(item, { skipSetGroupActive: true });
7393
+ this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
7331
7394
  }
7332
7395
  else {
7333
7396
  group = item;
@@ -7400,7 +7463,7 @@ class DockviewComponent extends BaseGrid {
7400
7463
  // this is either a resize or a move
7401
7464
  // to inform the panels .layout(...) the group with it's current size
7402
7465
  // don't care about resize since the above watcher handles that
7403
- group.layout(group.height, group.width);
7466
+ group.layout(group.width, group.height);
7404
7467
  }), overlay.onDidChangeEnd(() => {
7405
7468
  this._bufferOnDidLayoutChange.fire();
7406
7469
  }), group.onDidChange((event) => {
@@ -7455,16 +7518,11 @@ class DockviewComponent extends BaseGrid {
7455
7518
  }
7456
7519
  updateOptions(options) {
7457
7520
  var _a, _b;
7458
- const changed_orientation = typeof options.orientation === 'string' &&
7459
- this.gridview.orientation !== options.orientation;
7460
- const changed_floatingGroupBounds = options.floatingGroupBounds !== undefined &&
7521
+ const changed_floatingGroupBounds = 'floatingGroupBounds' in options &&
7461
7522
  options.floatingGroupBounds !== this.options.floatingGroupBounds;
7462
- const changed_rootOverlayOptions = options.rootOverlayModel !== undefined &&
7523
+ const changed_rootOverlayOptions = 'rootOverlayModel' in options &&
7463
7524
  options.rootOverlayModel !== this.options.rootOverlayModel;
7464
7525
  this._options = Object.assign(Object.assign({}, this.options), options);
7465
- if (changed_orientation) {
7466
- this.gridview.orientation = options.orientation;
7467
- }
7468
7526
  if (changed_floatingGroupBounds) {
7469
7527
  for (const group of this._floatingGroups) {
7470
7528
  switch (this.options.floatingGroupBounds) {
@@ -7752,7 +7810,7 @@ class DockviewComponent extends BaseGrid {
7752
7810
  ? this.getGroupPanel(options.position.referencePanel)
7753
7811
  : options.position.referencePanel;
7754
7812
  if (!referencePanel) {
7755
- throw new Error(`referencePanel ${options.position.referencePanel} does not exist`);
7813
+ throw new Error(`referencePanel '${options.position.referencePanel}' does not exist`);
7756
7814
  }
7757
7815
  referenceGroup = this.findGroup(referencePanel);
7758
7816
  }
@@ -7762,14 +7820,19 @@ class DockviewComponent extends BaseGrid {
7762
7820
  ? (_a = this._groups.get(options.position.referenceGroup)) === null || _a === void 0 ? void 0 : _a.value
7763
7821
  : options.position.referenceGroup;
7764
7822
  if (!referenceGroup) {
7765
- throw new Error(`referencePanel ${options.position.referenceGroup} does not exist`);
7823
+ throw new Error(`referenceGroup '${options.position.referenceGroup}' does not exist`);
7766
7824
  }
7767
7825
  }
7768
7826
  else {
7769
7827
  const group = this.orthogonalize(directionToPosition(options.position.direction));
7770
7828
  const panel = this.createPanel(options, group);
7771
- group.model.openPanel(panel);
7772
- this.doSetGroupAndPanelActive(group);
7829
+ group.model.openPanel(panel, {
7830
+ skipSetActive: options.inactive,
7831
+ skipSetGroupActive: options.inactive,
7832
+ });
7833
+ if (!options.inactive) {
7834
+ this.doSetGroupAndPanelActive(group);
7835
+ }
7773
7836
  return panel;
7774
7837
  }
7775
7838
  }
@@ -7792,43 +7855,64 @@ class DockviewComponent extends BaseGrid {
7792
7855
  skipActiveGroup: true,
7793
7856
  });
7794
7857
  panel = this.createPanel(options, group);
7795
- group.model.openPanel(panel);
7858
+ group.model.openPanel(panel, {
7859
+ skipSetActive: options.inactive,
7860
+ skipSetGroupActive: options.inactive,
7861
+ });
7796
7862
  }
7797
7863
  else if (referenceGroup.api.location.type === 'floating' ||
7798
7864
  target === 'center') {
7799
7865
  panel = this.createPanel(options, referenceGroup);
7800
- referenceGroup.model.openPanel(panel);
7801
- this.doSetGroupAndPanelActive(referenceGroup);
7866
+ referenceGroup.model.openPanel(panel, {
7867
+ skipSetActive: options.inactive,
7868
+ skipSetGroupActive: options.inactive,
7869
+ });
7870
+ if (!options.inactive) {
7871
+ this.doSetGroupAndPanelActive(referenceGroup);
7872
+ }
7802
7873
  }
7803
7874
  else {
7804
7875
  const location = getGridLocation(referenceGroup.element);
7805
7876
  const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
7806
7877
  const group = this.createGroupAtLocation(relativeLocation);
7807
7878
  panel = this.createPanel(options, group);
7808
- group.model.openPanel(panel);
7809
- this.doSetGroupAndPanelActive(group);
7879
+ group.model.openPanel(panel, {
7880
+ skipSetActive: options.inactive,
7881
+ skipSetGroupActive: options.inactive,
7882
+ });
7883
+ if (!options.inactive) {
7884
+ this.doSetGroupAndPanelActive(group);
7885
+ }
7810
7886
  }
7811
7887
  }
7812
7888
  else if (options.floating) {
7813
7889
  const group = this.createGroup();
7814
7890
  this._onDidAddGroup.fire(group);
7815
- const o = typeof options.floating === 'object' &&
7891
+ const coordinates = typeof options.floating === 'object' &&
7816
7892
  options.floating !== null
7817
7893
  ? options.floating
7818
7894
  : {};
7819
- this.addFloatingGroup(group, o, {
7895
+ this.addFloatingGroup(group, coordinates, {
7820
7896
  inDragMode: false,
7821
7897
  skipRemoveGroup: true,
7822
7898
  skipActiveGroup: true,
7823
7899
  });
7824
7900
  panel = this.createPanel(options, group);
7825
- group.model.openPanel(panel);
7901
+ group.model.openPanel(panel, {
7902
+ skipSetActive: options.inactive,
7903
+ skipSetGroupActive: options.inactive,
7904
+ });
7826
7905
  }
7827
7906
  else {
7828
7907
  const group = this.createGroupAtLocation();
7829
7908
  panel = this.createPanel(options, group);
7830
- group.model.openPanel(panel);
7831
- this.doSetGroupAndPanelActive(group);
7909
+ group.model.openPanel(panel, {
7910
+ skipSetActive: options.inactive,
7911
+ skipSetGroupActive: options.inactive,
7912
+ });
7913
+ if (!options.inactive) {
7914
+ this.doSetGroupAndPanelActive(group);
7915
+ }
7832
7916
  }
7833
7917
  return panel;
7834
7918
  }
@@ -7852,12 +7936,10 @@ class DockviewComponent extends BaseGrid {
7852
7936
  }
7853
7937
  }
7854
7938
  createWatermarkComponent() {
7855
- var _a;
7856
- return createComponent('watermark-id', 'watermark-name', this.options.watermarkComponent
7857
- ? { 'watermark-name': this.options.watermarkComponent }
7858
- : {}, this.options.watermarkFrameworkComponent
7859
- ? { 'watermark-name': this.options.watermarkFrameworkComponent }
7860
- : {}, (_a = this.options.frameworkComponentFactory) === null || _a === void 0 ? void 0 : _a.watermark);
7939
+ if (this.options.createWatermarkComponent) {
7940
+ return this.options.createWatermarkComponent();
7941
+ }
7942
+ return new Watermark();
7861
7943
  }
7862
7944
  updateWatermark() {
7863
7945
  var _a, _b;
@@ -8238,6 +8320,8 @@ class DockviewComponent extends BaseGrid {
8238
8320
  return;
8239
8321
  }
8240
8322
  this._onWillShowOverlay.fire(event);
8323
+ }), view.model.onUnhandledDragOverEvent((event) => {
8324
+ this._onUnhandledDragOverEvent.fire(event);
8241
8325
  }), view.model.onDidAddPanel((event) => {
8242
8326
  if (this._moving) {
8243
8327
  return;
@@ -9271,6 +9355,7 @@ exports.DockviewGroupPanel = DockviewGroupPanel;
9271
9355
  exports.DockviewGroupPanelModel = DockviewGroupPanelModel;
9272
9356
  exports.DockviewMutableDisposable = MutableDisposable;
9273
9357
  exports.DockviewPanel = DockviewPanel;
9358
+ exports.DockviewUnhandledDragOverEvent = DockviewUnhandledDragOverEvent;
9274
9359
  exports.DockviewWillDropEvent = DockviewWillDropEvent;
9275
9360
  exports.DraggablePaneviewPanel = DraggablePaneviewPanel;
9276
9361
  exports.Gridview = Gridview;
@@ -9278,6 +9363,7 @@ exports.GridviewApi = GridviewApi;
9278
9363
  exports.GridviewComponent = GridviewComponent;
9279
9364
  exports.GridviewPanel = GridviewPanel;
9280
9365
  exports.LocalSelectionTransfer = LocalSelectionTransfer;
9366
+ exports.PROPERTY_KEYS = PROPERTY_KEYS;
9281
9367
  exports.PaneFramework = PaneFramework;
9282
9368
  exports.PaneTransfer = PaneTransfer;
9283
9369
  exports.PanelTransfer = PanelTransfer;