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