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