dockview-core 8.3.0 → 8.4.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 (33) hide show
  1. package/dist/cjs/api/component.api.d.ts +26 -1
  2. package/dist/cjs/dismissableLayer.d.ts +19 -7
  3. package/dist/cjs/dnd/droptarget.d.ts +11 -0
  4. package/dist/cjs/dnd/ghost.d.ts +3 -0
  5. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +1 -0
  6. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -0
  7. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +3 -0
  8. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +6 -2
  9. package/dist/cjs/dnd/pointer/types.d.ts +5 -0
  10. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +12 -3
  11. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +52 -21
  12. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +4 -0
  13. package/dist/cjs/dockview/dndCapabilities.d.ts +3 -4
  14. package/dist/cjs/dockview/dockviewComponent.d.ts +31 -16
  15. package/dist/cjs/dockview/dockviewShell.d.ts +12 -0
  16. package/dist/cjs/dockview/options.d.ts +13 -0
  17. package/dist/cjs/dockview/popoutWindowService.d.ts +8 -2
  18. package/dist/cjs/dom.d.ts +61 -1
  19. package/dist/cjs/gridview/branchNode.d.ts +2 -1
  20. package/dist/cjs/gridview/gridview.d.ts +2 -1
  21. package/dist/cjs/index.d.ts +5 -1
  22. package/dist/cjs/popoutWindow.d.ts +57 -12
  23. package/dist/cjs/resizable.d.ts +12 -0
  24. package/dist/cjs/splitview/splitview.d.ts +3 -1
  25. package/dist/dockview-core.js +880 -390
  26. package/dist/dockview-core.min.js +29 -4
  27. package/dist/dockview-core.min.noStyle.js +2 -2
  28. package/dist/dockview-core.noStyle.js +879 -389
  29. package/dist/package/main.cjs.js +879 -389
  30. package/dist/package/main.cjs.min.js +2 -2
  31. package/dist/package/main.esm.min.mjs +2 -2
  32. package/dist/package/main.esm.mjs +878 -390
  33. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 8.3.0
3
+ * @version 8.4.0
4
4
  * @link https://github.com/dockview/dockview
5
5
  * @license MIT
6
6
  */
@@ -380,7 +380,7 @@ var FocusTracker = class extends CompositeDisposable {
380
380
  this._onDidBlur = new Emitter();
381
381
  this.onDidBlur = this._onDidBlur.event;
382
382
  this.addDisposables(this._onDidFocus, this._onDidBlur);
383
- let hasFocus = isAncestor(document.activeElement, element);
383
+ let hasFocus = isAncestor(getActiveElement(element), element);
384
384
  let loosingFocus = false;
385
385
  const onFocus = () => {
386
386
  loosingFocus = false;
@@ -402,7 +402,7 @@ var FocusTracker = class extends CompositeDisposable {
402
402
  }
403
403
  };
404
404
  this._refreshStateHandler = () => {
405
- if (isAncestor(document.activeElement, element) !== hasFocus) if (hasFocus) onBlur();
405
+ if (isAncestor(getActiveElement(element), element) !== hasFocus) if (hasFocus) onBlur();
406
406
  else onFocus();
407
407
  };
408
408
  this.addDisposables(addDisposableListener(element, "focus", onFocus, true));
@@ -419,6 +419,49 @@ function quasiPreventDefault(event) {
419
419
  function quasiDefaultPrevented(event) {
420
420
  return event[QUASI_PREVENT_DEFAULT_KEY];
421
421
  }
422
+ /** Whether the event originated within any of `elements`. Checks the
423
+ * composed path, so it also holds for elements inside a shadow root, which a
424
+ * window or document listener sees retargeted to the shadow host. */
425
+ function isEventWithin(event, elements) {
426
+ var _event$composedPath, _event$composedPath2;
427
+ const path = (_event$composedPath = (_event$composedPath2 = event.composedPath) === null || _event$composedPath2 === void 0 ? void 0 : _event$composedPath2.call(event)) !== null && _event$composedPath !== void 0 ? _event$composedPath : [];
428
+ if (path.length > 0) return elements.some((el) => path.includes(el));
429
+ const target = event.target;
430
+ return target instanceof Node && elements.some((el) => el.contains(target));
431
+ }
432
+ /** Every shadow root between `element` and its document, innermost first. An
433
+ * element in a component nested inside another component sits in more than
434
+ * one, and an event is cut at each boundary. */
435
+ function shadowRootsOf(node) {
436
+ const roots = [];
437
+ let root = node.getRootNode();
438
+ while (isShadowRoot(root)) {
439
+ roots.push(root);
440
+ root = root.host.getRootNode();
441
+ }
442
+ return roots;
443
+ }
444
+ /**
445
+ * `element` as a listener rooted in `scope`'s tree sees it. A node in a shadow
446
+ * root *below* that tree is retargeted to its host there, repeatedly for
447
+ * nested roots; a node already in the same tree is returned unchanged. Omit
448
+ * `scope` (or pass a node in the document) for the document-level view, which
449
+ * is what a window listener gets.
450
+ *
451
+ * The scope matters: a layer living inside a shadow root must be able to tell
452
+ * its own elements apart, and retargeting everything out to the document would
453
+ * collapse them all onto the one host.
454
+ */
455
+ function retargetInto(element, scope) {
456
+ const scopeRoot = scope === null || scope === void 0 ? void 0 : scope.getRootNode();
457
+ let current = element;
458
+ let root = current.getRootNode();
459
+ while (root !== scopeRoot && isShadowRoot(root)) {
460
+ current = root.host;
461
+ root = current.getRootNode();
462
+ }
463
+ return current;
464
+ }
422
465
  function addStyles(document, styleSheetList, options = {}) {
423
466
  const styleSheets = Array.from(styleSheetList);
424
467
  const { nonce } = options;
@@ -429,6 +472,7 @@ function addStyles(document, styleSheetList, options = {}) {
429
472
  link.href = styleSheet.href;
430
473
  link.type = styleSheet.type;
431
474
  link.rel = "stylesheet";
475
+ if (resolvedNonce) link.setAttribute("nonce", resolvedNonce);
432
476
  document.head.appendChild(link);
433
477
  continue;
434
478
  }
@@ -468,6 +512,23 @@ function isInDocument(element) {
468
512
  else currentElement = currentElement.parentNode;
469
513
  return false;
470
514
  }
515
+ /** Duck-typed so it holds for a shadow root from another window's realm. */
516
+ function isShadowRoot(node) {
517
+ return !!node && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && "host" in node && !!node.host;
518
+ }
519
+ /**
520
+ * The document or shadow root to hit-test (`elementFromPoint` /
521
+ * `elementsFromPoint`) against for `node`. Hit-testing on the document stops
522
+ * at a shadow host, so when dockview is mounted in a shadow root it has to go
523
+ * through that root to reach its own elements. Falls back to the owning
524
+ * document (which may be a popout's) for a detached node.
525
+ */
526
+ function getHitTestRoot(node) {
527
+ var _node$ownerDocument;
528
+ const root = node.getRootNode();
529
+ if (root !== node && typeof root.elementsFromPoint === "function") return root;
530
+ return (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 ? _node$ownerDocument : document;
531
+ }
471
532
  function addTestId(element, id) {
472
533
  element.dataset.testid = id;
473
534
  }
@@ -502,6 +563,38 @@ function disableIframePointEvents(rootNode = document) {
502
563
  iframes.splice(0, iframes.length);
503
564
  } };
504
565
  }
566
+ /**
567
+ * Suppress text selection for the duration of a pointer drag.
568
+ *
569
+ * A pointer drag is just a held button as far as the browser is concerned, so
570
+ * it selects text under the cursor as it travels. HTML5 drag-and-drop is
571
+ * exempt - the browser owns the gesture - which is why this is only needed on
572
+ * the pointer backend.
573
+ *
574
+ * `user-select: none` alone is not enough on WebKit: it starts the selection
575
+ * gesture from a mousedown on a `user-select: none` element unless that
576
+ * element is also natively draggable, then extends it into whatever the
577
+ * pointer crosses. Cancelling `selectstart` refuses that first extension,
578
+ * which ends the gesture for the rest of the drag.
579
+ *
580
+ * An existing selection is left alone: a mousedown on a `user-select: none`
581
+ * element does not clear one natively, and a pointer drag should not either.
582
+ */
583
+ function disableTextSelection(rootNode = document) {
584
+ const doc = rootNode instanceof Document ? rootNode : rootNode.ownerDocument;
585
+ const root = doc === null || doc === void 0 ? void 0 : doc.documentElement;
586
+ if (!doc || !root) return { release: () => void 0 };
587
+ const properties = ["user-select", "-webkit-user-select"];
588
+ const previous = properties.map((name) => [name, root.style.getPropertyValue(name)]);
589
+ for (const name of properties) root.style.setProperty(name, "none");
590
+ const onSelectStart = (event) => event.preventDefault();
591
+ doc.addEventListener("selectstart", onSelectStart);
592
+ return { release: () => {
593
+ doc.removeEventListener("selectstart", onSelectStart);
594
+ for (const [name, value] of previous) if (value) root.style.setProperty(name, value);
595
+ else root.style.removeProperty(name);
596
+ } };
597
+ }
505
598
  function getDockviewTheme(element) {
506
599
  function toClassList(element) {
507
600
  const list = [];
@@ -513,6 +606,11 @@ function getDockviewTheme(element) {
513
606
  while (parent !== null) {
514
607
  theme = toClassList(parent).find((cls) => cls.startsWith("dockview-theme-"));
515
608
  if (typeof theme === "string") break;
609
+ if (parent.parentElement === null) {
610
+ const root = parent.getRootNode();
611
+ parent = isShadowRoot(root) ? root.host : null;
612
+ continue;
613
+ }
516
614
  parent = parent.parentElement;
517
615
  }
518
616
  return theme;
@@ -624,6 +722,285 @@ function resolveOpaqueBackground(element) {
624
722
  }
625
723
  return "";
626
724
  }
725
+ /** The focused element as seen from `node`'s own tree. Unlike
726
+ * `document.activeElement`, which is the shadow host when focus is inside a
727
+ * shadow root, this reaches into the root `node` lives in (and a popout's
728
+ * own document), while a web component nested inside that tree still
729
+ * resolves to its host there. */
730
+ function getActiveElement(node) {
731
+ var _root$activeElement;
732
+ const root = node.getRootNode();
733
+ const doc = root.nodeType === Node.DOCUMENT_NODE ? root : node.ownerDocument;
734
+ if (doc && typeof doc.hasFocus === "function" && !doc.hasFocus()) return null;
735
+ return (_root$activeElement = root.activeElement) !== null && _root$activeElement !== void 0 ? _root$activeElement : null;
736
+ }
737
+ /** Where to append a floating element (e.g. a drag ghost) for `node`: its
738
+ * shadow root when it lives in one, so styles scoped there still apply,
739
+ * otherwise the body of its own document (which may be a popout's). */
740
+ function getOverlayParent(node) {
741
+ var _node$ownerDocument2;
742
+ const root = node.getRootNode();
743
+ if (isShadowRoot(root)) return root;
744
+ return ((_node$ownerDocument2 = node.ownerDocument) !== null && _node$ownerDocument2 !== void 0 ? _node$ownerDocument2 : document).body;
745
+ }
746
+
747
+ //#endregion
748
+ //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
749
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
750
+ try {
751
+ var i = n[a](c), u = i.value;
752
+ } catch (n) {
753
+ e(n);
754
+ return;
755
+ }
756
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
757
+ }
758
+ function _asyncToGenerator(n) {
759
+ return function() {
760
+ var t = this, e = arguments;
761
+ return new Promise(function(r, o) {
762
+ var a = n.apply(t, e);
763
+ function _next(n) {
764
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
765
+ }
766
+ function _throw(n) {
767
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
768
+ }
769
+ _next(void 0);
770
+ });
771
+ };
772
+ }
773
+
774
+ //#endregion
775
+ //#region src/popoutWindow.ts
776
+ /**
777
+ * Throwing form of {@link getPopoutUrlError}, for callers with no way to
778
+ * recover from a refused URL.
779
+ */
780
+ function assertSameOriginPopoutUrl(url) {
781
+ const error = getPopoutUrlError(url);
782
+ if (error) throw error;
783
+ }
784
+ /**
785
+ * Schemes a popout must never open: each runs script in a context the browser
786
+ * still associates with the opener, or (for `file:`) has no origin to check.
787
+ */
788
+ const UNSAFE_POPOUT_PROTOCOLS = /* @__PURE__ */ new Set([
789
+ "javascript:",
790
+ "data:",
791
+ "blob:",
792
+ "vbscript:",
793
+ "file:"
794
+ ]);
795
+ /** How often an open popout window's `closed` flag is checked. */
796
+ const CLOSED_POLL_INTERVAL_MS = 250;
797
+ /**
798
+ * The reason `url` is unusable as a popout target, or `undefined` if it is
799
+ * allowed. Rejects anything that isn't same-origin with the page (scheme and
800
+ * host, so a packaged webview's own scheme such as `tauri://` qualifies), and
801
+ * the `javascript:`, `data:`, `blob:`, `vbscript:` and `file:` schemes that
802
+ * would otherwise execute in a context the browser still associates with the
803
+ * opener via `window.opener`.
804
+ *
805
+ * Callers that can recover from a refusal use this rather than catching, so it
806
+ * can be handled without a rejected promise. `page` is what the URL resolves
807
+ * against, and defaults to this page.
808
+ */
809
+ function getPopoutUrlError(url, page = globalThis.location) {
810
+ let resolved;
811
+ try {
812
+ resolved = new URL(url, page.href);
813
+ } catch (_unused) {
814
+ return /* @__PURE__ */ new Error(`dockview: invalid popout URL: ${url}`);
815
+ }
816
+ if (UNSAFE_POPOUT_PROTOCOLS.has(resolved.protocol)) return /* @__PURE__ */ new Error(`dockview: popout URL must not use the "${resolved.protocol}" protocol, which would run in the opener's context; got: ${url}`);
817
+ if (!(resolved.protocol === page.protocol && resolved.host === page.host)) return /* @__PURE__ */ new Error(`dockview: popout URL must be same-origin with the page (${page.protocol}//${page.host}); got: ${url}`);
818
+ }
819
+ var PopoutWindow = class extends CompositeDisposable {
820
+ get window() {
821
+ var _this$_window$value, _this$_window;
822
+ return (_this$_window$value = (_this$_window = this._window) === null || _this$_window === void 0 ? void 0 : _this$_window.value) !== null && _this$_window$value !== void 0 ? _this$_window$value : null;
823
+ }
824
+ /** Set when {@link open} resolved `null`, saying which way it failed. */
825
+ get failure() {
826
+ return this._failure;
827
+ }
828
+ constructor(target, className, options) {
829
+ super();
830
+ this.target = target;
831
+ this.className = className;
832
+ this.options = options;
833
+ this._onWillClose = new Emitter();
834
+ this.onWillClose = this._onWillClose.event;
835
+ this._onDidClose = new Emitter();
836
+ this.onDidClose = this._onDidClose.event;
837
+ this._window = null;
838
+ this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
839
+ this.close();
840
+ } });
841
+ }
842
+ dimensions() {
843
+ if (!this._window) return null;
844
+ const left = this._window.value.screenX;
845
+ return {
846
+ top: this._window.value.screenY,
847
+ left,
848
+ width: this._window.value.innerWidth,
849
+ height: this._window.value.innerHeight
850
+ };
851
+ }
852
+ close() {
853
+ var _this$options$onWillC, _this$options;
854
+ const current = this._window;
855
+ if (!current) return;
856
+ this._window = null;
857
+ this._onWillClose.fire();
858
+ (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
859
+ id: this.target,
860
+ window: current.value
861
+ });
862
+ current.disposable.dispose();
863
+ this._onDidClose.fire();
864
+ }
865
+ open() {
866
+ var _this = this;
867
+ return _asyncToGenerator(function* () {
868
+ var _this$options$onDidOp, _this$options2;
869
+ if (_this._window) throw new Error("instance of popout window is already open");
870
+ const url = `${_this.options.url}`;
871
+ assertSameOriginPopoutUrl(url);
872
+ const features = Object.entries({
873
+ top: _this.options.top,
874
+ left: _this.options.left,
875
+ width: _this.options.width,
876
+ height: _this.options.height
877
+ }).map(([key, value]) => `${key}=${value}`).join(",");
878
+ /**
879
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
880
+ */
881
+ const externalWindow = window.open(url, _this.target, features);
882
+ if (!externalWindow) {
883
+ _this._failure = { reason: "blocked" };
884
+ return null;
885
+ }
886
+ const disposable = new CompositeDisposable();
887
+ _this._window = {
888
+ value: externalWindow,
889
+ disposable
890
+ };
891
+ disposable.addDisposables(Disposable.from(() => {
892
+ externalWindow.close();
893
+ }), _this.watchForClose(externalWindow), addDisposableListener(globalThis.window, "beforeunload", () => {
894
+ /**
895
+ * before the main window closes we should close this popup too
896
+ * to be good citizens
897
+ *
898
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
899
+ */
900
+ _this.close();
901
+ }));
902
+ const container = _this.createPopoutWindowContainer();
903
+ if (_this.className) container.classList.add(_this.className);
904
+ (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
905
+ id: _this.target,
906
+ window: externalWindow
907
+ });
908
+ return new Promise((resolve) => {
909
+ /**
910
+ * A host can answer `window.open` with a window in its own
911
+ * JavaScript context, which throws on first touch and cannot be
912
+ * filled with panel DOM. Settle as a blocked popup does, so the
913
+ * caller's fallback returns the group to the grid.
914
+ */
915
+ const abandon = (err) => {
916
+ _this._failure = {
917
+ reason: "unscriptable",
918
+ error: err instanceof Error ? err : new Error(String(err))
919
+ };
920
+ _this.close();
921
+ resolve(null);
922
+ };
923
+ try {
924
+ externalWindow.addEventListener("unload", () => {});
925
+ } catch (err) {
926
+ abandon(err);
927
+ return;
928
+ }
929
+ /**
930
+ * `load` is the only event that resolves this promise with a
931
+ * container, so a window that goes away first would leave the
932
+ * caller awaiting a promise that never settles - and
933
+ * `addPopoutGroup` holds its layout transaction open until it does.
934
+ * Settle with `null` on close, the same signal a blocked popup
935
+ * gives and one the caller already handles. `resolve` after the
936
+ * fact is a no-op, so a `load` that arrived first still wins.
937
+ */
938
+ disposable.addDisposables(_this.onWillClose(() => {
939
+ var _this$_failure;
940
+ (_this$_failure = _this._failure) !== null && _this$_failure !== void 0 || (_this._failure = { reason: "closed" });
941
+ resolve(null);
942
+ }));
943
+ externalWindow.addEventListener("load", () => {
944
+ /**
945
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
946
+ */
947
+ try {
948
+ var _globalThis$document$, _this$options$styleRo, _this$options3;
949
+ const externalDocument = externalWindow.document;
950
+ externalDocument.title = document.title;
951
+ externalDocument.body.appendChild(container);
952
+ addStyles(externalDocument, [...Array.from(globalThis.document.styleSheets), ...(_globalThis$document$ = globalThis.document.adoptedStyleSheets) !== null && _globalThis$document$ !== void 0 ? _globalThis$document$ : []], { nonce: _this.options.nonce });
953
+ const sheets = [];
954
+ for (let root = (_this$options$styleRo = (_this$options3 = _this.options).styleRoot) === null || _this$options$styleRo === void 0 ? void 0 : _this$options$styleRo.call(_this$options3); isShadowRoot(root); root = root.host.getRootNode()) {
955
+ var _root$styleSheets, _root$adoptedStyleShe;
956
+ sheets.push(...Array.from((_root$styleSheets = root.styleSheets) !== null && _root$styleSheets !== void 0 ? _root$styleSheets : []), ...(_root$adoptedStyleShe = root.adoptedStyleSheets) !== null && _root$adoptedStyleShe !== void 0 ? _root$adoptedStyleShe : []);
957
+ }
958
+ if (sheets.length > 0) addStyles(externalDocument, sheets, { nonce: _this.options.nonce });
959
+ /**
960
+ * beforeunload must be registered after load for reasons I could not determine
961
+ * otherwise the beforeunload event will not fire when the window is closed
962
+ */
963
+ addDisposableListener(externalWindow, "beforeunload", () => {
964
+ /**
965
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
966
+ */
967
+ _this.close();
968
+ });
969
+ resolve(container);
970
+ } catch (err) {
971
+ abandon(err);
972
+ }
973
+ });
974
+ });
975
+ })();
976
+ }
977
+ /**
978
+ * Backstop for the `beforeunload` signal, which a window torn down without
979
+ * running its unload handlers never sends: a native shell destroying the
980
+ * webview, or a browser discarding the page. `closed` is readable on any
981
+ * handle, cross-origin included. Whichever signal arrives first wins.
982
+ */
983
+ watchForClose(externalWindow) {
984
+ if (typeof externalWindow.closed !== "boolean") return Disposable.NONE;
985
+ const handle = setInterval(() => {
986
+ if (externalWindow.closed) this.close();
987
+ }, CLOSED_POLL_INTERVAL_MS);
988
+ return Disposable.from(() => {
989
+ clearInterval(handle);
990
+ });
991
+ }
992
+ createPopoutWindowContainer() {
993
+ const el = document.createElement("div");
994
+ el.classList.add("dv-popout-window");
995
+ el.id = "dv-popout-window";
996
+ el.style.position = "absolute";
997
+ el.style.width = "100%";
998
+ el.style.height = "100%";
999
+ el.style.top = "0px";
1000
+ el.style.left = "0px";
1001
+ return el;
1002
+ }
1003
+ };
627
1004
 
628
1005
  //#endregion
629
1006
  //#region src/array.ts
@@ -843,6 +1220,15 @@ var Splitview = class {
843
1220
  get proportions() {
844
1221
  return this._proportions ? [...this._proportions] : void 0;
845
1222
  }
1223
+ get proportionalLayout() {
1224
+ return this._proportionalLayout;
1225
+ }
1226
+ set proportionalLayout(value) {
1227
+ if (this._proportionalLayout === value) return;
1228
+ this._proportionalLayout = value;
1229
+ if (value) this.saveProportions();
1230
+ else this._proportions = void 0;
1231
+ }
846
1232
  get orientation() {
847
1233
  return this._orientation;
848
1234
  }
@@ -967,7 +1353,7 @@ var Splitview = class {
967
1353
  this._orientation = (_options$orientation = options.orientation) !== null && _options$orientation !== void 0 ? _options$orientation : "VERTICAL";
968
1354
  this.element = this.createContainer();
969
1355
  this.margin = (_options$margin = options.margin) !== null && _options$margin !== void 0 ? _options$margin : 0;
970
- this.proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
1356
+ this._proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
971
1357
  this.viewContainer = this.createViewContainer();
972
1358
  this.sashContainer = this.createSashContainer();
973
1359
  this.element.appendChild(this.sashContainer);
@@ -1691,10 +2077,18 @@ var BranchNode = class BranchNode extends CompositeDisposable {
1691
2077
  if (child instanceof BranchNode) child.margin = value;
1692
2078
  });
1693
2079
  }
2080
+ get proportionalLayout() {
2081
+ return this.splitview.proportionalLayout;
2082
+ }
2083
+ set proportionalLayout(value) {
2084
+ this.splitview.proportionalLayout = value;
2085
+ this.children.forEach((child) => {
2086
+ if (child instanceof BranchNode) child.proportionalLayout = value;
2087
+ });
2088
+ }
1694
2089
  constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, margin, childDescriptors) {
1695
2090
  super();
1696
2091
  this.orientation = orientation;
1697
- this.proportionalLayout = proportionalLayout;
1698
2092
  this.styles = styles;
1699
2093
  this._childrenDisposable = Disposable.NONE;
1700
2094
  this.children = [];
@@ -2236,8 +2630,13 @@ var Gridview = class {
2236
2630
  }
2237
2631
  return findLeaf(this.root, reverse);
2238
2632
  }
2633
+ get proportionalLayout() {
2634
+ return this.root.proportionalLayout;
2635
+ }
2636
+ set proportionalLayout(value) {
2637
+ this.root.proportionalLayout = value;
2638
+ }
2239
2639
  constructor(proportionalLayout, styles, orientation, locked, margin) {
2240
- this.proportionalLayout = proportionalLayout;
2241
2640
  this.styles = styles;
2242
2641
  this._locked = false;
2243
2642
  this._margin = 0;
@@ -2431,6 +2830,25 @@ var Resizable = class extends CompositeDisposable {
2431
2830
  this.layout(width, height);
2432
2831
  }));
2433
2832
  }
2833
+ /**
2834
+ * Lay out from the element's current size.
2835
+ *
2836
+ * The ResizeObserver above only reports asynchronously, so between
2837
+ * construction and its first callback the component believes it has no
2838
+ * size - and anything built in that window (panels added right after
2839
+ * `createDockview`, say) resolves its sizes against zero and collapses to
2840
+ * minimums. Concrete components call this once they are fully constructed
2841
+ * so that work sees the real size. The same guards as the observer apply:
2842
+ * a detached or hidden element has no size worth propagating.
2843
+ */
2844
+ layoutFromElement() {
2845
+ if (this.disableResizing || !this._element.offsetParent) return;
2846
+ if (!isInDocument(this._element)) return;
2847
+ const width = Math.round(this._element.clientWidth);
2848
+ const height = Math.round(this._element.clientHeight);
2849
+ if (width === 0 || height === 0) return;
2850
+ this.layout(width, height);
2851
+ }
2434
2852
  };
2435
2853
 
2436
2854
  //#endregion
@@ -2531,7 +2949,10 @@ var BaseGrid = class extends Resizable {
2531
2949
  return this.gridview.isViewVisible(getGridLocation(panel.element));
2532
2950
  }
2533
2951
  updateOptions(options) {
2534
- if (typeof options.proportionalLayout === "boolean") {}
2952
+ if ("proportionalLayout" in options) {
2953
+ var _options$proportional;
2954
+ this.gridview.proportionalLayout = (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true;
2955
+ }
2535
2956
  if (options.orientation) this.gridview.orientation = options.orientation;
2536
2957
  if ("styles" in options) {}
2537
2958
  if ("disableAutoResizing" in options) {
@@ -3340,6 +3761,15 @@ var DockviewApi = class {
3340
3761
  get onUnhandledDragOver() {
3341
3762
  return this.component.onUnhandledDragOver;
3342
3763
  }
3764
+ /**
3765
+ * The drag-and-drop backends currently live: `dndStrategy` resolved against
3766
+ * this device, which `'auto'` reads from the primary input device. Only an
3767
+ * HTML5 drag can leave the window it started in, so check `html5` before
3768
+ * relying on a drag between a popout window and the main window.
3769
+ */
3770
+ get dndCapabilities() {
3771
+ return this.component.dndCapabilities;
3772
+ }
3343
3773
  get onDidPopoutGroupSizeChange() {
3344
3774
  return this.component.onDidPopoutGroupSizeChange;
3345
3775
  }
@@ -3362,9 +3792,27 @@ var DockviewApi = class {
3362
3792
  get onDidRemovePopoutGroup() {
3363
3793
  return this.component.onDidRemovePopoutGroup;
3364
3794
  }
3795
+ /**
3796
+ * Fires when a popout window could not be used, carrying which way it
3797
+ * failed: the URL was refused, the browser blocked the window, the host
3798
+ * returned a window whose document the opener cannot reach, or it closed
3799
+ * before loading. The group stays in (or returns to) the main grid.
3800
+ */
3365
3801
  get onDidOpenPopoutWindowFail() {
3366
3802
  return this.component.onDidOpenPopoutWindowFail;
3367
3803
  }
3804
+ /**
3805
+ * Fires as dockview lets go of a popout window, while that window is still
3806
+ * open, carrying its live `Window` handle. Covers every popout the component
3807
+ * opened and every reason for closing one, disposal included;
3808
+ * {@link onDidAddPopoutGroup} is the opening half.
3809
+ *
3810
+ * For hosts that own their windows: in a desktop webview the page's own
3811
+ * `close()` can be a no-op, so the shell has to be told.
3812
+ */
3813
+ get onWillClosePopoutWindow() {
3814
+ return this.component.onWillClosePopoutWindow;
3815
+ }
3368
3816
  /** Enumerate the popout groups currently open in their own windows. */
3369
3817
  getPopouts() {
3370
3818
  return this.component.getPopouts();
@@ -4331,7 +4779,8 @@ function addGhostImage(dataTransfer, ghostElement, options) {
4331
4779
  var _options$ownerDocumen, _options$x, _options$y;
4332
4780
  addClasses(ghostElement, "dv-dragged");
4333
4781
  ghostElement.style.top = "-9999px";
4334
- ((_options$ownerDocumen = options === null || options === void 0 ? void 0 : options.ownerDocument) !== null && _options$ownerDocumen !== void 0 ? _options$ownerDocumen : document).body.appendChild(ghostElement);
4782
+ ghostElement.style.position = "absolute";
4783
+ ((options === null || options === void 0 ? void 0 : options.owner) ? getOverlayParent(options.owner) : ((_options$ownerDocumen = options === null || options === void 0 ? void 0 : options.ownerDocument) !== null && _options$ownerDocumen !== void 0 ? _options$ownerDocumen : document).body).appendChild(ghostElement);
4335
4784
  dataTransfer.setDragImage(ghostElement, (_options$x = options === null || options === void 0 ? void 0 : options.x) !== null && _options$x !== void 0 ? _options$x : 0, (_options$y = options === null || options === void 0 ? void 0 : options.y) !== null && _options$y !== void 0 ? _options$y : 0);
4336
4785
  setTimeout(() => {
4337
4786
  removeClasses(ghostElement, "dv-dragged");
@@ -4383,7 +4832,7 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4383
4832
  } };
4384
4833
  }
4385
4834
  beginDrag(args) {
4386
- var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3;
4835
+ var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3, _source$ownerDocument4;
4387
4836
  if (this._active) this.cancel();
4388
4837
  const { pointerEvent, source } = args;
4389
4838
  const dataDisposable = args.getData();
@@ -4399,13 +4848,14 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4399
4848
  this._dataDisposable = dataDisposable;
4400
4849
  this._ghost = args.ghost;
4401
4850
  this._iframeShield = disableIframePointEvents((_source$ownerDocument = source.ownerDocument) !== null && _source$ownerDocument !== void 0 ? _source$ownerDocument : document);
4851
+ this._selectionShield = disableTextSelection((_source$ownerDocument2 = source.ownerDocument) !== null && _source$ownerDocument2 !== void 0 ? _source$ownerDocument2 : document);
4402
4852
  const startEvent = {
4403
4853
  clientX: pointerEvent.clientX,
4404
4854
  clientY: pointerEvent.clientY,
4405
4855
  pointerEvent
4406
4856
  };
4407
4857
  this._onDragStart.fire(startEvent);
4408
- const targetWindow = (_source$ownerDocument2 = (_source$ownerDocument3 = source.ownerDocument) === null || _source$ownerDocument3 === void 0 ? void 0 : _source$ownerDocument3.defaultView) !== null && _source$ownerDocument2 !== void 0 ? _source$ownerDocument2 : globalThis.window;
4858
+ const targetWindow = (_source$ownerDocument3 = (_source$ownerDocument4 = source.ownerDocument) === null || _source$ownerDocument4 === void 0 ? void 0 : _source$ownerDocument4.defaultView) !== null && _source$ownerDocument3 !== void 0 ? _source$ownerDocument3 : globalThis.window;
4409
4859
  this._moveListener = addDisposableListener(targetWindow, "pointermove", (e) => {
4410
4860
  var _this$_active;
4411
4861
  if (e.pointerId !== ((_this$_active = this._active) === null || _this$_active === void 0 ? void 0 : _this$_active.pointerId)) return;
@@ -4442,13 +4892,13 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4442
4892
  }
4443
4893
  }
4444
4894
  _findTargetUnder(x, y) {
4445
- var _this$_active$source$, _this$_active4;
4446
- const elements = ((_this$_active$source$ = (_this$_active4 = this._active) === null || _this$_active4 === void 0 ? void 0 : _this$_active4.source.ownerDocument) !== null && _this$_active$source$ !== void 0 ? _this$_active$source$ : document).elementsFromPoint(x, y);
4895
+ const elements = (this._active ? getHitTestRoot(this._active.source) : document).elementsFromPoint(x, y);
4447
4896
  for (const el of elements) {
4448
4897
  let current = el;
4449
4898
  while (current) {
4899
+ var _target$isHitTestTran;
4450
4900
  const target = this._targetByElement.get(current);
4451
- if (target) return target;
4901
+ if (target && !((_target$isHitTestTran = target.isHitTestTransparent) === null || _target$isHitTestTran === void 0 ? void 0 : _target$isHitTestTran.call(target))) return target;
4452
4902
  current = current.parentElement;
4453
4903
  }
4454
4904
  }
@@ -4492,7 +4942,7 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4492
4942
  this._onDragEnd.fire(dragEvent);
4493
4943
  }
4494
4944
  _teardown() {
4495
- var _this$_ghost2, _this$_iframeShield, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4945
+ var _this$_ghost2, _this$_iframeShield, _this$_selectionShiel, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4496
4946
  this._currentTarget = void 0;
4497
4947
  this._active = void 0;
4498
4948
  this._lastPointerEvent = void 0;
@@ -4502,6 +4952,8 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4502
4952
  this._ghost = void 0;
4503
4953
  (_this$_iframeShield = this._iframeShield) === null || _this$_iframeShield === void 0 || _this$_iframeShield.release();
4504
4954
  this._iframeShield = void 0;
4955
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
4956
+ this._selectionShield = void 0;
4505
4957
  (_this$_moveListener = this._moveListener) === null || _this$_moveListener === void 0 || _this$_moveListener.dispose();
4506
4958
  (_this$_upListener = this._upListener) === null || _this$_upListener === void 0 || _this$_upListener.dispose();
4507
4959
  (_this$_cancelListener = this._cancelListener) === null || _this$_cancelListener === void 0 || _this$_cancelListener.dispose();
@@ -4544,10 +4996,14 @@ var PointerDropTarget = class extends CompositeDisposable {
4544
4996
  element: this.element,
4545
4997
  handleDragOver: (e) => this._onDragOver(e),
4546
4998
  handleDragLeave: () => this._onDragLeave(),
4547
- handleDrop: (e) => this._onDropEvent(e)
4999
+ handleDrop: (e) => this._onDropEvent(e),
5000
+ isHitTestTransparent: options.isHitTestTransparent
4548
5001
  };
4549
5002
  this.addDisposables(this._onDrop, this._onWillShowOverlay, PointerDragController.getInstance().registerTarget(handle));
4550
5003
  }
5004
+ clearOverlay() {
5005
+ this._clearOwnOverlay();
5006
+ }
4551
5007
  setTargetZones(zones) {
4552
5008
  this._acceptedTargetZonesSet = new Set(zones);
4553
5009
  }
@@ -4766,9 +5222,10 @@ var PointerDragSource = class extends CompositeDisposable {
4766
5222
  return true;
4767
5223
  }
4768
5224
  _onPointerDown(event) {
4769
- var _ref, _this$options$thresho, _ref2, _this$element$ownerDo, _this$element$ownerDo2;
5225
+ var _this$element$ownerDo, _ref, _this$options$thresho, _ref2, _this$element$ownerDo2, _this$element$ownerDo3;
4770
5226
  if (!this._shouldHandle(event)) return;
4771
5227
  this._cancelPending();
5228
+ this._selectionShield = disableTextSelection((_this$element$ownerDo = this.element.ownerDocument) !== null && _this$element$ownerDo !== void 0 ? _this$element$ownerDo : document);
4772
5229
  this._pendingPointerId = event.pointerId;
4773
5230
  this._startX = event.clientX;
4774
5231
  this._startY = event.clientY;
@@ -4784,7 +5241,7 @@ var PointerDragSource = class extends CompositeDisposable {
4784
5241
  const threshold = (_this$options$thresho = this.options.threshold) !== null && _this$options$thresho !== void 0 ? _this$options$thresho : DEFAULT_THRESHOLD;
4785
5242
  const pressToleranceOpt = this.options.pressTolerance;
4786
5243
  const pressTolerance = (_ref2 = typeof pressToleranceOpt === "function" ? pressToleranceOpt() : pressToleranceOpt) !== null && _ref2 !== void 0 ? _ref2 : DEFAULT_PRESS_TOLERANCE;
4787
- const targetWindow = (_this$element$ownerDo = (_this$element$ownerDo2 = this.element.ownerDocument) === null || _this$element$ownerDo2 === void 0 ? void 0 : _this$element$ownerDo2.defaultView) !== null && _this$element$ownerDo !== void 0 ? _this$element$ownerDo : globalThis.window;
5244
+ const targetWindow = (_this$element$ownerDo2 = (_this$element$ownerDo3 = this.element.ownerDocument) === null || _this$element$ownerDo3 === void 0 ? void 0 : _this$element$ownerDo3.defaultView) !== null && _this$element$ownerDo2 !== void 0 ? _this$element$ownerDo2 : globalThis.window;
4788
5245
  this._pendingMoveListener = addDisposableListener(targetWindow, "pointermove", (moveEvent) => {
4789
5246
  if (moveEvent.pointerId !== this._pendingPointerId) return;
4790
5247
  const dx = moveEvent.clientX - this._startX;
@@ -4810,7 +5267,9 @@ var PointerDragSource = class extends CompositeDisposable {
4810
5267
  this._cancelPending();
4811
5268
  }
4812
5269
  _cancelPending() {
4813
- var _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5270
+ var _this$_selectionShiel, _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5271
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
5272
+ this._selectionShield = void 0;
4814
5273
  this._pendingPointerId = void 0;
4815
5274
  if (this._armTimer !== void 0) {
4816
5275
  clearTimeout(this._armTimer);
@@ -4855,29 +5314,51 @@ var PointerDragSource = class extends CompositeDisposable {
4855
5314
  */
4856
5315
  var PointerGhost = class {
4857
5316
  constructor(opts) {
4858
- var _opts$offsetX, _opts$offsetY, _opts$opacity, _opts$owner$ownerDocu, _opts$owner;
5317
+ var _opts$offsetX, _opts$offsetY, _popover, _opts$opacity;
4859
5318
  this._disposed = false;
4860
5319
  this.element = opts.element;
4861
5320
  this.offsetX = (_opts$offsetX = opts.offsetX) !== null && _opts$offsetX !== void 0 ? _opts$offsetX : 0;
4862
5321
  this.offsetY = (_opts$offsetY = opts.offsetY) !== null && _opts$offsetY !== void 0 ? _opts$offsetY : 0;
4863
- this.element.style.position = "fixed";
4864
- this.element.style.left = "0px";
4865
- this.element.style.top = "0px";
4866
- this.element.style.pointerEvents = "none";
4867
- this.element.style.zIndex = "99999";
4868
- this.element.style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
4869
- this.element.style.willChange = "transform";
4870
- this.element.style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
4871
- ((_opts$owner$ownerDocu = (_opts$owner = opts.owner) === null || _opts$owner === void 0 ? void 0 : _opts$owner.ownerDocument) !== null && _opts$owner$ownerDocu !== void 0 ? _opts$owner$ownerDocu : document).body.appendChild(this.element);
5322
+ const parent = opts.owner ? getOverlayParent(opts.owner) : document.body;
5323
+ let popover;
5324
+ if (isShadowRoot(parent) && typeof this.element.showPopover === "function") {
5325
+ popover = this.element.ownerDocument.createElement("div");
5326
+ popover.popover = "manual";
5327
+ Object.assign(popover.style, {
5328
+ inset: "auto",
5329
+ margin: "0",
5330
+ padding: "0",
5331
+ border: "0",
5332
+ background: "transparent",
5333
+ color: "inherit",
5334
+ overflow: "visible"
5335
+ });
5336
+ popover.appendChild(this.element);
5337
+ this.element.style.pointerEvents = "none";
5338
+ this.element.style.transform = "none";
5339
+ }
5340
+ this.container = (_popover = popover) !== null && _popover !== void 0 ? _popover : this.element;
5341
+ const style = this.container.style;
5342
+ style.position = "fixed";
5343
+ style.left = "0px";
5344
+ style.top = "0px";
5345
+ style.pointerEvents = "none";
5346
+ style.zIndex = "99999";
5347
+ style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
5348
+ style.willChange = "transform";
5349
+ style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
5350
+ parent.appendChild(this.container);
5351
+ popover === null || popover === void 0 || popover.showPopover();
4872
5352
  }
4873
5353
  update(clientX, clientY) {
4874
5354
  if (this._disposed) return;
4875
- this.element.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
5355
+ this.container.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
4876
5356
  }
4877
5357
  dispose() {
4878
5358
  if (this._disposed) return;
4879
5359
  this._disposed = true;
4880
5360
  this.element.remove();
5361
+ if (this.container !== this.element) this.container.remove();
4881
5362
  }
4882
5363
  };
4883
5364
 
@@ -4914,7 +5395,8 @@ var Html5DragSource = class extends CompositeDisposable {
4914
5395
  addGhostImage(event.dataTransfer, ghost.element, {
4915
5396
  x: (_ghost$offsetX = ghost.offsetX) !== null && _ghost$offsetX !== void 0 ? _ghost$offsetX : 0,
4916
5397
  y: (_ghost$offsetY = ghost.offsetY) !== null && _ghost$offsetY !== void 0 ? _ghost$offsetY : 0,
4917
- ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0
5398
+ ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0,
5399
+ owner: this.el
4918
5400
  });
4919
5401
  if (ghost.dispose) {
4920
5402
  const disposeGhost = ghost.dispose;
@@ -5750,8 +6232,7 @@ var LongPressDetector = class extends CompositeDisposable {
5750
6232
  let guard;
5751
6233
  const timeout = setTimeout(() => guard === null || guard === void 0 ? void 0 : guard.dispose(), 500);
5752
6234
  guard = addDisposableListener(targetWindow, "click", (event) => {
5753
- const target = event.target;
5754
- if (target && this.element.contains(target)) {
6235
+ if (isEventWithin(event, [this.element])) {
5755
6236
  event.preventDefault();
5756
6237
  event.stopPropagation();
5757
6238
  }
@@ -5867,6 +6348,7 @@ var Tab = class extends CompositeDisposable {
5867
6348
  if (this.accessor.id === (data === null || data === void 0 ? void 0 : data.viewId)) {
5868
6349
  var _this$accessor$option;
5869
6350
  if (((_this$accessor$option = this.accessor.options.theme) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.tabAnimation) === "smooth") return false;
6351
+ if (data.tabGroupId && data.groupId === this.group.id && this.group.model.getTabGroupForPanel(this.panel.id)) return false;
5870
6352
  return true;
5871
6353
  }
5872
6354
  return this.group.model.canDisplayOverlay(event, position, "tab");
@@ -6479,6 +6961,7 @@ var DockviewUnhandledDragOverEvent = class extends AcceptableEvent {
6479
6961
  const PROPERTY_KEYS_DOCKVIEW = (() => {
6480
6962
  return Object.keys({
6481
6963
  disableAutoResizing: void 0,
6964
+ proportionalLayout: void 0,
6482
6965
  hideBorders: void 0,
6483
6966
  singleTabMode: void 0,
6484
6967
  disableFloatingGroups: void 0,
@@ -7314,12 +7797,34 @@ var TabGroupManager = class {
7314
7797
  }
7315
7798
  updateDirection() {
7316
7799
  const isVertical = this._ctx.getDirection() === "vertical";
7317
- for (const [, entry] of this._chipRenderers) entry.dropTarget.setTargetZones(isVertical ? ["top"] : ["left"]);
7800
+ for (const [, entry] of this._chipRenderers) {
7801
+ const zones = isVertical ? ["top"] : ["left"];
7802
+ entry.dropTarget.setTargetZones(zones);
7803
+ entry.pointerDropTarget.setTargetZones(zones);
7804
+ }
7318
7805
  }
7319
- snapshotChipWidths() {
7320
- const widths = /* @__PURE__ */ new Map();
7321
- for (const [groupId, entry] of this._chipRenderers) widths.set(groupId, entry.chip.element.getBoundingClientRect().width);
7322
- return widths;
7806
+ /**
7807
+ * Drop any overlay the chips are showing. A group move is committed by a
7808
+ * capturing listener on the tabs list that stops the event, so the chip
7809
+ * target under the cursor never sees the drop that would clear its own.
7810
+ */
7811
+ clearChipDropOverlays() {
7812
+ for (const [, entry] of this._chipRenderers) {
7813
+ var _entry$dropTarget, _entry$pointerDropTar;
7814
+ (_entry$dropTarget = entry.dropTarget) === null || _entry$dropTarget === void 0 || _entry$dropTarget.clearOverlay();
7815
+ (_entry$pointerDropTar = entry.pointerDropTarget) === null || _entry$pointerDropTar === void 0 || _entry$pointerDropTar.clearOverlay();
7816
+ }
7817
+ }
7818
+ /** Each chip's extent along the strip's main axis: width for a horizontal
7819
+ * header, height for a vertical one. */
7820
+ snapshotChipSizes() {
7821
+ const isVertical = this._ctx.getDirection() === "vertical";
7822
+ const sizes = /* @__PURE__ */ new Map();
7823
+ for (const [groupId, entry] of this._chipRenderers) {
7824
+ const rect = entry.chip.element.getBoundingClientRect();
7825
+ sizes.set(groupId, isVertical ? rect.height : rect.width);
7826
+ }
7827
+ return sizes;
7323
7828
  }
7324
7829
  positionUnderlines() {
7325
7830
  var _this$_indicator2;
@@ -7563,9 +8068,8 @@ var TabGroupManager = class {
7563
8068
  };
7564
8069
  if (chip instanceof TabGroupChip) disposables.push(chip.onContextMenu(onContextMenu));
7565
8070
  else disposables.push(new LongPressDetector(chip.element, { onLongPress: onContextMenu }), addDisposableListener(chip.element, "contextmenu", onContextMenu));
7566
- const isVertical = this._ctx.getDirection() === "vertical";
7567
- const dropTarget = new Droptarget(chip.element, {
7568
- acceptedTargetZones: isVertical ? ["top"] : ["left"],
8071
+ const dropTargetOptions = {
8072
+ acceptedTargetZones: this._ctx.getDirection() === "vertical" ? ["top"] : ["left"],
7569
8073
  overlayModel: { activationSize: {
7570
8074
  value: 100,
7571
8075
  type: "percentage"
@@ -7576,15 +8080,18 @@ var TabGroupManager = class {
7576
8080
  const data = getPanelData();
7577
8081
  if (this._ctx.accessor.id === (data === null || data === void 0 ? void 0 : data.viewId)) {
7578
8082
  var _this$_ctx$accessor$o3;
7579
- if (((_this$_ctx$accessor$o3 = this._ctx.accessor.options.theme) === null || _this$_ctx$accessor$o3 === void 0 ? void 0 : _this$_ctx$accessor$o3.tabAnimation) === "smooth") return false;
8083
+ if (((_this$_ctx$accessor$o3 = this._ctx.accessor.options.theme) === null || _this$_ctx$accessor$o3 === void 0 ? void 0 : _this$_ctx$accessor$o3.tabAnimation) === "smooth" && !data.tabGroupId) return false;
7580
8084
  return true;
7581
8085
  }
7582
8086
  return this._ctx.group.model.canDisplayOverlay(event, position, "tab");
7583
8087
  }
7584
- });
7585
- disposables.push(dropTarget, dropTarget.onDrop((event) => {
8088
+ };
8089
+ const dropTarget = html5Backend.createDropTarget(chip.element, dropTargetOptions);
8090
+ const pointerDropTarget = pointerBackend.createDropTarget(chip.element, dropTargetOptions);
8091
+ const onDrop = (event) => {
7586
8092
  this._callbacks.onChipDrop(tabGroup, event);
7587
- }));
8093
+ };
8094
+ disposables.push(dropTarget, dropTarget.onDrop(onDrop), pointerDropTarget, pointerDropTarget.onDrop(onDrop));
7588
8095
  const disposable = new CompositeDisposable(...disposables);
7589
8096
  this._chipRenderers.set(tabGroup.id, {
7590
8097
  chip,
@@ -7592,7 +8099,8 @@ var TabGroupManager = class {
7592
8099
  pointerDragSource: dragSources.pointerDragSource,
7593
8100
  dragSourcesDisposable: dragSources.disposable,
7594
8101
  disposable,
7595
- dropTarget
8102
+ dropTarget,
8103
+ pointerDropTarget
7596
8104
  });
7597
8105
  if (tabGroup.collapsed) this._skipNextCollapseAnimation = true;
7598
8106
  }
@@ -7708,6 +8216,22 @@ var TabGroupManager = class {
7708
8216
  //#endregion
7709
8217
  //#region src/dockview/components/titlebar/tabReorderController.ts
7710
8218
  /**
8219
+ * Main-axis extent of a rect. Tabs flow along x in a horizontal header
8220
+ * (top/bottom) and along y in a vertical one (the left/right edge groups),
8221
+ * so the reorder math reads every size through this.
8222
+ */
8223
+ function mainAxisSize(rect, direction) {
8224
+ return direction === "vertical" ? rect.height : rect.width;
8225
+ }
8226
+ /** Leading edge of a rect along the main axis. */
8227
+ function mainAxisStart(rect, direction) {
8228
+ return direction === "vertical" ? rect.top : rect.left;
8229
+ }
8230
+ /** A cursor position projected onto the main axis. */
8231
+ function mainAxisCursor(event, direction) {
8232
+ return direction === "vertical" ? event.clientY : event.clientX;
8233
+ }
8234
+ /**
7711
8235
  * Tab drag-reorder + FLIP animation subsystem extracted from `Tabs`. The DOM
7712
8236
  * event wiring remains in `Tabs` and delegates the reorder/animation logic to
7713
8237
  * this controller. All access back into `Tabs` goes through
@@ -7802,14 +8326,30 @@ var TabReorderController = class extends CompositeDisposable {
7802
8326
  for (const tab of this._tabs) positions.set(tab.value.panel.id, tab.value.element.getBoundingClientRect());
7803
8327
  return positions;
7804
8328
  }
7805
- getAverageTabWidth() {
8329
+ /** Main-axis extent of a rect for this header's orientation. */
8330
+ _mainAxisSize(rect) {
8331
+ return mainAxisSize(rect, this._direction);
8332
+ }
8333
+ /** Main-axis leading edge of a rect for this header's orientation. */
8334
+ _mainAxisStart(rect) {
8335
+ return mainAxisStart(rect, this._direction);
8336
+ }
8337
+ /** The cursor coordinate along the main axis. */
8338
+ _mainAxisCoord(clientX, clientY) {
8339
+ return mainAxisCursor({
8340
+ clientX,
8341
+ clientY
8342
+ }, this._direction);
8343
+ }
8344
+ /** The margin that opens the insertion gap. It must run along the main
8345
+ * axis, so a vertical header pushes tabs down rather than sideways. */
8346
+ get _gapMarginProperty() {
8347
+ return this._direction === "vertical" ? "margin-top" : "margin-left";
8348
+ }
8349
+ getAverageTabSize() {
7806
8350
  if (this._tabs.length === 0) return 0;
7807
- const isVertical = this._direction === "vertical";
7808
8351
  let total = 0;
7809
- for (const tab of this._tabs) {
7810
- const rect = tab.value.element.getBoundingClientRect();
7811
- total += isVertical ? rect.height : rect.width;
7812
- }
8352
+ for (const tab of this._tabs) total += this._mainAxisSize(tab.value.element.getBoundingClientRect());
7813
8353
  return total / this._tabs.length;
7814
8354
  }
7815
8355
  /**
@@ -7819,8 +8359,7 @@ var TabReorderController = class extends CompositeDisposable {
7819
8359
  * `processDragOver` / `processDragLeave` helpers.
7820
8360
  */
7821
8361
  handlePointerDragMove(clientX, clientY) {
7822
- var _this$_tabsList$owner;
7823
- const elAtPoint = ((_this$_tabsList$owner = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner !== void 0 ? _this$_tabsList$owner : document).elementFromPoint(clientX, clientY);
8362
+ const elAtPoint = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7824
8363
  if (!(!!elAtPoint && (this._tabsList.contains(elAtPoint) || !!this._extendedDropZone && this._extendedDropZone.contains(elAtPoint)))) {
7825
8364
  if (this._pointerInsideTabsList) {
7826
8365
  this._pointerInsideTabsList = false;
@@ -7837,13 +8376,19 @@ var TabReorderController = class extends CompositeDisposable {
7837
8376
  * dragover bridge may have installed.
7838
8377
  */
7839
8378
  handlePointerDragEnd(e) {
7840
- if (e && this._animState && this._animState.sourceIndex !== -1 && !this._animState.sourceTabGroupId && this._animState.currentInsertionIndex !== null && this.isPointInsideTabsList(e.clientX, e.clientY)) this.commitPointerReorder(e.pointerEvent);
8379
+ if (e && this._animState && this._animState.sourceIndex !== -1 && this._animState.currentInsertionIndex !== null && this.isPointInsideTabsList(e.clientX, e.clientY)) {
8380
+ const sourceTabGroupId = this._animState.sourceTabGroupId;
8381
+ if (sourceTabGroupId) {
8382
+ const insertionIndex = this._animState.currentInsertionIndex;
8383
+ this._animState = null;
8384
+ this.commitGroupMove(sourceTabGroupId, insertionIndex);
8385
+ } else this.commitPointerReorder(e.pointerEvent);
8386
+ }
7841
8387
  this._pointerInsideTabsList = false;
7842
8388
  this.resetDragAnimation();
7843
8389
  }
7844
8390
  isPointInsideTabsList(clientX, clientY) {
7845
- var _this$_tabsList$owner2;
7846
- const el = ((_this$_tabsList$owner2 = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner2 !== void 0 ? _this$_tabsList$owner2 : document).elementFromPoint(clientX, clientY);
8391
+ const el = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7847
8392
  return !!el && this._tabsList.contains(el);
7848
8393
  }
7849
8394
  /** Commit a smooth-mode intra-group reorder from the current insertion
@@ -7907,46 +8452,46 @@ var TabReorderController = class extends CompositeDisposable {
7907
8452
  const data = getPanelData();
7908
8453
  if (((_this$accessor$option = this.accessor.options.theme) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.tabAnimation) === "default" && !(data === null || data === void 0 ? void 0 : data.tabGroupId)) return false;
7909
8454
  if (!data || !(data.panelId || data.tabGroupId) || data.groupId === this.group.id) return false;
7910
- const avgWidth = this.getAverageTabWidth();
7911
- this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgWidth) : this._makeTabDragAnimState(data, avgWidth);
8455
+ const avgSize = this.getAverageTabSize();
8456
+ this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgSize) : this._makeTabDragAnimState(data, avgSize);
7912
8457
  return true;
7913
8458
  }
7914
8459
  /** Anim state for an external group-chip drag (gap sized to the group). */
7915
- _makeGroupDragAnimState(data, avgWidth) {
8460
+ _makeGroupDragAnimState(data, avgSize) {
7916
8461
  var _sourceTg$panelIds$le;
7917
8462
  const sourceGroup = this.accessor.getPanel(data.groupId);
7918
8463
  const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
7919
- const groupGapWidth = avgWidth * ((_sourceTg$panelIds$le = sourceTg === null || sourceTg === void 0 ? void 0 : sourceTg.panelIds.length) !== null && _sourceTg$panelIds$le !== void 0 ? _sourceTg$panelIds$le : 1) + avgWidth;
8464
+ const groupGapSize = avgSize * ((_sourceTg$panelIds$le = sourceTg === null || sourceTg === void 0 ? void 0 : sourceTg.panelIds.length) !== null && _sourceTg$panelIds$le !== void 0 ? _sourceTg$panelIds$le : 1) + avgSize;
7920
8465
  return {
7921
8466
  sourceTabId: "",
7922
8467
  sourceIndex: -1,
7923
8468
  tabPositions: this.snapshotTabPositions(),
7924
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8469
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7925
8470
  currentInsertionIndex: null,
7926
8471
  targetTabGroupId: null,
7927
8472
  sourceTabGroupId: data.tabGroupId,
7928
8473
  sourceGroupPanelIds: sourceTg ? new Set(sourceTg.panelIds) : /* @__PURE__ */ new Set(),
7929
- sourceChipWidth: avgWidth,
7930
- cursorOffsetFromDragLeft: groupGapWidth / 2,
7931
- sourceGapWidth: groupGapWidth,
7932
- containerLeft: this._tabsList.getBoundingClientRect().left
8474
+ sourceChipSize: avgSize,
8475
+ cursorOffsetFromDragStart: groupGapSize / 2,
8476
+ sourceGapSize: groupGapSize,
8477
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7933
8478
  };
7934
8479
  }
7935
8480
  /** Anim state for an external single-tab drag. */
7936
- _makeTabDragAnimState(data, avgWidth) {
8481
+ _makeTabDragAnimState(data, avgSize) {
7937
8482
  return {
7938
8483
  sourceTabId: data.panelId,
7939
8484
  sourceIndex: -1,
7940
8485
  tabPositions: this.snapshotTabPositions(),
7941
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8486
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7942
8487
  currentInsertionIndex: null,
7943
8488
  targetTabGroupId: null,
7944
8489
  sourceTabGroupId: null,
7945
8490
  sourceGroupPanelIds: null,
7946
- sourceChipWidth: 0,
7947
- cursorOffsetFromDragLeft: avgWidth / 2,
7948
- sourceGapWidth: avgWidth,
7949
- containerLeft: this._tabsList.getBoundingClientRect().left
8491
+ sourceChipSize: 0,
8492
+ cursorOffsetFromDragStart: avgSize / 2,
8493
+ sourceGapSize: avgSize,
8494
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7950
8495
  };
7951
8496
  }
7952
8497
  /**
@@ -7989,19 +8534,19 @@ var TabReorderController = class extends CompositeDisposable {
7989
8534
  container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
7990
8535
  }
7991
8536
  handleDragOver(event) {
7992
- var _this$accessor$option2;
8537
+ var _event$clientY2, _this$accessor$option2;
7993
8538
  if (!this._animState) return;
7994
8539
  if (this._wrapMode && !this._animState.sourceTabGroupId) {
7995
8540
  var _event$clientY;
7996
8541
  this.handleWrappedDragOver(event.clientX, (_event$clientY = event.clientY) !== null && _event$clientY !== void 0 ? _event$clientY : 0);
7997
8542
  return;
7998
8543
  }
7999
- const mouseX = event.clientX;
8544
+ const mousePos = this._mainAxisCoord(event.clientX, (_event$clientY2 = event.clientY) !== null && _event$clientY2 !== void 0 ? _event$clientY2 : 0);
8000
8545
  const firstPanelToGroup = this._buildFirstPanelToGroupMap();
8001
- let insertionIndex = this._computeDragOverInsertionIndex(mouseX, firstPanelToGroup);
8546
+ let insertionIndex = this._computeDragOverInsertionIndex(mousePos, firstPanelToGroup);
8002
8547
  let targetTabGroupId = null;
8003
8548
  if (insertionIndex !== null && this._tabGroupManager.chipRenderers.size > 0) {
8004
- const resolved = this._resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup);
8549
+ const resolved = this._resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup);
8005
8550
  insertionIndex = resolved.insertionIndex;
8006
8551
  targetTabGroupId = resolved.targetTabGroupId;
8007
8552
  }
@@ -8025,14 +8570,15 @@ var TabReorderController = class extends CompositeDisposable {
8025
8570
  return firstPanelToGroup;
8026
8571
  }
8027
8572
  /**
8028
- * Walk the tabs left-to-right by their original widths and return the
8029
- * insertion slot for the drag image's left edge (null if no slot fits).
8573
+ * Walk the tabs in flow order by their original main-axis sizes and return
8574
+ * the insertion slot for the drag image's leading edge (null if no slot
8575
+ * fits).
8030
8576
  */
8031
- _computeDragOverInsertionIndex(mouseX, firstPanelToGroup) {
8577
+ _computeDragOverInsertionIndex(mousePos, firstPanelToGroup) {
8032
8578
  const animState = this._animState;
8033
8579
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8034
- const availableSpace = mouseX - animState.cursorOffsetFromDragLeft - animState.containerLeft;
8035
- let accWidth = 0;
8580
+ const availableSpace = mousePos - animState.cursorOffsetFromDragStart - animState.containerStart;
8581
+ let accSize = 0;
8036
8582
  let insertionIndex = null;
8037
8583
  for (let i = 0; i < this._tabs.length; i++) {
8038
8584
  const tab = this._tabs[i].value;
@@ -8040,19 +8586,19 @@ var TabReorderController = class extends CompositeDisposable {
8040
8586
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8041
8587
  const groupId = firstPanelToGroup.get(tab.panel.id);
8042
8588
  if (groupId) {
8043
- var _animState$chipPositi;
8044
- const chipWidth = (_animState$chipPositi = animState.chipPositions.get(groupId)) !== null && _animState$chipPositi !== void 0 ? _animState$chipPositi : 0;
8045
- if (accWidth + chipWidth > availableSpace) {
8589
+ var _animState$chipSizes$;
8590
+ const chipSize = (_animState$chipSizes$ = animState.chipSizes.get(groupId)) !== null && _animState$chipSizes$ !== void 0 ? _animState$chipSizes$ : 0;
8591
+ if (accSize + chipSize > availableSpace) {
8046
8592
  var _insertionIndex;
8047
8593
  (_insertionIndex = insertionIndex) !== null && _insertionIndex !== void 0 || (insertionIndex = i);
8048
8594
  break;
8049
8595
  }
8050
- accWidth += chipWidth;
8596
+ accSize += chipSize;
8051
8597
  }
8052
8598
  const origRect = animState.tabPositions.get(tab.panel.id);
8053
- const tabWidth = origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8054
- if (accWidth + tabWidth / 2 <= availableSpace) {
8055
- accWidth += tabWidth;
8599
+ const tabSize = this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8600
+ if (accSize + tabSize / 2 <= availableSpace) {
8601
+ accSize += tabSize;
8056
8602
  insertionIndex = i + 1;
8057
8603
  } else {
8058
8604
  var _insertionIndex2;
@@ -8063,11 +8609,12 @@ var TabReorderController = class extends CompositeDisposable {
8063
8609
  return insertionIndex;
8064
8610
  }
8065
8611
  /**
8066
- * Rebuild the accumulated original width up to `insertionIndex`, walking the
8067
- * tabs exactly the way the accumulation loop does, so callers know the
8068
- * original right edge of the chip (if any) that precedes the insertion slot.
8612
+ * Rebuild the accumulated original main-axis size up to `insertionIndex`,
8613
+ * walking the tabs exactly the way the accumulation loop does, so callers
8614
+ * know the original trailing edge of the chip (if any) that precedes the
8615
+ * insertion slot.
8069
8616
  */
8070
- _accumulatedWidthUpTo(insertionIndex, firstPanelToGroup) {
8617
+ _accumulatedSizeUpTo(insertionIndex, firstPanelToGroup) {
8071
8618
  const animState = this._animState;
8072
8619
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8073
8620
  let accUpTo = 0;
@@ -8078,11 +8625,11 @@ var TabReorderController = class extends CompositeDisposable {
8078
8625
  if (i >= insertionIndex) break;
8079
8626
  const gid = firstPanelToGroup.get(tab.panel.id);
8080
8627
  if (gid) {
8081
- var _animState$chipPositi2;
8082
- accUpTo += (_animState$chipPositi2 = animState.chipPositions.get(gid)) !== null && _animState$chipPositi2 !== void 0 ? _animState$chipPositi2 : 0;
8628
+ var _animState$chipSizes$2;
8629
+ accUpTo += (_animState$chipSizes$2 = animState.chipSizes.get(gid)) !== null && _animState$chipSizes$2 !== void 0 ? _animState$chipSizes$2 : 0;
8083
8630
  }
8084
8631
  const origRect = animState.tabPositions.get(tab.panel.id);
8085
- accUpTo += origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8632
+ accUpTo += this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8086
8633
  }
8087
8634
  return accUpTo;
8088
8635
  }
@@ -8090,11 +8637,11 @@ var TabReorderController = class extends CompositeDisposable {
8090
8637
  * Given a raw insertion index, snap it out of / into any tab group it falls
8091
8638
  * within and resolve the target group (if the drop should merge into one).
8092
8639
  */
8093
- _resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup) {
8640
+ _resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup) {
8094
8641
  const isGroupDrag = !!this._animState.sourceTabGroupId;
8095
- const accUpTo = this._accumulatedWidthUpTo(insertionIndex, firstPanelToGroup);
8642
+ const accUpTo = this._accumulatedSizeUpTo(insertionIndex, firstPanelToGroup);
8096
8643
  for (const tg of this.group.model.getTabGroups()) {
8097
- const resolved = this._evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag);
8644
+ const resolved = this._evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag);
8098
8645
  if (resolved) return resolved;
8099
8646
  }
8100
8647
  return {
@@ -8108,7 +8655,7 @@ var TabReorderController = class extends CompositeDisposable {
8108
8655
  * group governs the slot (the caller stops iterating), or `null` when the
8109
8656
  * group is irrelevant and the caller should keep looking.
8110
8657
  */
8111
- _evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag) {
8658
+ _evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag) {
8112
8659
  const range = this._resolveGroupRange(tg);
8113
8660
  if (!range) return null;
8114
8661
  const { firstIdx, lastIdx } = range;
@@ -8116,7 +8663,7 @@ var TabReorderController = class extends CompositeDisposable {
8116
8663
  const isJustBeforeGroup = !isInsideRange && insertionIndex === firstIdx - 1;
8117
8664
  if (!isInsideRange && !isJustBeforeGroup) return null;
8118
8665
  if (isGroupDrag) return this._resolveGroupDragTarget(insertionIndex, firstIdx, lastIdx, isInsideRange);
8119
- return this._resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8666
+ return this._resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8120
8667
  }
8121
8668
  /**
8122
8669
  * The index range this group occupies in the live tab list, excluding the
@@ -8151,13 +8698,13 @@ var TabReorderController = class extends CompositeDisposable {
8151
8698
  }
8152
8699
  /** Insertion target for a single-tab drag against a group: decide whether
8153
8700
  * the drop merges into the group based on the cursor vs the chip edge. */
8154
- _resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8155
- var _animState$chipPositi3;
8701
+ _resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8702
+ var _animState$chipSizes$3;
8156
8703
  const animState = this._animState;
8157
- const chipWidth = (_animState$chipPositi3 = animState.chipPositions.get(tg.id)) !== null && _animState$chipPositi3 !== void 0 ? _animState$chipPositi3 : 0;
8704
+ const chipSize = (_animState$chipSizes$3 = animState.chipSizes.get(tg.id)) !== null && _animState$chipSizes$3 !== void 0 ? _animState$chipSizes$3 : 0;
8158
8705
  if (isJustBeforeGroup) {
8159
8706
  if (!this._onlySourceBetween(insertionIndex, firstIdx)) return null;
8160
- if (mouseX >= (tg.collapsed ? animState.containerLeft + accUpTo + chipWidth / 2 : animState.containerLeft + accUpTo + chipWidth)) return {
8707
+ if (mousePos >= (tg.collapsed ? animState.containerStart + accUpTo + chipSize / 2 : animState.containerStart + accUpTo + chipSize)) return {
8161
8708
  insertionIndex: firstIdx,
8162
8709
  targetTabGroupId: tg.id
8163
8710
  };
@@ -8166,10 +8713,10 @@ var TabReorderController = class extends CompositeDisposable {
8166
8713
  targetTabGroupId: null
8167
8714
  };
8168
8715
  }
8169
- const chipOriginalRight = animState.containerLeft + accUpTo + chipWidth;
8716
+ const chipOriginalEnd = animState.containerStart + accUpTo + chipSize;
8170
8717
  if (insertionIndex === firstIdx) return {
8171
8718
  insertionIndex,
8172
- targetTabGroupId: mouseX >= chipOriginalRight ? tg.id : null
8719
+ targetTabGroupId: mousePos >= chipOriginalEnd ? tg.id : null
8173
8720
  };
8174
8721
  return {
8175
8722
  insertionIndex,
@@ -8332,17 +8879,17 @@ var TabReorderController = class extends CompositeDisposable {
8332
8879
  }
8333
8880
  if (this._pendingCollapse) return;
8334
8881
  const insertionIndex = this._animState.currentInsertionIndex;
8335
- const gapWidth = this._computeGapWidth();
8882
+ const gapSize = this._computeGapSize();
8336
8883
  const chipToShift = this._computeChipToShift(insertionIndex);
8337
- this._applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition);
8884
+ this._applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition);
8338
8885
  }
8339
- /** Gap width for the current drag: the whole group's span for a group
8340
- * drag, otherwise the source tab's own width. */
8341
- _computeGapWidth() {
8886
+ /** Gap size for the current drag: the whole group's span for a group
8887
+ * drag, otherwise the source tab's own main-axis size. */
8888
+ _computeGapSize() {
8342
8889
  const animState = this._animState;
8343
- if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapWidth;
8890
+ if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapSize;
8344
8891
  const sourceRect = animState.tabPositions.get(animState.sourceTabId);
8345
- return sourceRect ? sourceRect.width : this.getAverageTabWidth();
8892
+ return sourceRect ? this._mainAxisSize(sourceRect) : this.getAverageTabSize();
8346
8893
  }
8347
8894
  /**
8348
8895
  * When the insertion lands at or before a group's first tab, the chip is
@@ -8386,7 +8933,7 @@ var TabReorderController = class extends CompositeDisposable {
8386
8933
  }
8387
8934
  /** Reset non-source chip margins, then apply the gap margin to the chip or
8388
8935
  * the first tab at/after the insertion index. */
8389
- _applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition) {
8936
+ _applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition) {
8390
8937
  const animState = this._animState;
8391
8938
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8392
8939
  let gapApplied = false;
@@ -8395,7 +8942,7 @@ var TabReorderController = class extends CompositeDisposable {
8395
8942
  this._clearMargin(entry.chip.element, skipTransition);
8396
8943
  }
8397
8944
  if (chipToShift) {
8398
- this._setMargin(chipToShift, `${gapWidth}px`, skipTransition);
8945
+ this._setMargin(chipToShift, `${gapSize}px`, skipTransition);
8399
8946
  gapApplied = true;
8400
8947
  }
8401
8948
  for (let i = 0; i < this._tabs.length; i++) {
@@ -8403,7 +8950,7 @@ var TabReorderController = class extends CompositeDisposable {
8403
8950
  if (tab.panel.id === animState.sourceTabId) continue;
8404
8951
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8405
8952
  if (!gapApplied && i >= insertionIndex) {
8406
- this._setMargin(tab.element, `${gapWidth}px`, skipTransition);
8953
+ this._setMargin(tab.element, `${gapSize}px`, skipTransition);
8407
8954
  gapApplied = true;
8408
8955
  } else this._clearMargin(tab.element, skipTransition);
8409
8956
  }
@@ -8413,31 +8960,33 @@ var TabReorderController = class extends CompositeDisposable {
8413
8960
  _shiftingClass(el) {
8414
8961
  return el.classList.contains("dv-tab-group-chip") ? "dv-tab-group-chip--shifting" : "dv-tab--shifting";
8415
8962
  }
8416
- /** Apply a margin-left value to an element, optionally bypassing CSS
8963
+ /** Apply the main-axis gap margin to an element, optionally bypassing CSS
8417
8964
  * transitions for instant positioning. */
8418
8965
  _setMargin(el, value, skipTransition) {
8966
+ const property = this._gapMarginProperty;
8419
8967
  if (skipTransition) {
8420
8968
  el.style.transition = "none";
8421
- el.style.marginLeft = value;
8969
+ el.style.setProperty(property, value);
8422
8970
  el.getBoundingClientRect();
8423
8971
  el.style.removeProperty("transition");
8424
- } else el.style.marginLeft = value;
8972
+ } else el.style.setProperty(property, value);
8425
8973
  toggleClass(el, this._shiftingClass(el), true);
8426
8974
  }
8427
8975
  /** Clear an element's gap margin, animating it back to zero unless
8428
8976
  * transitions are skipped. */
8429
8977
  _clearMargin(el, skipTransition) {
8430
8978
  const cls = this._shiftingClass(el);
8979
+ const property = this._gapMarginProperty;
8431
8980
  const prev = this._pendingMarginCleanups.get(el);
8432
8981
  if (prev) prev();
8433
- if (skipTransition || !el.style.marginLeft) {
8434
- el.style.removeProperty("margin-left");
8982
+ if (skipTransition || !el.style.getPropertyValue(property)) {
8983
+ el.style.removeProperty(property);
8435
8984
  toggleClass(el, cls, false);
8436
8985
  } else {
8437
- el.style.marginLeft = "0px";
8986
+ el.style.setProperty(property, "0px");
8438
8987
  toggleClass(el, cls, true);
8439
8988
  const onEnd = () => {
8440
- el.style.removeProperty("margin-left");
8989
+ el.style.removeProperty(property);
8441
8990
  toggleClass(el, cls, false);
8442
8991
  el.removeEventListener("transitionend", onEnd);
8443
8992
  clearTimeout(fallbackTimer);
@@ -8462,6 +9011,7 @@ var TabReorderController = class extends CompositeDisposable {
8462
9011
  }
8463
9012
  for (const [, entry] of this._tabGroupManager.chipRenderers) {
8464
9013
  entry.chip.element.style.removeProperty("margin-left");
9014
+ entry.chip.element.style.removeProperty("margin-top");
8465
9015
  toggleClass(entry.chip.element, "dv-tab-group-chip--shifting", false);
8466
9016
  }
8467
9017
  this._tabGroupManager.positionUnderlines();
@@ -8473,6 +9023,7 @@ var TabReorderController = class extends CompositeDisposable {
8473
9023
  commitGroupMove(sourceTabGroupId, insertionIndex) {
8474
9024
  const data = getPanelData();
8475
9025
  this._tabGroupManager.disposeChipDrag(sourceTabGroupId);
9026
+ this._tabGroupManager.clearChipDropOverlays();
8476
9027
  if (this.group.model.getTabGroups().some((tg) => tg.id === sourceTabGroupId)) {
8477
9028
  var _this$accessor$option3;
8478
9029
  if (((_this$accessor$option3 = this.accessor.options.theme) === null || _this$accessor$option3 === void 0 ? void 0 : _this$accessor$option3.tabAnimation) === "smooth") {
@@ -8830,7 +9381,16 @@ var Tabs = class extends CompositeDisposable {
8830
9381
  }
8831
9382
  });
8832
9383
  this._reorder = new TabReorderController(this);
8833
- this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, this._pointerActivation, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._reorder, PointerDragController.getInstance().onDragEnd((e) => {
9384
+ const tabsListPointerTarget = pointerBackend.createDropTarget(this._tabsList, {
9385
+ acceptedTargetZones: ["center"],
9386
+ canDisplayOverlay: () => false,
9387
+ isHitTestTransparent: () => {
9388
+ const data = getPanelData();
9389
+ if ((data === null || data === void 0 ? void 0 : data.viewId) !== this.accessor.id || data.groupId !== this.group.id) return true;
9390
+ return data.panelId === null && !data.tabGroupId;
9391
+ }
9392
+ });
9393
+ this.addDisposables(tabsListPointerTarget, this._onOverflowTabsChange, this._observerDisposable, this._pointerActivation, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._reorder, PointerDragController.getInstance().onDragEnd((e) => {
8834
9394
  this._reorder.handlePointerDragEnd(e);
8835
9395
  }), PointerDragController.getInstance().onDragMove((e) => {
8836
9396
  this._reorder.handlePointerDragMove(e.clientX, e.clientY);
@@ -9046,21 +9606,21 @@ var Tabs = class extends CompositeDisposable {
9046
9606
  panel
9047
9607
  });
9048
9608
  if (((_this$accessor$option2 = this.accessor.options.theme) === null || _this$accessor$option2 === void 0 ? void 0 : _this$accessor$option2.tabAnimation) === "smooth") {
9049
- const tabWidth = tab.element.getBoundingClientRect().width;
9609
+ const tabSize = mainAxisSize(tab.element.getBoundingClientRect(), this._direction);
9050
9610
  const sourceIndex = this._tabs.findIndex((x) => x.value === tab);
9051
9611
  this._animState = {
9052
9612
  sourceTabId: panel.id,
9053
9613
  sourceIndex,
9054
9614
  tabPositions: this.snapshotTabPositions(),
9055
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9615
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9056
9616
  currentInsertionIndex: null,
9057
9617
  targetTabGroupId: null,
9058
9618
  sourceTabGroupId: null,
9059
9619
  sourceGroupPanelIds: null,
9060
- sourceChipWidth: 0,
9061
- cursorOffsetFromDragLeft: tabWidth / 2,
9062
- sourceGapWidth: tabWidth,
9063
- containerLeft: this._tabsList.getBoundingClientRect().left
9620
+ sourceChipSize: 0,
9621
+ cursorOffsetFromDragStart: tabSize / 2,
9622
+ sourceGapSize: tabSize,
9623
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9064
9624
  };
9065
9625
  this._pendingCollapse = true;
9066
9626
  requestAnimationFrame(() => {
@@ -9156,7 +9716,7 @@ var Tabs = class extends CompositeDisposable {
9156
9716
  this._tabGroupManager.positionAllChips();
9157
9717
  if (this._animState) {
9158
9718
  this._animState.tabPositions = this.snapshotTabPositions();
9159
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9719
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9160
9720
  this.applyDragOverTransforms();
9161
9721
  }
9162
9722
  }
@@ -9178,7 +9738,7 @@ var Tabs = class extends CompositeDisposable {
9178
9738
  }
9179
9739
  if (this._animState) {
9180
9740
  this._animState.tabPositions = this.snapshotTabPositions();
9181
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9741
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9182
9742
  this.applyDragOverTransforms();
9183
9743
  }
9184
9744
  }
@@ -9256,24 +9816,24 @@ var Tabs = class extends CompositeDisposable {
9256
9816
  const firstPanelId = tabGroup.panelIds[0];
9257
9817
  const firstIdx = firstPanelId ? this._tabs.findIndex((t) => t.value.panel.id === firstPanelId) : -1;
9258
9818
  const chipRect = chip.element.getBoundingClientRect();
9259
- let groupGapWidth = chipRect.width;
9819
+ let groupGapSize = mainAxisSize(chipRect, this._direction);
9260
9820
  for (const pid of tabGroup.panelIds) {
9261
9821
  const tabEntry = this._tabMap.get(pid);
9262
- if (tabEntry) groupGapWidth += tabEntry.value.element.getBoundingClientRect().width;
9822
+ if (tabEntry) groupGapSize += mainAxisSize(tabEntry.value.element.getBoundingClientRect(), this._direction);
9263
9823
  }
9264
9824
  this._animState = {
9265
9825
  sourceTabId: "",
9266
9826
  sourceIndex: firstIdx,
9267
9827
  tabPositions: this.snapshotTabPositions(),
9268
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9828
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9269
9829
  currentInsertionIndex: null,
9270
9830
  targetTabGroupId: null,
9271
9831
  sourceTabGroupId: tabGroup.id,
9272
9832
  sourceGroupPanelIds: new Set(tabGroup.panelIds),
9273
- sourceChipWidth: chipRect.width,
9274
- cursorOffsetFromDragLeft: event.clientX - chipRect.left,
9275
- sourceGapWidth: groupGapWidth,
9276
- containerLeft: this._tabsList.getBoundingClientRect().left
9833
+ sourceChipSize: mainAxisSize(chipRect, this._direction),
9834
+ cursorOffsetFromDragStart: mainAxisCursor(event, this._direction) - mainAxisStart(chipRect, this._direction),
9835
+ sourceGapSize: groupGapSize,
9836
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9277
9837
  };
9278
9838
  if (((_this$accessor$option4 = this.accessor.options.theme) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.tabAnimation) !== "smooth") return;
9279
9839
  const groupPanelIds = new Set(tabGroup.panelIds);
@@ -9306,6 +9866,10 @@ var Tabs = class extends CompositeDisposable {
9306
9866
  * (when the source tab is currently to the left of the target slot, its
9307
9867
  * removal shifts the insertion index down by one). Always clears
9308
9868
  * `targetTabGroupId` so the dropped tab lands outside the group.
9869
+ *
9870
+ * A chip dropped on a chip is a group move: the panel path would route it
9871
+ * through the cross-group machinery, which rebuilds the tab group under a
9872
+ * new id.
9309
9873
  */
9310
9874
  _handleChipDrop(tabGroup, event) {
9311
9875
  const firstPanelId = tabGroup.panelIds[0];
@@ -9313,6 +9877,14 @@ var Tabs = class extends CompositeDisposable {
9313
9877
  const insertionIndex = this._tabs.findIndex((x) => x.value.panel.id === firstPanelId);
9314
9878
  if (insertionIndex === -1) return;
9315
9879
  const data = getPanelData();
9880
+ if (data === null || data === void 0 ? void 0 : data.tabGroupId) {
9881
+ var _animState$currentIns2;
9882
+ const animState = this._animState;
9883
+ this._animState = null;
9884
+ this._pendingCollapse = false;
9885
+ this._commitGroupMove(data.tabGroupId, (_animState$currentIns2 = animState === null || animState === void 0 ? void 0 : animState.currentInsertionIndex) !== null && _animState$currentIns2 !== void 0 ? _animState$currentIns2 : insertionIndex);
9886
+ return;
9887
+ }
9316
9888
  const sourceIndex = (data === null || data === void 0 ? void 0 : data.groupId) === this.group.id && (data === null || data === void 0 ? void 0 : data.panelId) ? this._tabs.findIndex((x) => x.value.panel.id === data.panelId) : -1;
9317
9889
  const adjustedIndex = insertionIndex - (sourceIndex !== -1 && sourceIndex < insertionIndex ? 1 : 0);
9318
9890
  this._onDrop.fire({
@@ -10019,8 +10591,10 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
10019
10591
  return this.tabsContainer.getPanelForTab(element);
10020
10592
  }
10021
10593
  get isContentFocused() {
10022
- if (!document.activeElement) return false;
10023
- return isAncestor(document.activeElement, this.contentContainer.element);
10594
+ const element = this.contentContainer.element;
10595
+ const activeElement = getActiveElement(element);
10596
+ if (!activeElement) return false;
10597
+ return isAncestor(activeElement, element);
10024
10598
  }
10025
10599
  get headerPosition() {
10026
10600
  var _this$_headerPosition;
@@ -12931,6 +13505,12 @@ var PopoutWindowService = class {
12931
13505
  observer.observe(gridview.element);
12932
13506
  return { dispose: () => observer.disconnect() };
12933
13507
  }
13508
+ /**
13509
+ * Runs `work` after `delayMs`, resolving once it has finished. Work that
13510
+ * returns a promise is awaited, so a caller holding
13511
+ * `restorationPromise` waits for the popout window itself rather than
13512
+ * only for the timer that starts it.
13513
+ */
12934
13514
  scheduleRestoration(delayMs, work, onCancel) {
12935
13515
  return new Promise((resolve) => {
12936
13516
  const cleanup = () => {
@@ -12945,8 +13525,7 @@ var PopoutWindowService = class {
12945
13525
  resolve();
12946
13526
  return;
12947
13527
  }
12948
- work();
12949
- resolve();
13528
+ Promise.resolve(work()).then(() => resolve(), () => resolve());
12950
13529
  }, delayMs);
12951
13530
  this._restorationCleanups.add(cleanup);
12952
13531
  });
@@ -14204,188 +14783,6 @@ var OverlayRenderContainer = class extends CompositeDisposable {
14204
14783
  }
14205
14784
  };
14206
14785
 
14207
- //#endregion
14208
- //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
14209
- function asyncGeneratorStep(n, t, e, r, o, a, c) {
14210
- try {
14211
- var i = n[a](c), u = i.value;
14212
- } catch (n) {
14213
- e(n);
14214
- return;
14215
- }
14216
- i.done ? t(u) : Promise.resolve(u).then(r, o);
14217
- }
14218
- function _asyncToGenerator(n) {
14219
- return function() {
14220
- var t = this, e = arguments;
14221
- return new Promise(function(r, o) {
14222
- var a = n.apply(t, e);
14223
- function _next(n) {
14224
- asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
14225
- }
14226
- function _throw(n) {
14227
- asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
14228
- }
14229
- _next(void 0);
14230
- });
14231
- };
14232
- }
14233
-
14234
- //#endregion
14235
- //#region src/popoutWindow.ts
14236
- /**
14237
- * Reject popout URLs that aren't same-origin http(s). Blocks `javascript:`,
14238
- * `data:`, `blob:`, `vbscript:`, and cross-origin URLs that would otherwise
14239
- * execute in a context the browser still associates with the opener via
14240
- * `window.opener`.
14241
- */
14242
- function assertSameOriginPopoutUrl(url) {
14243
- let resolved;
14244
- try {
14245
- resolved = new URL(url, globalThis.location.href);
14246
- } catch (_unused) {
14247
- throw new Error(`dockview: invalid popout URL: ${url}`);
14248
- }
14249
- if (!(resolved.protocol === "http:" || resolved.protocol === "https:") || resolved.origin !== globalThis.location.origin) throw new Error(`dockview: popout URL must be same-origin http(s); got: ${url}`);
14250
- }
14251
- var PopoutWindow = class extends CompositeDisposable {
14252
- get window() {
14253
- var _this$_window$value, _this$_window;
14254
- return (_this$_window$value = (_this$_window = this._window) === null || _this$_window === void 0 ? void 0 : _this$_window.value) !== null && _this$_window$value !== void 0 ? _this$_window$value : null;
14255
- }
14256
- constructor(target, className, options) {
14257
- super();
14258
- this.target = target;
14259
- this.className = className;
14260
- this.options = options;
14261
- this._onWillClose = new Emitter();
14262
- this.onWillClose = this._onWillClose.event;
14263
- this._onDidClose = new Emitter();
14264
- this.onDidClose = this._onDidClose.event;
14265
- this._window = null;
14266
- this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
14267
- this.close();
14268
- } });
14269
- }
14270
- dimensions() {
14271
- if (!this._window) return null;
14272
- const left = this._window.value.screenX;
14273
- return {
14274
- top: this._window.value.screenY,
14275
- left,
14276
- width: this._window.value.innerWidth,
14277
- height: this._window.value.innerHeight
14278
- };
14279
- }
14280
- close() {
14281
- if (this._window) {
14282
- var _this$options$onWillC, _this$options;
14283
- this._onWillClose.fire();
14284
- (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
14285
- id: this.target,
14286
- window: this._window.value
14287
- });
14288
- this._window.disposable.dispose();
14289
- this._window = null;
14290
- this._onDidClose.fire();
14291
- }
14292
- }
14293
- open() {
14294
- var _this = this;
14295
- return _asyncToGenerator(function* () {
14296
- var _this$options$onDidOp, _this$options2;
14297
- if (_this._window) throw new Error("instance of popout window is already open");
14298
- const url = `${_this.options.url}`;
14299
- assertSameOriginPopoutUrl(url);
14300
- const features = Object.entries({
14301
- top: _this.options.top,
14302
- left: _this.options.left,
14303
- width: _this.options.width,
14304
- height: _this.options.height
14305
- }).map(([key, value]) => `${key}=${value}`).join(",");
14306
- /**
14307
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
14308
- */
14309
- const externalWindow = window.open(url, _this.target, features);
14310
- if (!externalWindow)
14311
- /**
14312
- * Popup blocked
14313
- */
14314
- return null;
14315
- const disposable = new CompositeDisposable();
14316
- _this._window = {
14317
- value: externalWindow,
14318
- disposable
14319
- };
14320
- disposable.addDisposables(Disposable.from(() => {
14321
- externalWindow.close();
14322
- }), addDisposableListener(globalThis.window, "beforeunload", () => {
14323
- /**
14324
- * before the main window closes we should close this popup too
14325
- * to be good citizens
14326
- *
14327
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14328
- */
14329
- _this.close();
14330
- }));
14331
- const container = _this.createPopoutWindowContainer();
14332
- if (_this.className) container.classList.add(_this.className);
14333
- (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
14334
- id: _this.target,
14335
- window: externalWindow
14336
- });
14337
- return new Promise((resolve, reject) => {
14338
- externalWindow.addEventListener("unload", () => {});
14339
- /**
14340
- * `load` is the only event that resolves this promise with a
14341
- * container, so a window that goes away first would leave the
14342
- * caller awaiting a promise that never settles - and
14343
- * `addPopoutGroup` holds its layout transaction open until it does.
14344
- * Settle with `null` on close, the same signal a blocked popup
14345
- * gives and one the caller already handles. `resolve` after the
14346
- * fact is a no-op, so a `load` that arrived first still wins.
14347
- */
14348
- disposable.addDisposables(_this.onWillClose(() => resolve(null)));
14349
- externalWindow.addEventListener("load", () => {
14350
- /**
14351
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
14352
- */
14353
- try {
14354
- const externalDocument = externalWindow.document;
14355
- externalDocument.title = document.title;
14356
- externalDocument.body.appendChild(container);
14357
- addStyles(externalDocument, globalThis.document.styleSheets, { nonce: _this.options.nonce });
14358
- /**
14359
- * beforeunload must be registered after load for reasons I could not determine
14360
- * otherwise the beforeunload event will not fire when the window is closed
14361
- */
14362
- addDisposableListener(externalWindow, "beforeunload", () => {
14363
- /**
14364
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14365
- */
14366
- _this.close();
14367
- });
14368
- resolve(container);
14369
- } catch (err) {
14370
- reject(err);
14371
- }
14372
- });
14373
- });
14374
- })();
14375
- }
14376
- createPopoutWindowContainer() {
14377
- const el = document.createElement("div");
14378
- el.classList.add("dv-popout-window");
14379
- el.id = "dv-popout-window";
14380
- el.style.position = "absolute";
14381
- el.style.width = "100%";
14382
- el.style.height = "100%";
14383
- el.style.top = "0px";
14384
- el.style.left = "0px";
14385
- return el;
14386
- }
14387
- };
14388
-
14389
14786
  //#endregion
14390
14787
  //#region src/dockview/strictEventsSequencing.ts
14391
14788
  var StrictEventsSequencing = class extends CompositeDisposable {
@@ -14429,8 +14826,8 @@ function isCoarsePrimaryInput(win) {
14429
14826
  * peeks): while it lives it watches a configurable set of dismiss signals
14430
14827
  * (Escape / extra keys, outside-pointerdown with an optional grace window,
14431
14828
  * window resize, focus moving outside) and calls `onDismiss`. Inside/outside is
14432
- * decided by an `isInside` predicate (geometry) or a `contains` check against
14433
- * `elements`. Dispose to detach every listener.
14829
+ * decided by an `isInside` predicate (geometry) or by checking the event's
14830
+ * composed path against `elements`. Dispose to detach every listener.
14434
14831
  *
14435
14832
  * It owns only the *signals*, not the surface element, its position, or any
14436
14833
  * hover/keep-open policy, so callers keep their own element lifecycle and
@@ -14450,9 +14847,7 @@ function createDismissableLayer(options) {
14450
14847
  const isInside = (event) => {
14451
14848
  var _options$elements, _options$elements2;
14452
14849
  if (options.isInside) return options.isInside(event);
14453
- const target = event.target;
14454
- if (!(target instanceof Node)) return false;
14455
- return ((_options$elements = (_options$elements2 = options.elements) === null || _options$elements2 === void 0 ? void 0 : _options$elements2.call(options)) !== null && _options$elements !== void 0 ? _options$elements : []).some((el) => el.contains(target));
14850
+ return isEventWithin(event, (_options$elements = (_options$elements2 = options.elements) === null || _options$elements2 === void 0 ? void 0 : _options$elements2.call(options)) !== null && _options$elements !== void 0 ? _options$elements : []);
14456
14851
  };
14457
14852
  if (escape || keys.length > 0) disposables.addDisposables(addDisposableListener(win, "keydown", (event) => {
14458
14853
  if (escape && event.key === "Escape" || keys.includes(event.key)) options.onDismiss();
@@ -14471,17 +14866,45 @@ function createDismissableLayer(options) {
14471
14866
  options.onDismiss();
14472
14867
  }));
14473
14868
  if (options.focusOut) {
14474
- const isFocusInside = (focused) => {
14475
- var _options$elements3, _options$elements4;
14476
- if (options.isFocusInside) return options.isFocusInside(focused);
14477
- return ((_options$elements3 = (_options$elements4 = options.elements) === null || _options$elements4 === void 0 ? void 0 : _options$elements4.call(options)) !== null && _options$elements3 !== void 0 ? _options$elements3 : []).some((el) => el.contains(focused));
14869
+ /** A node in the layer's own tree, to scope retargeting and to locate
14870
+ * the shadow roots to listen on. */
14871
+ const layerScope = () => {
14872
+ var _options$anchor, _options$anchor2, _options$elements3;
14873
+ return (_options$anchor = (_options$anchor2 = options.anchor) === null || _options$anchor2 === void 0 ? void 0 : _options$anchor2.call(options)) !== null && _options$anchor !== void 0 ? _options$anchor : (_options$elements3 = options.elements) === null || _options$elements3 === void 0 ? void 0 : _options$elements3.call(options)[0];
14478
14874
  };
14875
+ const seen = /* @__PURE__ */ new WeakSet();
14479
14876
  const onFocusIn = (event) => {
14877
+ var _options$elements4, _options$elements5;
14878
+ if (seen.has(event)) return;
14879
+ seen.add(event);
14480
14880
  const target = event.target;
14481
- if (target instanceof Element && !isFocusInside(target)) options.onDismiss();
14881
+ if (!(target instanceof Element)) return;
14882
+ if (!(options.isFocusInside ? options.isFocusInside(retargetInto(target, layerScope())) : isEventWithin(event, (_options$elements4 = (_options$elements5 = options.elements) === null || _options$elements5 === void 0 ? void 0 : _options$elements5.call(options)) !== null && _options$elements4 !== void 0 ? _options$elements4 : []))) options.onDismiss();
14482
14883
  };
14483
- win.addEventListener("focusin", onFocusIn, capture);
14484
- disposables.addDisposables({ dispose: () => win.removeEventListener("focusin", onFocusIn, capture) });
14884
+ const bound = /* @__PURE__ */ new Map();
14885
+ const syncShadowRoots = () => {
14886
+ var _options$anchor3, _options$elements6, _options$elements7;
14887
+ const wanted = /* @__PURE__ */ new Set();
14888
+ const anchor = (_options$anchor3 = options.anchor) === null || _options$anchor3 === void 0 ? void 0 : _options$anchor3.call(options);
14889
+ const sources = [...(_options$elements6 = (_options$elements7 = options.elements) === null || _options$elements7 === void 0 ? void 0 : _options$elements7.call(options)) !== null && _options$elements6 !== void 0 ? _options$elements6 : [], ...anchor ? [anchor] : []];
14890
+ for (const node of sources) for (const root of shadowRootsOf(node)) wanted.add(root);
14891
+ for (const [root, listener] of bound) if (!wanted.has(root)) {
14892
+ listener.dispose();
14893
+ bound.delete(root);
14894
+ }
14895
+ for (const root of wanted) {
14896
+ if (bound.has(root)) continue;
14897
+ bound.set(root, addDisposableListener(root, "focusin", onFocusIn, capture));
14898
+ }
14899
+ };
14900
+ disposables.addDisposables(addDisposableListener(win, "focusin", (event) => {
14901
+ syncShadowRoots();
14902
+ onFocusIn(event);
14903
+ }, capture), { dispose: () => {
14904
+ for (const [, listener] of bound) listener.dispose();
14905
+ bound.clear();
14906
+ } });
14907
+ syncShadowRoots();
14485
14908
  }
14486
14909
  return disposables;
14487
14910
  }
@@ -14974,6 +15397,24 @@ var ShellManager = class {
14974
15397
  this.updateTheme(this._gap, this._defaultCollapsedSize);
14975
15398
  return view;
14976
15399
  }
15400
+ /**
15401
+ * Lay out from the shell's current size.
15402
+ *
15403
+ * The ResizeObserver above only reports asynchronously, so between
15404
+ * construction and its first callback the shell believes it has no size -
15405
+ * and any layout built in that window (panels added straight after
15406
+ * `createDockview`, say) resolves its sizes against zero and collapses to
15407
+ * minimums, permanently. Seeding the size synchronously gives that work
15408
+ * the real dimensions. Same guards as the observer: a detached or hidden
15409
+ * shell has no size worth propagating.
15410
+ */
15411
+ layoutFromElement() {
15412
+ if (!this._shellElement.offsetParent || !isInDocument(this._shellElement)) return;
15413
+ const width = Math.round(this._shellElement.clientWidth);
15414
+ const height = Math.round(this._shellElement.clientHeight);
15415
+ if (width === 0 || height === 0) return;
15416
+ this.layout(width, height);
15417
+ }
14977
15418
  layout(width, height) {
14978
15419
  this._outerSplitview.layout(width, height);
14979
15420
  this._flushPendingSizes();
@@ -15233,6 +15674,15 @@ var ShellManager = class {
15233
15674
 
15234
15675
  //#endregion
15235
15676
  //#region src/dockview/dockviewComponent.ts
15677
+ /**
15678
+ * An error says the most about why, so it wins; a blocked window has none, and
15679
+ * its usual cause is more useful than its name.
15680
+ */
15681
+ function logFailedPopout(failure) {
15682
+ if (failure.error) console.error("dockview: failed to create popout.", failure.error);
15683
+ else if (failure.reason === "blocked") console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
15684
+ else console.error(`dockview: failed to create popout (${failure.reason}).`);
15685
+ }
15236
15686
  function buildTabGroupColorPalette(options) {
15237
15687
  var _options$tabGroupColo;
15238
15688
  return new TabGroupColorPalette((_options$tabGroupColo = options.tabGroupColors) !== null && _options$tabGroupColo !== void 0 ? _options$tabGroupColo : DEFAULT_TAB_GROUP_COLORS, options.tabGroupAccent !== "off");
@@ -15284,6 +15734,10 @@ var DockviewComponent = class extends BaseGrid {
15284
15734
  get panels() {
15285
15735
  return this.groups.flatMap((group) => group.panels);
15286
15736
  }
15737
+ /** `dndStrategy` resolved against this device; see `DockviewApi`. */
15738
+ get dndCapabilities() {
15739
+ return resolveDndCapabilities(this.options);
15740
+ }
15287
15741
  get options() {
15288
15742
  return this._options;
15289
15743
  }
@@ -15793,9 +16247,9 @@ var DockviewComponent = class extends BaseGrid {
15793
16247
  return (_this$_popoutWindowSe = (_this$_popoutWindowSe2 = this._popoutWindowService) === null || _this$_popoutWindowSe2 === void 0 ? void 0 : _this$_popoutWindowSe2.restorationPromise) !== null && _this$_popoutWindowSe !== void 0 ? _this$_popoutWindowSe : Promise.resolve();
15794
16248
  }
15795
16249
  constructor(container, options) {
15796
- var _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
16250
+ var _options$proportional, _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
15797
16251
  super(container, {
15798
- proportionalLayout: true,
16252
+ proportionalLayout: (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true,
15799
16253
  orientation: "HORIZONTAL",
15800
16254
  styles: options.hideBorders ? { separatorBorder: "transparent" } : void 0,
15801
16255
  disableAutoResizing: options.disableAutoResizing,
@@ -15842,6 +16296,8 @@ var DockviewComponent = class extends BaseGrid {
15842
16296
  this.onDidChangePopouts = this._onDidChangePopouts.event;
15843
16297
  this._onDidOpenPopoutWindowFail = new Emitter();
15844
16298
  this.onDidOpenPopoutWindowFail = this._onDidOpenPopoutWindowFail.event;
16299
+ this._onWillClosePopoutWindow = new Emitter();
16300
+ this.onWillClosePopoutWindow = this._onWillClosePopoutWindow.event;
15845
16301
  this._onDidStartFloatingGroupDrag = new Emitter();
15846
16302
  this.onDidStartFloatingGroupDrag = this._onDidStartFloatingGroupDrag.event;
15847
16303
  this._onDidEndFloatingGroupDrag = new Emitter();
@@ -15943,7 +16399,7 @@ var DockviewComponent = class extends BaseGrid {
15943
16399
  var _this$_shellManager2;
15944
16400
  this._moduleRegistry.dispose();
15945
16401
  (_this$_shellManager2 = this._shellManager) === null || _this$_shellManager2 === void 0 || _this$_shellManager2.dispose();
15946
- }));
16402
+ }), this._onWillClosePopoutWindow);
15947
16403
  const rootDropTarget = this._rootDropTargetService;
15948
16404
  if (rootDropTarget) this.addDisposables(rootDropTarget.onWillShowOverlay((event) => {
15949
16405
  if (this.gridview.length > 0 && event.position === "center") return;
@@ -15956,6 +16412,7 @@ var DockviewComponent = class extends BaseGrid {
15956
16412
  }));
15957
16413
  }), rootDropTarget.onDrop((event) => this.dockToLayoutEdge(event.nativeEvent, event.position)));
15958
16414
  this._moduleRegistry.postConstruct(this);
16415
+ this._shellManager.layoutFromElement();
15959
16416
  }
15960
16417
  setVisible(panel, visible) {
15961
16418
  switch (panel.api.location.type) {
@@ -16025,22 +16482,36 @@ var DockviewComponent = class extends BaseGrid {
16025
16482
  const box = getBox();
16026
16483
  const groupId = (_options$overridePopo = options === null || options === void 0 || (_options$overridePopo2 = options.overridePopoutGroup) === null || _options$overridePopo2 === void 0 ? void 0 : _options$overridePopo2.id) !== null && _options$overridePopo !== void 0 ? _options$overridePopo : this.getNextGroupId();
16027
16484
  const resolvedPopoutUrl = (_options$popoutUrl = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _options$popoutUrl !== void 0 ? _options$popoutUrl : (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.popoutUrl;
16485
+ const popoutUrl = resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html";
16028
16486
  const _window = new PopoutWindow(`${this.id}-${groupId}`, theme !== null && theme !== void 0 ? theme : "", {
16029
- url: resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html",
16487
+ url: popoutUrl,
16030
16488
  left: box.left,
16031
16489
  top: box.top,
16032
16490
  width: box.width,
16033
16491
  height: box.height,
16034
16492
  onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
16035
- onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
16036
- nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce
16493
+ onWillClose: (event) => {
16494
+ var _options$onWillClose;
16495
+ options === null || options === void 0 || (_options$onWillClose = options.onWillClose) === null || _options$onWillClose === void 0 || _options$onWillClose.call(options, event);
16496
+ this._onWillClosePopoutWindow.fire(event);
16497
+ },
16498
+ nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce,
16499
+ styleRoot: () => this.element.getRootNode()
16037
16500
  });
16038
16501
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
16039
16502
  popoutWindowDisposable.dispose();
16040
16503
  }));
16041
- return _window.open().then((popoutContainer) => {
16504
+ const openError = getPopoutUrlError(popoutUrl);
16505
+ return (openError ? Promise.resolve(null) : _window.open()).then((popoutContainer) => {
16042
16506
  var _options$referenceGro, _options$overridePopo4;
16043
- if (_window.isDisposed) return false;
16507
+ if (_window.isDisposed) {
16508
+ const failure = _window.failure;
16509
+ if (failure && !this.isDisposed) {
16510
+ logFailedPopout(failure);
16511
+ this._onDidOpenPopoutWindowFail.fire(failure);
16512
+ }
16513
+ return false;
16514
+ }
16044
16515
  const referenceGroup = (_options$referenceGro = options === null || options === void 0 ? void 0 : options.referenceGroup) !== null && _options$referenceGro !== void 0 ? _options$referenceGro : itemToPopout instanceof DockviewPanel ? itemToPopout.group : itemToPopout;
16045
16516
  const referenceLocation = itemToPopout.api.location.type;
16046
16517
  /**
@@ -16059,11 +16530,16 @@ var DockviewComponent = class extends BaseGrid {
16059
16530
  if (popoutContainer) this._onDidAddGroup.fire(group);
16060
16531
  }
16061
16532
  if (popoutContainer === null) {
16533
+ var _window$failure;
16062
16534
  this.handleBlockedPopout({
16063
16535
  group,
16064
16536
  referenceGroup,
16065
16537
  options,
16066
- popoutWindowDisposable
16538
+ popoutWindowDisposable,
16539
+ failure: openError ? {
16540
+ reason: "url-refused",
16541
+ error: openError
16542
+ } : (_window$failure = _window.failure) !== null && _window$failure !== void 0 ? _window$failure : { reason: "blocked" }
16067
16543
  });
16068
16544
  return false;
16069
16545
  }
@@ -16226,16 +16702,17 @@ var DockviewComponent = class extends BaseGrid {
16226
16702
  });
16227
16703
  }
16228
16704
  /**
16229
- * The popout window was blocked (e.g. by the browser's popup blocker,
16230
- * common when restoring popouts on load). Fall back gracefully so the
16231
- * group(s) end up valid and visible in the main grid rather than as
16232
- * orphans that later crash clear()/remove().
16705
+ * The popout window never opened - blocked by the browser's popup blocker
16706
+ * (common when restoring popouts on load), or refused outright because its
16707
+ * URL failed the same-origin guard. Fall back gracefully so the group(s)
16708
+ * end up valid and visible in the main grid rather than as orphans that
16709
+ * render nothing and later crash clear()/remove().
16233
16710
  */
16234
16711
  handleBlockedPopout(params) {
16235
- const { group, referenceGroup, options, popoutWindowDisposable } = params;
16236
- console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
16712
+ const { group, referenceGroup, options, popoutWindowDisposable, failure } = params;
16713
+ logFailedPopout(failure);
16237
16714
  popoutWindowDisposable.dispose();
16238
- this._onDidOpenPopoutWindowFail.fire();
16715
+ this._onDidOpenPopoutWindowFail.fire(failure);
16239
16716
  if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
16240
16717
  const blockedGridview = options.overridePopoutGridview;
16241
16718
  const members = this.groups.filter((candidate) => blockedGridview.element.contains(candidate.element));
@@ -16390,10 +16867,11 @@ var DockviewComponent = class extends BaseGrid {
16390
16867
  group = this.createGroup();
16391
16868
  this._onDidAddGroup.fire(group);
16392
16869
  this.movingLock(() => this.removePanel(item, {
16393
- removeEmptyGroup: true,
16870
+ removeEmptyGroup: false,
16394
16871
  skipDispose: true,
16395
16872
  skipSetActiveGroup: true
16396
16873
  }));
16874
+ this.removeGroupIfEmpty(sourceGroup);
16397
16875
  this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
16398
16876
  movedPanels = [{
16399
16877
  panel: item,
@@ -16464,13 +16942,17 @@ var DockviewComponent = class extends BaseGrid {
16464
16942
  });
16465
16943
  for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
16466
16944
  }
16945
+ removeGroupIfEmpty(group) {
16946
+ if (group.model.size === 0) this.doRemoveGroup(group, { skipActive: true });
16947
+ }
16467
16948
  /**
16468
- * Build an empty gridview configured to match the main grid's styling, for
16469
- * hosting a nested layout inside a floating or popout window.
16949
+ * Build an empty gridview configured to match the main grid's styling and
16950
+ * resize behaviour, for hosting a nested layout inside a floating or popout
16951
+ * window.
16470
16952
  */
16471
16953
  createNestedGridview(orientation = "HORIZONTAL") {
16472
16954
  var _this$options$theme$g, _this$options$theme2;
16473
- return new Gridview(true, this.options.hideBorders ? { separatorBorder: "transparent" } : void 0, orientation, false, (_this$options$theme$g = (_this$options$theme2 = this.options.theme) === null || _this$options$theme2 === void 0 ? void 0 : _this$options$theme2.gap) !== null && _this$options$theme$g !== void 0 ? _this$options$theme$g : 0);
16955
+ return new Gridview(this.gridview.proportionalLayout, this.options.hideBorders ? { separatorBorder: "transparent" } : void 0, orientation, false, (_this$options$theme$g = (_this$options$theme2 = this.options.theme) === null || _this$options$theme2 === void 0 ? void 0 : _this$options$theme2.gap) !== null && _this$options$theme$g !== void 0 ? _this$options$theme$g : 0);
16474
16956
  }
16475
16957
  /**
16476
16958
  * Wrap a (populated) floating gridview in an overlay window: title bar /
@@ -16543,6 +17025,12 @@ var DockviewComponent = class extends BaseGrid {
16543
17025
  const newDisableDnd = this.options.disableDnd;
16544
17026
  const newDndStrategy = this.options.dndStrategy;
16545
17027
  if (oldDisableDnd !== newDisableDnd || oldDndStrategy !== newDndStrategy) this.updateDragAndDropState();
17028
+ if ("proportionalLayout" in options) {
17029
+ var _this$_popoutWindowSe9, _this$_popoutWindowSe10;
17030
+ const proportionalLayout = this.gridview.proportionalLayout;
17031
+ for (const floating of this.floatingGroups) floating.gridview.proportionalLayout = proportionalLayout;
17032
+ for (const entry of (_this$_popoutWindowSe9 = (_this$_popoutWindowSe10 = this._popoutWindowService) === null || _this$_popoutWindowSe10 === void 0 ? void 0 : _this$_popoutWindowSe10.entries) !== null && _this$_popoutWindowSe9 !== void 0 ? _this$_popoutWindowSe9 : []) entry.gridview.proportionalLayout = proportionalLayout;
17033
+ }
16546
17034
  if ("theme" in options) this.updateTheme();
16547
17035
  if ("createRightHeaderActionComponent" in options || "createLeftHeaderActionComponent" in options || "createPrefixHeaderActionComponent" in options) {
16548
17036
  var _this$headerActionsSe;
@@ -16850,14 +17338,14 @@ var DockviewComponent = class extends BaseGrid {
16850
17338
  * @returns A JSON respresentation of the layout
16851
17339
  */
16852
17340
  toJSON() {
16853
- var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe9, _this$_popoutWindowSe10, _this$activeGroup2;
17341
+ var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe11, _this$_popoutWindowSe12, _this$activeGroup2;
16854
17342
  const data = this.gridview.serialize();
16855
17343
  const panels = this.panels.reduce((collection, panel) => {
16856
17344
  collection[panel.id] = panel.toJSON();
16857
17345
  return collection;
16858
17346
  }, {});
16859
17347
  const floats = (_this$_floatingGroupS3 = (_this$_floatingGroupS4 = this._floatingGroupService) === null || _this$_floatingGroupS4 === void 0 ? void 0 : _this$_floatingGroupS4.serialize()) !== null && _this$_floatingGroupS3 !== void 0 ? _this$_floatingGroupS3 : [];
16860
- const popoutGroups = (_this$_popoutWindowSe9 = (_this$_popoutWindowSe10 = this._popoutWindowService) === null || _this$_popoutWindowSe10 === void 0 ? void 0 : _this$_popoutWindowSe10.serialize()) !== null && _this$_popoutWindowSe9 !== void 0 ? _this$_popoutWindowSe9 : [];
17348
+ const popoutGroups = (_this$_popoutWindowSe11 = (_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 ? void 0 : _this$_popoutWindowSe12.serialize()) !== null && _this$_popoutWindowSe11 !== void 0 ? _this$_popoutWindowSe11 : [];
16861
17349
  const result = {
16862
17350
  grid: data,
16863
17351
  panels,
@@ -16896,8 +17384,8 @@ var DockviewComponent = class extends BaseGrid {
16896
17384
  this.mutation("load", () => this._doFromJSON(data, options));
16897
17385
  }
16898
17386
  _doFromJSON(data, options) {
16899
- var _this$_popoutWindowSe11, _data$grid$root;
16900
- (_this$_popoutWindowSe11 = this._popoutWindowService) === null || _this$_popoutWindowSe11 === void 0 || _this$_popoutWindowSe11.cancelPendingRestorations();
17387
+ var _this$_popoutWindowSe13, _data$grid$root;
17388
+ (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 || _this$_popoutWindowSe13.cancelPendingRestorations();
16901
17389
  if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
16902
17390
  if (!data.grid || ((_data$grid$root = data.grid.root) === null || _data$grid$root === void 0 ? void 0 : _data$grid$root.type) !== "branch" || !Array.isArray(data.grid.root.data)) throw new Error("dockview: root must be of type branch");
16903
17391
  const existingPanels = /* @__PURE__ */ new Map();
@@ -17016,7 +17504,7 @@ var DockviewComponent = class extends BaseGrid {
17016
17504
  } else this.clear();
17017
17505
  const { grid, panels, activeGroup } = data;
17018
17506
  try {
17019
- var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
17507
+ var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe14, _this$_floatingGroupS5, _this$_watermarkServi2;
17020
17508
  const width = this.width;
17021
17509
  const height = this.height;
17022
17510
  const createGroupFromSerializedState = (data) => {
@@ -17081,7 +17569,7 @@ var DockviewComponent = class extends BaseGrid {
17081
17569
  if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
17082
17570
  this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
17083
17571
  const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
17084
- (_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
17572
+ (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 || _this$_popoutWindowSe14.finishRestoration(popoutPromises);
17085
17573
  (_this$_floatingGroupS5 = this._floatingGroupService) === null || _this$_floatingGroupS5 === void 0 || _this$_floatingGroupS5.constrainBounds();
17086
17574
  if (typeof activeGroup === "string") {
17087
17575
  const panel = this.getPanel(activeGroup);
@@ -17249,15 +17737,13 @@ var DockviewComponent = class extends BaseGrid {
17249
17737
  }
17250
17738
  }
17251
17739
  const group = grid ? members[0] : createGroup(data);
17252
- return popoutService.scheduleRestoration(index * 100, () => {
17253
- this.addPopoutGroup(group, {
17254
- position: position !== null && position !== void 0 ? position : void 0,
17255
- overridePopoutGroup: gridReferenceGroup ? group : void 0,
17256
- overridePopoutGridview,
17257
- referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17258
- popoutUrl: url
17259
- });
17260
- }, () => {
17740
+ return popoutService.scheduleRestoration(index * 100, () => this.addPopoutGroup(group, {
17741
+ position: position !== null && position !== void 0 ? position : void 0,
17742
+ overridePopoutGroup: gridReferenceGroup ? group : void 0,
17743
+ overridePopoutGridview,
17744
+ referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17745
+ popoutUrl: url
17746
+ }), () => {
17261
17747
  for (const orphan of members.length > 0 ? members : [group]) if (!this.isDisposed && this._groups.has(orphan.id) && orphan.element.parentElement === null) {
17262
17748
  for (const panel of [...orphan.panels]) this.removePanel(panel, { removeEmptyGroup: false });
17263
17749
  orphan.dispose();
@@ -17492,7 +17978,7 @@ var DockviewComponent = class extends BaseGrid {
17492
17978
  * window.
17493
17979
  */
17494
17980
  detachFromNestedWindow(group) {
17495
- var _this$_floatingGroupS7, _this$_popoutWindowSe13;
17981
+ var _this$_floatingGroupS7, _this$_popoutWindowSe15;
17496
17982
  const floating = (_this$_floatingGroupS7 = this._floatingGroupService) === null || _this$_floatingGroupS7 === void 0 ? void 0 : _this$_floatingGroupS7.findByGroup(group);
17497
17983
  if (floating) {
17498
17984
  const members = this.nestedWindowMembers(group);
@@ -17501,7 +17987,7 @@ var DockviewComponent = class extends BaseGrid {
17501
17987
  if (floating.group === group) floating.setAnchorGroup(members.find((m) => m !== group));
17502
17988
  return true;
17503
17989
  }
17504
- const popout = (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 ? void 0 : _this$_popoutWindowSe13.findByGroup(group);
17990
+ const popout = (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 ? void 0 : _this$_popoutWindowSe15.findByGroup(group);
17505
17991
  if (popout) {
17506
17992
  const members = this.nestedWindowMembers(group);
17507
17993
  if (members.length <= 1) return false;
@@ -17558,8 +18044,8 @@ var DockviewComponent = class extends BaseGrid {
17558
18044
  return group;
17559
18045
  }
17560
18046
  if (group.api.location.type === "popout") {
17561
- var _this$_popoutWindowSe14, _this$_popoutWindowSe15;
17562
- const selectedGroup = (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 ? void 0 : _this$_popoutWindowSe14.findByGroup(group);
18047
+ var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18048
+ const selectedGroup = (_this$_popoutWindowSe16 = this._popoutWindowService) === null || _this$_popoutWindowSe16 === void 0 ? void 0 : _this$_popoutWindowSe16.findByGroup(group);
17563
18049
  if (!selectedGroup) throw new Error("dockview: failed to find popout group");
17564
18050
  if (this.detachFromNestedWindow(group)) {
17565
18051
  if (options === null || options === void 0 ? void 0 : options.skipDispose) group.model.location = { type: "grid" };
@@ -17576,7 +18062,7 @@ var DockviewComponent = class extends BaseGrid {
17576
18062
  this._groups.delete(group.id);
17577
18063
  this._onDidRemoveGroup.fire(group);
17578
18064
  }
17579
- (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 || _this$_popoutWindowSe15.remove(selectedGroup);
18065
+ (_this$_popoutWindowSe17 = this._popoutWindowService) === null || _this$_popoutWindowSe17 === void 0 || _this$_popoutWindowSe17.remove(selectedGroup);
17580
18066
  const removedGroup = selectedGroup.disposable.dispose();
17581
18067
  if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
17582
18068
  this.doAddGroup(removedGroup, [0]);
@@ -17603,10 +18089,10 @@ var DockviewComponent = class extends BaseGrid {
17603
18089
  debouncedUpdateAllPositions() {
17604
18090
  if (this._updatePositionsFrameId !== void 0) cancelAnimationFrame(this._updatePositionsFrameId);
17605
18091
  this._updatePositionsFrameId = requestAnimationFrame(() => {
17606
- var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18092
+ var _this$_popoutWindowSe18, _this$_popoutWindowSe19;
17607
18093
  this._updatePositionsFrameId = void 0;
17608
18094
  this.overlayRenderContainer.updateAllPositions();
17609
- for (const entry of (_this$_popoutWindowSe16 = (_this$_popoutWindowSe17 = this._popoutWindowService) === null || _this$_popoutWindowSe17 === void 0 ? void 0 : _this$_popoutWindowSe17.entries) !== null && _this$_popoutWindowSe16 !== void 0 ? _this$_popoutWindowSe16 : []) entry.overlayRenderContainer.updateAllPositions();
18095
+ for (const entry of (_this$_popoutWindowSe18 = (_this$_popoutWindowSe19 = this._popoutWindowService) === null || _this$_popoutWindowSe19 === void 0 ? void 0 : _this$_popoutWindowSe19.entries) !== null && _this$_popoutWindowSe18 !== void 0 ? _this$_popoutWindowSe18 : []) entry.overlayRenderContainer.updateAllPositions();
17610
18096
  });
17611
18097
  }
17612
18098
  movingLock(func) {
@@ -17856,7 +18342,7 @@ var DockviewComponent = class extends BaseGrid {
17856
18342
  }
17857
18343
  }
17858
18344
  if (sourceGroup.api.location.type === "popout" && this.nestedWindowMembers(sourceGroup).length <= 1) {
17859
- var _this$_popoutWindowSe18;
18345
+ var _this$_popoutWindowSe20;
17860
18346
  /**
17861
18347
  * the source group is the only group in a popout window and
17862
18348
  * has a single panel
@@ -17871,7 +18357,7 @@ var DockviewComponent = class extends BaseGrid {
17871
18357
  * Multi-group popout windows fall through to the generic
17872
18358
  * detach-and-re-add path so the window stays alive.
17873
18359
  */
17874
- const popoutGroup = (_this$_popoutWindowSe18 = this._popoutWindowService) === null || _this$_popoutWindowSe18 === void 0 ? void 0 : _this$_popoutWindowSe18.findByGroup(sourceGroup);
18360
+ const popoutGroup = (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 ? void 0 : _this$_popoutWindowSe20.findByGroup(sourceGroup);
17875
18361
  if (!popoutGroup) return;
17876
18362
  const removedPanel = this.movingLock(() => popoutGroup.popoutGroup.model.removePanel(popoutGroup.popoutGroup.panels[0], {
17877
18363
  skipSetActive: true,
@@ -18080,11 +18566,11 @@ var DockviewComponent = class extends BaseGrid {
18080
18566
  break;
18081
18567
  }
18082
18568
  case "popout": {
18083
- var _this$_popoutWindowSe19, _this$_popoutWindowSe20;
18084
- const selectedPopoutGroup = (_this$_popoutWindowSe19 = this._popoutWindowService) === null || _this$_popoutWindowSe19 === void 0 ? void 0 : _this$_popoutWindowSe19.findByGroup(from);
18569
+ var _this$_popoutWindowSe21, _this$_popoutWindowSe22;
18570
+ const selectedPopoutGroup = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.findByGroup(from);
18085
18571
  if (!selectedPopoutGroup) throw new Error("dockview: failed to find popout group");
18086
18572
  if (this.detachFromNestedWindow(from)) break;
18087
- (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 || _this$_popoutWindowSe20.remove(selectedPopoutGroup);
18573
+ (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 || _this$_popoutWindowSe22.remove(selectedPopoutGroup);
18088
18574
  if (selectedPopoutGroup.referenceGroup) {
18089
18575
  const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
18090
18576
  if (referenceGroup && !referenceGroup.api.isVisible) this.doRemoveGroup(referenceGroup, { skipActive: true });
@@ -18249,8 +18735,8 @@ var DockviewComponent = class extends BaseGrid {
18249
18735
  * window-local containers).
18250
18736
  */
18251
18737
  setGroupLocationForRoot(group, gridview) {
18252
- var _this$_popoutWindowSe21;
18253
- const popout = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.entries.find((entry) => entry.gridview === gridview);
18738
+ var _this$_popoutWindowSe23;
18739
+ const popout = (_this$_popoutWindowSe23 = this._popoutWindowService) === null || _this$_popoutWindowSe23 === void 0 ? void 0 : _this$_popoutWindowSe23.entries.find((entry) => entry.gridview === gridview);
18254
18740
  if (popout) {
18255
18741
  if (group.model.renderContainer !== popout.overlayRenderContainer) group.model.renderContainer = popout.overlayRenderContainer;
18256
18742
  group.model.dropTargetContainer = popout.dropTargetContainer;
@@ -18270,10 +18756,10 @@ var DockviewComponent = class extends BaseGrid {
18270
18756
  * the nested gridview of the floating / popout window it lives in.
18271
18757
  */
18272
18758
  getGridviewForGroup(group) {
18273
- var _this$_floatingGroupS10, _this$_popoutWindowSe22;
18759
+ var _this$_floatingGroupS10, _this$_popoutWindowSe24;
18274
18760
  const floating = (_this$_floatingGroupS10 = this._floatingGroupService) === null || _this$_floatingGroupS10 === void 0 ? void 0 : _this$_floatingGroupS10.findByGroup(group);
18275
18761
  if (floating) return floating.gridview;
18276
- const popout = (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 ? void 0 : _this$_popoutWindowSe22.findByGroup(group);
18762
+ const popout = (_this$_popoutWindowSe24 = this._popoutWindowService) === null || _this$_popoutWindowSe24 === void 0 ? void 0 : _this$_popoutWindowSe24.findByGroup(group);
18277
18763
  if (popout) return popout.gridview;
18278
18764
  return this.gridview;
18279
18765
  }
@@ -18295,13 +18781,13 @@ var DockviewComponent = class extends BaseGrid {
18295
18781
  return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
18296
18782
  }
18297
18783
  updateTheme() {
18298
- var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18784
+ var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe25, _this$_popoutWindowSe26, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18299
18785
  const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
18300
18786
  (_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
18301
18787
  const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
18302
18788
  this.gridview.margin = gap;
18303
18789
  for (const floating of this.floatingGroups) floating.gridview.margin = gap;
18304
- for (const entry of (_this$_popoutWindowSe23 = (_this$_popoutWindowSe24 = this._popoutWindowService) === null || _this$_popoutWindowSe24 === void 0 ? void 0 : _this$_popoutWindowSe24.entries) !== null && _this$_popoutWindowSe23 !== void 0 ? _this$_popoutWindowSe23 : []) entry.gridview.margin = gap;
18790
+ for (const entry of (_this$_popoutWindowSe25 = (_this$_popoutWindowSe26 = this._popoutWindowService) === null || _this$_popoutWindowSe26 === void 0 ? void 0 : _this$_popoutWindowSe26.entries) !== null && _this$_popoutWindowSe25 !== void 0 ? _this$_popoutWindowSe25 : []) entry.gridview.margin = gap;
18305
18791
  (_this$_shellManager5 = this._shellManager) === null || _this$_shellManager5 === void 0 || _this$_shellManager5.updateTheme(gap, (_theme$edgeGroupColla = theme.edgeGroupCollapsedSize) !== null && _theme$edgeGroupColla !== void 0 ? _theme$edgeGroupColla : 35);
18306
18792
  if (theme.dndOverlayBorder === void 0) {
18307
18793
  var _this$_shellManager6;
@@ -18370,6 +18856,7 @@ var GridviewComponent = class extends BaseGrid {
18370
18856
  }), this.onDidActiveChange((event) => {
18371
18857
  this._onDidActiveGroupChange.fire(event);
18372
18858
  }));
18859
+ this.layoutFromElement();
18373
18860
  }
18374
18861
  updateOptions(options) {
18375
18862
  super.updateOptions(options);
@@ -18615,6 +19102,7 @@ var SplitviewComponent = class extends Resizable {
18615
19102
  this._options = options;
18616
19103
  this.splitview = new Splitview(this.element, options);
18617
19104
  this.addDisposables(this._onDidAddView, this._onDidLayoutfromJSON, this._onDidRemoveView, this._onDidLayoutChange);
19105
+ this.layoutFromElement();
18618
19106
  }
18619
19107
  updateOptions(options) {
18620
19108
  if ("className" in options) {
@@ -19209,4 +19697,4 @@ function createPaneview(element, options) {
19209
19697
  }
19210
19698
 
19211
19699
  //#endregion
19212
- export { AdvancedDnDModule, AdvancedDnDService, BaseGrid, ContentContainer, ContextMenuController, ContextMenuModule, DEFAULT_TAB_GROUP_COLORS, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDidDropEvent, Disposable as DockviewDisposable, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewUnhandledDragOverEvent, DockviewWillDropEvent, DockviewWillShowOverlayLocationEvent, DraggablePaneviewPanel, EdgeGroupModule, FloatingGroupModule, Gridview, GridviewApi, GridviewComponent, GridviewPanel, LayoutPriority, LiveRegionModule, LocalSelectionTransfer, OVERFLOW_MAX_TAB_ROWS_VARIABLE, OVERFLOW_WRAP_TABS_CAPPED_CLASS, OVERFLOW_WRAP_TABS_CLASS, OVERFLOW_WRAP_TABS_VERTICAL_TAB_HEIGHT_VARIABLE, Orientation, PROPERTY_KEYS_DOCKVIEW, PROPERTY_KEYS_GRIDVIEW, PROPERTY_KEYS_PANEVIEW, PROPERTY_KEYS_SPLITVIEW, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewUnhandledDragOverEvent, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, Tab, TabGroupChipsModule, TabGroupChipsService, TabGroupColorPalette, applyTabGroupAccent, clearRegisteredModules, createCloseButton, createDismissableLayer, createDockview, createGridview, createPaneview, createPinButton, createSplitview, defineModule, directionToPosition, findRelativeZIndexParent, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRegisteredModules, getRelativeLocation, indexInParent, isAnyEdgeGroupEnabled, isEdgeGroupEnabled, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, orthogonal, positionToDirection, prefersReducedMotion, registerModules, resolveMessages, resolveOpaqueBackground, resolveTabGroupAccent, themeAbyss, themeAbyssSpaced, themeCatppuccinMocha, themeCatppuccinMochaSpaced, themeDark, themeDracula, themeGithubDark, themeGithubDarkSpaced, themeGithubLight, themeGithubLightSpaced, themeLight, themeLightSpaced, themeMonokai, themeNord, themeNordSpaced, themeSolarizedLight, themeSolarizedLightSpaced, themeVisualStudio, toTarget };
19700
+ export { AdvancedDnDModule, AdvancedDnDService, BaseGrid, ContentContainer, ContextMenuController, ContextMenuModule, DEFAULT_TAB_GROUP_COLORS, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDidDropEvent, Disposable as DockviewDisposable, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewUnhandledDragOverEvent, DockviewWillDropEvent, DockviewWillShowOverlayLocationEvent, DraggablePaneviewPanel, EdgeGroupModule, FloatingGroupModule, Gridview, GridviewApi, GridviewComponent, GridviewPanel, LayoutPriority, LiveRegionModule, LocalSelectionTransfer, OVERFLOW_MAX_TAB_ROWS_VARIABLE, OVERFLOW_WRAP_TABS_CAPPED_CLASS, OVERFLOW_WRAP_TABS_CLASS, OVERFLOW_WRAP_TABS_VERTICAL_TAB_HEIGHT_VARIABLE, Orientation, PROPERTY_KEYS_DOCKVIEW, PROPERTY_KEYS_GRIDVIEW, PROPERTY_KEYS_PANEVIEW, PROPERTY_KEYS_SPLITVIEW, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewUnhandledDragOverEvent, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, Tab, TabGroupChipsModule, TabGroupChipsService, TabGroupColorPalette, applyTabGroupAccent, clearRegisteredModules, createCloseButton, createDismissableLayer, createDockview, createGridview, createPaneview, createPinButton, createSplitview, defineModule, directionToPosition, findRelativeZIndexParent, getActiveElement, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getPopoutUrlError, getRegisteredModules, getRelativeLocation, indexInParent, isAnyEdgeGroupEnabled, isEdgeGroupEnabled, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, orthogonal, positionToDirection, prefersReducedMotion, registerModules, resolveMessages, resolveOpaqueBackground, resolveTabGroupAccent, themeAbyss, themeAbyssSpaced, themeCatppuccinMocha, themeCatppuccinMochaSpaced, themeDark, themeDracula, themeGithubDark, themeGithubDarkSpaced, themeGithubLight, themeGithubLightSpaced, themeLight, themeLightSpaced, themeMonokai, themeNord, themeNordSpaced, themeSolarizedLight, themeSolarizedLightSpaced, themeVisualStudio, toTarget };