dockview-core 8.3.1 → 8.4.1

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 (31) 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/ghost.d.ts +3 -0
  4. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +1 -0
  5. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -0
  6. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +6 -2
  7. package/dist/cjs/dockview/components/popupService.d.ts +2 -0
  8. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +3 -1
  9. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +52 -21
  10. package/dist/cjs/dockview/dndCapabilities.d.ts +3 -4
  11. package/dist/cjs/dockview/dockviewComponent.d.ts +34 -16
  12. package/dist/cjs/dockview/dockviewShell.d.ts +12 -0
  13. package/dist/cjs/dockview/moduleContracts.d.ts +2 -0
  14. package/dist/cjs/dockview/options.d.ts +13 -0
  15. package/dist/cjs/dockview/popoutWindowService.d.ts +8 -2
  16. package/dist/cjs/dom.d.ts +61 -1
  17. package/dist/cjs/gridview/branchNode.d.ts +2 -1
  18. package/dist/cjs/gridview/gridview.d.ts +2 -1
  19. package/dist/cjs/index.d.ts +5 -1
  20. package/dist/cjs/popoutWindow.d.ts +57 -12
  21. package/dist/cjs/resizable.d.ts +12 -0
  22. package/dist/cjs/splitview/splitview.d.ts +3 -1
  23. package/dist/dockview-core.js +979 -469
  24. package/dist/dockview-core.min.js +11 -4
  25. package/dist/dockview-core.min.noStyle.js +2 -2
  26. package/dist/dockview-core.noStyle.js +978 -468
  27. package/dist/package/main.cjs.js +978 -468
  28. package/dist/package/main.cjs.min.js +2 -2
  29. package/dist/package/main.esm.min.mjs +2 -2
  30. package/dist/package/main.esm.mjs +977 -469
  31. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 8.3.1
3
+ * @version 8.4.1
4
4
  * @link https://github.com/dockview/dockview
5
5
  * @license MIT
6
6
  */
@@ -333,21 +333,29 @@ var OverflowObserver = class extends CompositeDisposable {
333
333
  }
334
334
  };
335
335
  function watchElementResize(element, cb) {
336
+ const pendingFrames = /* @__PURE__ */ new Set();
336
337
  const observer = new ResizeObserver((entires) => {
337
338
  /**
338
339
  * Fast browser window resize produces Error: ResizeObserver loop limit exceeded.
339
340
  * The error isn't visible in browser console, doesn't affect functionality, but degrades performance.
340
341
  * See https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/58701523#58701523
341
342
  */
342
- requestAnimationFrame(() => {
343
+ let ran = false;
344
+ let frame;
345
+ frame = requestAnimationFrame(() => {
346
+ ran = true;
347
+ if (frame !== void 0) pendingFrames.delete(frame);
343
348
  const firstEntry = entires[0];
344
349
  cb(firstEntry);
345
350
  });
351
+ if (!ran) pendingFrames.add(frame);
346
352
  });
347
353
  observer.observe(element);
348
354
  return { dispose: () => {
349
355
  observer.unobserve(element);
350
356
  observer.disconnect();
357
+ for (const frame of pendingFrames) cancelAnimationFrame(frame);
358
+ pendingFrames.clear();
351
359
  } };
352
360
  }
353
361
  const removeClasses = (element, ...classes) => {
@@ -382,7 +390,7 @@ var FocusTracker = class extends CompositeDisposable {
382
390
  this._onDidBlur = new Emitter();
383
391
  this.onDidBlur = this._onDidBlur.event;
384
392
  this.addDisposables(this._onDidFocus, this._onDidBlur);
385
- let hasFocus = isAncestor(document.activeElement, element);
393
+ let hasFocus = isAncestor(getActiveElement(element), element);
386
394
  let loosingFocus = false;
387
395
  const onFocus = () => {
388
396
  loosingFocus = false;
@@ -404,7 +412,7 @@ var FocusTracker = class extends CompositeDisposable {
404
412
  }
405
413
  };
406
414
  this._refreshStateHandler = () => {
407
- if (isAncestor(document.activeElement, element) !== hasFocus) if (hasFocus) onBlur();
415
+ if (isAncestor(getActiveElement(element), element) !== hasFocus) if (hasFocus) onBlur();
408
416
  else onFocus();
409
417
  };
410
418
  this.addDisposables(addDisposableListener(element, "focus", onFocus, true));
@@ -421,6 +429,49 @@ function quasiPreventDefault(event) {
421
429
  function quasiDefaultPrevented(event) {
422
430
  return event[QUASI_PREVENT_DEFAULT_KEY];
423
431
  }
432
+ /** Whether the event originated within any of `elements`. Checks the
433
+ * composed path, so it also holds for elements inside a shadow root, which a
434
+ * window or document listener sees retargeted to the shadow host. */
435
+ function isEventWithin(event, elements) {
436
+ var _event$composedPath, _event$composedPath2;
437
+ 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 : [];
438
+ if (path.length > 0) return elements.some((el) => path.includes(el));
439
+ const target = event.target;
440
+ return target instanceof Node && elements.some((el) => el.contains(target));
441
+ }
442
+ /** Every shadow root between `element` and its document, innermost first. An
443
+ * element in a component nested inside another component sits in more than
444
+ * one, and an event is cut at each boundary. */
445
+ function shadowRootsOf(node) {
446
+ const roots = [];
447
+ let root = node.getRootNode();
448
+ while (isShadowRoot(root)) {
449
+ roots.push(root);
450
+ root = root.host.getRootNode();
451
+ }
452
+ return roots;
453
+ }
454
+ /**
455
+ * `element` as a listener rooted in `scope`'s tree sees it. A node in a shadow
456
+ * root *below* that tree is retargeted to its host there, repeatedly for
457
+ * nested roots; a node already in the same tree is returned unchanged. Omit
458
+ * `scope` (or pass a node in the document) for the document-level view, which
459
+ * is what a window listener gets.
460
+ *
461
+ * The scope matters: a layer living inside a shadow root must be able to tell
462
+ * its own elements apart, and retargeting everything out to the document would
463
+ * collapse them all onto the one host.
464
+ */
465
+ function retargetInto(element, scope) {
466
+ const scopeRoot = scope === null || scope === void 0 ? void 0 : scope.getRootNode();
467
+ let current = element;
468
+ let root = current.getRootNode();
469
+ while (root !== scopeRoot && isShadowRoot(root)) {
470
+ current = root.host;
471
+ root = current.getRootNode();
472
+ }
473
+ return current;
474
+ }
424
475
  function addStyles(document, styleSheetList, options = {}) {
425
476
  const styleSheets = Array.from(styleSheetList);
426
477
  const { nonce } = options;
@@ -431,6 +482,7 @@ function addStyles(document, styleSheetList, options = {}) {
431
482
  link.href = styleSheet.href;
432
483
  link.type = styleSheet.type;
433
484
  link.rel = "stylesheet";
485
+ if (resolvedNonce) link.setAttribute("nonce", resolvedNonce);
434
486
  document.head.appendChild(link);
435
487
  continue;
436
488
  }
@@ -470,6 +522,23 @@ function isInDocument(element) {
470
522
  else currentElement = currentElement.parentNode;
471
523
  return false;
472
524
  }
525
+ /** Duck-typed so it holds for a shadow root from another window's realm. */
526
+ function isShadowRoot(node) {
527
+ return !!node && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && "host" in node && !!node.host;
528
+ }
529
+ /**
530
+ * The document or shadow root to hit-test (`elementFromPoint` /
531
+ * `elementsFromPoint`) against for `node`. Hit-testing on the document stops
532
+ * at a shadow host, so when dockview is mounted in a shadow root it has to go
533
+ * through that root to reach its own elements. Falls back to the owning
534
+ * document (which may be a popout's) for a detached node.
535
+ */
536
+ function getHitTestRoot(node) {
537
+ var _node$ownerDocument;
538
+ const root = node.getRootNode();
539
+ if (root !== node && typeof root.elementsFromPoint === "function") return root;
540
+ return (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 ? _node$ownerDocument : document;
541
+ }
473
542
  function addTestId(element, id) {
474
543
  element.dataset.testid = id;
475
544
  }
@@ -504,6 +573,38 @@ function disableIframePointEvents(rootNode = document) {
504
573
  iframes.splice(0, iframes.length);
505
574
  } };
506
575
  }
576
+ /**
577
+ * Suppress text selection for the duration of a pointer drag.
578
+ *
579
+ * A pointer drag is just a held button as far as the browser is concerned, so
580
+ * it selects text under the cursor as it travels. HTML5 drag-and-drop is
581
+ * exempt - the browser owns the gesture - which is why this is only needed on
582
+ * the pointer backend.
583
+ *
584
+ * `user-select: none` alone is not enough on WebKit: it starts the selection
585
+ * gesture from a mousedown on a `user-select: none` element unless that
586
+ * element is also natively draggable, then extends it into whatever the
587
+ * pointer crosses. Cancelling `selectstart` refuses that first extension,
588
+ * which ends the gesture for the rest of the drag.
589
+ *
590
+ * An existing selection is left alone: a mousedown on a `user-select: none`
591
+ * element does not clear one natively, and a pointer drag should not either.
592
+ */
593
+ function disableTextSelection(rootNode = document) {
594
+ const doc = rootNode instanceof Document ? rootNode : rootNode.ownerDocument;
595
+ const root = doc === null || doc === void 0 ? void 0 : doc.documentElement;
596
+ if (!doc || !root) return { release: () => void 0 };
597
+ const properties = ["user-select", "-webkit-user-select"];
598
+ const previous = properties.map((name) => [name, root.style.getPropertyValue(name)]);
599
+ for (const name of properties) root.style.setProperty(name, "none");
600
+ const onSelectStart = (event) => event.preventDefault();
601
+ doc.addEventListener("selectstart", onSelectStart);
602
+ return { release: () => {
603
+ doc.removeEventListener("selectstart", onSelectStart);
604
+ for (const [name, value] of previous) if (value) root.style.setProperty(name, value);
605
+ else root.style.removeProperty(name);
606
+ } };
607
+ }
507
608
  function getDockviewTheme(element) {
508
609
  function toClassList(element) {
509
610
  const list = [];
@@ -515,6 +616,11 @@ function getDockviewTheme(element) {
515
616
  while (parent !== null) {
516
617
  theme = toClassList(parent).find((cls) => cls.startsWith("dockview-theme-"));
517
618
  if (typeof theme === "string") break;
619
+ if (parent.parentElement === null) {
620
+ const root = parent.getRootNode();
621
+ parent = isShadowRoot(root) ? root.host : null;
622
+ continue;
623
+ }
518
624
  parent = parent.parentElement;
519
625
  }
520
626
  return theme;
@@ -626,6 +732,285 @@ function resolveOpaqueBackground(element) {
626
732
  }
627
733
  return "";
628
734
  }
735
+ /** The focused element as seen from `node`'s own tree. Unlike
736
+ * `document.activeElement`, which is the shadow host when focus is inside a
737
+ * shadow root, this reaches into the root `node` lives in (and a popout's
738
+ * own document), while a web component nested inside that tree still
739
+ * resolves to its host there. */
740
+ function getActiveElement(node) {
741
+ var _root$activeElement;
742
+ const root = node.getRootNode();
743
+ const doc = root.nodeType === Node.DOCUMENT_NODE ? root : node.ownerDocument;
744
+ if (doc && typeof doc.hasFocus === "function" && !doc.hasFocus()) return null;
745
+ return (_root$activeElement = root.activeElement) !== null && _root$activeElement !== void 0 ? _root$activeElement : null;
746
+ }
747
+ /** Where to append a floating element (e.g. a drag ghost) for `node`: its
748
+ * shadow root when it lives in one, so styles scoped there still apply,
749
+ * otherwise the body of its own document (which may be a popout's). */
750
+ function getOverlayParent(node) {
751
+ var _node$ownerDocument2;
752
+ const root = node.getRootNode();
753
+ if (isShadowRoot(root)) return root;
754
+ return ((_node$ownerDocument2 = node.ownerDocument) !== null && _node$ownerDocument2 !== void 0 ? _node$ownerDocument2 : document).body;
755
+ }
756
+
757
+ //#endregion
758
+ //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
759
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
760
+ try {
761
+ var i = n[a](c), u = i.value;
762
+ } catch (n) {
763
+ e(n);
764
+ return;
765
+ }
766
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
767
+ }
768
+ function _asyncToGenerator(n) {
769
+ return function() {
770
+ var t = this, e = arguments;
771
+ return new Promise(function(r, o) {
772
+ var a = n.apply(t, e);
773
+ function _next(n) {
774
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
775
+ }
776
+ function _throw(n) {
777
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
778
+ }
779
+ _next(void 0);
780
+ });
781
+ };
782
+ }
783
+
784
+ //#endregion
785
+ //#region src/popoutWindow.ts
786
+ /**
787
+ * Throwing form of {@link getPopoutUrlError}, for callers with no way to
788
+ * recover from a refused URL.
789
+ */
790
+ function assertSameOriginPopoutUrl(url) {
791
+ const error = getPopoutUrlError(url);
792
+ if (error) throw error;
793
+ }
794
+ /**
795
+ * Schemes a popout must never open: each runs script in a context the browser
796
+ * still associates with the opener, or (for `file:`) has no origin to check.
797
+ */
798
+ const UNSAFE_POPOUT_PROTOCOLS = /* @__PURE__ */ new Set([
799
+ "javascript:",
800
+ "data:",
801
+ "blob:",
802
+ "vbscript:",
803
+ "file:"
804
+ ]);
805
+ /** How often an open popout window's `closed` flag is checked. */
806
+ const CLOSED_POLL_INTERVAL_MS = 250;
807
+ /**
808
+ * The reason `url` is unusable as a popout target, or `undefined` if it is
809
+ * allowed. Rejects anything that isn't same-origin with the page (scheme and
810
+ * host, so a packaged webview's own scheme such as `tauri://` qualifies), and
811
+ * the `javascript:`, `data:`, `blob:`, `vbscript:` and `file:` schemes that
812
+ * would otherwise execute in a context the browser still associates with the
813
+ * opener via `window.opener`.
814
+ *
815
+ * Callers that can recover from a refusal use this rather than catching, so it
816
+ * can be handled without a rejected promise. `page` is what the URL resolves
817
+ * against, and defaults to this page.
818
+ */
819
+ function getPopoutUrlError(url, page = globalThis.location) {
820
+ let resolved;
821
+ try {
822
+ resolved = new URL(url, page.href);
823
+ } catch (_unused) {
824
+ return /* @__PURE__ */ new Error(`dockview: invalid popout URL: ${url}`);
825
+ }
826
+ 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}`);
827
+ 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}`);
828
+ }
829
+ var PopoutWindow = class extends CompositeDisposable {
830
+ get window() {
831
+ var _this$_window$value, _this$_window;
832
+ 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;
833
+ }
834
+ /** Set when {@link open} resolved `null`, saying which way it failed. */
835
+ get failure() {
836
+ return this._failure;
837
+ }
838
+ constructor(target, className, options) {
839
+ super();
840
+ this.target = target;
841
+ this.className = className;
842
+ this.options = options;
843
+ this._onWillClose = new Emitter();
844
+ this.onWillClose = this._onWillClose.event;
845
+ this._onDidClose = new Emitter();
846
+ this.onDidClose = this._onDidClose.event;
847
+ this._window = null;
848
+ this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
849
+ this.close();
850
+ } });
851
+ }
852
+ dimensions() {
853
+ if (!this._window) return null;
854
+ const left = this._window.value.screenX;
855
+ return {
856
+ top: this._window.value.screenY,
857
+ left,
858
+ width: this._window.value.innerWidth,
859
+ height: this._window.value.innerHeight
860
+ };
861
+ }
862
+ close() {
863
+ var _this$options$onWillC, _this$options;
864
+ const current = this._window;
865
+ if (!current) return;
866
+ this._window = null;
867
+ this._onWillClose.fire();
868
+ (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
869
+ id: this.target,
870
+ window: current.value
871
+ });
872
+ current.disposable.dispose();
873
+ this._onDidClose.fire();
874
+ }
875
+ open() {
876
+ var _this = this;
877
+ return _asyncToGenerator(function* () {
878
+ var _this$options$onDidOp, _this$options2;
879
+ if (_this._window) throw new Error("instance of popout window is already open");
880
+ const url = `${_this.options.url}`;
881
+ assertSameOriginPopoutUrl(url);
882
+ const features = Object.entries({
883
+ top: _this.options.top,
884
+ left: _this.options.left,
885
+ width: _this.options.width,
886
+ height: _this.options.height
887
+ }).map(([key, value]) => `${key}=${value}`).join(",");
888
+ /**
889
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
890
+ */
891
+ const externalWindow = window.open(url, _this.target, features);
892
+ if (!externalWindow) {
893
+ _this._failure = { reason: "blocked" };
894
+ return null;
895
+ }
896
+ const disposable = new CompositeDisposable();
897
+ _this._window = {
898
+ value: externalWindow,
899
+ disposable
900
+ };
901
+ disposable.addDisposables(Disposable.from(() => {
902
+ externalWindow.close();
903
+ }), _this.watchForClose(externalWindow), addDisposableListener(globalThis.window, "beforeunload", () => {
904
+ /**
905
+ * before the main window closes we should close this popup too
906
+ * to be good citizens
907
+ *
908
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
909
+ */
910
+ _this.close();
911
+ }));
912
+ const container = _this.createPopoutWindowContainer();
913
+ if (_this.className) container.classList.add(_this.className);
914
+ (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
915
+ id: _this.target,
916
+ window: externalWindow
917
+ });
918
+ return new Promise((resolve) => {
919
+ /**
920
+ * A host can answer `window.open` with a window in its own
921
+ * JavaScript context, which throws on first touch and cannot be
922
+ * filled with panel DOM. Settle as a blocked popup does, so the
923
+ * caller's fallback returns the group to the grid.
924
+ */
925
+ const abandon = (err) => {
926
+ _this._failure = {
927
+ reason: "unscriptable",
928
+ error: err instanceof Error ? err : new Error(String(err))
929
+ };
930
+ _this.close();
931
+ resolve(null);
932
+ };
933
+ try {
934
+ externalWindow.addEventListener("unload", () => {});
935
+ } catch (err) {
936
+ abandon(err);
937
+ return;
938
+ }
939
+ /**
940
+ * `load` is the only event that resolves this promise with a
941
+ * container, so a window that goes away first would leave the
942
+ * caller awaiting a promise that never settles - and
943
+ * `addPopoutGroup` holds its layout transaction open until it does.
944
+ * Settle with `null` on close, the same signal a blocked popup
945
+ * gives and one the caller already handles. `resolve` after the
946
+ * fact is a no-op, so a `load` that arrived first still wins.
947
+ */
948
+ disposable.addDisposables(_this.onWillClose(() => {
949
+ var _this$_failure;
950
+ (_this$_failure = _this._failure) !== null && _this$_failure !== void 0 || (_this._failure = { reason: "closed" });
951
+ resolve(null);
952
+ }));
953
+ externalWindow.addEventListener("load", () => {
954
+ /**
955
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
956
+ */
957
+ try {
958
+ var _globalThis$document$, _this$options$styleRo, _this$options3;
959
+ const externalDocument = externalWindow.document;
960
+ externalDocument.title = document.title;
961
+ externalDocument.body.appendChild(container);
962
+ addStyles(externalDocument, [...Array.from(globalThis.document.styleSheets), ...(_globalThis$document$ = globalThis.document.adoptedStyleSheets) !== null && _globalThis$document$ !== void 0 ? _globalThis$document$ : []], { nonce: _this.options.nonce });
963
+ const sheets = [];
964
+ 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()) {
965
+ var _root$styleSheets, _root$adoptedStyleShe;
966
+ 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 : []);
967
+ }
968
+ if (sheets.length > 0) addStyles(externalDocument, sheets, { nonce: _this.options.nonce });
969
+ /**
970
+ * beforeunload must be registered after load for reasons I could not determine
971
+ * otherwise the beforeunload event will not fire when the window is closed
972
+ */
973
+ addDisposableListener(externalWindow, "beforeunload", () => {
974
+ /**
975
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
976
+ */
977
+ _this.close();
978
+ });
979
+ resolve(container);
980
+ } catch (err) {
981
+ abandon(err);
982
+ }
983
+ });
984
+ });
985
+ })();
986
+ }
987
+ /**
988
+ * Backstop for the `beforeunload` signal, which a window torn down without
989
+ * running its unload handlers never sends: a native shell destroying the
990
+ * webview, or a browser discarding the page. `closed` is readable on any
991
+ * handle, cross-origin included. Whichever signal arrives first wins.
992
+ */
993
+ watchForClose(externalWindow) {
994
+ if (typeof externalWindow.closed !== "boolean") return Disposable.NONE;
995
+ const handle = setInterval(() => {
996
+ if (externalWindow.closed) this.close();
997
+ }, CLOSED_POLL_INTERVAL_MS);
998
+ return Disposable.from(() => {
999
+ clearInterval(handle);
1000
+ });
1001
+ }
1002
+ createPopoutWindowContainer() {
1003
+ const el = document.createElement("div");
1004
+ el.classList.add("dv-popout-window");
1005
+ el.id = "dv-popout-window";
1006
+ el.style.position = "absolute";
1007
+ el.style.width = "100%";
1008
+ el.style.height = "100%";
1009
+ el.style.top = "0px";
1010
+ el.style.left = "0px";
1011
+ return el;
1012
+ }
1013
+ };
629
1014
 
630
1015
  //#endregion
631
1016
  //#region src/array.ts
@@ -845,6 +1230,15 @@ var Splitview = class {
845
1230
  get proportions() {
846
1231
  return this._proportions ? [...this._proportions] : void 0;
847
1232
  }
1233
+ get proportionalLayout() {
1234
+ return this._proportionalLayout;
1235
+ }
1236
+ set proportionalLayout(value) {
1237
+ if (this._proportionalLayout === value) return;
1238
+ this._proportionalLayout = value;
1239
+ if (value) this.saveProportions();
1240
+ else this._proportions = void 0;
1241
+ }
848
1242
  get orientation() {
849
1243
  return this._orientation;
850
1244
  }
@@ -969,7 +1363,7 @@ var Splitview = class {
969
1363
  this._orientation = (_options$orientation = options.orientation) !== null && _options$orientation !== void 0 ? _options$orientation : "VERTICAL";
970
1364
  this.element = this.createContainer();
971
1365
  this.margin = (_options$margin = options.margin) !== null && _options$margin !== void 0 ? _options$margin : 0;
972
- this.proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
1366
+ this._proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
973
1367
  this.viewContainer = this.createViewContainer();
974
1368
  this.sashContainer = this.createSashContainer();
975
1369
  this.element.appendChild(this.sashContainer);
@@ -1693,10 +2087,18 @@ var BranchNode = class BranchNode extends CompositeDisposable {
1693
2087
  if (child instanceof BranchNode) child.margin = value;
1694
2088
  });
1695
2089
  }
2090
+ get proportionalLayout() {
2091
+ return this.splitview.proportionalLayout;
2092
+ }
2093
+ set proportionalLayout(value) {
2094
+ this.splitview.proportionalLayout = value;
2095
+ this.children.forEach((child) => {
2096
+ if (child instanceof BranchNode) child.proportionalLayout = value;
2097
+ });
2098
+ }
1696
2099
  constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, margin, childDescriptors) {
1697
2100
  super();
1698
2101
  this.orientation = orientation;
1699
- this.proportionalLayout = proportionalLayout;
1700
2102
  this.styles = styles;
1701
2103
  this._childrenDisposable = Disposable.NONE;
1702
2104
  this.children = [];
@@ -2238,8 +2640,13 @@ var Gridview = class {
2238
2640
  }
2239
2641
  return findLeaf(this.root, reverse);
2240
2642
  }
2643
+ get proportionalLayout() {
2644
+ return this.root.proportionalLayout;
2645
+ }
2646
+ set proportionalLayout(value) {
2647
+ this.root.proportionalLayout = value;
2648
+ }
2241
2649
  constructor(proportionalLayout, styles, orientation, locked, margin) {
2242
- this.proportionalLayout = proportionalLayout;
2243
2650
  this.styles = styles;
2244
2651
  this._locked = false;
2245
2652
  this._margin = 0;
@@ -2433,6 +2840,25 @@ var Resizable = class extends CompositeDisposable {
2433
2840
  this.layout(width, height);
2434
2841
  }));
2435
2842
  }
2843
+ /**
2844
+ * Lay out from the element's current size.
2845
+ *
2846
+ * The ResizeObserver above only reports asynchronously, so between
2847
+ * construction and its first callback the component believes it has no
2848
+ * size - and anything built in that window (panels added right after
2849
+ * `createDockview`, say) resolves its sizes against zero and collapses to
2850
+ * minimums. Concrete components call this once they are fully constructed
2851
+ * so that work sees the real size. The same guards as the observer apply:
2852
+ * a detached or hidden element has no size worth propagating.
2853
+ */
2854
+ layoutFromElement() {
2855
+ if (this.disableResizing || !this._element.offsetParent) return;
2856
+ if (!isInDocument(this._element)) return;
2857
+ const width = Math.round(this._element.clientWidth);
2858
+ const height = Math.round(this._element.clientHeight);
2859
+ if (width === 0 || height === 0) return;
2860
+ this.layout(width, height);
2861
+ }
2436
2862
  };
2437
2863
 
2438
2864
  //#endregion
@@ -2533,7 +2959,10 @@ var BaseGrid = class extends Resizable {
2533
2959
  return this.gridview.isViewVisible(getGridLocation(panel.element));
2534
2960
  }
2535
2961
  updateOptions(options) {
2536
- if (typeof options.proportionalLayout === "boolean") {}
2962
+ if ("proportionalLayout" in options) {
2963
+ var _options$proportional;
2964
+ this.gridview.proportionalLayout = (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true;
2965
+ }
2537
2966
  if (options.orientation) this.gridview.orientation = options.orientation;
2538
2967
  if ("styles" in options) {}
2539
2968
  if ("disableAutoResizing" in options) {
@@ -3342,6 +3771,15 @@ var DockviewApi = class {
3342
3771
  get onUnhandledDragOver() {
3343
3772
  return this.component.onUnhandledDragOver;
3344
3773
  }
3774
+ /**
3775
+ * The drag-and-drop backends currently live: `dndStrategy` resolved against
3776
+ * this device, which `'auto'` reads from the primary input device. Only an
3777
+ * HTML5 drag can leave the window it started in, so check `html5` before
3778
+ * relying on a drag between a popout window and the main window.
3779
+ */
3780
+ get dndCapabilities() {
3781
+ return this.component.dndCapabilities;
3782
+ }
3345
3783
  get onDidPopoutGroupSizeChange() {
3346
3784
  return this.component.onDidPopoutGroupSizeChange;
3347
3785
  }
@@ -3364,9 +3802,27 @@ var DockviewApi = class {
3364
3802
  get onDidRemovePopoutGroup() {
3365
3803
  return this.component.onDidRemovePopoutGroup;
3366
3804
  }
3805
+ /**
3806
+ * Fires when a popout window could not be used, carrying which way it
3807
+ * failed: the URL was refused, the browser blocked the window, the host
3808
+ * returned a window whose document the opener cannot reach, or it closed
3809
+ * before loading. The group stays in (or returns to) the main grid.
3810
+ */
3367
3811
  get onDidOpenPopoutWindowFail() {
3368
3812
  return this.component.onDidOpenPopoutWindowFail;
3369
3813
  }
3814
+ /**
3815
+ * Fires as dockview lets go of a popout window, while that window is still
3816
+ * open, carrying its live `Window` handle. Covers every popout the component
3817
+ * opened and every reason for closing one, disposal included;
3818
+ * {@link onDidAddPopoutGroup} is the opening half.
3819
+ *
3820
+ * For hosts that own their windows: in a desktop webview the page's own
3821
+ * `close()` can be a no-op, so the shell has to be told.
3822
+ */
3823
+ get onWillClosePopoutWindow() {
3824
+ return this.component.onWillClosePopoutWindow;
3825
+ }
3370
3826
  /** Enumerate the popout groups currently open in their own windows. */
3371
3827
  getPopouts() {
3372
3828
  return this.component.getPopouts();
@@ -4333,7 +4789,8 @@ function addGhostImage(dataTransfer, ghostElement, options) {
4333
4789
  var _options$ownerDocumen, _options$x, _options$y;
4334
4790
  addClasses(ghostElement, "dv-dragged");
4335
4791
  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);
4792
+ ghostElement.style.position = "absolute";
4793
+ ((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
4794
  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
4795
  setTimeout(() => {
4339
4796
  removeClasses(ghostElement, "dv-dragged");
@@ -4385,7 +4842,7 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4385
4842
  } };
4386
4843
  }
4387
4844
  beginDrag(args) {
4388
- var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3;
4845
+ var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3, _source$ownerDocument4;
4389
4846
  if (this._active) this.cancel();
4390
4847
  const { pointerEvent, source } = args;
4391
4848
  const dataDisposable = args.getData();
@@ -4401,13 +4858,14 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4401
4858
  this._dataDisposable = dataDisposable;
4402
4859
  this._ghost = args.ghost;
4403
4860
  this._iframeShield = disableIframePointEvents((_source$ownerDocument = source.ownerDocument) !== null && _source$ownerDocument !== void 0 ? _source$ownerDocument : document);
4861
+ this._selectionShield = disableTextSelection((_source$ownerDocument2 = source.ownerDocument) !== null && _source$ownerDocument2 !== void 0 ? _source$ownerDocument2 : document);
4404
4862
  const startEvent = {
4405
4863
  clientX: pointerEvent.clientX,
4406
4864
  clientY: pointerEvent.clientY,
4407
4865
  pointerEvent
4408
4866
  };
4409
4867
  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;
4868
+ 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
4869
  this._moveListener = addDisposableListener(targetWindow, "pointermove", (e) => {
4412
4870
  var _this$_active;
4413
4871
  if (e.pointerId !== ((_this$_active = this._active) === null || _this$_active === void 0 ? void 0 : _this$_active.pointerId)) return;
@@ -4444,8 +4902,7 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4444
4902
  }
4445
4903
  }
4446
4904
  _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);
4905
+ const elements = (this._active ? getHitTestRoot(this._active.source) : document).elementsFromPoint(x, y);
4449
4906
  for (const el of elements) {
4450
4907
  let current = el;
4451
4908
  while (current) {
@@ -4495,7 +4952,7 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4495
4952
  this._onDragEnd.fire(dragEvent);
4496
4953
  }
4497
4954
  _teardown() {
4498
- var _this$_ghost2, _this$_iframeShield, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4955
+ var _this$_ghost2, _this$_iframeShield, _this$_selectionShiel, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4499
4956
  this._currentTarget = void 0;
4500
4957
  this._active = void 0;
4501
4958
  this._lastPointerEvent = void 0;
@@ -4505,6 +4962,8 @@ var PointerDragController = class PointerDragController extends CompositeDisposa
4505
4962
  this._ghost = void 0;
4506
4963
  (_this$_iframeShield = this._iframeShield) === null || _this$_iframeShield === void 0 || _this$_iframeShield.release();
4507
4964
  this._iframeShield = void 0;
4965
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
4966
+ this._selectionShield = void 0;
4508
4967
  (_this$_moveListener = this._moveListener) === null || _this$_moveListener === void 0 || _this$_moveListener.dispose();
4509
4968
  (_this$_upListener = this._upListener) === null || _this$_upListener === void 0 || _this$_upListener.dispose();
4510
4969
  (_this$_cancelListener = this._cancelListener) === null || _this$_cancelListener === void 0 || _this$_cancelListener.dispose();
@@ -4773,9 +5232,10 @@ var PointerDragSource = class extends CompositeDisposable {
4773
5232
  return true;
4774
5233
  }
4775
5234
  _onPointerDown(event) {
4776
- var _ref, _this$options$thresho, _ref2, _this$element$ownerDo, _this$element$ownerDo2;
5235
+ var _this$element$ownerDo, _ref, _this$options$thresho, _ref2, _this$element$ownerDo2, _this$element$ownerDo3;
4777
5236
  if (!this._shouldHandle(event)) return;
4778
5237
  this._cancelPending();
5238
+ this._selectionShield = disableTextSelection((_this$element$ownerDo = this.element.ownerDocument) !== null && _this$element$ownerDo !== void 0 ? _this$element$ownerDo : document);
4779
5239
  this._pendingPointerId = event.pointerId;
4780
5240
  this._startX = event.clientX;
4781
5241
  this._startY = event.clientY;
@@ -4791,7 +5251,7 @@ var PointerDragSource = class extends CompositeDisposable {
4791
5251
  const threshold = (_this$options$thresho = this.options.threshold) !== null && _this$options$thresho !== void 0 ? _this$options$thresho : DEFAULT_THRESHOLD;
4792
5252
  const pressToleranceOpt = this.options.pressTolerance;
4793
5253
  const pressTolerance = (_ref2 = typeof pressToleranceOpt === "function" ? pressToleranceOpt() : pressToleranceOpt) !== null && _ref2 !== void 0 ? _ref2 : DEFAULT_PRESS_TOLERANCE;
4794
- 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;
5254
+ 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;
4795
5255
  this._pendingMoveListener = addDisposableListener(targetWindow, "pointermove", (moveEvent) => {
4796
5256
  if (moveEvent.pointerId !== this._pendingPointerId) return;
4797
5257
  const dx = moveEvent.clientX - this._startX;
@@ -4817,7 +5277,9 @@ var PointerDragSource = class extends CompositeDisposable {
4817
5277
  this._cancelPending();
4818
5278
  }
4819
5279
  _cancelPending() {
4820
- var _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5280
+ var _this$_selectionShiel, _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5281
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
5282
+ this._selectionShield = void 0;
4821
5283
  this._pendingPointerId = void 0;
4822
5284
  if (this._armTimer !== void 0) {
4823
5285
  clearTimeout(this._armTimer);
@@ -4862,29 +5324,51 @@ var PointerDragSource = class extends CompositeDisposable {
4862
5324
  */
4863
5325
  var PointerGhost = class {
4864
5326
  constructor(opts) {
4865
- var _opts$offsetX, _opts$offsetY, _opts$opacity, _opts$owner$ownerDocu, _opts$owner;
5327
+ var _opts$offsetX, _opts$offsetY, _popover, _opts$opacity;
4866
5328
  this._disposed = false;
4867
5329
  this.element = opts.element;
4868
5330
  this.offsetX = (_opts$offsetX = opts.offsetX) !== null && _opts$offsetX !== void 0 ? _opts$offsetX : 0;
4869
5331
  this.offsetY = (_opts$offsetY = opts.offsetY) !== null && _opts$offsetY !== void 0 ? _opts$offsetY : 0;
4870
- this.element.style.position = "fixed";
4871
- this.element.style.left = "0px";
4872
- this.element.style.top = "0px";
4873
- this.element.style.pointerEvents = "none";
4874
- this.element.style.zIndex = "99999";
4875
- this.element.style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
4876
- this.element.style.willChange = "transform";
4877
- this.element.style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
4878
- ((_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);
5332
+ const parent = opts.owner ? getOverlayParent(opts.owner) : document.body;
5333
+ let popover;
5334
+ if (isShadowRoot(parent) && typeof this.element.showPopover === "function") {
5335
+ popover = this.element.ownerDocument.createElement("div");
5336
+ popover.popover = "manual";
5337
+ Object.assign(popover.style, {
5338
+ inset: "auto",
5339
+ margin: "0",
5340
+ padding: "0",
5341
+ border: "0",
5342
+ background: "transparent",
5343
+ color: "inherit",
5344
+ overflow: "visible"
5345
+ });
5346
+ popover.appendChild(this.element);
5347
+ this.element.style.pointerEvents = "none";
5348
+ this.element.style.transform = "none";
5349
+ }
5350
+ this.container = (_popover = popover) !== null && _popover !== void 0 ? _popover : this.element;
5351
+ const style = this.container.style;
5352
+ style.position = "fixed";
5353
+ style.left = "0px";
5354
+ style.top = "0px";
5355
+ style.pointerEvents = "none";
5356
+ style.zIndex = "99999";
5357
+ style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
5358
+ style.willChange = "transform";
5359
+ style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
5360
+ parent.appendChild(this.container);
5361
+ popover === null || popover === void 0 || popover.showPopover();
4879
5362
  }
4880
5363
  update(clientX, clientY) {
4881
5364
  if (this._disposed) return;
4882
- this.element.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
5365
+ this.container.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
4883
5366
  }
4884
5367
  dispose() {
4885
5368
  if (this._disposed) return;
4886
5369
  this._disposed = true;
4887
5370
  this.element.remove();
5371
+ if (this.container !== this.element) this.container.remove();
4888
5372
  }
4889
5373
  };
4890
5374
 
@@ -4921,7 +5405,8 @@ var Html5DragSource = class extends CompositeDisposable {
4921
5405
  addGhostImage(event.dataTransfer, ghost.element, {
4922
5406
  x: (_ghost$offsetX = ghost.offsetX) !== null && _ghost$offsetX !== void 0 ? _ghost$offsetX : 0,
4923
5407
  y: (_ghost$offsetY = ghost.offsetY) !== null && _ghost$offsetY !== void 0 ? _ghost$offsetY : 0,
4924
- ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0
5408
+ ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0,
5409
+ owner: this.el
4925
5410
  });
4926
5411
  if (ghost.dispose) {
4927
5412
  const disposeGhost = ghost.dispose;
@@ -5757,8 +6242,7 @@ var LongPressDetector = class extends CompositeDisposable {
5757
6242
  let guard;
5758
6243
  const timeout = setTimeout(() => guard === null || guard === void 0 ? void 0 : guard.dispose(), 500);
5759
6244
  guard = addDisposableListener(targetWindow, "click", (event) => {
5760
- const target = event.target;
5761
- if (target && this.element.contains(target)) {
6245
+ if (isEventWithin(event, [this.element])) {
5762
6246
  event.preventDefault();
5763
6247
  event.stopPropagation();
5764
6248
  }
@@ -5874,7 +6358,7 @@ var Tab = class extends CompositeDisposable {
5874
6358
  if (this.accessor.id === (data === null || data === void 0 ? void 0 : data.viewId)) {
5875
6359
  var _this$accessor$option;
5876
6360
  if (((_this$accessor$option = this.accessor.options.theme) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.tabAnimation) === "smooth") return false;
5877
- if (data.tabGroupId && this.group.model.getTabGroupForPanel(this.panel.id)) return false;
6361
+ if (data.tabGroupId && data.groupId === this.group.id && this.group.model.getTabGroupForPanel(this.panel.id)) return false;
5878
6362
  return true;
5879
6363
  }
5880
6364
  return this.group.model.canDisplayOverlay(event, position, "tab");
@@ -6487,6 +6971,7 @@ var DockviewUnhandledDragOverEvent = class extends AcceptableEvent {
6487
6971
  const PROPERTY_KEYS_DOCKVIEW = (() => {
6488
6972
  return Object.keys({
6489
6973
  disableAutoResizing: void 0,
6974
+ proportionalLayout: void 0,
6490
6975
  hideBorders: void 0,
6491
6976
  singleTabMode: void 0,
6492
6977
  disableFloatingGroups: void 0,
@@ -7340,10 +7825,16 @@ var TabGroupManager = class {
7340
7825
  (_entry$pointerDropTar = entry.pointerDropTarget) === null || _entry$pointerDropTar === void 0 || _entry$pointerDropTar.clearOverlay();
7341
7826
  }
7342
7827
  }
7343
- snapshotChipWidths() {
7344
- const widths = /* @__PURE__ */ new Map();
7345
- for (const [groupId, entry] of this._chipRenderers) widths.set(groupId, entry.chip.element.getBoundingClientRect().width);
7346
- return widths;
7828
+ /** Each chip's extent along the strip's main axis: width for a horizontal
7829
+ * header, height for a vertical one. */
7830
+ snapshotChipSizes() {
7831
+ const isVertical = this._ctx.getDirection() === "vertical";
7832
+ const sizes = /* @__PURE__ */ new Map();
7833
+ for (const [groupId, entry] of this._chipRenderers) {
7834
+ const rect = entry.chip.element.getBoundingClientRect();
7835
+ sizes.set(groupId, isVertical ? rect.height : rect.width);
7836
+ }
7837
+ return sizes;
7347
7838
  }
7348
7839
  positionUnderlines() {
7349
7840
  var _this$_indicator2;
@@ -7735,6 +8226,22 @@ var TabGroupManager = class {
7735
8226
  //#endregion
7736
8227
  //#region src/dockview/components/titlebar/tabReorderController.ts
7737
8228
  /**
8229
+ * Main-axis extent of a rect. Tabs flow along x in a horizontal header
8230
+ * (top/bottom) and along y in a vertical one (the left/right edge groups),
8231
+ * so the reorder math reads every size through this.
8232
+ */
8233
+ function mainAxisSize(rect, direction) {
8234
+ return direction === "vertical" ? rect.height : rect.width;
8235
+ }
8236
+ /** Leading edge of a rect along the main axis. */
8237
+ function mainAxisStart(rect, direction) {
8238
+ return direction === "vertical" ? rect.top : rect.left;
8239
+ }
8240
+ /** A cursor position projected onto the main axis. */
8241
+ function mainAxisCursor(event, direction) {
8242
+ return direction === "vertical" ? event.clientY : event.clientX;
8243
+ }
8244
+ /**
7738
8245
  * Tab drag-reorder + FLIP animation subsystem extracted from `Tabs`. The DOM
7739
8246
  * event wiring remains in `Tabs` and delegates the reorder/animation logic to
7740
8247
  * this controller. All access back into `Tabs` goes through
@@ -7829,14 +8336,30 @@ var TabReorderController = class extends CompositeDisposable {
7829
8336
  for (const tab of this._tabs) positions.set(tab.value.panel.id, tab.value.element.getBoundingClientRect());
7830
8337
  return positions;
7831
8338
  }
7832
- getAverageTabWidth() {
8339
+ /** Main-axis extent of a rect for this header's orientation. */
8340
+ _mainAxisSize(rect) {
8341
+ return mainAxisSize(rect, this._direction);
8342
+ }
8343
+ /** Main-axis leading edge of a rect for this header's orientation. */
8344
+ _mainAxisStart(rect) {
8345
+ return mainAxisStart(rect, this._direction);
8346
+ }
8347
+ /** The cursor coordinate along the main axis. */
8348
+ _mainAxisCoord(clientX, clientY) {
8349
+ return mainAxisCursor({
8350
+ clientX,
8351
+ clientY
8352
+ }, this._direction);
8353
+ }
8354
+ /** The margin that opens the insertion gap. It must run along the main
8355
+ * axis, so a vertical header pushes tabs down rather than sideways. */
8356
+ get _gapMarginProperty() {
8357
+ return this._direction === "vertical" ? "margin-top" : "margin-left";
8358
+ }
8359
+ getAverageTabSize() {
7833
8360
  if (this._tabs.length === 0) return 0;
7834
- const isVertical = this._direction === "vertical";
7835
8361
  let total = 0;
7836
- for (const tab of this._tabs) {
7837
- const rect = tab.value.element.getBoundingClientRect();
7838
- total += isVertical ? rect.height : rect.width;
7839
- }
8362
+ for (const tab of this._tabs) total += this._mainAxisSize(tab.value.element.getBoundingClientRect());
7840
8363
  return total / this._tabs.length;
7841
8364
  }
7842
8365
  /**
@@ -7846,8 +8369,7 @@ var TabReorderController = class extends CompositeDisposable {
7846
8369
  * `processDragOver` / `processDragLeave` helpers.
7847
8370
  */
7848
8371
  handlePointerDragMove(clientX, clientY) {
7849
- var _this$_tabsList$owner;
7850
- const elAtPoint = ((_this$_tabsList$owner = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner !== void 0 ? _this$_tabsList$owner : document).elementFromPoint(clientX, clientY);
8372
+ const elAtPoint = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7851
8373
  if (!(!!elAtPoint && (this._tabsList.contains(elAtPoint) || !!this._extendedDropZone && this._extendedDropZone.contains(elAtPoint)))) {
7852
8374
  if (this._pointerInsideTabsList) {
7853
8375
  this._pointerInsideTabsList = false;
@@ -7876,8 +8398,7 @@ var TabReorderController = class extends CompositeDisposable {
7876
8398
  this.resetDragAnimation();
7877
8399
  }
7878
8400
  isPointInsideTabsList(clientX, clientY) {
7879
- var _this$_tabsList$owner2;
7880
- const el = ((_this$_tabsList$owner2 = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner2 !== void 0 ? _this$_tabsList$owner2 : document).elementFromPoint(clientX, clientY);
8401
+ const el = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7881
8402
  return !!el && this._tabsList.contains(el);
7882
8403
  }
7883
8404
  /** Commit a smooth-mode intra-group reorder from the current insertion
@@ -7941,46 +8462,46 @@ var TabReorderController = class extends CompositeDisposable {
7941
8462
  const data = getPanelData();
7942
8463
  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;
7943
8464
  if (!data || !(data.panelId || data.tabGroupId) || data.groupId === this.group.id) return false;
7944
- const avgWidth = this.getAverageTabWidth();
7945
- this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgWidth) : this._makeTabDragAnimState(data, avgWidth);
8465
+ const avgSize = this.getAverageTabSize();
8466
+ this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgSize) : this._makeTabDragAnimState(data, avgSize);
7946
8467
  return true;
7947
8468
  }
7948
8469
  /** Anim state for an external group-chip drag (gap sized to the group). */
7949
- _makeGroupDragAnimState(data, avgWidth) {
8470
+ _makeGroupDragAnimState(data, avgSize) {
7950
8471
  var _sourceTg$panelIds$le;
7951
8472
  const sourceGroup = this.accessor.getPanel(data.groupId);
7952
8473
  const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
7953
- 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;
8474
+ 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;
7954
8475
  return {
7955
8476
  sourceTabId: "",
7956
8477
  sourceIndex: -1,
7957
8478
  tabPositions: this.snapshotTabPositions(),
7958
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8479
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7959
8480
  currentInsertionIndex: null,
7960
8481
  targetTabGroupId: null,
7961
8482
  sourceTabGroupId: data.tabGroupId,
7962
8483
  sourceGroupPanelIds: sourceTg ? new Set(sourceTg.panelIds) : /* @__PURE__ */ new Set(),
7963
- sourceChipWidth: avgWidth,
7964
- cursorOffsetFromDragLeft: groupGapWidth / 2,
7965
- sourceGapWidth: groupGapWidth,
7966
- containerLeft: this._tabsList.getBoundingClientRect().left
8484
+ sourceChipSize: avgSize,
8485
+ cursorOffsetFromDragStart: groupGapSize / 2,
8486
+ sourceGapSize: groupGapSize,
8487
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7967
8488
  };
7968
8489
  }
7969
8490
  /** Anim state for an external single-tab drag. */
7970
- _makeTabDragAnimState(data, avgWidth) {
8491
+ _makeTabDragAnimState(data, avgSize) {
7971
8492
  return {
7972
8493
  sourceTabId: data.panelId,
7973
8494
  sourceIndex: -1,
7974
8495
  tabPositions: this.snapshotTabPositions(),
7975
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8496
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7976
8497
  currentInsertionIndex: null,
7977
8498
  targetTabGroupId: null,
7978
8499
  sourceTabGroupId: null,
7979
8500
  sourceGroupPanelIds: null,
7980
- sourceChipWidth: 0,
7981
- cursorOffsetFromDragLeft: avgWidth / 2,
7982
- sourceGapWidth: avgWidth,
7983
- containerLeft: this._tabsList.getBoundingClientRect().left
8501
+ sourceChipSize: 0,
8502
+ cursorOffsetFromDragStart: avgSize / 2,
8503
+ sourceGapSize: avgSize,
8504
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7984
8505
  };
7985
8506
  }
7986
8507
  /**
@@ -8023,19 +8544,19 @@ var TabReorderController = class extends CompositeDisposable {
8023
8544
  container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
8024
8545
  }
8025
8546
  handleDragOver(event) {
8026
- var _this$accessor$option2;
8547
+ var _event$clientY2, _this$accessor$option2;
8027
8548
  if (!this._animState) return;
8028
8549
  if (this._wrapMode && !this._animState.sourceTabGroupId) {
8029
8550
  var _event$clientY;
8030
8551
  this.handleWrappedDragOver(event.clientX, (_event$clientY = event.clientY) !== null && _event$clientY !== void 0 ? _event$clientY : 0);
8031
8552
  return;
8032
8553
  }
8033
- const mouseX = event.clientX;
8554
+ const mousePos = this._mainAxisCoord(event.clientX, (_event$clientY2 = event.clientY) !== null && _event$clientY2 !== void 0 ? _event$clientY2 : 0);
8034
8555
  const firstPanelToGroup = this._buildFirstPanelToGroupMap();
8035
- let insertionIndex = this._computeDragOverInsertionIndex(mouseX, firstPanelToGroup);
8556
+ let insertionIndex = this._computeDragOverInsertionIndex(mousePos, firstPanelToGroup);
8036
8557
  let targetTabGroupId = null;
8037
8558
  if (insertionIndex !== null && this._tabGroupManager.chipRenderers.size > 0) {
8038
- const resolved = this._resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup);
8559
+ const resolved = this._resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup);
8039
8560
  insertionIndex = resolved.insertionIndex;
8040
8561
  targetTabGroupId = resolved.targetTabGroupId;
8041
8562
  }
@@ -8059,14 +8580,15 @@ var TabReorderController = class extends CompositeDisposable {
8059
8580
  return firstPanelToGroup;
8060
8581
  }
8061
8582
  /**
8062
- * Walk the tabs left-to-right by their original widths and return the
8063
- * insertion slot for the drag image's left edge (null if no slot fits).
8583
+ * Walk the tabs in flow order by their original main-axis sizes and return
8584
+ * the insertion slot for the drag image's leading edge (null if no slot
8585
+ * fits).
8064
8586
  */
8065
- _computeDragOverInsertionIndex(mouseX, firstPanelToGroup) {
8587
+ _computeDragOverInsertionIndex(mousePos, firstPanelToGroup) {
8066
8588
  const animState = this._animState;
8067
8589
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8068
- const availableSpace = mouseX - animState.cursorOffsetFromDragLeft - animState.containerLeft;
8069
- let accWidth = 0;
8590
+ const availableSpace = mousePos - animState.cursorOffsetFromDragStart - animState.containerStart;
8591
+ let accSize = 0;
8070
8592
  let insertionIndex = null;
8071
8593
  for (let i = 0; i < this._tabs.length; i++) {
8072
8594
  const tab = this._tabs[i].value;
@@ -8074,19 +8596,19 @@ var TabReorderController = class extends CompositeDisposable {
8074
8596
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8075
8597
  const groupId = firstPanelToGroup.get(tab.panel.id);
8076
8598
  if (groupId) {
8077
- var _animState$chipPositi;
8078
- const chipWidth = (_animState$chipPositi = animState.chipPositions.get(groupId)) !== null && _animState$chipPositi !== void 0 ? _animState$chipPositi : 0;
8079
- if (accWidth + chipWidth > availableSpace) {
8599
+ var _animState$chipSizes$;
8600
+ const chipSize = (_animState$chipSizes$ = animState.chipSizes.get(groupId)) !== null && _animState$chipSizes$ !== void 0 ? _animState$chipSizes$ : 0;
8601
+ if (accSize + chipSize > availableSpace) {
8080
8602
  var _insertionIndex;
8081
8603
  (_insertionIndex = insertionIndex) !== null && _insertionIndex !== void 0 || (insertionIndex = i);
8082
8604
  break;
8083
8605
  }
8084
- accWidth += chipWidth;
8606
+ accSize += chipSize;
8085
8607
  }
8086
8608
  const origRect = animState.tabPositions.get(tab.panel.id);
8087
- const tabWidth = origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8088
- if (accWidth + tabWidth / 2 <= availableSpace) {
8089
- accWidth += tabWidth;
8609
+ const tabSize = this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8610
+ if (accSize + tabSize / 2 <= availableSpace) {
8611
+ accSize += tabSize;
8090
8612
  insertionIndex = i + 1;
8091
8613
  } else {
8092
8614
  var _insertionIndex2;
@@ -8097,11 +8619,12 @@ var TabReorderController = class extends CompositeDisposable {
8097
8619
  return insertionIndex;
8098
8620
  }
8099
8621
  /**
8100
- * Rebuild the accumulated original width up to `insertionIndex`, walking the
8101
- * tabs exactly the way the accumulation loop does, so callers know the
8102
- * original right edge of the chip (if any) that precedes the insertion slot.
8622
+ * Rebuild the accumulated original main-axis size up to `insertionIndex`,
8623
+ * walking the tabs exactly the way the accumulation loop does, so callers
8624
+ * know the original trailing edge of the chip (if any) that precedes the
8625
+ * insertion slot.
8103
8626
  */
8104
- _accumulatedWidthUpTo(insertionIndex, firstPanelToGroup) {
8627
+ _accumulatedSizeUpTo(insertionIndex, firstPanelToGroup) {
8105
8628
  const animState = this._animState;
8106
8629
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8107
8630
  let accUpTo = 0;
@@ -8112,11 +8635,11 @@ var TabReorderController = class extends CompositeDisposable {
8112
8635
  if (i >= insertionIndex) break;
8113
8636
  const gid = firstPanelToGroup.get(tab.panel.id);
8114
8637
  if (gid) {
8115
- var _animState$chipPositi2;
8116
- accUpTo += (_animState$chipPositi2 = animState.chipPositions.get(gid)) !== null && _animState$chipPositi2 !== void 0 ? _animState$chipPositi2 : 0;
8638
+ var _animState$chipSizes$2;
8639
+ accUpTo += (_animState$chipSizes$2 = animState.chipSizes.get(gid)) !== null && _animState$chipSizes$2 !== void 0 ? _animState$chipSizes$2 : 0;
8117
8640
  }
8118
8641
  const origRect = animState.tabPositions.get(tab.panel.id);
8119
- accUpTo += origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8642
+ accUpTo += this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8120
8643
  }
8121
8644
  return accUpTo;
8122
8645
  }
@@ -8124,11 +8647,11 @@ var TabReorderController = class extends CompositeDisposable {
8124
8647
  * Given a raw insertion index, snap it out of / into any tab group it falls
8125
8648
  * within and resolve the target group (if the drop should merge into one).
8126
8649
  */
8127
- _resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup) {
8650
+ _resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup) {
8128
8651
  const isGroupDrag = !!this._animState.sourceTabGroupId;
8129
- const accUpTo = this._accumulatedWidthUpTo(insertionIndex, firstPanelToGroup);
8652
+ const accUpTo = this._accumulatedSizeUpTo(insertionIndex, firstPanelToGroup);
8130
8653
  for (const tg of this.group.model.getTabGroups()) {
8131
- const resolved = this._evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag);
8654
+ const resolved = this._evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag);
8132
8655
  if (resolved) return resolved;
8133
8656
  }
8134
8657
  return {
@@ -8142,7 +8665,7 @@ var TabReorderController = class extends CompositeDisposable {
8142
8665
  * group governs the slot (the caller stops iterating), or `null` when the
8143
8666
  * group is irrelevant and the caller should keep looking.
8144
8667
  */
8145
- _evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag) {
8668
+ _evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag) {
8146
8669
  const range = this._resolveGroupRange(tg);
8147
8670
  if (!range) return null;
8148
8671
  const { firstIdx, lastIdx } = range;
@@ -8150,7 +8673,7 @@ var TabReorderController = class extends CompositeDisposable {
8150
8673
  const isJustBeforeGroup = !isInsideRange && insertionIndex === firstIdx - 1;
8151
8674
  if (!isInsideRange && !isJustBeforeGroup) return null;
8152
8675
  if (isGroupDrag) return this._resolveGroupDragTarget(insertionIndex, firstIdx, lastIdx, isInsideRange);
8153
- return this._resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8676
+ return this._resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8154
8677
  }
8155
8678
  /**
8156
8679
  * The index range this group occupies in the live tab list, excluding the
@@ -8185,13 +8708,13 @@ var TabReorderController = class extends CompositeDisposable {
8185
8708
  }
8186
8709
  /** Insertion target for a single-tab drag against a group: decide whether
8187
8710
  * the drop merges into the group based on the cursor vs the chip edge. */
8188
- _resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8189
- var _animState$chipPositi3;
8711
+ _resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8712
+ var _animState$chipSizes$3;
8190
8713
  const animState = this._animState;
8191
- const chipWidth = (_animState$chipPositi3 = animState.chipPositions.get(tg.id)) !== null && _animState$chipPositi3 !== void 0 ? _animState$chipPositi3 : 0;
8714
+ const chipSize = (_animState$chipSizes$3 = animState.chipSizes.get(tg.id)) !== null && _animState$chipSizes$3 !== void 0 ? _animState$chipSizes$3 : 0;
8192
8715
  if (isJustBeforeGroup) {
8193
8716
  if (!this._onlySourceBetween(insertionIndex, firstIdx)) return null;
8194
- if (mouseX >= (tg.collapsed ? animState.containerLeft + accUpTo + chipWidth / 2 : animState.containerLeft + accUpTo + chipWidth)) return {
8717
+ if (mousePos >= (tg.collapsed ? animState.containerStart + accUpTo + chipSize / 2 : animState.containerStart + accUpTo + chipSize)) return {
8195
8718
  insertionIndex: firstIdx,
8196
8719
  targetTabGroupId: tg.id
8197
8720
  };
@@ -8200,10 +8723,10 @@ var TabReorderController = class extends CompositeDisposable {
8200
8723
  targetTabGroupId: null
8201
8724
  };
8202
8725
  }
8203
- const chipOriginalRight = animState.containerLeft + accUpTo + chipWidth;
8726
+ const chipOriginalEnd = animState.containerStart + accUpTo + chipSize;
8204
8727
  if (insertionIndex === firstIdx) return {
8205
8728
  insertionIndex,
8206
- targetTabGroupId: mouseX >= chipOriginalRight ? tg.id : null
8729
+ targetTabGroupId: mousePos >= chipOriginalEnd ? tg.id : null
8207
8730
  };
8208
8731
  return {
8209
8732
  insertionIndex,
@@ -8366,17 +8889,17 @@ var TabReorderController = class extends CompositeDisposable {
8366
8889
  }
8367
8890
  if (this._pendingCollapse) return;
8368
8891
  const insertionIndex = this._animState.currentInsertionIndex;
8369
- const gapWidth = this._computeGapWidth();
8892
+ const gapSize = this._computeGapSize();
8370
8893
  const chipToShift = this._computeChipToShift(insertionIndex);
8371
- this._applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition);
8894
+ this._applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition);
8372
8895
  }
8373
- /** Gap width for the current drag: the whole group's span for a group
8374
- * drag, otherwise the source tab's own width. */
8375
- _computeGapWidth() {
8896
+ /** Gap size for the current drag: the whole group's span for a group
8897
+ * drag, otherwise the source tab's own main-axis size. */
8898
+ _computeGapSize() {
8376
8899
  const animState = this._animState;
8377
- if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapWidth;
8900
+ if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapSize;
8378
8901
  const sourceRect = animState.tabPositions.get(animState.sourceTabId);
8379
- return sourceRect ? sourceRect.width : this.getAverageTabWidth();
8902
+ return sourceRect ? this._mainAxisSize(sourceRect) : this.getAverageTabSize();
8380
8903
  }
8381
8904
  /**
8382
8905
  * When the insertion lands at or before a group's first tab, the chip is
@@ -8420,7 +8943,7 @@ var TabReorderController = class extends CompositeDisposable {
8420
8943
  }
8421
8944
  /** Reset non-source chip margins, then apply the gap margin to the chip or
8422
8945
  * the first tab at/after the insertion index. */
8423
- _applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition) {
8946
+ _applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition) {
8424
8947
  const animState = this._animState;
8425
8948
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8426
8949
  let gapApplied = false;
@@ -8429,7 +8952,7 @@ var TabReorderController = class extends CompositeDisposable {
8429
8952
  this._clearMargin(entry.chip.element, skipTransition);
8430
8953
  }
8431
8954
  if (chipToShift) {
8432
- this._setMargin(chipToShift, `${gapWidth}px`, skipTransition);
8955
+ this._setMargin(chipToShift, `${gapSize}px`, skipTransition);
8433
8956
  gapApplied = true;
8434
8957
  }
8435
8958
  for (let i = 0; i < this._tabs.length; i++) {
@@ -8437,7 +8960,7 @@ var TabReorderController = class extends CompositeDisposable {
8437
8960
  if (tab.panel.id === animState.sourceTabId) continue;
8438
8961
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8439
8962
  if (!gapApplied && i >= insertionIndex) {
8440
- this._setMargin(tab.element, `${gapWidth}px`, skipTransition);
8963
+ this._setMargin(tab.element, `${gapSize}px`, skipTransition);
8441
8964
  gapApplied = true;
8442
8965
  } else this._clearMargin(tab.element, skipTransition);
8443
8966
  }
@@ -8447,31 +8970,33 @@ var TabReorderController = class extends CompositeDisposable {
8447
8970
  _shiftingClass(el) {
8448
8971
  return el.classList.contains("dv-tab-group-chip") ? "dv-tab-group-chip--shifting" : "dv-tab--shifting";
8449
8972
  }
8450
- /** Apply a margin-left value to an element, optionally bypassing CSS
8973
+ /** Apply the main-axis gap margin to an element, optionally bypassing CSS
8451
8974
  * transitions for instant positioning. */
8452
8975
  _setMargin(el, value, skipTransition) {
8976
+ const property = this._gapMarginProperty;
8453
8977
  if (skipTransition) {
8454
8978
  el.style.transition = "none";
8455
- el.style.marginLeft = value;
8979
+ el.style.setProperty(property, value);
8456
8980
  el.getBoundingClientRect();
8457
8981
  el.style.removeProperty("transition");
8458
- } else el.style.marginLeft = value;
8982
+ } else el.style.setProperty(property, value);
8459
8983
  toggleClass(el, this._shiftingClass(el), true);
8460
8984
  }
8461
8985
  /** Clear an element's gap margin, animating it back to zero unless
8462
8986
  * transitions are skipped. */
8463
8987
  _clearMargin(el, skipTransition) {
8464
8988
  const cls = this._shiftingClass(el);
8989
+ const property = this._gapMarginProperty;
8465
8990
  const prev = this._pendingMarginCleanups.get(el);
8466
8991
  if (prev) prev();
8467
- if (skipTransition || !el.style.marginLeft) {
8468
- el.style.removeProperty("margin-left");
8992
+ if (skipTransition || !el.style.getPropertyValue(property)) {
8993
+ el.style.removeProperty(property);
8469
8994
  toggleClass(el, cls, false);
8470
8995
  } else {
8471
- el.style.marginLeft = "0px";
8996
+ el.style.setProperty(property, "0px");
8472
8997
  toggleClass(el, cls, true);
8473
8998
  const onEnd = () => {
8474
- el.style.removeProperty("margin-left");
8999
+ el.style.removeProperty(property);
8475
9000
  toggleClass(el, cls, false);
8476
9001
  el.removeEventListener("transitionend", onEnd);
8477
9002
  clearTimeout(fallbackTimer);
@@ -8496,6 +9021,7 @@ var TabReorderController = class extends CompositeDisposable {
8496
9021
  }
8497
9022
  for (const [, entry] of this._tabGroupManager.chipRenderers) {
8498
9023
  entry.chip.element.style.removeProperty("margin-left");
9024
+ entry.chip.element.style.removeProperty("margin-top");
8499
9025
  toggleClass(entry.chip.element, "dv-tab-group-chip--shifting", false);
8500
9026
  }
8501
9027
  this._tabGroupManager.positionUnderlines();
@@ -9090,21 +9616,21 @@ var Tabs = class extends CompositeDisposable {
9090
9616
  panel
9091
9617
  });
9092
9618
  if (((_this$accessor$option2 = this.accessor.options.theme) === null || _this$accessor$option2 === void 0 ? void 0 : _this$accessor$option2.tabAnimation) === "smooth") {
9093
- const tabWidth = tab.element.getBoundingClientRect().width;
9619
+ const tabSize = mainAxisSize(tab.element.getBoundingClientRect(), this._direction);
9094
9620
  const sourceIndex = this._tabs.findIndex((x) => x.value === tab);
9095
9621
  this._animState = {
9096
9622
  sourceTabId: panel.id,
9097
9623
  sourceIndex,
9098
9624
  tabPositions: this.snapshotTabPositions(),
9099
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9625
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9100
9626
  currentInsertionIndex: null,
9101
9627
  targetTabGroupId: null,
9102
9628
  sourceTabGroupId: null,
9103
9629
  sourceGroupPanelIds: null,
9104
- sourceChipWidth: 0,
9105
- cursorOffsetFromDragLeft: tabWidth / 2,
9106
- sourceGapWidth: tabWidth,
9107
- containerLeft: this._tabsList.getBoundingClientRect().left
9630
+ sourceChipSize: 0,
9631
+ cursorOffsetFromDragStart: tabSize / 2,
9632
+ sourceGapSize: tabSize,
9633
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9108
9634
  };
9109
9635
  this._pendingCollapse = true;
9110
9636
  requestAnimationFrame(() => {
@@ -9200,7 +9726,7 @@ var Tabs = class extends CompositeDisposable {
9200
9726
  this._tabGroupManager.positionAllChips();
9201
9727
  if (this._animState) {
9202
9728
  this._animState.tabPositions = this.snapshotTabPositions();
9203
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9729
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9204
9730
  this.applyDragOverTransforms();
9205
9731
  }
9206
9732
  }
@@ -9222,7 +9748,7 @@ var Tabs = class extends CompositeDisposable {
9222
9748
  }
9223
9749
  if (this._animState) {
9224
9750
  this._animState.tabPositions = this.snapshotTabPositions();
9225
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9751
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9226
9752
  this.applyDragOverTransforms();
9227
9753
  }
9228
9754
  }
@@ -9300,24 +9826,24 @@ var Tabs = class extends CompositeDisposable {
9300
9826
  const firstPanelId = tabGroup.panelIds[0];
9301
9827
  const firstIdx = firstPanelId ? this._tabs.findIndex((t) => t.value.panel.id === firstPanelId) : -1;
9302
9828
  const chipRect = chip.element.getBoundingClientRect();
9303
- let groupGapWidth = chipRect.width;
9829
+ let groupGapSize = mainAxisSize(chipRect, this._direction);
9304
9830
  for (const pid of tabGroup.panelIds) {
9305
9831
  const tabEntry = this._tabMap.get(pid);
9306
- if (tabEntry) groupGapWidth += tabEntry.value.element.getBoundingClientRect().width;
9832
+ if (tabEntry) groupGapSize += mainAxisSize(tabEntry.value.element.getBoundingClientRect(), this._direction);
9307
9833
  }
9308
9834
  this._animState = {
9309
9835
  sourceTabId: "",
9310
9836
  sourceIndex: firstIdx,
9311
9837
  tabPositions: this.snapshotTabPositions(),
9312
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9838
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9313
9839
  currentInsertionIndex: null,
9314
9840
  targetTabGroupId: null,
9315
9841
  sourceTabGroupId: tabGroup.id,
9316
9842
  sourceGroupPanelIds: new Set(tabGroup.panelIds),
9317
- sourceChipWidth: chipRect.width,
9318
- cursorOffsetFromDragLeft: event.clientX - chipRect.left,
9319
- sourceGapWidth: groupGapWidth,
9320
- containerLeft: this._tabsList.getBoundingClientRect().left
9843
+ sourceChipSize: mainAxisSize(chipRect, this._direction),
9844
+ cursorOffsetFromDragStart: mainAxisCursor(event, this._direction) - mainAxisStart(chipRect, this._direction),
9845
+ sourceGapSize: groupGapSize,
9846
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9321
9847
  };
9322
9848
  if (((_this$accessor$option4 = this.accessor.options.theme) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.tabAnimation) !== "smooth") return;
9323
9849
  const groupPanelIds = new Set(tabGroup.panelIds);
@@ -9698,16 +10224,21 @@ var TabsContainer = class extends CompositeDisposable {
9698
10224
  y: event.clientY,
9699
10225
  zIndex: (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0
9700
10226
  };
9701
- const context = this.createOverflowRenderContext(root, anchor);
10227
+ const { context, rowRenderers } = this.createOverflowRenderContext(root, anchor);
9702
10228
  const advancedOverflow = this.accessor.advancedOverflowService;
9703
- if (advancedOverflow) advancedOverflow.renderOverflow({
9704
- group: this.group,
9705
- overflowTabs: [...this._overflowTabs],
9706
- overflowTabGroups: [...this._overflowTabGroups],
9707
- pinnedOverflowTabs: [...this._overflowPinnedTabs],
9708
- context
9709
- });
9710
- else context.open(this.renderFreeOverflowList(context));
10229
+ try {
10230
+ if (advancedOverflow) advancedOverflow.renderOverflow({
10231
+ group: this.group,
10232
+ overflowTabs: [...this._overflowTabs],
10233
+ overflowTabGroups: [...this._overflowTabGroups],
10234
+ pinnedOverflowTabs: [...this._overflowPinnedTabs],
10235
+ context
10236
+ });
10237
+ else context.open(this.renderFreeOverflowList(context));
10238
+ } catch (err) {
10239
+ rowRenderers.dispose();
10240
+ throw err;
10241
+ }
9711
10242
  }));
9712
10243
  }
9713
10244
  /**
@@ -9728,6 +10259,7 @@ var TabsContainer = class extends CompositeDisposable {
9728
10259
  if (overflowGroupSet.has(tg.id)) for (const pid of tg.panelIds) panelToGroup.set(pid, tg);
9729
10260
  }
9730
10261
  const popup = () => this.accessor.getPopupServiceForGroup(this.group);
10262
+ const rowRenderers = new CompositeDisposable();
9731
10263
  const buildGroupHeader = (tg) => {
9732
10264
  const groupHeader = document.createElement("div");
9733
10265
  groupHeader.className = "dv-tabs-overflow-group-header";
@@ -9757,69 +10289,87 @@ var TabsContainer = class extends CompositeDisposable {
9757
10289
  return groupHeader;
9758
10290
  };
9759
10291
  return {
9760
- overflowGroupIdForPanel: (panelId) => {
9761
- var _panelToGroup$get;
9762
- return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
9763
- },
9764
- buildGroupHeader: (tabGroupId) => {
9765
- const tg = groupById.get(tabGroupId);
9766
- if (!tg || !overflowGroupSet.has(tg.id)) return;
9767
- return buildGroupHeader(tg);
9768
- },
9769
- buildPinnedHeader: () => {
9770
- const header = document.createElement("div");
9771
- header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
9772
- const glyph = createPinButton();
9773
- glyph.classList.add("dv-tabs-overflow-pinned-icon");
9774
- header.appendChild(glyph);
9775
- const labelSpan = document.createElement("span");
9776
- labelSpan.className = "dv-tabs-overflow-group-label";
9777
- labelSpan.textContent = "Pinned";
9778
- header.appendChild(labelSpan);
9779
- return header;
9780
- },
9781
- buildRow: (panelId) => {
9782
- const panel = this.group.panels.find((p) => p.id === panelId);
9783
- if (!panel) return;
9784
- const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
9785
- const tg = panelToGroup.get(panelId);
9786
- const child = panel.view.createTabRenderer("headerOverflow").element;
9787
- const wrapper = document.createElement("div");
9788
- toggleClass(wrapper, "dv-tab", true);
9789
- toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
9790
- toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
9791
- if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
9792
- const doActivate = () => {
9793
- if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
9794
- tab === null || tab === void 0 || tab.element.scrollIntoView({
9795
- block: "nearest",
9796
- inline: "nearest"
10292
+ context: {
10293
+ overflowGroupIdForPanel: (panelId) => {
10294
+ var _panelToGroup$get;
10295
+ return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
10296
+ },
10297
+ buildGroupHeader: (tabGroupId) => {
10298
+ const tg = groupById.get(tabGroupId);
10299
+ if (!tg || !overflowGroupSet.has(tg.id)) return;
10300
+ return buildGroupHeader(tg);
10301
+ },
10302
+ buildPinnedHeader: () => {
10303
+ const header = document.createElement("div");
10304
+ header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
10305
+ const glyph = createPinButton();
10306
+ glyph.classList.add("dv-tabs-overflow-pinned-icon");
10307
+ header.appendChild(glyph);
10308
+ const labelSpan = document.createElement("span");
10309
+ labelSpan.className = "dv-tabs-overflow-group-label";
10310
+ labelSpan.textContent = "Pinned";
10311
+ header.appendChild(labelSpan);
10312
+ return header;
10313
+ },
10314
+ buildRow: (panelId) => {
10315
+ const panel = this.group.panels.find((p) => p.id === panelId);
10316
+ if (!panel) return;
10317
+ const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
10318
+ const tg = panelToGroup.get(panelId);
10319
+ const tabComponent = panel.view.createTabRenderer("headerOverflow");
10320
+ let rowDisposed = false;
10321
+ const disposeRow = Disposable.from(() => {
10322
+ if (!rowDisposed) {
10323
+ var _tabComponent$dispose;
10324
+ rowDisposed = true;
10325
+ (_tabComponent$dispose = tabComponent.dispose) === null || _tabComponent$dispose === void 0 || _tabComponent$dispose.call(tabComponent);
10326
+ }
9797
10327
  });
9798
- this.accessor.withOrigin("user", () => panel.api.setActive());
9799
- };
9800
- wrapper.addEventListener("click", (event) => {
9801
- popup().close();
9802
- if (event.defaultPrevented) return;
9803
- doActivate();
9804
- });
9805
- wrapper.appendChild(child);
9806
- return {
9807
- element: wrapper,
9808
- panel,
9809
- activate: () => {
10328
+ if (rowRenderers.isDisposed) disposeRow.dispose();
10329
+ else rowRenderers.addDisposables(disposeRow);
10330
+ const child = tabComponent.element;
10331
+ const wrapper = document.createElement("div");
10332
+ toggleClass(wrapper, "dv-tab", true);
10333
+ toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
10334
+ toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
10335
+ if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
10336
+ const doActivate = () => {
10337
+ if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
10338
+ tab === null || tab === void 0 || tab.element.scrollIntoView({
10339
+ block: "nearest",
10340
+ inline: "nearest"
10341
+ });
10342
+ this.accessor.withOrigin("user", () => panel.api.setActive());
10343
+ };
10344
+ wrapper.addEventListener("click", (event) => {
9810
10345
  popup().close();
10346
+ if (event.defaultPrevented) return;
9811
10347
  doActivate();
9812
- }
9813
- };
9814
- },
9815
- open: (body) => {
9816
- popup().openPopover(body, anchor);
10348
+ });
10349
+ wrapper.appendChild(child);
10350
+ return {
10351
+ element: wrapper,
10352
+ panel,
10353
+ activate: () => {
10354
+ popup().close();
10355
+ doActivate();
10356
+ },
10357
+ dispose: () => {
10358
+ rowRenderers.removeDisposable(disposeRow);
10359
+ disposeRow.dispose();
10360
+ }
10361
+ };
10362
+ },
10363
+ open: (body) => {
10364
+ popup().openPopover(body, anchor, { onClose: () => rowRenderers.dispose() });
10365
+ },
10366
+ close: () => popup().close(),
10367
+ focusTrigger: () => {
10368
+ root.tabIndex = -1;
10369
+ root.focus();
10370
+ }
9817
10371
  },
9818
- close: () => popup().close(),
9819
- focusTrigger: () => {
9820
- root.tabIndex = -1;
9821
- root.focus();
9822
- }
10372
+ rowRenderers
9823
10373
  };
9824
10374
  }
9825
10375
  /**
@@ -10075,8 +10625,10 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
10075
10625
  return this.tabsContainer.getPanelForTab(element);
10076
10626
  }
10077
10627
  get isContentFocused() {
10078
- if (!document.activeElement) return false;
10079
- return isAncestor(document.activeElement, this.contentContainer.element);
10628
+ const element = this.contentContainer.element;
10629
+ const activeElement = getActiveElement(element);
10630
+ if (!activeElement) return false;
10631
+ return isAncestor(activeElement, element);
10080
10632
  }
10081
10633
  get headerPosition() {
10082
10634
  var _this$_headerPosition;
@@ -10734,6 +11286,7 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
10734
11286
  this.tabsContainer.setRightActionsElement(element);
10735
11287
  }
10736
11288
  setActive(isGroupActive, force = false) {
11289
+ if (this.isDisposed) return;
10737
11290
  if (!force && this.isActive === isGroupActive) return;
10738
11291
  this._isGroupActive = isGroupActive;
10739
11292
  toggleClass(this.container, "dv-active-group", isGroupActive);
@@ -12987,6 +13540,12 @@ var PopoutWindowService = class {
12987
13540
  observer.observe(gridview.element);
12988
13541
  return { dispose: () => observer.disconnect() };
12989
13542
  }
13543
+ /**
13544
+ * Runs `work` after `delayMs`, resolving once it has finished. Work that
13545
+ * returns a promise is awaited, so a caller holding
13546
+ * `restorationPromise` waits for the popout window itself rather than
13547
+ * only for the timer that starts it.
13548
+ */
12990
13549
  scheduleRestoration(delayMs, work, onCancel) {
12991
13550
  return new Promise((resolve) => {
12992
13551
  const cleanup = () => {
@@ -13001,8 +13560,7 @@ var PopoutWindowService = class {
13001
13560
  resolve();
13002
13561
  return;
13003
13562
  }
13004
- work();
13005
- resolve();
13563
+ Promise.resolve(work()).then(() => resolve(), () => resolve());
13006
13564
  }, delayMs);
13007
13565
  this._restorationCleanups.add(cleanup);
13008
13566
  });
@@ -13773,13 +14331,14 @@ var ContextMenuController = class {
13773
14331
  * menu passes the `tabGroup`. No-op when no renderer could be created (no
13774
14332
  * factory configured, or the factory declined the component).
13775
14333
  */
13776
- appendComponentItem(menuEl, item, identity, group, close) {
14334
+ appendComponentItem(menuEl, item, identity, group, close, renderers) {
13777
14335
  var _this$accessor$option4, _this$accessor$option5;
13778
14336
  const renderer = (_this$accessor$option4 = (_this$accessor$option5 = this.accessor.options).createContextMenuItemComponent) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.call(_this$accessor$option5, {
13779
14337
  id: nextContextMenuItemId(),
13780
14338
  component: item.component
13781
14339
  });
13782
14340
  if (!renderer) return;
14341
+ renderers.addDisposables(renderer);
13783
14342
  renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
13784
14343
  group,
13785
14344
  api: this.accessor.api,
@@ -13830,9 +14389,9 @@ var ContextMenuController = class {
13830
14389
  * default row; an item carrying none of the three renders nothing. Shared
13831
14390
  * by both menus, which differ only in `identity`.
13832
14391
  */
13833
- appendConfigItem(menuEl, item, identity, group, close) {
14392
+ appendConfigItem(menuEl, item, identity, group, close, renderers) {
13834
14393
  if (item.element) menuEl.appendChild(item.element);
13835
- else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
14394
+ else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close, renderers);
13836
14395
  else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
13837
14396
  var _item$action;
13838
14397
  return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
@@ -13844,22 +14403,28 @@ var ContextMenuController = class {
13844
14403
  event.preventDefault();
13845
14404
  const popupService = this.accessor.getPopupServiceForGroup(group);
13846
14405
  const close = () => popupService.close();
14406
+ const renderers = new CompositeDisposable();
13847
14407
  const menuEl = document.createElement("div");
13848
14408
  menuEl.className = "dv-context-menu";
13849
14409
  menuEl.setAttribute("role", "menu");
13850
- for (const item of items) {
13851
- if (isItemConfig(item)) {
13852
- this.appendConfigItem(menuEl, item, { panel }, group, close);
13853
- continue;
14410
+ try {
14411
+ for (const item of items) {
14412
+ if (isItemConfig(item)) {
14413
+ this.appendConfigItem(menuEl, item, { panel }, group, close, renderers);
14414
+ continue;
14415
+ }
14416
+ const el = this.buildBuiltInTabItem(item, panel, group, close);
14417
+ if (el) menuEl.appendChild(el);
13854
14418
  }
13855
- const el = this.buildBuiltInTabItem(item, panel, group, close);
13856
- if (el) menuEl.appendChild(el);
14419
+ } catch (err) {
14420
+ renderers.dispose();
14421
+ throw err;
13857
14422
  }
13858
14423
  popupService.openPopover(menuEl, {
13859
14424
  x: event.clientX,
13860
14425
  y: event.clientY,
13861
14426
  zIndex: popoverZIndexFor(event.target, group)
13862
- });
14427
+ }, { onClose: () => renderers.dispose() });
13863
14428
  }
13864
14429
  showForChip(tabGroup, group, event) {
13865
14430
  if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
@@ -13873,22 +14438,28 @@ var ContextMenuController = class {
13873
14438
  event.preventDefault();
13874
14439
  const popupService = this.accessor.getPopupServiceForGroup(group);
13875
14440
  const close = () => popupService.close();
14441
+ const renderers = new CompositeDisposable();
13876
14442
  const menuEl = document.createElement("div");
13877
14443
  menuEl.className = "dv-context-menu";
13878
14444
  menuEl.setAttribute("role", "menu");
13879
- for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
13880
- else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
13881
- else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
13882
- else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
13883
- else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
13884
- group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
13885
- }));
13886
- else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
14445
+ try {
14446
+ for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
14447
+ else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
14448
+ else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
14449
+ else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
14450
+ else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
14451
+ group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
14452
+ }));
14453
+ else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close, renderers);
14454
+ } catch (err) {
14455
+ renderers.dispose();
14456
+ throw err;
14457
+ }
13887
14458
  popupService.openPopover(menuEl, {
13888
14459
  x: event.clientX,
13889
14460
  y: event.clientY,
13890
14461
  zIndex: popoverZIndexFor(event.target, group)
13891
- });
14462
+ }, { onClose: () => renderers.dispose() });
13892
14463
  }
13893
14464
  };
13894
14465
  const ContextMenuModule = defineModule({
@@ -14178,6 +14749,7 @@ var OverlayRenderContainer = class extends CompositeDisposable {
14178
14749
  const observerDisposable = new MutableDisposable();
14179
14750
  const correctLayerPosition = () => {
14180
14751
  if (panel.api.location.type === "floating") queueMicrotask(() => {
14752
+ if (disposable.isDisposed) return;
14181
14753
  const floatingGroup = this.accessor.getFloatingWindowForGroup(panel.api.group);
14182
14754
  if (!floatingGroup) return;
14183
14755
  const element = floatingGroup.overlay.element;
@@ -14260,188 +14832,6 @@ var OverlayRenderContainer = class extends CompositeDisposable {
14260
14832
  }
14261
14833
  };
14262
14834
 
14263
- //#endregion
14264
- //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
14265
- function asyncGeneratorStep(n, t, e, r, o, a, c) {
14266
- try {
14267
- var i = n[a](c), u = i.value;
14268
- } catch (n) {
14269
- e(n);
14270
- return;
14271
- }
14272
- i.done ? t(u) : Promise.resolve(u).then(r, o);
14273
- }
14274
- function _asyncToGenerator(n) {
14275
- return function() {
14276
- var t = this, e = arguments;
14277
- return new Promise(function(r, o) {
14278
- var a = n.apply(t, e);
14279
- function _next(n) {
14280
- asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
14281
- }
14282
- function _throw(n) {
14283
- asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
14284
- }
14285
- _next(void 0);
14286
- });
14287
- };
14288
- }
14289
-
14290
- //#endregion
14291
- //#region src/popoutWindow.ts
14292
- /**
14293
- * Reject popout URLs that aren't same-origin http(s). Blocks `javascript:`,
14294
- * `data:`, `blob:`, `vbscript:`, and cross-origin URLs that would otherwise
14295
- * execute in a context the browser still associates with the opener via
14296
- * `window.opener`.
14297
- */
14298
- function assertSameOriginPopoutUrl(url) {
14299
- let resolved;
14300
- try {
14301
- resolved = new URL(url, globalThis.location.href);
14302
- } catch (_unused) {
14303
- throw new Error(`dockview: invalid popout URL: ${url}`);
14304
- }
14305
- 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}`);
14306
- }
14307
- var PopoutWindow = class extends CompositeDisposable {
14308
- get window() {
14309
- var _this$_window$value, _this$_window;
14310
- 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;
14311
- }
14312
- constructor(target, className, options) {
14313
- super();
14314
- this.target = target;
14315
- this.className = className;
14316
- this.options = options;
14317
- this._onWillClose = new Emitter();
14318
- this.onWillClose = this._onWillClose.event;
14319
- this._onDidClose = new Emitter();
14320
- this.onDidClose = this._onDidClose.event;
14321
- this._window = null;
14322
- this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
14323
- this.close();
14324
- } });
14325
- }
14326
- dimensions() {
14327
- if (!this._window) return null;
14328
- const left = this._window.value.screenX;
14329
- return {
14330
- top: this._window.value.screenY,
14331
- left,
14332
- width: this._window.value.innerWidth,
14333
- height: this._window.value.innerHeight
14334
- };
14335
- }
14336
- close() {
14337
- if (this._window) {
14338
- var _this$options$onWillC, _this$options;
14339
- this._onWillClose.fire();
14340
- (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
14341
- id: this.target,
14342
- window: this._window.value
14343
- });
14344
- this._window.disposable.dispose();
14345
- this._window = null;
14346
- this._onDidClose.fire();
14347
- }
14348
- }
14349
- open() {
14350
- var _this = this;
14351
- return _asyncToGenerator(function* () {
14352
- var _this$options$onDidOp, _this$options2;
14353
- if (_this._window) throw new Error("instance of popout window is already open");
14354
- const url = `${_this.options.url}`;
14355
- assertSameOriginPopoutUrl(url);
14356
- const features = Object.entries({
14357
- top: _this.options.top,
14358
- left: _this.options.left,
14359
- width: _this.options.width,
14360
- height: _this.options.height
14361
- }).map(([key, value]) => `${key}=${value}`).join(",");
14362
- /**
14363
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
14364
- */
14365
- const externalWindow = window.open(url, _this.target, features);
14366
- if (!externalWindow)
14367
- /**
14368
- * Popup blocked
14369
- */
14370
- return null;
14371
- const disposable = new CompositeDisposable();
14372
- _this._window = {
14373
- value: externalWindow,
14374
- disposable
14375
- };
14376
- disposable.addDisposables(Disposable.from(() => {
14377
- externalWindow.close();
14378
- }), addDisposableListener(globalThis.window, "beforeunload", () => {
14379
- /**
14380
- * before the main window closes we should close this popup too
14381
- * to be good citizens
14382
- *
14383
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14384
- */
14385
- _this.close();
14386
- }));
14387
- const container = _this.createPopoutWindowContainer();
14388
- if (_this.className) container.classList.add(_this.className);
14389
- (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
14390
- id: _this.target,
14391
- window: externalWindow
14392
- });
14393
- return new Promise((resolve, reject) => {
14394
- externalWindow.addEventListener("unload", () => {});
14395
- /**
14396
- * `load` is the only event that resolves this promise with a
14397
- * container, so a window that goes away first would leave the
14398
- * caller awaiting a promise that never settles - and
14399
- * `addPopoutGroup` holds its layout transaction open until it does.
14400
- * Settle with `null` on close, the same signal a blocked popup
14401
- * gives and one the caller already handles. `resolve` after the
14402
- * fact is a no-op, so a `load` that arrived first still wins.
14403
- */
14404
- disposable.addDisposables(_this.onWillClose(() => resolve(null)));
14405
- externalWindow.addEventListener("load", () => {
14406
- /**
14407
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
14408
- */
14409
- try {
14410
- const externalDocument = externalWindow.document;
14411
- externalDocument.title = document.title;
14412
- externalDocument.body.appendChild(container);
14413
- addStyles(externalDocument, globalThis.document.styleSheets, { nonce: _this.options.nonce });
14414
- /**
14415
- * beforeunload must be registered after load for reasons I could not determine
14416
- * otherwise the beforeunload event will not fire when the window is closed
14417
- */
14418
- addDisposableListener(externalWindow, "beforeunload", () => {
14419
- /**
14420
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14421
- */
14422
- _this.close();
14423
- });
14424
- resolve(container);
14425
- } catch (err) {
14426
- reject(err);
14427
- }
14428
- });
14429
- });
14430
- })();
14431
- }
14432
- createPopoutWindowContainer() {
14433
- const el = document.createElement("div");
14434
- el.classList.add("dv-popout-window");
14435
- el.id = "dv-popout-window";
14436
- el.style.position = "absolute";
14437
- el.style.width = "100%";
14438
- el.style.height = "100%";
14439
- el.style.top = "0px";
14440
- el.style.left = "0px";
14441
- return el;
14442
- }
14443
- };
14444
-
14445
14835
  //#endregion
14446
14836
  //#region src/dockview/strictEventsSequencing.ts
14447
14837
  var StrictEventsSequencing = class extends CompositeDisposable {
@@ -14485,8 +14875,8 @@ function isCoarsePrimaryInput(win) {
14485
14875
  * peeks): while it lives it watches a configurable set of dismiss signals
14486
14876
  * (Escape / extra keys, outside-pointerdown with an optional grace window,
14487
14877
  * window resize, focus moving outside) and calls `onDismiss`. Inside/outside is
14488
- * decided by an `isInside` predicate (geometry) or a `contains` check against
14489
- * `elements`. Dispose to detach every listener.
14878
+ * decided by an `isInside` predicate (geometry) or by checking the event's
14879
+ * composed path against `elements`. Dispose to detach every listener.
14490
14880
  *
14491
14881
  * It owns only the *signals*, not the surface element, its position, or any
14492
14882
  * hover/keep-open policy, so callers keep their own element lifecycle and
@@ -14506,9 +14896,7 @@ function createDismissableLayer(options) {
14506
14896
  const isInside = (event) => {
14507
14897
  var _options$elements, _options$elements2;
14508
14898
  if (options.isInside) return options.isInside(event);
14509
- const target = event.target;
14510
- if (!(target instanceof Node)) return false;
14511
- 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));
14899
+ 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 : []);
14512
14900
  };
14513
14901
  if (escape || keys.length > 0) disposables.addDisposables(addDisposableListener(win, "keydown", (event) => {
14514
14902
  if (escape && event.key === "Escape" || keys.includes(event.key)) options.onDismiss();
@@ -14527,17 +14915,45 @@ function createDismissableLayer(options) {
14527
14915
  options.onDismiss();
14528
14916
  }));
14529
14917
  if (options.focusOut) {
14530
- const isFocusInside = (focused) => {
14531
- var _options$elements3, _options$elements4;
14532
- if (options.isFocusInside) return options.isFocusInside(focused);
14533
- 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));
14918
+ /** A node in the layer's own tree, to scope retargeting and to locate
14919
+ * the shadow roots to listen on. */
14920
+ const layerScope = () => {
14921
+ var _options$anchor, _options$anchor2, _options$elements3;
14922
+ 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];
14534
14923
  };
14924
+ const seen = /* @__PURE__ */ new WeakSet();
14535
14925
  const onFocusIn = (event) => {
14926
+ var _options$elements4, _options$elements5;
14927
+ if (seen.has(event)) return;
14928
+ seen.add(event);
14536
14929
  const target = event.target;
14537
- if (target instanceof Element && !isFocusInside(target)) options.onDismiss();
14930
+ if (!(target instanceof Element)) return;
14931
+ 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();
14538
14932
  };
14539
- win.addEventListener("focusin", onFocusIn, capture);
14540
- disposables.addDisposables({ dispose: () => win.removeEventListener("focusin", onFocusIn, capture) });
14933
+ const bound = /* @__PURE__ */ new Map();
14934
+ const syncShadowRoots = () => {
14935
+ var _options$anchor3, _options$elements6, _options$elements7;
14936
+ const wanted = /* @__PURE__ */ new Set();
14937
+ const anchor = (_options$anchor3 = options.anchor) === null || _options$anchor3 === void 0 ? void 0 : _options$anchor3.call(options);
14938
+ 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] : []];
14939
+ for (const node of sources) for (const root of shadowRootsOf(node)) wanted.add(root);
14940
+ for (const [root, listener] of bound) if (!wanted.has(root)) {
14941
+ listener.dispose();
14942
+ bound.delete(root);
14943
+ }
14944
+ for (const root of wanted) {
14945
+ if (bound.has(root)) continue;
14946
+ bound.set(root, addDisposableListener(root, "focusin", onFocusIn, capture));
14947
+ }
14948
+ };
14949
+ disposables.addDisposables(addDisposableListener(win, "focusin", (event) => {
14950
+ syncShadowRoots();
14951
+ onFocusIn(event);
14952
+ }, capture), { dispose: () => {
14953
+ for (const [, listener] of bound) listener.dispose();
14954
+ bound.clear();
14955
+ } });
14956
+ syncShadowRoots();
14541
14957
  }
14542
14958
  return disposables;
14543
14959
  }
@@ -14568,7 +14984,7 @@ var PopupService = class extends CompositeDisposable {
14568
14984
  newRoot.prepend(this._element);
14569
14985
  this._root = newRoot;
14570
14986
  }
14571
- openPopover(element, position) {
14987
+ openPopover(element, position, options) {
14572
14988
  var _position$zIndex;
14573
14989
  this.close();
14574
14990
  const wrapper = this._window.document.createElement("div");
@@ -14583,14 +14999,14 @@ var PopupService = class extends CompositeDisposable {
14583
14999
  this._element.appendChild(wrapper);
14584
15000
  this._active = wrapper;
14585
15001
  const POINTERDOWN_GRACE_MS = 200;
14586
- this._activeDisposable.value = createDismissableLayer({
15002
+ this._activeDisposable.value = new CompositeDisposable(createDismissableLayer({
14587
15003
  window: this._window,
14588
15004
  onDismiss: () => this.close(),
14589
15005
  elements: () => this._active ? [this._active] : [],
14590
15006
  keys: ["Enter"],
14591
15007
  pointerDownGraceMs: POINTERDOWN_GRACE_MS,
14592
15008
  resize: true
14593
- });
15009
+ }), (options === null || options === void 0 ? void 0 : options.onClose) ? Disposable.from(options.onClose) : Disposable.NONE);
14594
15010
  this._window.requestAnimationFrame(() => {
14595
15011
  shiftAbsoluteElementIntoView(wrapper, this._root);
14596
15012
  });
@@ -15030,6 +15446,24 @@ var ShellManager = class {
15030
15446
  this.updateTheme(this._gap, this._defaultCollapsedSize);
15031
15447
  return view;
15032
15448
  }
15449
+ /**
15450
+ * Lay out from the shell's current size.
15451
+ *
15452
+ * The ResizeObserver above only reports asynchronously, so between
15453
+ * construction and its first callback the shell believes it has no size -
15454
+ * and any layout built in that window (panels added straight after
15455
+ * `createDockview`, say) resolves its sizes against zero and collapses to
15456
+ * minimums, permanently. Seeding the size synchronously gives that work
15457
+ * the real dimensions. Same guards as the observer: a detached or hidden
15458
+ * shell has no size worth propagating.
15459
+ */
15460
+ layoutFromElement() {
15461
+ if (!this._shellElement.offsetParent || !isInDocument(this._shellElement)) return;
15462
+ const width = Math.round(this._shellElement.clientWidth);
15463
+ const height = Math.round(this._shellElement.clientHeight);
15464
+ if (width === 0 || height === 0) return;
15465
+ this.layout(width, height);
15466
+ }
15033
15467
  layout(width, height) {
15034
15468
  this._outerSplitview.layout(width, height);
15035
15469
  this._flushPendingSizes();
@@ -15289,6 +15723,15 @@ var ShellManager = class {
15289
15723
 
15290
15724
  //#endregion
15291
15725
  //#region src/dockview/dockviewComponent.ts
15726
+ /**
15727
+ * An error says the most about why, so it wins; a blocked window has none, and
15728
+ * its usual cause is more useful than its name.
15729
+ */
15730
+ function logFailedPopout(failure) {
15731
+ if (failure.error) console.error("dockview: failed to create popout.", failure.error);
15732
+ else if (failure.reason === "blocked") console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
15733
+ else console.error(`dockview: failed to create popout (${failure.reason}).`);
15734
+ }
15292
15735
  function buildTabGroupColorPalette(options) {
15293
15736
  var _options$tabGroupColo;
15294
15737
  return new TabGroupColorPalette((_options$tabGroupColo = options.tabGroupColors) !== null && _options$tabGroupColo !== void 0 ? _options$tabGroupColo : DEFAULT_TAB_GROUP_COLORS, options.tabGroupAccent !== "off");
@@ -15340,6 +15783,10 @@ var DockviewComponent = class extends BaseGrid {
15340
15783
  get panels() {
15341
15784
  return this.groups.flatMap((group) => group.panels);
15342
15785
  }
15786
+ /** `dndStrategy` resolved against this device; see `DockviewApi`. */
15787
+ get dndCapabilities() {
15788
+ return resolveDndCapabilities(this.options);
15789
+ }
15343
15790
  get options() {
15344
15791
  return this._options;
15345
15792
  }
@@ -15849,9 +16296,9 @@ var DockviewComponent = class extends BaseGrid {
15849
16296
  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();
15850
16297
  }
15851
16298
  constructor(container, options) {
15852
- var _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
16299
+ var _options$proportional, _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
15853
16300
  super(container, {
15854
- proportionalLayout: true,
16301
+ proportionalLayout: (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true,
15855
16302
  orientation: "HORIZONTAL",
15856
16303
  styles: options.hideBorders ? { separatorBorder: "transparent" } : void 0,
15857
16304
  disableAutoResizing: options.disableAutoResizing,
@@ -15871,7 +16318,9 @@ var DockviewComponent = class extends BaseGrid {
15871
16318
  this._onWillDrop = new Emitter();
15872
16319
  this.onWillDrop = this._onWillDrop.event;
15873
16320
  this._mutationDepth = 0;
16321
+ this._syncMutationDepth = 0;
15874
16322
  this._pendingLocationChanges = /* @__PURE__ */ new Map();
16323
+ this._openingPopoutWindows = /* @__PURE__ */ new Set();
15875
16324
  this._origin = "user";
15876
16325
  this._originDepth = 0;
15877
16326
  this._onWillMutateLayout = new Emitter();
@@ -15898,6 +16347,8 @@ var DockviewComponent = class extends BaseGrid {
15898
16347
  this.onDidChangePopouts = this._onDidChangePopouts.event;
15899
16348
  this._onDidOpenPopoutWindowFail = new Emitter();
15900
16349
  this.onDidOpenPopoutWindowFail = this._onDidOpenPopoutWindowFail.event;
16350
+ this._onWillClosePopoutWindow = new Emitter();
16351
+ this.onWillClosePopoutWindow = this._onWillClosePopoutWindow.event;
15901
16352
  this._onDidStartFloatingGroupDrag = new Emitter();
15902
16353
  this.onDidStartFloatingGroupDrag = this._onDidStartFloatingGroupDrag.event;
15903
16354
  this._onDidEndFloatingGroupDrag = new Emitter();
@@ -15953,6 +16404,10 @@ var DockviewComponent = class extends BaseGrid {
15953
16404
  });
15954
16405
  }));
15955
16406
  this.popupService = new PopupService(this.element);
16407
+ this.addDisposables(this.popupService, Disposable.from(() => {
16408
+ for (const opening of this._openingPopoutWindows) opening.dispose();
16409
+ this._openingPopoutWindows.clear();
16410
+ }));
15956
16411
  this._api = new DockviewApi(this);
15957
16412
  this.disableResizing = true;
15958
16413
  this.element.remove();
@@ -15999,7 +16454,7 @@ var DockviewComponent = class extends BaseGrid {
15999
16454
  var _this$_shellManager2;
16000
16455
  this._moduleRegistry.dispose();
16001
16456
  (_this$_shellManager2 = this._shellManager) === null || _this$_shellManager2 === void 0 || _this$_shellManager2.dispose();
16002
- }));
16457
+ }), this._onWillClosePopoutWindow);
16003
16458
  const rootDropTarget = this._rootDropTargetService;
16004
16459
  if (rootDropTarget) this.addDisposables(rootDropTarget.onWillShowOverlay((event) => {
16005
16460
  if (this.gridview.length > 0 && event.position === "center") return;
@@ -16012,6 +16467,7 @@ var DockviewComponent = class extends BaseGrid {
16012
16467
  }));
16013
16468
  }), rootDropTarget.onDrop((event) => this.dockToLayoutEdge(event.nativeEvent, event.position)));
16014
16469
  this._moduleRegistry.postConstruct(this);
16470
+ this._shellManager.layoutFromElement();
16015
16471
  }
16016
16472
  setVisible(panel, visible) {
16017
16473
  switch (panel.api.location.type) {
@@ -16081,22 +16537,42 @@ var DockviewComponent = class extends BaseGrid {
16081
16537
  const box = getBox();
16082
16538
  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();
16083
16539
  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;
16540
+ const popoutUrl = resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html";
16084
16541
  const _window = new PopoutWindow(`${this.id}-${groupId}`, theme !== null && theme !== void 0 ? theme : "", {
16085
- url: resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html",
16542
+ url: popoutUrl,
16086
16543
  left: box.left,
16087
16544
  top: box.top,
16088
16545
  width: box.width,
16089
16546
  height: box.height,
16090
16547
  onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
16091
- onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
16092
- nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce
16548
+ onWillClose: (event) => {
16549
+ var _options$onWillClose;
16550
+ options === null || options === void 0 || (_options$onWillClose = options.onWillClose) === null || _options$onWillClose === void 0 || _options$onWillClose.call(options, event);
16551
+ this._onWillClosePopoutWindow.fire(event);
16552
+ },
16553
+ nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce,
16554
+ styleRoot: () => this.element.getRootNode()
16093
16555
  });
16094
16556
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
16095
16557
  popoutWindowDisposable.dispose();
16096
16558
  }));
16097
- return _window.open().then((popoutContainer) => {
16559
+ this._openingPopoutWindows.add(popoutWindowDisposable);
16560
+ const openError = getPopoutUrlError(popoutUrl);
16561
+ return (openError ? Promise.resolve(null) : _window.open()).then((popoutContainer) => {
16098
16562
  var _options$referenceGro, _options$overridePopo4;
16099
- if (_window.isDisposed) return false;
16563
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16564
+ if (this.isDisposed) {
16565
+ popoutWindowDisposable.dispose();
16566
+ return false;
16567
+ }
16568
+ if (_window.isDisposed) {
16569
+ const failure = _window.failure;
16570
+ if (failure && !this.isDisposed) {
16571
+ logFailedPopout(failure);
16572
+ this._onDidOpenPopoutWindowFail.fire(failure);
16573
+ }
16574
+ return false;
16575
+ }
16100
16576
  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;
16101
16577
  const referenceLocation = itemToPopout.api.location.type;
16102
16578
  /**
@@ -16115,11 +16591,16 @@ var DockviewComponent = class extends BaseGrid {
16115
16591
  if (popoutContainer) this._onDidAddGroup.fire(group);
16116
16592
  }
16117
16593
  if (popoutContainer === null) {
16594
+ var _window$failure;
16118
16595
  this.handleBlockedPopout({
16119
16596
  group,
16120
16597
  referenceGroup,
16121
16598
  options,
16122
- popoutWindowDisposable
16599
+ popoutWindowDisposable,
16600
+ failure: openError ? {
16601
+ reason: "url-refused",
16602
+ error: openError
16603
+ } : (_window$failure = _window.failure) !== null && _window$failure !== void 0 ? _window$failure : { reason: "blocked" }
16123
16604
  });
16124
16605
  return false;
16125
16606
  }
@@ -16277,21 +16758,23 @@ var DockviewComponent = class extends BaseGrid {
16277
16758
  for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
16278
16759
  return true;
16279
16760
  }).catch((err) => {
16761
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16280
16762
  console.error("dockview: failed to create popout.", err);
16281
16763
  return false;
16282
16764
  });
16283
16765
  }
16284
16766
  /**
16285
- * The popout window was blocked (e.g. by the browser's popup blocker,
16286
- * common when restoring popouts on load). Fall back gracefully so the
16287
- * group(s) end up valid and visible in the main grid rather than as
16288
- * orphans that later crash clear()/remove().
16767
+ * The popout window never opened - blocked by the browser's popup blocker
16768
+ * (common when restoring popouts on load), or refused outright because its
16769
+ * URL failed the same-origin guard. Fall back gracefully so the group(s)
16770
+ * end up valid and visible in the main grid rather than as orphans that
16771
+ * render nothing and later crash clear()/remove().
16289
16772
  */
16290
16773
  handleBlockedPopout(params) {
16291
- const { group, referenceGroup, options, popoutWindowDisposable } = params;
16292
- console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
16774
+ const { group, referenceGroup, options, popoutWindowDisposable, failure } = params;
16775
+ logFailedPopout(failure);
16293
16776
  popoutWindowDisposable.dispose();
16294
- this._onDidOpenPopoutWindowFail.fire();
16777
+ this._onDidOpenPopoutWindowFail.fire(failure);
16295
16778
  if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
16296
16779
  const blockedGridview = options.overridePopoutGridview;
16297
16780
  const members = this.groups.filter((candidate) => blockedGridview.element.contains(candidate.element));
@@ -16525,12 +17008,13 @@ var DockviewComponent = class extends BaseGrid {
16525
17008
  if (group.model.size === 0) this.doRemoveGroup(group, { skipActive: true });
16526
17009
  }
16527
17010
  /**
16528
- * Build an empty gridview configured to match the main grid's styling, for
16529
- * hosting a nested layout inside a floating or popout window.
17011
+ * Build an empty gridview configured to match the main grid's styling and
17012
+ * resize behaviour, for hosting a nested layout inside a floating or popout
17013
+ * window.
16530
17014
  */
16531
17015
  createNestedGridview(orientation = "HORIZONTAL") {
16532
17016
  var _this$options$theme$g, _this$options$theme2;
16533
- 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);
17017
+ 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);
16534
17018
  }
16535
17019
  /**
16536
17020
  * Wrap a (populated) floating gridview in an overlay window: title bar /
@@ -16603,6 +17087,12 @@ var DockviewComponent = class extends BaseGrid {
16603
17087
  const newDisableDnd = this.options.disableDnd;
16604
17088
  const newDndStrategy = this.options.dndStrategy;
16605
17089
  if (oldDisableDnd !== newDisableDnd || oldDndStrategy !== newDndStrategy) this.updateDragAndDropState();
17090
+ if ("proportionalLayout" in options) {
17091
+ var _this$_popoutWindowSe9, _this$_popoutWindowSe10;
17092
+ const proportionalLayout = this.gridview.proportionalLayout;
17093
+ for (const floating of this.floatingGroups) floating.gridview.proportionalLayout = proportionalLayout;
17094
+ 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;
17095
+ }
16606
17096
  if ("theme" in options) this.updateTheme();
16607
17097
  if ("createRightHeaderActionComponent" in options || "createLeftHeaderActionComponent" in options || "createPrefixHeaderActionComponent" in options) {
16608
17098
  var _this$headerActionsSe;
@@ -16808,6 +17298,7 @@ var DockviewComponent = class extends BaseGrid {
16808
17298
  group.dispose();
16809
17299
  this._groups.delete(group.id);
16810
17300
  this._onDidRemoveGroup.fire(group);
17301
+ this.activateFallbackGroupIfRemoved(group);
16811
17302
  });
16812
17303
  }
16813
17304
  setEdgeGroupCollapsed(group, collapsed) {
@@ -16910,14 +17401,14 @@ var DockviewComponent = class extends BaseGrid {
16910
17401
  * @returns A JSON respresentation of the layout
16911
17402
  */
16912
17403
  toJSON() {
16913
- var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe9, _this$_popoutWindowSe10, _this$activeGroup2;
17404
+ var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe11, _this$_popoutWindowSe12, _this$activeGroup2;
16914
17405
  const data = this.gridview.serialize();
16915
17406
  const panels = this.panels.reduce((collection, panel) => {
16916
17407
  collection[panel.id] = panel.toJSON();
16917
17408
  return collection;
16918
17409
  }, {});
16919
17410
  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 : [];
16920
- 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 : [];
17411
+ 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 : [];
16921
17412
  const result = {
16922
17413
  grid: data,
16923
17414
  panels,
@@ -16956,8 +17447,8 @@ var DockviewComponent = class extends BaseGrid {
16956
17447
  this.mutation("load", () => this._doFromJSON(data, options));
16957
17448
  }
16958
17449
  _doFromJSON(data, options) {
16959
- var _this$_popoutWindowSe11, _data$grid$root;
16960
- (_this$_popoutWindowSe11 = this._popoutWindowService) === null || _this$_popoutWindowSe11 === void 0 || _this$_popoutWindowSe11.cancelPendingRestorations();
17450
+ var _this$_popoutWindowSe13, _data$grid$root;
17451
+ (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 || _this$_popoutWindowSe13.cancelPendingRestorations();
16961
17452
  if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
16962
17453
  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");
16963
17454
  const existingPanels = /* @__PURE__ */ new Map();
@@ -17004,6 +17495,7 @@ var DockviewComponent = class extends BaseGrid {
17004
17495
  const record = this._groups.get(temporaryGroup.api.id);
17005
17496
  this._groups.delete(temporaryGroup.api.id);
17006
17497
  temporaryGroupDisposables.push(Disposable.from(() => {
17498
+ var _this$headerActionsSe2;
17007
17499
  /**
17008
17500
  * Reclaim the group's own resources, never its panels.
17009
17501
  * Staging is driven by the ids in `data.panels` while
@@ -17021,6 +17513,7 @@ var DockviewComponent = class extends BaseGrid {
17021
17513
  for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
17022
17514
  });
17023
17515
  record === null || record === void 0 || record.disposable.dispose();
17516
+ (_this$headerActionsSe2 = this.headerActionsService) === null || _this$headerActionsSe2 === void 0 || _this$headerActionsSe2.disposeGroup(temporaryGroup);
17024
17517
  temporaryGroup.dispose();
17025
17518
  }));
17026
17519
  return temporaryGroup;
@@ -17076,7 +17569,7 @@ var DockviewComponent = class extends BaseGrid {
17076
17569
  } else this.clear();
17077
17570
  const { grid, panels, activeGroup } = data;
17078
17571
  try {
17079
- var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
17572
+ var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe14, _this$_floatingGroupS5, _this$_watermarkServi2;
17080
17573
  const width = this.width;
17081
17574
  const height = this.height;
17082
17575
  const createGroupFromSerializedState = (data) => {
@@ -17141,7 +17634,7 @@ var DockviewComponent = class extends BaseGrid {
17141
17634
  if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
17142
17635
  this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
17143
17636
  const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
17144
- (_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
17637
+ (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 || _this$_popoutWindowSe14.finishRestoration(popoutPromises);
17145
17638
  (_this$_floatingGroupS5 = this._floatingGroupService) === null || _this$_floatingGroupS5 === void 0 || _this$_floatingGroupS5.constrainBounds();
17146
17639
  if (typeof activeGroup === "string") {
17147
17640
  const panel = this.getPanel(activeGroup);
@@ -17309,15 +17802,13 @@ var DockviewComponent = class extends BaseGrid {
17309
17802
  }
17310
17803
  }
17311
17804
  const group = grid ? members[0] : createGroup(data);
17312
- return popoutService.scheduleRestoration(index * 100, () => {
17313
- this.addPopoutGroup(group, {
17314
- position: position !== null && position !== void 0 ? position : void 0,
17315
- overridePopoutGroup: gridReferenceGroup ? group : void 0,
17316
- overridePopoutGridview,
17317
- referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17318
- popoutUrl: url
17319
- });
17320
- }, () => {
17805
+ return popoutService.scheduleRestoration(index * 100, () => this.addPopoutGroup(group, {
17806
+ position: position !== null && position !== void 0 ? position : void 0,
17807
+ overridePopoutGroup: gridReferenceGroup ? group : void 0,
17808
+ overridePopoutGridview,
17809
+ referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17810
+ popoutUrl: url
17811
+ }), () => {
17321
17812
  for (const orphan of members.length > 0 ? members : [group]) if (!this.isDisposed && this._groups.has(orphan.id) && orphan.element.parentElement === null) {
17322
17813
  for (const panel of [...orphan.panels]) this.removePanel(panel, { removeEmptyGroup: false });
17323
17814
  orphan.dispose();
@@ -17552,7 +18043,7 @@ var DockviewComponent = class extends BaseGrid {
17552
18043
  * window.
17553
18044
  */
17554
18045
  detachFromNestedWindow(group) {
17555
- var _this$_floatingGroupS7, _this$_popoutWindowSe13;
18046
+ var _this$_floatingGroupS7, _this$_popoutWindowSe15;
17556
18047
  const floating = (_this$_floatingGroupS7 = this._floatingGroupService) === null || _this$_floatingGroupS7 === void 0 ? void 0 : _this$_floatingGroupS7.findByGroup(group);
17557
18048
  if (floating) {
17558
18049
  const members = this.nestedWindowMembers(group);
@@ -17561,7 +18052,7 @@ var DockviewComponent = class extends BaseGrid {
17561
18052
  if (floating.group === group) floating.setAnchorGroup(members.find((m) => m !== group));
17562
18053
  return true;
17563
18054
  }
17564
- const popout = (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 ? void 0 : _this$_popoutWindowSe13.findByGroup(group);
18055
+ const popout = (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 ? void 0 : _this$_popoutWindowSe15.findByGroup(group);
17565
18056
  if (popout) {
17566
18057
  const members = this.nestedWindowMembers(group);
17567
18058
  if (members.length <= 1) return false;
@@ -17618,8 +18109,8 @@ var DockviewComponent = class extends BaseGrid {
17618
18109
  return group;
17619
18110
  }
17620
18111
  if (group.api.location.type === "popout") {
17621
- var _this$_popoutWindowSe14, _this$_popoutWindowSe15;
17622
- const selectedGroup = (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 ? void 0 : _this$_popoutWindowSe14.findByGroup(group);
18112
+ var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18113
+ const selectedGroup = (_this$_popoutWindowSe16 = this._popoutWindowService) === null || _this$_popoutWindowSe16 === void 0 ? void 0 : _this$_popoutWindowSe16.findByGroup(group);
17623
18114
  if (!selectedGroup) throw new Error("dockview: failed to find popout group");
17624
18115
  if (this.detachFromNestedWindow(group)) {
17625
18116
  if (options === null || options === void 0 ? void 0 : options.skipDispose) group.model.location = { type: "grid" };
@@ -17636,7 +18127,7 @@ var DockviewComponent = class extends BaseGrid {
17636
18127
  this._groups.delete(group.id);
17637
18128
  this._onDidRemoveGroup.fire(group);
17638
18129
  }
17639
- (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 || _this$_popoutWindowSe15.remove(selectedGroup);
18130
+ (_this$_popoutWindowSe17 = this._popoutWindowService) === null || _this$_popoutWindowSe17 === void 0 || _this$_popoutWindowSe17.remove(selectedGroup);
17640
18131
  const removedGroup = selectedGroup.disposable.dispose();
17641
18132
  if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
17642
18133
  this.doAddGroup(removedGroup, [0]);
@@ -17663,10 +18154,10 @@ var DockviewComponent = class extends BaseGrid {
17663
18154
  debouncedUpdateAllPositions() {
17664
18155
  if (this._updatePositionsFrameId !== void 0) cancelAnimationFrame(this._updatePositionsFrameId);
17665
18156
  this._updatePositionsFrameId = requestAnimationFrame(() => {
17666
- var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18157
+ var _this$_popoutWindowSe18, _this$_popoutWindowSe19;
17667
18158
  this._updatePositionsFrameId = void 0;
17668
18159
  this.overlayRenderContainer.updateAllPositions();
17669
- 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();
18160
+ 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();
17670
18161
  });
17671
18162
  }
17672
18163
  movingLock(func) {
@@ -17687,9 +18178,12 @@ var DockviewComponent = class extends BaseGrid {
17687
18178
  */
17688
18179
  mutation(kind, func) {
17689
18180
  const close = this.openMutation(kind);
18181
+ this._syncMutationDepth++;
17690
18182
  try {
17691
18183
  return func();
17692
18184
  } finally {
18185
+ this._syncMutationDepth--;
18186
+ if (this._syncMutationDepth === 0) this.releaseDisposedActiveGroup();
17693
18187
  close();
17694
18188
  }
17695
18189
  }
@@ -17736,6 +18230,7 @@ var DockviewComponent = class extends BaseGrid {
17736
18230
  return () => {
17737
18231
  this._mutationDepth--;
17738
18232
  if (this._mutationDepth === 0) {
18233
+ this.releaseDisposedActiveGroup();
17739
18234
  this.flushLocationChanges();
17740
18235
  this._onDidMutateLayout.fire({
17741
18236
  kind,
@@ -17744,6 +18239,11 @@ var DockviewComponent = class extends BaseGrid {
17744
18239
  }
17745
18240
  };
17746
18241
  }
18242
+ /** Covers removals with `skipActive` that disposed the active group. */
18243
+ releaseDisposedActiveGroup() {
18244
+ var _this$_activeGroup;
18245
+ if (!this.isDisposed && ((_this$_activeGroup = this._activeGroup) === null || _this$_activeGroup === void 0 ? void 0 : _this$_activeGroup.model.isDisposed)) this.activateFallbackGroupIfRemoved(this._activeGroup);
18246
+ }
17747
18247
  /**
17748
18248
  * Coalesce a panel's `onDidLocationChange` to the end of the enclosing
17749
18249
  * transaction, or fire it immediately when no transaction is in flight.
@@ -17881,7 +18381,7 @@ var DockviewComponent = class extends BaseGrid {
17881
18381
  skipSetActiveGroup: true
17882
18382
  }));
17883
18383
  if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
17884
- if (!options.keepEmptyGroups && sourceGroup.model.size === 0) this.doRemoveGroup(sourceGroup, { skipActive: true });
18384
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== destinationGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
17885
18385
  const isDestinationGroupEmpty = destinationGroup.model.size === 0;
17886
18386
  this.movingLock(() => {
17887
18387
  var _options$skipSetActiv;
@@ -17916,7 +18416,7 @@ var DockviewComponent = class extends BaseGrid {
17916
18416
  }
17917
18417
  }
17918
18418
  if (sourceGroup.api.location.type === "popout" && this.nestedWindowMembers(sourceGroup).length <= 1) {
17919
- var _this$_popoutWindowSe18;
18419
+ var _this$_popoutWindowSe20;
17920
18420
  /**
17921
18421
  * the source group is the only group in a popout window and
17922
18422
  * has a single panel
@@ -17931,7 +18431,7 @@ var DockviewComponent = class extends BaseGrid {
17931
18431
  * Multi-group popout windows fall through to the generic
17932
18432
  * detach-and-re-add path so the window stays alive.
17933
18433
  */
17934
- const popoutGroup = (_this$_popoutWindowSe18 = this._popoutWindowService) === null || _this$_popoutWindowSe18 === void 0 ? void 0 : _this$_popoutWindowSe18.findByGroup(sourceGroup);
18434
+ const popoutGroup = (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 ? void 0 : _this$_popoutWindowSe20.findByGroup(sourceGroup);
17935
18435
  if (!popoutGroup) return;
17936
18436
  const removedPanel = this.movingLock(() => popoutGroup.popoutGroup.model.removePanel(popoutGroup.popoutGroup.panels[0], {
17937
18437
  skipSetActive: true,
@@ -18046,6 +18546,7 @@ var DockviewComponent = class extends BaseGrid {
18046
18546
  const from = options.from.group;
18047
18547
  const to = options.to.group;
18048
18548
  const target = options.to.position;
18549
+ if (target === "center" && from === to) return;
18049
18550
  let source = from;
18050
18551
  let mergedPanels;
18051
18552
  if (target === "center") {
@@ -18140,11 +18641,11 @@ var DockviewComponent = class extends BaseGrid {
18140
18641
  break;
18141
18642
  }
18142
18643
  case "popout": {
18143
- var _this$_popoutWindowSe19, _this$_popoutWindowSe20;
18144
- const selectedPopoutGroup = (_this$_popoutWindowSe19 = this._popoutWindowService) === null || _this$_popoutWindowSe19 === void 0 ? void 0 : _this$_popoutWindowSe19.findByGroup(from);
18644
+ var _this$_popoutWindowSe21, _this$_popoutWindowSe22;
18645
+ const selectedPopoutGroup = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.findByGroup(from);
18145
18646
  if (!selectedPopoutGroup) throw new Error("dockview: failed to find popout group");
18146
18647
  if (this.detachFromNestedWindow(from)) break;
18147
- (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 || _this$_popoutWindowSe20.remove(selectedPopoutGroup);
18648
+ (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 || _this$_popoutWindowSe22.remove(selectedPopoutGroup);
18148
18649
  if (selectedPopoutGroup.referenceGroup) {
18149
18650
  const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
18150
18651
  if (referenceGroup && !referenceGroup.api.isVisible) this.doRemoveGroup(referenceGroup, { skipActive: true });
@@ -18309,8 +18810,8 @@ var DockviewComponent = class extends BaseGrid {
18309
18810
  * window-local containers).
18310
18811
  */
18311
18812
  setGroupLocationForRoot(group, gridview) {
18312
- var _this$_popoutWindowSe21;
18313
- const popout = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.entries.find((entry) => entry.gridview === gridview);
18813
+ var _this$_popoutWindowSe23;
18814
+ const popout = (_this$_popoutWindowSe23 = this._popoutWindowService) === null || _this$_popoutWindowSe23 === void 0 ? void 0 : _this$_popoutWindowSe23.entries.find((entry) => entry.gridview === gridview);
18314
18815
  if (popout) {
18315
18816
  if (group.model.renderContainer !== popout.overlayRenderContainer) group.model.renderContainer = popout.overlayRenderContainer;
18316
18817
  group.model.dropTargetContainer = popout.dropTargetContainer;
@@ -18330,10 +18831,10 @@ var DockviewComponent = class extends BaseGrid {
18330
18831
  * the nested gridview of the floating / popout window it lives in.
18331
18832
  */
18332
18833
  getGridviewForGroup(group) {
18333
- var _this$_floatingGroupS10, _this$_popoutWindowSe22;
18834
+ var _this$_floatingGroupS10, _this$_popoutWindowSe24;
18334
18835
  const floating = (_this$_floatingGroupS10 = this._floatingGroupService) === null || _this$_floatingGroupS10 === void 0 ? void 0 : _this$_floatingGroupS10.findByGroup(group);
18335
18836
  if (floating) return floating.gridview;
18336
- const popout = (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 ? void 0 : _this$_popoutWindowSe22.findByGroup(group);
18837
+ const popout = (_this$_popoutWindowSe24 = this._popoutWindowService) === null || _this$_popoutWindowSe24 === void 0 ? void 0 : _this$_popoutWindowSe24.findByGroup(group);
18337
18838
  if (popout) return popout.gridview;
18338
18839
  return this.gridview;
18339
18840
  }
@@ -18355,13 +18856,13 @@ var DockviewComponent = class extends BaseGrid {
18355
18856
  return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
18356
18857
  }
18357
18858
  updateTheme() {
18358
- var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18859
+ var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe25, _this$_popoutWindowSe26, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18359
18860
  const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
18360
18861
  (_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
18361
18862
  const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
18362
18863
  this.gridview.margin = gap;
18363
18864
  for (const floating of this.floatingGroups) floating.gridview.margin = gap;
18364
- 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;
18865
+ 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;
18365
18866
  (_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);
18366
18867
  if (theme.dndOverlayBorder === void 0) {
18367
18868
  var _this$_shellManager6;
@@ -18430,6 +18931,7 @@ var GridviewComponent = class extends BaseGrid {
18430
18931
  }), this.onDidActiveChange((event) => {
18431
18932
  this._onDidActiveGroupChange.fire(event);
18432
18933
  }));
18934
+ this.layoutFromElement();
18433
18935
  }
18434
18936
  updateOptions(options) {
18435
18937
  super.updateOptions(options);
@@ -18675,6 +19177,7 @@ var SplitviewComponent = class extends Resizable {
18675
19177
  this._options = options;
18676
19178
  this.splitview = new Splitview(this.element, options);
18677
19179
  this.addDisposables(this._onDidAddView, this._onDidLayoutfromJSON, this._onDidRemoveView, this._onDidLayoutChange);
19180
+ this.layoutFromElement();
18678
19181
  }
18679
19182
  updateOptions(options) {
18680
19183
  if ("className" in options) {
@@ -19075,6 +19578,7 @@ var PaneviewComponent = class extends Resizable {
19075
19578
  const queue = [];
19076
19579
  const width = this.width;
19077
19580
  const height = this.height;
19581
+ this.paneview.dispose();
19078
19582
  this.paneview = new Paneview(this.element, {
19079
19583
  orientation: "VERTICAL",
19080
19584
  descriptor: {
@@ -19138,7 +19642,11 @@ var PaneviewComponent = class extends Resizable {
19138
19642
  clear() {
19139
19643
  for (const [_, value] of this._viewDisposables.entries()) value.dispose();
19140
19644
  this._viewDisposables.clear();
19645
+ const width = this.width;
19646
+ const height = this.height;
19141
19647
  this.paneview.dispose();
19648
+ this.paneview = new Paneview(this.element, { orientation: "VERTICAL" });
19649
+ this.layout(width, height);
19142
19650
  }
19143
19651
  doAddPanel(panel) {
19144
19652
  const disposable = new CompositeDisposable(panel.onDidDrop((event) => {
@@ -19356,11 +19864,13 @@ exports.createSplitview = createSplitview;
19356
19864
  exports.defineModule = defineModule;
19357
19865
  exports.directionToPosition = directionToPosition;
19358
19866
  exports.findRelativeZIndexParent = findRelativeZIndexParent;
19867
+ exports.getActiveElement = getActiveElement;
19359
19868
  exports.getDirectionOrientation = getDirectionOrientation;
19360
19869
  exports.getGridLocation = getGridLocation;
19361
19870
  exports.getLocationOrientation = getLocationOrientation;
19362
19871
  exports.getPaneData = getPaneData;
19363
19872
  exports.getPanelData = getPanelData;
19873
+ exports.getPopoutUrlError = getPopoutUrlError;
19364
19874
  exports.getRegisteredModules = getRegisteredModules;
19365
19875
  exports.getRelativeLocation = getRelativeLocation;
19366
19876
  exports.indexInParent = indexInParent;