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
  */
@@ -338,21 +338,29 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
338
338
  }
339
339
  };
340
340
  function watchElementResize(element, cb) {
341
+ const pendingFrames = /* @__PURE__ */ new Set();
341
342
  const observer = new ResizeObserver((entires) => {
342
343
  /**
343
344
  * Fast browser window resize produces Error: ResizeObserver loop limit exceeded.
344
345
  * The error isn't visible in browser console, doesn't affect functionality, but degrades performance.
345
346
  * See https://stackoverflow.com/questions/49384120/resizeobserver-loop-limit-exceeded/58701523#58701523
346
347
  */
347
- requestAnimationFrame(() => {
348
+ let ran = false;
349
+ let frame;
350
+ frame = requestAnimationFrame(() => {
351
+ ran = true;
352
+ if (frame !== void 0) pendingFrames.delete(frame);
348
353
  const firstEntry = entires[0];
349
354
  cb(firstEntry);
350
355
  });
356
+ if (!ran) pendingFrames.add(frame);
351
357
  });
352
358
  observer.observe(element);
353
359
  return { dispose: () => {
354
360
  observer.unobserve(element);
355
361
  observer.disconnect();
362
+ for (const frame of pendingFrames) cancelAnimationFrame(frame);
363
+ pendingFrames.clear();
356
364
  } };
357
365
  }
358
366
  const removeClasses = (element, ...classes) => {
@@ -387,7 +395,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
387
395
  this._onDidBlur = new Emitter();
388
396
  this.onDidBlur = this._onDidBlur.event;
389
397
  this.addDisposables(this._onDidFocus, this._onDidBlur);
390
- let hasFocus = isAncestor(document.activeElement, element);
398
+ let hasFocus = isAncestor(getActiveElement(element), element);
391
399
  let loosingFocus = false;
392
400
  const onFocus = () => {
393
401
  loosingFocus = false;
@@ -409,7 +417,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
409
417
  }
410
418
  };
411
419
  this._refreshStateHandler = () => {
412
- if (isAncestor(document.activeElement, element) !== hasFocus) if (hasFocus) onBlur();
420
+ if (isAncestor(getActiveElement(element), element) !== hasFocus) if (hasFocus) onBlur();
413
421
  else onFocus();
414
422
  };
415
423
  this.addDisposables(addDisposableListener(element, "focus", onFocus, true));
@@ -426,6 +434,49 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
426
434
  function quasiDefaultPrevented(event) {
427
435
  return event[QUASI_PREVENT_DEFAULT_KEY];
428
436
  }
437
+ /** Whether the event originated within any of `elements`. Checks the
438
+ * composed path, so it also holds for elements inside a shadow root, which a
439
+ * window or document listener sees retargeted to the shadow host. */
440
+ function isEventWithin(event, elements) {
441
+ var _event$composedPath, _event$composedPath2;
442
+ 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 : [];
443
+ if (path.length > 0) return elements.some((el) => path.includes(el));
444
+ const target = event.target;
445
+ return target instanceof Node && elements.some((el) => el.contains(target));
446
+ }
447
+ /** Every shadow root between `element` and its document, innermost first. An
448
+ * element in a component nested inside another component sits in more than
449
+ * one, and an event is cut at each boundary. */
450
+ function shadowRootsOf(node) {
451
+ const roots = [];
452
+ let root = node.getRootNode();
453
+ while (isShadowRoot(root)) {
454
+ roots.push(root);
455
+ root = root.host.getRootNode();
456
+ }
457
+ return roots;
458
+ }
459
+ /**
460
+ * `element` as a listener rooted in `scope`'s tree sees it. A node in a shadow
461
+ * root *below* that tree is retargeted to its host there, repeatedly for
462
+ * nested roots; a node already in the same tree is returned unchanged. Omit
463
+ * `scope` (or pass a node in the document) for the document-level view, which
464
+ * is what a window listener gets.
465
+ *
466
+ * The scope matters: a layer living inside a shadow root must be able to tell
467
+ * its own elements apart, and retargeting everything out to the document would
468
+ * collapse them all onto the one host.
469
+ */
470
+ function retargetInto(element, scope) {
471
+ const scopeRoot = scope === null || scope === void 0 ? void 0 : scope.getRootNode();
472
+ let current = element;
473
+ let root = current.getRootNode();
474
+ while (root !== scopeRoot && isShadowRoot(root)) {
475
+ current = root.host;
476
+ root = current.getRootNode();
477
+ }
478
+ return current;
479
+ }
429
480
  function addStyles(document, styleSheetList, options = {}) {
430
481
  const styleSheets = Array.from(styleSheetList);
431
482
  const { nonce } = options;
@@ -436,6 +487,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
436
487
  link.href = styleSheet.href;
437
488
  link.type = styleSheet.type;
438
489
  link.rel = "stylesheet";
490
+ if (resolvedNonce) link.setAttribute("nonce", resolvedNonce);
439
491
  document.head.appendChild(link);
440
492
  continue;
441
493
  }
@@ -475,6 +527,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
475
527
  else currentElement = currentElement.parentNode;
476
528
  return false;
477
529
  }
530
+ /** Duck-typed so it holds for a shadow root from another window's realm. */
531
+ function isShadowRoot(node) {
532
+ return !!node && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && "host" in node && !!node.host;
533
+ }
534
+ /**
535
+ * The document or shadow root to hit-test (`elementFromPoint` /
536
+ * `elementsFromPoint`) against for `node`. Hit-testing on the document stops
537
+ * at a shadow host, so when dockview is mounted in a shadow root it has to go
538
+ * through that root to reach its own elements. Falls back to the owning
539
+ * document (which may be a popout's) for a detached node.
540
+ */
541
+ function getHitTestRoot(node) {
542
+ var _node$ownerDocument;
543
+ const root = node.getRootNode();
544
+ if (root !== node && typeof root.elementsFromPoint === "function") return root;
545
+ return (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 ? _node$ownerDocument : document;
546
+ }
478
547
  function addTestId(element, id) {
479
548
  element.dataset.testid = id;
480
549
  }
@@ -509,6 +578,38 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
509
578
  iframes.splice(0, iframes.length);
510
579
  } };
511
580
  }
581
+ /**
582
+ * Suppress text selection for the duration of a pointer drag.
583
+ *
584
+ * A pointer drag is just a held button as far as the browser is concerned, so
585
+ * it selects text under the cursor as it travels. HTML5 drag-and-drop is
586
+ * exempt - the browser owns the gesture - which is why this is only needed on
587
+ * the pointer backend.
588
+ *
589
+ * `user-select: none` alone is not enough on WebKit: it starts the selection
590
+ * gesture from a mousedown on a `user-select: none` element unless that
591
+ * element is also natively draggable, then extends it into whatever the
592
+ * pointer crosses. Cancelling `selectstart` refuses that first extension,
593
+ * which ends the gesture for the rest of the drag.
594
+ *
595
+ * An existing selection is left alone: a mousedown on a `user-select: none`
596
+ * element does not clear one natively, and a pointer drag should not either.
597
+ */
598
+ function disableTextSelection(rootNode = document) {
599
+ const doc = rootNode instanceof Document ? rootNode : rootNode.ownerDocument;
600
+ const root = doc === null || doc === void 0 ? void 0 : doc.documentElement;
601
+ if (!doc || !root) return { release: () => void 0 };
602
+ const properties = ["user-select", "-webkit-user-select"];
603
+ const previous = properties.map((name) => [name, root.style.getPropertyValue(name)]);
604
+ for (const name of properties) root.style.setProperty(name, "none");
605
+ const onSelectStart = (event) => event.preventDefault();
606
+ doc.addEventListener("selectstart", onSelectStart);
607
+ return { release: () => {
608
+ doc.removeEventListener("selectstart", onSelectStart);
609
+ for (const [name, value] of previous) if (value) root.style.setProperty(name, value);
610
+ else root.style.removeProperty(name);
611
+ } };
612
+ }
512
613
  function getDockviewTheme(element) {
513
614
  function toClassList(element) {
514
615
  const list = [];
@@ -520,6 +621,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
520
621
  while (parent !== null) {
521
622
  theme = toClassList(parent).find((cls) => cls.startsWith("dockview-theme-"));
522
623
  if (typeof theme === "string") break;
624
+ if (parent.parentElement === null) {
625
+ const root = parent.getRootNode();
626
+ parent = isShadowRoot(root) ? root.host : null;
627
+ continue;
628
+ }
523
629
  parent = parent.parentElement;
524
630
  }
525
631
  return theme;
@@ -631,6 +737,285 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
631
737
  }
632
738
  return "";
633
739
  }
740
+ /** The focused element as seen from `node`'s own tree. Unlike
741
+ * `document.activeElement`, which is the shadow host when focus is inside a
742
+ * shadow root, this reaches into the root `node` lives in (and a popout's
743
+ * own document), while a web component nested inside that tree still
744
+ * resolves to its host there. */
745
+ function getActiveElement(node) {
746
+ var _root$activeElement;
747
+ const root = node.getRootNode();
748
+ const doc = root.nodeType === Node.DOCUMENT_NODE ? root : node.ownerDocument;
749
+ if (doc && typeof doc.hasFocus === "function" && !doc.hasFocus()) return null;
750
+ return (_root$activeElement = root.activeElement) !== null && _root$activeElement !== void 0 ? _root$activeElement : null;
751
+ }
752
+ /** Where to append a floating element (e.g. a drag ghost) for `node`: its
753
+ * shadow root when it lives in one, so styles scoped there still apply,
754
+ * otherwise the body of its own document (which may be a popout's). */
755
+ function getOverlayParent(node) {
756
+ var _node$ownerDocument2;
757
+ const root = node.getRootNode();
758
+ if (isShadowRoot(root)) return root;
759
+ return ((_node$ownerDocument2 = node.ownerDocument) !== null && _node$ownerDocument2 !== void 0 ? _node$ownerDocument2 : document).body;
760
+ }
761
+
762
+ //#endregion
763
+ //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
764
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
765
+ try {
766
+ var i = n[a](c), u = i.value;
767
+ } catch (n) {
768
+ e(n);
769
+ return;
770
+ }
771
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
772
+ }
773
+ function _asyncToGenerator(n) {
774
+ return function() {
775
+ var t = this, e = arguments;
776
+ return new Promise(function(r, o) {
777
+ var a = n.apply(t, e);
778
+ function _next(n) {
779
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
780
+ }
781
+ function _throw(n) {
782
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
783
+ }
784
+ _next(void 0);
785
+ });
786
+ };
787
+ }
788
+
789
+ //#endregion
790
+ //#region src/popoutWindow.ts
791
+ /**
792
+ * Throwing form of {@link getPopoutUrlError}, for callers with no way to
793
+ * recover from a refused URL.
794
+ */
795
+ function assertSameOriginPopoutUrl(url) {
796
+ const error = getPopoutUrlError(url);
797
+ if (error) throw error;
798
+ }
799
+ /**
800
+ * Schemes a popout must never open: each runs script in a context the browser
801
+ * still associates with the opener, or (for `file:`) has no origin to check.
802
+ */
803
+ const UNSAFE_POPOUT_PROTOCOLS = /* @__PURE__ */ new Set([
804
+ "javascript:",
805
+ "data:",
806
+ "blob:",
807
+ "vbscript:",
808
+ "file:"
809
+ ]);
810
+ /** How often an open popout window's `closed` flag is checked. */
811
+ const CLOSED_POLL_INTERVAL_MS = 250;
812
+ /**
813
+ * The reason `url` is unusable as a popout target, or `undefined` if it is
814
+ * allowed. Rejects anything that isn't same-origin with the page (scheme and
815
+ * host, so a packaged webview's own scheme such as `tauri://` qualifies), and
816
+ * the `javascript:`, `data:`, `blob:`, `vbscript:` and `file:` schemes that
817
+ * would otherwise execute in a context the browser still associates with the
818
+ * opener via `window.opener`.
819
+ *
820
+ * Callers that can recover from a refusal use this rather than catching, so it
821
+ * can be handled without a rejected promise. `page` is what the URL resolves
822
+ * against, and defaults to this page.
823
+ */
824
+ function getPopoutUrlError(url, page = globalThis.location) {
825
+ let resolved;
826
+ try {
827
+ resolved = new URL(url, page.href);
828
+ } catch (_unused) {
829
+ return /* @__PURE__ */ new Error(`dockview: invalid popout URL: ${url}`);
830
+ }
831
+ 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}`);
832
+ 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}`);
833
+ }
834
+ var PopoutWindow = class extends CompositeDisposable {
835
+ get window() {
836
+ var _this$_window$value, _this$_window;
837
+ 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;
838
+ }
839
+ /** Set when {@link open} resolved `null`, saying which way it failed. */
840
+ get failure() {
841
+ return this._failure;
842
+ }
843
+ constructor(target, className, options) {
844
+ super();
845
+ this.target = target;
846
+ this.className = className;
847
+ this.options = options;
848
+ this._onWillClose = new Emitter();
849
+ this.onWillClose = this._onWillClose.event;
850
+ this._onDidClose = new Emitter();
851
+ this.onDidClose = this._onDidClose.event;
852
+ this._window = null;
853
+ this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
854
+ this.close();
855
+ } });
856
+ }
857
+ dimensions() {
858
+ if (!this._window) return null;
859
+ const left = this._window.value.screenX;
860
+ return {
861
+ top: this._window.value.screenY,
862
+ left,
863
+ width: this._window.value.innerWidth,
864
+ height: this._window.value.innerHeight
865
+ };
866
+ }
867
+ close() {
868
+ var _this$options$onWillC, _this$options;
869
+ const current = this._window;
870
+ if (!current) return;
871
+ this._window = null;
872
+ this._onWillClose.fire();
873
+ (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
874
+ id: this.target,
875
+ window: current.value
876
+ });
877
+ current.disposable.dispose();
878
+ this._onDidClose.fire();
879
+ }
880
+ open() {
881
+ var _this = this;
882
+ return _asyncToGenerator(function* () {
883
+ var _this$options$onDidOp, _this$options2;
884
+ if (_this._window) throw new Error("instance of popout window is already open");
885
+ const url = `${_this.options.url}`;
886
+ assertSameOriginPopoutUrl(url);
887
+ const features = Object.entries({
888
+ top: _this.options.top,
889
+ left: _this.options.left,
890
+ width: _this.options.width,
891
+ height: _this.options.height
892
+ }).map(([key, value]) => `${key}=${value}`).join(",");
893
+ /**
894
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
895
+ */
896
+ const externalWindow = window.open(url, _this.target, features);
897
+ if (!externalWindow) {
898
+ _this._failure = { reason: "blocked" };
899
+ return null;
900
+ }
901
+ const disposable = new CompositeDisposable();
902
+ _this._window = {
903
+ value: externalWindow,
904
+ disposable
905
+ };
906
+ disposable.addDisposables(Disposable.from(() => {
907
+ externalWindow.close();
908
+ }), _this.watchForClose(externalWindow), addDisposableListener(globalThis.window, "beforeunload", () => {
909
+ /**
910
+ * before the main window closes we should close this popup too
911
+ * to be good citizens
912
+ *
913
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
914
+ */
915
+ _this.close();
916
+ }));
917
+ const container = _this.createPopoutWindowContainer();
918
+ if (_this.className) container.classList.add(_this.className);
919
+ (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
920
+ id: _this.target,
921
+ window: externalWindow
922
+ });
923
+ return new Promise((resolve) => {
924
+ /**
925
+ * A host can answer `window.open` with a window in its own
926
+ * JavaScript context, which throws on first touch and cannot be
927
+ * filled with panel DOM. Settle as a blocked popup does, so the
928
+ * caller's fallback returns the group to the grid.
929
+ */
930
+ const abandon = (err) => {
931
+ _this._failure = {
932
+ reason: "unscriptable",
933
+ error: err instanceof Error ? err : new Error(String(err))
934
+ };
935
+ _this.close();
936
+ resolve(null);
937
+ };
938
+ try {
939
+ externalWindow.addEventListener("unload", () => {});
940
+ } catch (err) {
941
+ abandon(err);
942
+ return;
943
+ }
944
+ /**
945
+ * `load` is the only event that resolves this promise with a
946
+ * container, so a window that goes away first would leave the
947
+ * caller awaiting a promise that never settles - and
948
+ * `addPopoutGroup` holds its layout transaction open until it does.
949
+ * Settle with `null` on close, the same signal a blocked popup
950
+ * gives and one the caller already handles. `resolve` after the
951
+ * fact is a no-op, so a `load` that arrived first still wins.
952
+ */
953
+ disposable.addDisposables(_this.onWillClose(() => {
954
+ var _this$_failure;
955
+ (_this$_failure = _this._failure) !== null && _this$_failure !== void 0 || (_this._failure = { reason: "closed" });
956
+ resolve(null);
957
+ }));
958
+ externalWindow.addEventListener("load", () => {
959
+ /**
960
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
961
+ */
962
+ try {
963
+ var _globalThis$document$, _this$options$styleRo, _this$options3;
964
+ const externalDocument = externalWindow.document;
965
+ externalDocument.title = document.title;
966
+ externalDocument.body.appendChild(container);
967
+ addStyles(externalDocument, [...Array.from(globalThis.document.styleSheets), ...(_globalThis$document$ = globalThis.document.adoptedStyleSheets) !== null && _globalThis$document$ !== void 0 ? _globalThis$document$ : []], { nonce: _this.options.nonce });
968
+ const sheets = [];
969
+ 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()) {
970
+ var _root$styleSheets, _root$adoptedStyleShe;
971
+ 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 : []);
972
+ }
973
+ if (sheets.length > 0) addStyles(externalDocument, sheets, { nonce: _this.options.nonce });
974
+ /**
975
+ * beforeunload must be registered after load for reasons I could not determine
976
+ * otherwise the beforeunload event will not fire when the window is closed
977
+ */
978
+ addDisposableListener(externalWindow, "beforeunload", () => {
979
+ /**
980
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
981
+ */
982
+ _this.close();
983
+ });
984
+ resolve(container);
985
+ } catch (err) {
986
+ abandon(err);
987
+ }
988
+ });
989
+ });
990
+ })();
991
+ }
992
+ /**
993
+ * Backstop for the `beforeunload` signal, which a window torn down without
994
+ * running its unload handlers never sends: a native shell destroying the
995
+ * webview, or a browser discarding the page. `closed` is readable on any
996
+ * handle, cross-origin included. Whichever signal arrives first wins.
997
+ */
998
+ watchForClose(externalWindow) {
999
+ if (typeof externalWindow.closed !== "boolean") return Disposable.NONE;
1000
+ const handle = setInterval(() => {
1001
+ if (externalWindow.closed) this.close();
1002
+ }, CLOSED_POLL_INTERVAL_MS);
1003
+ return Disposable.from(() => {
1004
+ clearInterval(handle);
1005
+ });
1006
+ }
1007
+ createPopoutWindowContainer() {
1008
+ const el = document.createElement("div");
1009
+ el.classList.add("dv-popout-window");
1010
+ el.id = "dv-popout-window";
1011
+ el.style.position = "absolute";
1012
+ el.style.width = "100%";
1013
+ el.style.height = "100%";
1014
+ el.style.top = "0px";
1015
+ el.style.left = "0px";
1016
+ return el;
1017
+ }
1018
+ };
634
1019
 
635
1020
  //#endregion
636
1021
  //#region src/array.ts
@@ -850,6 +1235,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
850
1235
  get proportions() {
851
1236
  return this._proportions ? [...this._proportions] : void 0;
852
1237
  }
1238
+ get proportionalLayout() {
1239
+ return this._proportionalLayout;
1240
+ }
1241
+ set proportionalLayout(value) {
1242
+ if (this._proportionalLayout === value) return;
1243
+ this._proportionalLayout = value;
1244
+ if (value) this.saveProportions();
1245
+ else this._proportions = void 0;
1246
+ }
853
1247
  get orientation() {
854
1248
  return this._orientation;
855
1249
  }
@@ -974,7 +1368,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
974
1368
  this._orientation = (_options$orientation = options.orientation) !== null && _options$orientation !== void 0 ? _options$orientation : "VERTICAL";
975
1369
  this.element = this.createContainer();
976
1370
  this.margin = (_options$margin = options.margin) !== null && _options$margin !== void 0 ? _options$margin : 0;
977
- this.proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
1371
+ this._proportionalLayout = options.proportionalLayout === void 0 ? true : !!options.proportionalLayout;
978
1372
  this.viewContainer = this.createViewContainer();
979
1373
  this.sashContainer = this.createSashContainer();
980
1374
  this.element.appendChild(this.sashContainer);
@@ -1698,10 +2092,18 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
1698
2092
  if (child instanceof BranchNode) child.margin = value;
1699
2093
  });
1700
2094
  }
2095
+ get proportionalLayout() {
2096
+ return this.splitview.proportionalLayout;
2097
+ }
2098
+ set proportionalLayout(value) {
2099
+ this.splitview.proportionalLayout = value;
2100
+ this.children.forEach((child) => {
2101
+ if (child instanceof BranchNode) child.proportionalLayout = value;
2102
+ });
2103
+ }
1701
2104
  constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, margin, childDescriptors) {
1702
2105
  super();
1703
2106
  this.orientation = orientation;
1704
- this.proportionalLayout = proportionalLayout;
1705
2107
  this.styles = styles;
1706
2108
  this._childrenDisposable = Disposable.NONE;
1707
2109
  this.children = [];
@@ -2243,8 +2645,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
2243
2645
  }
2244
2646
  return findLeaf(this.root, reverse);
2245
2647
  }
2648
+ get proportionalLayout() {
2649
+ return this.root.proportionalLayout;
2650
+ }
2651
+ set proportionalLayout(value) {
2652
+ this.root.proportionalLayout = value;
2653
+ }
2246
2654
  constructor(proportionalLayout, styles, orientation, locked, margin) {
2247
- this.proportionalLayout = proportionalLayout;
2248
2655
  this.styles = styles;
2249
2656
  this._locked = false;
2250
2657
  this._margin = 0;
@@ -2438,6 +2845,25 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
2438
2845
  this.layout(width, height);
2439
2846
  }));
2440
2847
  }
2848
+ /**
2849
+ * Lay out from the element's current size.
2850
+ *
2851
+ * The ResizeObserver above only reports asynchronously, so between
2852
+ * construction and its first callback the component believes it has no
2853
+ * size - and anything built in that window (panels added right after
2854
+ * `createDockview`, say) resolves its sizes against zero and collapses to
2855
+ * minimums. Concrete components call this once they are fully constructed
2856
+ * so that work sees the real size. The same guards as the observer apply:
2857
+ * a detached or hidden element has no size worth propagating.
2858
+ */
2859
+ layoutFromElement() {
2860
+ if (this.disableResizing || !this._element.offsetParent) return;
2861
+ if (!isInDocument(this._element)) return;
2862
+ const width = Math.round(this._element.clientWidth);
2863
+ const height = Math.round(this._element.clientHeight);
2864
+ if (width === 0 || height === 0) return;
2865
+ this.layout(width, height);
2866
+ }
2441
2867
  };
2442
2868
 
2443
2869
  //#endregion
@@ -2538,7 +2964,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
2538
2964
  return this.gridview.isViewVisible(getGridLocation(panel.element));
2539
2965
  }
2540
2966
  updateOptions(options) {
2541
- if (typeof options.proportionalLayout === "boolean") {}
2967
+ if ("proportionalLayout" in options) {
2968
+ var _options$proportional;
2969
+ this.gridview.proportionalLayout = (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true;
2970
+ }
2542
2971
  if (options.orientation) this.gridview.orientation = options.orientation;
2543
2972
  if ("styles" in options) {}
2544
2973
  if ("disableAutoResizing" in options) {
@@ -3347,6 +3776,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3347
3776
  get onUnhandledDragOver() {
3348
3777
  return this.component.onUnhandledDragOver;
3349
3778
  }
3779
+ /**
3780
+ * The drag-and-drop backends currently live: `dndStrategy` resolved against
3781
+ * this device, which `'auto'` reads from the primary input device. Only an
3782
+ * HTML5 drag can leave the window it started in, so check `html5` before
3783
+ * relying on a drag between a popout window and the main window.
3784
+ */
3785
+ get dndCapabilities() {
3786
+ return this.component.dndCapabilities;
3787
+ }
3350
3788
  get onDidPopoutGroupSizeChange() {
3351
3789
  return this.component.onDidPopoutGroupSizeChange;
3352
3790
  }
@@ -3369,9 +3807,27 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3369
3807
  get onDidRemovePopoutGroup() {
3370
3808
  return this.component.onDidRemovePopoutGroup;
3371
3809
  }
3810
+ /**
3811
+ * Fires when a popout window could not be used, carrying which way it
3812
+ * failed: the URL was refused, the browser blocked the window, the host
3813
+ * returned a window whose document the opener cannot reach, or it closed
3814
+ * before loading. The group stays in (or returns to) the main grid.
3815
+ */
3372
3816
  get onDidOpenPopoutWindowFail() {
3373
3817
  return this.component.onDidOpenPopoutWindowFail;
3374
3818
  }
3819
+ /**
3820
+ * Fires as dockview lets go of a popout window, while that window is still
3821
+ * open, carrying its live `Window` handle. Covers every popout the component
3822
+ * opened and every reason for closing one, disposal included;
3823
+ * {@link onDidAddPopoutGroup} is the opening half.
3824
+ *
3825
+ * For hosts that own their windows: in a desktop webview the page's own
3826
+ * `close()` can be a no-op, so the shell has to be told.
3827
+ */
3828
+ get onWillClosePopoutWindow() {
3829
+ return this.component.onWillClosePopoutWindow;
3830
+ }
3375
3831
  /** Enumerate the popout groups currently open in their own windows. */
3376
3832
  getPopouts() {
3377
3833
  return this.component.getPopouts();
@@ -4338,7 +4794,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4338
4794
  var _options$ownerDocumen, _options$x, _options$y;
4339
4795
  addClasses(ghostElement, "dv-dragged");
4340
4796
  ghostElement.style.top = "-9999px";
4341
- ((_options$ownerDocumen = options === null || options === void 0 ? void 0 : options.ownerDocument) !== null && _options$ownerDocumen !== void 0 ? _options$ownerDocumen : document).body.appendChild(ghostElement);
4797
+ ghostElement.style.position = "absolute";
4798
+ ((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);
4342
4799
  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);
4343
4800
  setTimeout(() => {
4344
4801
  removeClasses(ghostElement, "dv-dragged");
@@ -4390,7 +4847,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4390
4847
  } };
4391
4848
  }
4392
4849
  beginDrag(args) {
4393
- var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3;
4850
+ var _source$ownerDocument, _source$ownerDocument2, _source$ownerDocument3, _source$ownerDocument4;
4394
4851
  if (this._active) this.cancel();
4395
4852
  const { pointerEvent, source } = args;
4396
4853
  const dataDisposable = args.getData();
@@ -4406,13 +4863,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4406
4863
  this._dataDisposable = dataDisposable;
4407
4864
  this._ghost = args.ghost;
4408
4865
  this._iframeShield = disableIframePointEvents((_source$ownerDocument = source.ownerDocument) !== null && _source$ownerDocument !== void 0 ? _source$ownerDocument : document);
4866
+ this._selectionShield = disableTextSelection((_source$ownerDocument2 = source.ownerDocument) !== null && _source$ownerDocument2 !== void 0 ? _source$ownerDocument2 : document);
4409
4867
  const startEvent = {
4410
4868
  clientX: pointerEvent.clientX,
4411
4869
  clientY: pointerEvent.clientY,
4412
4870
  pointerEvent
4413
4871
  };
4414
4872
  this._onDragStart.fire(startEvent);
4415
- 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;
4873
+ 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;
4416
4874
  this._moveListener = addDisposableListener(targetWindow, "pointermove", (e) => {
4417
4875
  var _this$_active;
4418
4876
  if (e.pointerId !== ((_this$_active = this._active) === null || _this$_active === void 0 ? void 0 : _this$_active.pointerId)) return;
@@ -4449,8 +4907,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4449
4907
  }
4450
4908
  }
4451
4909
  _findTargetUnder(x, y) {
4452
- var _this$_active$source$, _this$_active4;
4453
- 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);
4910
+ const elements = (this._active ? getHitTestRoot(this._active.source) : document).elementsFromPoint(x, y);
4454
4911
  for (const el of elements) {
4455
4912
  let current = el;
4456
4913
  while (current) {
@@ -4500,7 +4957,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4500
4957
  this._onDragEnd.fire(dragEvent);
4501
4958
  }
4502
4959
  _teardown() {
4503
- var _this$_ghost2, _this$_iframeShield, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4960
+ var _this$_ghost2, _this$_iframeShield, _this$_selectionShiel, _this$_moveListener, _this$_upListener, _this$_cancelListener;
4504
4961
  this._currentTarget = void 0;
4505
4962
  this._active = void 0;
4506
4963
  this._lastPointerEvent = void 0;
@@ -4510,6 +4967,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4510
4967
  this._ghost = void 0;
4511
4968
  (_this$_iframeShield = this._iframeShield) === null || _this$_iframeShield === void 0 || _this$_iframeShield.release();
4512
4969
  this._iframeShield = void 0;
4970
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
4971
+ this._selectionShield = void 0;
4513
4972
  (_this$_moveListener = this._moveListener) === null || _this$_moveListener === void 0 || _this$_moveListener.dispose();
4514
4973
  (_this$_upListener = this._upListener) === null || _this$_upListener === void 0 || _this$_upListener.dispose();
4515
4974
  (_this$_cancelListener = this._cancelListener) === null || _this$_cancelListener === void 0 || _this$_cancelListener.dispose();
@@ -4778,9 +5237,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4778
5237
  return true;
4779
5238
  }
4780
5239
  _onPointerDown(event) {
4781
- var _ref, _this$options$thresho, _ref2, _this$element$ownerDo, _this$element$ownerDo2;
5240
+ var _this$element$ownerDo, _ref, _this$options$thresho, _ref2, _this$element$ownerDo2, _this$element$ownerDo3;
4782
5241
  if (!this._shouldHandle(event)) return;
4783
5242
  this._cancelPending();
5243
+ this._selectionShield = disableTextSelection((_this$element$ownerDo = this.element.ownerDocument) !== null && _this$element$ownerDo !== void 0 ? _this$element$ownerDo : document);
4784
5244
  this._pendingPointerId = event.pointerId;
4785
5245
  this._startX = event.clientX;
4786
5246
  this._startY = event.clientY;
@@ -4796,7 +5256,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4796
5256
  const threshold = (_this$options$thresho = this.options.threshold) !== null && _this$options$thresho !== void 0 ? _this$options$thresho : DEFAULT_THRESHOLD;
4797
5257
  const pressToleranceOpt = this.options.pressTolerance;
4798
5258
  const pressTolerance = (_ref2 = typeof pressToleranceOpt === "function" ? pressToleranceOpt() : pressToleranceOpt) !== null && _ref2 !== void 0 ? _ref2 : DEFAULT_PRESS_TOLERANCE;
4799
- 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;
5259
+ 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;
4800
5260
  this._pendingMoveListener = addDisposableListener(targetWindow, "pointermove", (moveEvent) => {
4801
5261
  if (moveEvent.pointerId !== this._pendingPointerId) return;
4802
5262
  const dx = moveEvent.clientX - this._startX;
@@ -4822,7 +5282,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4822
5282
  this._cancelPending();
4823
5283
  }
4824
5284
  _cancelPending() {
4825
- var _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5285
+ var _this$_selectionShiel, _this$_pendingMoveLis, _this$_pendingUpListe, _this$_pendingCancelL;
5286
+ (_this$_selectionShiel = this._selectionShield) === null || _this$_selectionShiel === void 0 || _this$_selectionShiel.release();
5287
+ this._selectionShield = void 0;
4826
5288
  this._pendingPointerId = void 0;
4827
5289
  if (this._armTimer !== void 0) {
4828
5290
  clearTimeout(this._armTimer);
@@ -4867,29 +5329,51 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4867
5329
  */
4868
5330
  var PointerGhost = class {
4869
5331
  constructor(opts) {
4870
- var _opts$offsetX, _opts$offsetY, _opts$opacity, _opts$owner$ownerDocu, _opts$owner;
5332
+ var _opts$offsetX, _opts$offsetY, _popover, _opts$opacity;
4871
5333
  this._disposed = false;
4872
5334
  this.element = opts.element;
4873
5335
  this.offsetX = (_opts$offsetX = opts.offsetX) !== null && _opts$offsetX !== void 0 ? _opts$offsetX : 0;
4874
5336
  this.offsetY = (_opts$offsetY = opts.offsetY) !== null && _opts$offsetY !== void 0 ? _opts$offsetY : 0;
4875
- this.element.style.position = "fixed";
4876
- this.element.style.left = "0px";
4877
- this.element.style.top = "0px";
4878
- this.element.style.pointerEvents = "none";
4879
- this.element.style.zIndex = "99999";
4880
- this.element.style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
4881
- this.element.style.willChange = "transform";
4882
- this.element.style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
4883
- ((_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);
5337
+ const parent = opts.owner ? getOverlayParent(opts.owner) : document.body;
5338
+ let popover;
5339
+ if (isShadowRoot(parent) && typeof this.element.showPopover === "function") {
5340
+ popover = this.element.ownerDocument.createElement("div");
5341
+ popover.popover = "manual";
5342
+ Object.assign(popover.style, {
5343
+ inset: "auto",
5344
+ margin: "0",
5345
+ padding: "0",
5346
+ border: "0",
5347
+ background: "transparent",
5348
+ color: "inherit",
5349
+ overflow: "visible"
5350
+ });
5351
+ popover.appendChild(this.element);
5352
+ this.element.style.pointerEvents = "none";
5353
+ this.element.style.transform = "none";
5354
+ }
5355
+ this.container = (_popover = popover) !== null && _popover !== void 0 ? _popover : this.element;
5356
+ const style = this.container.style;
5357
+ style.position = "fixed";
5358
+ style.left = "0px";
5359
+ style.top = "0px";
5360
+ style.pointerEvents = "none";
5361
+ style.zIndex = "99999";
5362
+ style.opacity = String((_opts$opacity = opts.opacity) !== null && _opts$opacity !== void 0 ? _opts$opacity : .8);
5363
+ style.willChange = "transform";
5364
+ style.transform = `translate3d(${opts.initialX - this.offsetX}px, ${opts.initialY - this.offsetY}px, 0)`;
5365
+ parent.appendChild(this.container);
5366
+ popover === null || popover === void 0 || popover.showPopover();
4884
5367
  }
4885
5368
  update(clientX, clientY) {
4886
5369
  if (this._disposed) return;
4887
- this.element.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
5370
+ this.container.style.transform = `translate3d(${clientX - this.offsetX}px, ${clientY - this.offsetY}px, 0)`;
4888
5371
  }
4889
5372
  dispose() {
4890
5373
  if (this._disposed) return;
4891
5374
  this._disposed = true;
4892
5375
  this.element.remove();
5376
+ if (this.container !== this.element) this.container.remove();
4893
5377
  }
4894
5378
  };
4895
5379
 
@@ -4926,7 +5410,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
4926
5410
  addGhostImage(event.dataTransfer, ghost.element, {
4927
5411
  x: (_ghost$offsetX = ghost.offsetX) !== null && _ghost$offsetX !== void 0 ? _ghost$offsetX : 0,
4928
5412
  y: (_ghost$offsetY = ghost.offsetY) !== null && _ghost$offsetY !== void 0 ? _ghost$offsetY : 0,
4929
- ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0
5413
+ ownerDocument: (_this$el$ownerDocumen2 = this.el.ownerDocument) !== null && _this$el$ownerDocumen2 !== void 0 ? _this$el$ownerDocumen2 : void 0,
5414
+ owner: this.el
4930
5415
  });
4931
5416
  if (ghost.dispose) {
4932
5417
  const disposeGhost = ghost.dispose;
@@ -5762,8 +6247,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
5762
6247
  let guard;
5763
6248
  const timeout = setTimeout(() => guard === null || guard === void 0 ? void 0 : guard.dispose(), 500);
5764
6249
  guard = addDisposableListener(targetWindow, "click", (event) => {
5765
- const target = event.target;
5766
- if (target && this.element.contains(target)) {
6250
+ if (isEventWithin(event, [this.element])) {
5767
6251
  event.preventDefault();
5768
6252
  event.stopPropagation();
5769
6253
  }
@@ -5879,7 +6363,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
5879
6363
  if (this.accessor.id === (data === null || data === void 0 ? void 0 : data.viewId)) {
5880
6364
  var _this$accessor$option;
5881
6365
  if (((_this$accessor$option = this.accessor.options.theme) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.tabAnimation) === "smooth") return false;
5882
- if (data.tabGroupId && this.group.model.getTabGroupForPanel(this.panel.id)) return false;
6366
+ if (data.tabGroupId && data.groupId === this.group.id && this.group.model.getTabGroupForPanel(this.panel.id)) return false;
5883
6367
  return true;
5884
6368
  }
5885
6369
  return this.group.model.canDisplayOverlay(event, position, "tab");
@@ -6492,6 +6976,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
6492
6976
  const PROPERTY_KEYS_DOCKVIEW = (() => {
6493
6977
  return Object.keys({
6494
6978
  disableAutoResizing: void 0,
6979
+ proportionalLayout: void 0,
6495
6980
  hideBorders: void 0,
6496
6981
  singleTabMode: void 0,
6497
6982
  disableFloatingGroups: void 0,
@@ -7345,10 +7830,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7345
7830
  (_entry$pointerDropTar = entry.pointerDropTarget) === null || _entry$pointerDropTar === void 0 || _entry$pointerDropTar.clearOverlay();
7346
7831
  }
7347
7832
  }
7348
- snapshotChipWidths() {
7349
- const widths = /* @__PURE__ */ new Map();
7350
- for (const [groupId, entry] of this._chipRenderers) widths.set(groupId, entry.chip.element.getBoundingClientRect().width);
7351
- return widths;
7833
+ /** Each chip's extent along the strip's main axis: width for a horizontal
7834
+ * header, height for a vertical one. */
7835
+ snapshotChipSizes() {
7836
+ const isVertical = this._ctx.getDirection() === "vertical";
7837
+ const sizes = /* @__PURE__ */ new Map();
7838
+ for (const [groupId, entry] of this._chipRenderers) {
7839
+ const rect = entry.chip.element.getBoundingClientRect();
7840
+ sizes.set(groupId, isVertical ? rect.height : rect.width);
7841
+ }
7842
+ return sizes;
7352
7843
  }
7353
7844
  positionUnderlines() {
7354
7845
  var _this$_indicator2;
@@ -7740,6 +8231,22 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7740
8231
  //#endregion
7741
8232
  //#region src/dockview/components/titlebar/tabReorderController.ts
7742
8233
  /**
8234
+ * Main-axis extent of a rect. Tabs flow along x in a horizontal header
8235
+ * (top/bottom) and along y in a vertical one (the left/right edge groups),
8236
+ * so the reorder math reads every size through this.
8237
+ */
8238
+ function mainAxisSize(rect, direction) {
8239
+ return direction === "vertical" ? rect.height : rect.width;
8240
+ }
8241
+ /** Leading edge of a rect along the main axis. */
8242
+ function mainAxisStart(rect, direction) {
8243
+ return direction === "vertical" ? rect.top : rect.left;
8244
+ }
8245
+ /** A cursor position projected onto the main axis. */
8246
+ function mainAxisCursor(event, direction) {
8247
+ return direction === "vertical" ? event.clientY : event.clientX;
8248
+ }
8249
+ /**
7743
8250
  * Tab drag-reorder + FLIP animation subsystem extracted from `Tabs`. The DOM
7744
8251
  * event wiring remains in `Tabs` and delegates the reorder/animation logic to
7745
8252
  * this controller. All access back into `Tabs` goes through
@@ -7834,14 +8341,30 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7834
8341
  for (const tab of this._tabs) positions.set(tab.value.panel.id, tab.value.element.getBoundingClientRect());
7835
8342
  return positions;
7836
8343
  }
7837
- getAverageTabWidth() {
8344
+ /** Main-axis extent of a rect for this header's orientation. */
8345
+ _mainAxisSize(rect) {
8346
+ return mainAxisSize(rect, this._direction);
8347
+ }
8348
+ /** Main-axis leading edge of a rect for this header's orientation. */
8349
+ _mainAxisStart(rect) {
8350
+ return mainAxisStart(rect, this._direction);
8351
+ }
8352
+ /** The cursor coordinate along the main axis. */
8353
+ _mainAxisCoord(clientX, clientY) {
8354
+ return mainAxisCursor({
8355
+ clientX,
8356
+ clientY
8357
+ }, this._direction);
8358
+ }
8359
+ /** The margin that opens the insertion gap. It must run along the main
8360
+ * axis, so a vertical header pushes tabs down rather than sideways. */
8361
+ get _gapMarginProperty() {
8362
+ return this._direction === "vertical" ? "margin-top" : "margin-left";
8363
+ }
8364
+ getAverageTabSize() {
7838
8365
  if (this._tabs.length === 0) return 0;
7839
- const isVertical = this._direction === "vertical";
7840
8366
  let total = 0;
7841
- for (const tab of this._tabs) {
7842
- const rect = tab.value.element.getBoundingClientRect();
7843
- total += isVertical ? rect.height : rect.width;
7844
- }
8367
+ for (const tab of this._tabs) total += this._mainAxisSize(tab.value.element.getBoundingClientRect());
7845
8368
  return total / this._tabs.length;
7846
8369
  }
7847
8370
  /**
@@ -7851,8 +8374,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7851
8374
  * `processDragOver` / `processDragLeave` helpers.
7852
8375
  */
7853
8376
  handlePointerDragMove(clientX, clientY) {
7854
- var _this$_tabsList$owner;
7855
- const elAtPoint = ((_this$_tabsList$owner = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner !== void 0 ? _this$_tabsList$owner : document).elementFromPoint(clientX, clientY);
8377
+ const elAtPoint = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7856
8378
  if (!(!!elAtPoint && (this._tabsList.contains(elAtPoint) || !!this._extendedDropZone && this._extendedDropZone.contains(elAtPoint)))) {
7857
8379
  if (this._pointerInsideTabsList) {
7858
8380
  this._pointerInsideTabsList = false;
@@ -7881,8 +8403,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7881
8403
  this.resetDragAnimation();
7882
8404
  }
7883
8405
  isPointInsideTabsList(clientX, clientY) {
7884
- var _this$_tabsList$owner2;
7885
- const el = ((_this$_tabsList$owner2 = this._tabsList.ownerDocument) !== null && _this$_tabsList$owner2 !== void 0 ? _this$_tabsList$owner2 : document).elementFromPoint(clientX, clientY);
8406
+ const el = getHitTestRoot(this._tabsList).elementFromPoint(clientX, clientY);
7886
8407
  return !!el && this._tabsList.contains(el);
7887
8408
  }
7888
8409
  /** Commit a smooth-mode intra-group reorder from the current insertion
@@ -7946,46 +8467,46 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
7946
8467
  const data = getPanelData();
7947
8468
  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;
7948
8469
  if (!data || !(data.panelId || data.tabGroupId) || data.groupId === this.group.id) return false;
7949
- const avgWidth = this.getAverageTabWidth();
7950
- this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgWidth) : this._makeTabDragAnimState(data, avgWidth);
8470
+ const avgSize = this.getAverageTabSize();
8471
+ this._animState = data.tabGroupId ? this._makeGroupDragAnimState(data, avgSize) : this._makeTabDragAnimState(data, avgSize);
7951
8472
  return true;
7952
8473
  }
7953
8474
  /** Anim state for an external group-chip drag (gap sized to the group). */
7954
- _makeGroupDragAnimState(data, avgWidth) {
8475
+ _makeGroupDragAnimState(data, avgSize) {
7955
8476
  var _sourceTg$panelIds$le;
7956
8477
  const sourceGroup = this.accessor.getPanel(data.groupId);
7957
8478
  const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
7958
- 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;
8479
+ 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;
7959
8480
  return {
7960
8481
  sourceTabId: "",
7961
8482
  sourceIndex: -1,
7962
8483
  tabPositions: this.snapshotTabPositions(),
7963
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8484
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7964
8485
  currentInsertionIndex: null,
7965
8486
  targetTabGroupId: null,
7966
8487
  sourceTabGroupId: data.tabGroupId,
7967
8488
  sourceGroupPanelIds: sourceTg ? new Set(sourceTg.panelIds) : /* @__PURE__ */ new Set(),
7968
- sourceChipWidth: avgWidth,
7969
- cursorOffsetFromDragLeft: groupGapWidth / 2,
7970
- sourceGapWidth: groupGapWidth,
7971
- containerLeft: this._tabsList.getBoundingClientRect().left
8489
+ sourceChipSize: avgSize,
8490
+ cursorOffsetFromDragStart: groupGapSize / 2,
8491
+ sourceGapSize: groupGapSize,
8492
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7972
8493
  };
7973
8494
  }
7974
8495
  /** Anim state for an external single-tab drag. */
7975
- _makeTabDragAnimState(data, avgWidth) {
8496
+ _makeTabDragAnimState(data, avgSize) {
7976
8497
  return {
7977
8498
  sourceTabId: data.panelId,
7978
8499
  sourceIndex: -1,
7979
8500
  tabPositions: this.snapshotTabPositions(),
7980
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
8501
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
7981
8502
  currentInsertionIndex: null,
7982
8503
  targetTabGroupId: null,
7983
8504
  sourceTabGroupId: null,
7984
8505
  sourceGroupPanelIds: null,
7985
- sourceChipWidth: 0,
7986
- cursorOffsetFromDragLeft: avgWidth / 2,
7987
- sourceGapWidth: avgWidth,
7988
- containerLeft: this._tabsList.getBoundingClientRect().left
8506
+ sourceChipSize: 0,
8507
+ cursorOffsetFromDragStart: avgSize / 2,
8508
+ sourceGapSize: avgSize,
8509
+ containerStart: this._mainAxisStart(this._tabsList.getBoundingClientRect())
7989
8510
  };
7990
8511
  }
7991
8512
  /**
@@ -8028,19 +8549,19 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8028
8549
  container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
8029
8550
  }
8030
8551
  handleDragOver(event) {
8031
- var _this$accessor$option2;
8552
+ var _event$clientY2, _this$accessor$option2;
8032
8553
  if (!this._animState) return;
8033
8554
  if (this._wrapMode && !this._animState.sourceTabGroupId) {
8034
8555
  var _event$clientY;
8035
8556
  this.handleWrappedDragOver(event.clientX, (_event$clientY = event.clientY) !== null && _event$clientY !== void 0 ? _event$clientY : 0);
8036
8557
  return;
8037
8558
  }
8038
- const mouseX = event.clientX;
8559
+ const mousePos = this._mainAxisCoord(event.clientX, (_event$clientY2 = event.clientY) !== null && _event$clientY2 !== void 0 ? _event$clientY2 : 0);
8039
8560
  const firstPanelToGroup = this._buildFirstPanelToGroupMap();
8040
- let insertionIndex = this._computeDragOverInsertionIndex(mouseX, firstPanelToGroup);
8561
+ let insertionIndex = this._computeDragOverInsertionIndex(mousePos, firstPanelToGroup);
8041
8562
  let targetTabGroupId = null;
8042
8563
  if (insertionIndex !== null && this._tabGroupManager.chipRenderers.size > 0) {
8043
- const resolved = this._resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup);
8564
+ const resolved = this._resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup);
8044
8565
  insertionIndex = resolved.insertionIndex;
8045
8566
  targetTabGroupId = resolved.targetTabGroupId;
8046
8567
  }
@@ -8064,14 +8585,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8064
8585
  return firstPanelToGroup;
8065
8586
  }
8066
8587
  /**
8067
- * Walk the tabs left-to-right by their original widths and return the
8068
- * insertion slot for the drag image's left edge (null if no slot fits).
8588
+ * Walk the tabs in flow order by their original main-axis sizes and return
8589
+ * the insertion slot for the drag image's leading edge (null if no slot
8590
+ * fits).
8069
8591
  */
8070
- _computeDragOverInsertionIndex(mouseX, firstPanelToGroup) {
8592
+ _computeDragOverInsertionIndex(mousePos, firstPanelToGroup) {
8071
8593
  const animState = this._animState;
8072
8594
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8073
- const availableSpace = mouseX - animState.cursorOffsetFromDragLeft - animState.containerLeft;
8074
- let accWidth = 0;
8595
+ const availableSpace = mousePos - animState.cursorOffsetFromDragStart - animState.containerStart;
8596
+ let accSize = 0;
8075
8597
  let insertionIndex = null;
8076
8598
  for (let i = 0; i < this._tabs.length; i++) {
8077
8599
  const tab = this._tabs[i].value;
@@ -8079,19 +8601,19 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8079
8601
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8080
8602
  const groupId = firstPanelToGroup.get(tab.panel.id);
8081
8603
  if (groupId) {
8082
- var _animState$chipPositi;
8083
- const chipWidth = (_animState$chipPositi = animState.chipPositions.get(groupId)) !== null && _animState$chipPositi !== void 0 ? _animState$chipPositi : 0;
8084
- if (accWidth + chipWidth > availableSpace) {
8604
+ var _animState$chipSizes$;
8605
+ const chipSize = (_animState$chipSizes$ = animState.chipSizes.get(groupId)) !== null && _animState$chipSizes$ !== void 0 ? _animState$chipSizes$ : 0;
8606
+ if (accSize + chipSize > availableSpace) {
8085
8607
  var _insertionIndex;
8086
8608
  (_insertionIndex = insertionIndex) !== null && _insertionIndex !== void 0 || (insertionIndex = i);
8087
8609
  break;
8088
8610
  }
8089
- accWidth += chipWidth;
8611
+ accSize += chipSize;
8090
8612
  }
8091
8613
  const origRect = animState.tabPositions.get(tab.panel.id);
8092
- const tabWidth = origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8093
- if (accWidth + tabWidth / 2 <= availableSpace) {
8094
- accWidth += tabWidth;
8614
+ const tabSize = this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8615
+ if (accSize + tabSize / 2 <= availableSpace) {
8616
+ accSize += tabSize;
8095
8617
  insertionIndex = i + 1;
8096
8618
  } else {
8097
8619
  var _insertionIndex2;
@@ -8102,11 +8624,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8102
8624
  return insertionIndex;
8103
8625
  }
8104
8626
  /**
8105
- * Rebuild the accumulated original width up to `insertionIndex`, walking the
8106
- * tabs exactly the way the accumulation loop does, so callers know the
8107
- * original right edge of the chip (if any) that precedes the insertion slot.
8627
+ * Rebuild the accumulated original main-axis size up to `insertionIndex`,
8628
+ * walking the tabs exactly the way the accumulation loop does, so callers
8629
+ * know the original trailing edge of the chip (if any) that precedes the
8630
+ * insertion slot.
8108
8631
  */
8109
- _accumulatedWidthUpTo(insertionIndex, firstPanelToGroup) {
8632
+ _accumulatedSizeUpTo(insertionIndex, firstPanelToGroup) {
8110
8633
  const animState = this._animState;
8111
8634
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8112
8635
  let accUpTo = 0;
@@ -8117,11 +8640,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8117
8640
  if (i >= insertionIndex) break;
8118
8641
  const gid = firstPanelToGroup.get(tab.panel.id);
8119
8642
  if (gid) {
8120
- var _animState$chipPositi2;
8121
- accUpTo += (_animState$chipPositi2 = animState.chipPositions.get(gid)) !== null && _animState$chipPositi2 !== void 0 ? _animState$chipPositi2 : 0;
8643
+ var _animState$chipSizes$2;
8644
+ accUpTo += (_animState$chipSizes$2 = animState.chipSizes.get(gid)) !== null && _animState$chipSizes$2 !== void 0 ? _animState$chipSizes$2 : 0;
8122
8645
  }
8123
8646
  const origRect = animState.tabPositions.get(tab.panel.id);
8124
- accUpTo += origRect ? origRect.width : tab.element.getBoundingClientRect().width;
8647
+ accUpTo += this._mainAxisSize(origRect !== null && origRect !== void 0 ? origRect : tab.element.getBoundingClientRect());
8125
8648
  }
8126
8649
  return accUpTo;
8127
8650
  }
@@ -8129,11 +8652,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8129
8652
  * Given a raw insertion index, snap it out of / into any tab group it falls
8130
8653
  * within and resolve the target group (if the drop should merge into one).
8131
8654
  */
8132
- _resolveInsertionAgainstTabGroups(mouseX, insertionIndex, firstPanelToGroup) {
8655
+ _resolveInsertionAgainstTabGroups(mousePos, insertionIndex, firstPanelToGroup) {
8133
8656
  const isGroupDrag = !!this._animState.sourceTabGroupId;
8134
- const accUpTo = this._accumulatedWidthUpTo(insertionIndex, firstPanelToGroup);
8657
+ const accUpTo = this._accumulatedSizeUpTo(insertionIndex, firstPanelToGroup);
8135
8658
  for (const tg of this.group.model.getTabGroups()) {
8136
- const resolved = this._evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag);
8659
+ const resolved = this._evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag);
8137
8660
  if (resolved) return resolved;
8138
8661
  }
8139
8662
  return {
@@ -8147,7 +8670,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8147
8670
  * group governs the slot (the caller stops iterating), or `null` when the
8148
8671
  * group is irrelevant and the caller should keep looking.
8149
8672
  */
8150
- _evaluateTabGroupForInsertion(tg, mouseX, insertionIndex, accUpTo, isGroupDrag) {
8673
+ _evaluateTabGroupForInsertion(tg, mousePos, insertionIndex, accUpTo, isGroupDrag) {
8151
8674
  const range = this._resolveGroupRange(tg);
8152
8675
  if (!range) return null;
8153
8676
  const { firstIdx, lastIdx } = range;
@@ -8155,7 +8678,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8155
8678
  const isJustBeforeGroup = !isInsideRange && insertionIndex === firstIdx - 1;
8156
8679
  if (!isInsideRange && !isJustBeforeGroup) return null;
8157
8680
  if (isGroupDrag) return this._resolveGroupDragTarget(insertionIndex, firstIdx, lastIdx, isInsideRange);
8158
- return this._resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8681
+ return this._resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup);
8159
8682
  }
8160
8683
  /**
8161
8684
  * The index range this group occupies in the live tab list, excluding the
@@ -8190,13 +8713,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8190
8713
  }
8191
8714
  /** Insertion target for a single-tab drag against a group: decide whether
8192
8715
  * the drop merges into the group based on the cursor vs the chip edge. */
8193
- _resolveTabDragTarget(tg, mouseX, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8194
- var _animState$chipPositi3;
8716
+ _resolveTabDragTarget(tg, mousePos, insertionIndex, accUpTo, firstIdx, isJustBeforeGroup) {
8717
+ var _animState$chipSizes$3;
8195
8718
  const animState = this._animState;
8196
- const chipWidth = (_animState$chipPositi3 = animState.chipPositions.get(tg.id)) !== null && _animState$chipPositi3 !== void 0 ? _animState$chipPositi3 : 0;
8719
+ const chipSize = (_animState$chipSizes$3 = animState.chipSizes.get(tg.id)) !== null && _animState$chipSizes$3 !== void 0 ? _animState$chipSizes$3 : 0;
8197
8720
  if (isJustBeforeGroup) {
8198
8721
  if (!this._onlySourceBetween(insertionIndex, firstIdx)) return null;
8199
- if (mouseX >= (tg.collapsed ? animState.containerLeft + accUpTo + chipWidth / 2 : animState.containerLeft + accUpTo + chipWidth)) return {
8722
+ if (mousePos >= (tg.collapsed ? animState.containerStart + accUpTo + chipSize / 2 : animState.containerStart + accUpTo + chipSize)) return {
8200
8723
  insertionIndex: firstIdx,
8201
8724
  targetTabGroupId: tg.id
8202
8725
  };
@@ -8205,10 +8728,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8205
8728
  targetTabGroupId: null
8206
8729
  };
8207
8730
  }
8208
- const chipOriginalRight = animState.containerLeft + accUpTo + chipWidth;
8731
+ const chipOriginalEnd = animState.containerStart + accUpTo + chipSize;
8209
8732
  if (insertionIndex === firstIdx) return {
8210
8733
  insertionIndex,
8211
- targetTabGroupId: mouseX >= chipOriginalRight ? tg.id : null
8734
+ targetTabGroupId: mousePos >= chipOriginalEnd ? tg.id : null
8212
8735
  };
8213
8736
  return {
8214
8737
  insertionIndex,
@@ -8371,17 +8894,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8371
8894
  }
8372
8895
  if (this._pendingCollapse) return;
8373
8896
  const insertionIndex = this._animState.currentInsertionIndex;
8374
- const gapWidth = this._computeGapWidth();
8897
+ const gapSize = this._computeGapSize();
8375
8898
  const chipToShift = this._computeChipToShift(insertionIndex);
8376
- this._applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition);
8899
+ this._applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition);
8377
8900
  }
8378
- /** Gap width for the current drag: the whole group's span for a group
8379
- * drag, otherwise the source tab's own width. */
8380
- _computeGapWidth() {
8901
+ /** Gap size for the current drag: the whole group's span for a group
8902
+ * drag, otherwise the source tab's own main-axis size. */
8903
+ _computeGapSize() {
8381
8904
  const animState = this._animState;
8382
- if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapWidth;
8905
+ if (animState.sourceTabGroupId && animState.sourceGroupPanelIds) return animState.sourceGapSize;
8383
8906
  const sourceRect = animState.tabPositions.get(animState.sourceTabId);
8384
- return sourceRect ? sourceRect.width : this.getAverageTabWidth();
8907
+ return sourceRect ? this._mainAxisSize(sourceRect) : this.getAverageTabSize();
8385
8908
  }
8386
8909
  /**
8387
8910
  * When the insertion lands at or before a group's first tab, the chip is
@@ -8425,7 +8948,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8425
8948
  }
8426
8949
  /** Reset non-source chip margins, then apply the gap margin to the chip or
8427
8950
  * the first tab at/after the insertion index. */
8428
- _applyGapMargins(insertionIndex, gapWidth, chipToShift, skipTransition) {
8951
+ _applyGapMargins(insertionIndex, gapSize, chipToShift, skipTransition) {
8429
8952
  const animState = this._animState;
8430
8953
  const sourceGroupPanelIds = animState.sourceGroupPanelIds;
8431
8954
  let gapApplied = false;
@@ -8434,7 +8957,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8434
8957
  this._clearMargin(entry.chip.element, skipTransition);
8435
8958
  }
8436
8959
  if (chipToShift) {
8437
- this._setMargin(chipToShift, `${gapWidth}px`, skipTransition);
8960
+ this._setMargin(chipToShift, `${gapSize}px`, skipTransition);
8438
8961
  gapApplied = true;
8439
8962
  }
8440
8963
  for (let i = 0; i < this._tabs.length; i++) {
@@ -8442,7 +8965,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8442
8965
  if (tab.panel.id === animState.sourceTabId) continue;
8443
8966
  if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) continue;
8444
8967
  if (!gapApplied && i >= insertionIndex) {
8445
- this._setMargin(tab.element, `${gapWidth}px`, skipTransition);
8968
+ this._setMargin(tab.element, `${gapSize}px`, skipTransition);
8446
8969
  gapApplied = true;
8447
8970
  } else this._clearMargin(tab.element, skipTransition);
8448
8971
  }
@@ -8452,31 +8975,33 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8452
8975
  _shiftingClass(el) {
8453
8976
  return el.classList.contains("dv-tab-group-chip") ? "dv-tab-group-chip--shifting" : "dv-tab--shifting";
8454
8977
  }
8455
- /** Apply a margin-left value to an element, optionally bypassing CSS
8978
+ /** Apply the main-axis gap margin to an element, optionally bypassing CSS
8456
8979
  * transitions for instant positioning. */
8457
8980
  _setMargin(el, value, skipTransition) {
8981
+ const property = this._gapMarginProperty;
8458
8982
  if (skipTransition) {
8459
8983
  el.style.transition = "none";
8460
- el.style.marginLeft = value;
8984
+ el.style.setProperty(property, value);
8461
8985
  el.getBoundingClientRect();
8462
8986
  el.style.removeProperty("transition");
8463
- } else el.style.marginLeft = value;
8987
+ } else el.style.setProperty(property, value);
8464
8988
  toggleClass(el, this._shiftingClass(el), true);
8465
8989
  }
8466
8990
  /** Clear an element's gap margin, animating it back to zero unless
8467
8991
  * transitions are skipped. */
8468
8992
  _clearMargin(el, skipTransition) {
8469
8993
  const cls = this._shiftingClass(el);
8994
+ const property = this._gapMarginProperty;
8470
8995
  const prev = this._pendingMarginCleanups.get(el);
8471
8996
  if (prev) prev();
8472
- if (skipTransition || !el.style.marginLeft) {
8473
- el.style.removeProperty("margin-left");
8997
+ if (skipTransition || !el.style.getPropertyValue(property)) {
8998
+ el.style.removeProperty(property);
8474
8999
  toggleClass(el, cls, false);
8475
9000
  } else {
8476
- el.style.marginLeft = "0px";
9001
+ el.style.setProperty(property, "0px");
8477
9002
  toggleClass(el, cls, true);
8478
9003
  const onEnd = () => {
8479
- el.style.removeProperty("margin-left");
9004
+ el.style.removeProperty(property);
8480
9005
  toggleClass(el, cls, false);
8481
9006
  el.removeEventListener("transitionend", onEnd);
8482
9007
  clearTimeout(fallbackTimer);
@@ -8501,6 +9026,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
8501
9026
  }
8502
9027
  for (const [, entry] of this._tabGroupManager.chipRenderers) {
8503
9028
  entry.chip.element.style.removeProperty("margin-left");
9029
+ entry.chip.element.style.removeProperty("margin-top");
8504
9030
  toggleClass(entry.chip.element, "dv-tab-group-chip--shifting", false);
8505
9031
  }
8506
9032
  this._tabGroupManager.positionUnderlines();
@@ -9095,21 +9621,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9095
9621
  panel
9096
9622
  });
9097
9623
  if (((_this$accessor$option2 = this.accessor.options.theme) === null || _this$accessor$option2 === void 0 ? void 0 : _this$accessor$option2.tabAnimation) === "smooth") {
9098
- const tabWidth = tab.element.getBoundingClientRect().width;
9624
+ const tabSize = mainAxisSize(tab.element.getBoundingClientRect(), this._direction);
9099
9625
  const sourceIndex = this._tabs.findIndex((x) => x.value === tab);
9100
9626
  this._animState = {
9101
9627
  sourceTabId: panel.id,
9102
9628
  sourceIndex,
9103
9629
  tabPositions: this.snapshotTabPositions(),
9104
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9630
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9105
9631
  currentInsertionIndex: null,
9106
9632
  targetTabGroupId: null,
9107
9633
  sourceTabGroupId: null,
9108
9634
  sourceGroupPanelIds: null,
9109
- sourceChipWidth: 0,
9110
- cursorOffsetFromDragLeft: tabWidth / 2,
9111
- sourceGapWidth: tabWidth,
9112
- containerLeft: this._tabsList.getBoundingClientRect().left
9635
+ sourceChipSize: 0,
9636
+ cursorOffsetFromDragStart: tabSize / 2,
9637
+ sourceGapSize: tabSize,
9638
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9113
9639
  };
9114
9640
  this._pendingCollapse = true;
9115
9641
  requestAnimationFrame(() => {
@@ -9205,7 +9731,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9205
9731
  this._tabGroupManager.positionAllChips();
9206
9732
  if (this._animState) {
9207
9733
  this._animState.tabPositions = this.snapshotTabPositions();
9208
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9734
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9209
9735
  this.applyDragOverTransforms();
9210
9736
  }
9211
9737
  }
@@ -9227,7 +9753,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9227
9753
  }
9228
9754
  if (this._animState) {
9229
9755
  this._animState.tabPositions = this.snapshotTabPositions();
9230
- this._animState.chipPositions = this._tabGroupManager.snapshotChipWidths();
9756
+ this._animState.chipSizes = this._tabGroupManager.snapshotChipSizes();
9231
9757
  this.applyDragOverTransforms();
9232
9758
  }
9233
9759
  }
@@ -9305,24 +9831,24 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9305
9831
  const firstPanelId = tabGroup.panelIds[0];
9306
9832
  const firstIdx = firstPanelId ? this._tabs.findIndex((t) => t.value.panel.id === firstPanelId) : -1;
9307
9833
  const chipRect = chip.element.getBoundingClientRect();
9308
- let groupGapWidth = chipRect.width;
9834
+ let groupGapSize = mainAxisSize(chipRect, this._direction);
9309
9835
  for (const pid of tabGroup.panelIds) {
9310
9836
  const tabEntry = this._tabMap.get(pid);
9311
- if (tabEntry) groupGapWidth += tabEntry.value.element.getBoundingClientRect().width;
9837
+ if (tabEntry) groupGapSize += mainAxisSize(tabEntry.value.element.getBoundingClientRect(), this._direction);
9312
9838
  }
9313
9839
  this._animState = {
9314
9840
  sourceTabId: "",
9315
9841
  sourceIndex: firstIdx,
9316
9842
  tabPositions: this.snapshotTabPositions(),
9317
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
9843
+ chipSizes: this._tabGroupManager.snapshotChipSizes(),
9318
9844
  currentInsertionIndex: null,
9319
9845
  targetTabGroupId: null,
9320
9846
  sourceTabGroupId: tabGroup.id,
9321
9847
  sourceGroupPanelIds: new Set(tabGroup.panelIds),
9322
- sourceChipWidth: chipRect.width,
9323
- cursorOffsetFromDragLeft: event.clientX - chipRect.left,
9324
- sourceGapWidth: groupGapWidth,
9325
- containerLeft: this._tabsList.getBoundingClientRect().left
9848
+ sourceChipSize: mainAxisSize(chipRect, this._direction),
9849
+ cursorOffsetFromDragStart: mainAxisCursor(event, this._direction) - mainAxisStart(chipRect, this._direction),
9850
+ sourceGapSize: groupGapSize,
9851
+ containerStart: mainAxisStart(this._tabsList.getBoundingClientRect(), this._direction)
9326
9852
  };
9327
9853
  if (((_this$accessor$option4 = this.accessor.options.theme) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.tabAnimation) !== "smooth") return;
9328
9854
  const groupPanelIds = new Set(tabGroup.panelIds);
@@ -9703,16 +10229,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9703
10229
  y: event.clientY,
9704
10230
  zIndex: (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0
9705
10231
  };
9706
- const context = this.createOverflowRenderContext(root, anchor);
10232
+ const { context, rowRenderers } = this.createOverflowRenderContext(root, anchor);
9707
10233
  const advancedOverflow = this.accessor.advancedOverflowService;
9708
- if (advancedOverflow) advancedOverflow.renderOverflow({
9709
- group: this.group,
9710
- overflowTabs: [...this._overflowTabs],
9711
- overflowTabGroups: [...this._overflowTabGroups],
9712
- pinnedOverflowTabs: [...this._overflowPinnedTabs],
9713
- context
9714
- });
9715
- else context.open(this.renderFreeOverflowList(context));
10234
+ try {
10235
+ if (advancedOverflow) advancedOverflow.renderOverflow({
10236
+ group: this.group,
10237
+ overflowTabs: [...this._overflowTabs],
10238
+ overflowTabGroups: [...this._overflowTabGroups],
10239
+ pinnedOverflowTabs: [...this._overflowPinnedTabs],
10240
+ context
10241
+ });
10242
+ else context.open(this.renderFreeOverflowList(context));
10243
+ } catch (err) {
10244
+ rowRenderers.dispose();
10245
+ throw err;
10246
+ }
9716
10247
  }));
9717
10248
  }
9718
10249
  /**
@@ -9733,6 +10264,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9733
10264
  if (overflowGroupSet.has(tg.id)) for (const pid of tg.panelIds) panelToGroup.set(pid, tg);
9734
10265
  }
9735
10266
  const popup = () => this.accessor.getPopupServiceForGroup(this.group);
10267
+ const rowRenderers = new CompositeDisposable();
9736
10268
  const buildGroupHeader = (tg) => {
9737
10269
  const groupHeader = document.createElement("div");
9738
10270
  groupHeader.className = "dv-tabs-overflow-group-header";
@@ -9762,69 +10294,87 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
9762
10294
  return groupHeader;
9763
10295
  };
9764
10296
  return {
9765
- overflowGroupIdForPanel: (panelId) => {
9766
- var _panelToGroup$get;
9767
- return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
9768
- },
9769
- buildGroupHeader: (tabGroupId) => {
9770
- const tg = groupById.get(tabGroupId);
9771
- if (!tg || !overflowGroupSet.has(tg.id)) return;
9772
- return buildGroupHeader(tg);
9773
- },
9774
- buildPinnedHeader: () => {
9775
- const header = document.createElement("div");
9776
- header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
9777
- const glyph = createPinButton();
9778
- glyph.classList.add("dv-tabs-overflow-pinned-icon");
9779
- header.appendChild(glyph);
9780
- const labelSpan = document.createElement("span");
9781
- labelSpan.className = "dv-tabs-overflow-group-label";
9782
- labelSpan.textContent = "Pinned";
9783
- header.appendChild(labelSpan);
9784
- return header;
9785
- },
9786
- buildRow: (panelId) => {
9787
- const panel = this.group.panels.find((p) => p.id === panelId);
9788
- if (!panel) return;
9789
- const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
9790
- const tg = panelToGroup.get(panelId);
9791
- const child = panel.view.createTabRenderer("headerOverflow").element;
9792
- const wrapper = document.createElement("div");
9793
- toggleClass(wrapper, "dv-tab", true);
9794
- toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
9795
- toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
9796
- if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
9797
- const doActivate = () => {
9798
- if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
9799
- tab === null || tab === void 0 || tab.element.scrollIntoView({
9800
- block: "nearest",
9801
- inline: "nearest"
10297
+ context: {
10298
+ overflowGroupIdForPanel: (panelId) => {
10299
+ var _panelToGroup$get;
10300
+ return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
10301
+ },
10302
+ buildGroupHeader: (tabGroupId) => {
10303
+ const tg = groupById.get(tabGroupId);
10304
+ if (!tg || !overflowGroupSet.has(tg.id)) return;
10305
+ return buildGroupHeader(tg);
10306
+ },
10307
+ buildPinnedHeader: () => {
10308
+ const header = document.createElement("div");
10309
+ header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
10310
+ const glyph = createPinButton();
10311
+ glyph.classList.add("dv-tabs-overflow-pinned-icon");
10312
+ header.appendChild(glyph);
10313
+ const labelSpan = document.createElement("span");
10314
+ labelSpan.className = "dv-tabs-overflow-group-label";
10315
+ labelSpan.textContent = "Pinned";
10316
+ header.appendChild(labelSpan);
10317
+ return header;
10318
+ },
10319
+ buildRow: (panelId) => {
10320
+ const panel = this.group.panels.find((p) => p.id === panelId);
10321
+ if (!panel) return;
10322
+ const tab = this.tabs.tabs.find((t) => t.panel.id === panelId);
10323
+ const tg = panelToGroup.get(panelId);
10324
+ const tabComponent = panel.view.createTabRenderer("headerOverflow");
10325
+ let rowDisposed = false;
10326
+ const disposeRow = Disposable.from(() => {
10327
+ if (!rowDisposed) {
10328
+ var _tabComponent$dispose;
10329
+ rowDisposed = true;
10330
+ (_tabComponent$dispose = tabComponent.dispose) === null || _tabComponent$dispose === void 0 || _tabComponent$dispose.call(tabComponent);
10331
+ }
9802
10332
  });
9803
- this.accessor.withOrigin("user", () => panel.api.setActive());
9804
- };
9805
- wrapper.addEventListener("click", (event) => {
9806
- popup().close();
9807
- if (event.defaultPrevented) return;
9808
- doActivate();
9809
- });
9810
- wrapper.appendChild(child);
9811
- return {
9812
- element: wrapper,
9813
- panel,
9814
- activate: () => {
10333
+ if (rowRenderers.isDisposed) disposeRow.dispose();
10334
+ else rowRenderers.addDisposables(disposeRow);
10335
+ const child = tabComponent.element;
10336
+ const wrapper = document.createElement("div");
10337
+ toggleClass(wrapper, "dv-tab", true);
10338
+ toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
10339
+ toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
10340
+ if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
10341
+ const doActivate = () => {
10342
+ if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
10343
+ tab === null || tab === void 0 || tab.element.scrollIntoView({
10344
+ block: "nearest",
10345
+ inline: "nearest"
10346
+ });
10347
+ this.accessor.withOrigin("user", () => panel.api.setActive());
10348
+ };
10349
+ wrapper.addEventListener("click", (event) => {
9815
10350
  popup().close();
10351
+ if (event.defaultPrevented) return;
9816
10352
  doActivate();
9817
- }
9818
- };
9819
- },
9820
- open: (body) => {
9821
- popup().openPopover(body, anchor);
10353
+ });
10354
+ wrapper.appendChild(child);
10355
+ return {
10356
+ element: wrapper,
10357
+ panel,
10358
+ activate: () => {
10359
+ popup().close();
10360
+ doActivate();
10361
+ },
10362
+ dispose: () => {
10363
+ rowRenderers.removeDisposable(disposeRow);
10364
+ disposeRow.dispose();
10365
+ }
10366
+ };
10367
+ },
10368
+ open: (body) => {
10369
+ popup().openPopover(body, anchor, { onClose: () => rowRenderers.dispose() });
10370
+ },
10371
+ close: () => popup().close(),
10372
+ focusTrigger: () => {
10373
+ root.tabIndex = -1;
10374
+ root.focus();
10375
+ }
9822
10376
  },
9823
- close: () => popup().close(),
9824
- focusTrigger: () => {
9825
- root.tabIndex = -1;
9826
- root.focus();
9827
- }
10377
+ rowRenderers
9828
10378
  };
9829
10379
  }
9830
10380
  /**
@@ -10080,8 +10630,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
10080
10630
  return this.tabsContainer.getPanelForTab(element);
10081
10631
  }
10082
10632
  get isContentFocused() {
10083
- if (!document.activeElement) return false;
10084
- return isAncestor(document.activeElement, this.contentContainer.element);
10633
+ const element = this.contentContainer.element;
10634
+ const activeElement = getActiveElement(element);
10635
+ if (!activeElement) return false;
10636
+ return isAncestor(activeElement, element);
10085
10637
  }
10086
10638
  get headerPosition() {
10087
10639
  var _this$_headerPosition;
@@ -10739,6 +11291,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
10739
11291
  this.tabsContainer.setRightActionsElement(element);
10740
11292
  }
10741
11293
  setActive(isGroupActive, force = false) {
11294
+ if (this.isDisposed) return;
10742
11295
  if (!force && this.isActive === isGroupActive) return;
10743
11296
  this._isGroupActive = isGroupActive;
10744
11297
  toggleClass(this.container, "dv-active-group", isGroupActive);
@@ -12992,6 +13545,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
12992
13545
  observer.observe(gridview.element);
12993
13546
  return { dispose: () => observer.disconnect() };
12994
13547
  }
13548
+ /**
13549
+ * Runs `work` after `delayMs`, resolving once it has finished. Work that
13550
+ * returns a promise is awaited, so a caller holding
13551
+ * `restorationPromise` waits for the popout window itself rather than
13552
+ * only for the timer that starts it.
13553
+ */
12995
13554
  scheduleRestoration(delayMs, work, onCancel) {
12996
13555
  return new Promise((resolve) => {
12997
13556
  const cleanup = () => {
@@ -13006,8 +13565,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
13006
13565
  resolve();
13007
13566
  return;
13008
13567
  }
13009
- work();
13010
- resolve();
13568
+ Promise.resolve(work()).then(() => resolve(), () => resolve());
13011
13569
  }, delayMs);
13012
13570
  this._restorationCleanups.add(cleanup);
13013
13571
  });
@@ -13778,13 +14336,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
13778
14336
  * menu passes the `tabGroup`. No-op when no renderer could be created (no
13779
14337
  * factory configured, or the factory declined the component).
13780
14338
  */
13781
- appendComponentItem(menuEl, item, identity, group, close) {
14339
+ appendComponentItem(menuEl, item, identity, group, close, renderers) {
13782
14340
  var _this$accessor$option4, _this$accessor$option5;
13783
14341
  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, {
13784
14342
  id: nextContextMenuItemId(),
13785
14343
  component: item.component
13786
14344
  });
13787
14345
  if (!renderer) return;
14346
+ renderers.addDisposables(renderer);
13788
14347
  renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
13789
14348
  group,
13790
14349
  api: this.accessor.api,
@@ -13835,9 +14394,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
13835
14394
  * default row; an item carrying none of the three renders nothing. Shared
13836
14395
  * by both menus, which differ only in `identity`.
13837
14396
  */
13838
- appendConfigItem(menuEl, item, identity, group, close) {
14397
+ appendConfigItem(menuEl, item, identity, group, close, renderers) {
13839
14398
  if (item.element) menuEl.appendChild(item.element);
13840
- else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
14399
+ else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close, renderers);
13841
14400
  else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
13842
14401
  var _item$action;
13843
14402
  return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
@@ -13849,22 +14408,28 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
13849
14408
  event.preventDefault();
13850
14409
  const popupService = this.accessor.getPopupServiceForGroup(group);
13851
14410
  const close = () => popupService.close();
14411
+ const renderers = new CompositeDisposable();
13852
14412
  const menuEl = document.createElement("div");
13853
14413
  menuEl.className = "dv-context-menu";
13854
14414
  menuEl.setAttribute("role", "menu");
13855
- for (const item of items) {
13856
- if (isItemConfig(item)) {
13857
- this.appendConfigItem(menuEl, item, { panel }, group, close);
13858
- continue;
14415
+ try {
14416
+ for (const item of items) {
14417
+ if (isItemConfig(item)) {
14418
+ this.appendConfigItem(menuEl, item, { panel }, group, close, renderers);
14419
+ continue;
14420
+ }
14421
+ const el = this.buildBuiltInTabItem(item, panel, group, close);
14422
+ if (el) menuEl.appendChild(el);
13859
14423
  }
13860
- const el = this.buildBuiltInTabItem(item, panel, group, close);
13861
- if (el) menuEl.appendChild(el);
14424
+ } catch (err) {
14425
+ renderers.dispose();
14426
+ throw err;
13862
14427
  }
13863
14428
  popupService.openPopover(menuEl, {
13864
14429
  x: event.clientX,
13865
14430
  y: event.clientY,
13866
14431
  zIndex: popoverZIndexFor(event.target, group)
13867
- });
14432
+ }, { onClose: () => renderers.dispose() });
13868
14433
  }
13869
14434
  showForChip(tabGroup, group, event) {
13870
14435
  if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
@@ -13878,22 +14443,28 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
13878
14443
  event.preventDefault();
13879
14444
  const popupService = this.accessor.getPopupServiceForGroup(group);
13880
14445
  const close = () => popupService.close();
14446
+ const renderers = new CompositeDisposable();
13881
14447
  const menuEl = document.createElement("div");
13882
14448
  menuEl.className = "dv-context-menu";
13883
14449
  menuEl.setAttribute("role", "menu");
13884
- for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
13885
- else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
13886
- else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
13887
- else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
13888
- else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
13889
- group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
13890
- }));
13891
- else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
14450
+ try {
14451
+ for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
14452
+ else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
14453
+ else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
14454
+ else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
14455
+ else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
14456
+ group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
14457
+ }));
14458
+ else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close, renderers);
14459
+ } catch (err) {
14460
+ renderers.dispose();
14461
+ throw err;
14462
+ }
13892
14463
  popupService.openPopover(menuEl, {
13893
14464
  x: event.clientX,
13894
14465
  y: event.clientY,
13895
14466
  zIndex: popoverZIndexFor(event.target, group)
13896
- });
14467
+ }, { onClose: () => renderers.dispose() });
13897
14468
  }
13898
14469
  };
13899
14470
  const ContextMenuModule = defineModule({
@@ -14183,6 +14754,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14183
14754
  const observerDisposable = new MutableDisposable();
14184
14755
  const correctLayerPosition = () => {
14185
14756
  if (panel.api.location.type === "floating") queueMicrotask(() => {
14757
+ if (disposable.isDisposed) return;
14186
14758
  const floatingGroup = this.accessor.getFloatingWindowForGroup(panel.api.group);
14187
14759
  if (!floatingGroup) return;
14188
14760
  const element = floatingGroup.overlay.element;
@@ -14265,188 +14837,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14265
14837
  }
14266
14838
  };
14267
14839
 
14268
- //#endregion
14269
- //#region \0@oxc-project+runtime@0.139.0/helpers/esm/asyncToGenerator.js
14270
- function asyncGeneratorStep(n, t, e, r, o, a, c) {
14271
- try {
14272
- var i = n[a](c), u = i.value;
14273
- } catch (n) {
14274
- e(n);
14275
- return;
14276
- }
14277
- i.done ? t(u) : Promise.resolve(u).then(r, o);
14278
- }
14279
- function _asyncToGenerator(n) {
14280
- return function() {
14281
- var t = this, e = arguments;
14282
- return new Promise(function(r, o) {
14283
- var a = n.apply(t, e);
14284
- function _next(n) {
14285
- asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
14286
- }
14287
- function _throw(n) {
14288
- asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
14289
- }
14290
- _next(void 0);
14291
- });
14292
- };
14293
- }
14294
-
14295
- //#endregion
14296
- //#region src/popoutWindow.ts
14297
- /**
14298
- * Reject popout URLs that aren't same-origin http(s). Blocks `javascript:`,
14299
- * `data:`, `blob:`, `vbscript:`, and cross-origin URLs that would otherwise
14300
- * execute in a context the browser still associates with the opener via
14301
- * `window.opener`.
14302
- */
14303
- function assertSameOriginPopoutUrl(url) {
14304
- let resolved;
14305
- try {
14306
- resolved = new URL(url, globalThis.location.href);
14307
- } catch (_unused) {
14308
- throw new Error(`dockview: invalid popout URL: ${url}`);
14309
- }
14310
- 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}`);
14311
- }
14312
- var PopoutWindow = class extends CompositeDisposable {
14313
- get window() {
14314
- var _this$_window$value, _this$_window;
14315
- 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;
14316
- }
14317
- constructor(target, className, options) {
14318
- super();
14319
- this.target = target;
14320
- this.className = className;
14321
- this.options = options;
14322
- this._onWillClose = new Emitter();
14323
- this.onWillClose = this._onWillClose.event;
14324
- this._onDidClose = new Emitter();
14325
- this.onDidClose = this._onDidClose.event;
14326
- this._window = null;
14327
- this.addDisposables(this._onWillClose, this._onDidClose, { dispose: () => {
14328
- this.close();
14329
- } });
14330
- }
14331
- dimensions() {
14332
- if (!this._window) return null;
14333
- const left = this._window.value.screenX;
14334
- return {
14335
- top: this._window.value.screenY,
14336
- left,
14337
- width: this._window.value.innerWidth,
14338
- height: this._window.value.innerHeight
14339
- };
14340
- }
14341
- close() {
14342
- if (this._window) {
14343
- var _this$options$onWillC, _this$options;
14344
- this._onWillClose.fire();
14345
- (_this$options$onWillC = (_this$options = this.options).onWillClose) === null || _this$options$onWillC === void 0 || _this$options$onWillC.call(_this$options, {
14346
- id: this.target,
14347
- window: this._window.value
14348
- });
14349
- this._window.disposable.dispose();
14350
- this._window = null;
14351
- this._onDidClose.fire();
14352
- }
14353
- }
14354
- open() {
14355
- var _this = this;
14356
- return _asyncToGenerator(function* () {
14357
- var _this$options$onDidOp, _this$options2;
14358
- if (_this._window) throw new Error("instance of popout window is already open");
14359
- const url = `${_this.options.url}`;
14360
- assertSameOriginPopoutUrl(url);
14361
- const features = Object.entries({
14362
- top: _this.options.top,
14363
- left: _this.options.left,
14364
- width: _this.options.width,
14365
- height: _this.options.height
14366
- }).map(([key, value]) => `${key}=${value}`).join(",");
14367
- /**
14368
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
14369
- */
14370
- const externalWindow = window.open(url, _this.target, features);
14371
- if (!externalWindow)
14372
- /**
14373
- * Popup blocked
14374
- */
14375
- return null;
14376
- const disposable = new CompositeDisposable();
14377
- _this._window = {
14378
- value: externalWindow,
14379
- disposable
14380
- };
14381
- disposable.addDisposables(Disposable.from(() => {
14382
- externalWindow.close();
14383
- }), addDisposableListener(globalThis.window, "beforeunload", () => {
14384
- /**
14385
- * before the main window closes we should close this popup too
14386
- * to be good citizens
14387
- *
14388
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14389
- */
14390
- _this.close();
14391
- }));
14392
- const container = _this.createPopoutWindowContainer();
14393
- if (_this.className) container.classList.add(_this.className);
14394
- (_this$options$onDidOp = (_this$options2 = _this.options).onDidOpen) === null || _this$options$onDidOp === void 0 || _this$options$onDidOp.call(_this$options2, {
14395
- id: _this.target,
14396
- window: externalWindow
14397
- });
14398
- return new Promise((resolve, reject) => {
14399
- externalWindow.addEventListener("unload", () => {});
14400
- /**
14401
- * `load` is the only event that resolves this promise with a
14402
- * container, so a window that goes away first would leave the
14403
- * caller awaiting a promise that never settles - and
14404
- * `addPopoutGroup` holds its layout transaction open until it does.
14405
- * Settle with `null` on close, the same signal a blocked popup
14406
- * gives and one the caller already handles. `resolve` after the
14407
- * fact is a no-op, so a `load` that arrived first still wins.
14408
- */
14409
- disposable.addDisposables(_this.onWillClose(() => resolve(null)));
14410
- externalWindow.addEventListener("load", () => {
14411
- /**
14412
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
14413
- */
14414
- try {
14415
- const externalDocument = externalWindow.document;
14416
- externalDocument.title = document.title;
14417
- externalDocument.body.appendChild(container);
14418
- addStyles(externalDocument, globalThis.document.styleSheets, { nonce: _this.options.nonce });
14419
- /**
14420
- * beforeunload must be registered after load for reasons I could not determine
14421
- * otherwise the beforeunload event will not fire when the window is closed
14422
- */
14423
- addDisposableListener(externalWindow, "beforeunload", () => {
14424
- /**
14425
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
14426
- */
14427
- _this.close();
14428
- });
14429
- resolve(container);
14430
- } catch (err) {
14431
- reject(err);
14432
- }
14433
- });
14434
- });
14435
- })();
14436
- }
14437
- createPopoutWindowContainer() {
14438
- const el = document.createElement("div");
14439
- el.classList.add("dv-popout-window");
14440
- el.id = "dv-popout-window";
14441
- el.style.position = "absolute";
14442
- el.style.width = "100%";
14443
- el.style.height = "100%";
14444
- el.style.top = "0px";
14445
- el.style.left = "0px";
14446
- return el;
14447
- }
14448
- };
14449
-
14450
14840
  //#endregion
14451
14841
  //#region src/dockview/strictEventsSequencing.ts
14452
14842
  var StrictEventsSequencing = class extends CompositeDisposable {
@@ -14490,8 +14880,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14490
14880
  * peeks): while it lives it watches a configurable set of dismiss signals
14491
14881
  * (Escape / extra keys, outside-pointerdown with an optional grace window,
14492
14882
  * window resize, focus moving outside) and calls `onDismiss`. Inside/outside is
14493
- * decided by an `isInside` predicate (geometry) or a `contains` check against
14494
- * `elements`. Dispose to detach every listener.
14883
+ * decided by an `isInside` predicate (geometry) or by checking the event's
14884
+ * composed path against `elements`. Dispose to detach every listener.
14495
14885
  *
14496
14886
  * It owns only the *signals*, not the surface element, its position, or any
14497
14887
  * hover/keep-open policy, so callers keep their own element lifecycle and
@@ -14511,9 +14901,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14511
14901
  const isInside = (event) => {
14512
14902
  var _options$elements, _options$elements2;
14513
14903
  if (options.isInside) return options.isInside(event);
14514
- const target = event.target;
14515
- if (!(target instanceof Node)) return false;
14516
- 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));
14904
+ 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 : []);
14517
14905
  };
14518
14906
  if (escape || keys.length > 0) disposables.addDisposables(addDisposableListener(win, "keydown", (event) => {
14519
14907
  if (escape && event.key === "Escape" || keys.includes(event.key)) options.onDismiss();
@@ -14532,17 +14920,45 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14532
14920
  options.onDismiss();
14533
14921
  }));
14534
14922
  if (options.focusOut) {
14535
- const isFocusInside = (focused) => {
14536
- var _options$elements3, _options$elements4;
14537
- if (options.isFocusInside) return options.isFocusInside(focused);
14538
- 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));
14923
+ /** A node in the layer's own tree, to scope retargeting and to locate
14924
+ * the shadow roots to listen on. */
14925
+ const layerScope = () => {
14926
+ var _options$anchor, _options$anchor2, _options$elements3;
14927
+ 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];
14539
14928
  };
14929
+ const seen = /* @__PURE__ */ new WeakSet();
14540
14930
  const onFocusIn = (event) => {
14931
+ var _options$elements4, _options$elements5;
14932
+ if (seen.has(event)) return;
14933
+ seen.add(event);
14541
14934
  const target = event.target;
14542
- if (target instanceof Element && !isFocusInside(target)) options.onDismiss();
14935
+ if (!(target instanceof Element)) return;
14936
+ 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();
14543
14937
  };
14544
- win.addEventListener("focusin", onFocusIn, capture);
14545
- disposables.addDisposables({ dispose: () => win.removeEventListener("focusin", onFocusIn, capture) });
14938
+ const bound = /* @__PURE__ */ new Map();
14939
+ const syncShadowRoots = () => {
14940
+ var _options$anchor3, _options$elements6, _options$elements7;
14941
+ const wanted = /* @__PURE__ */ new Set();
14942
+ const anchor = (_options$anchor3 = options.anchor) === null || _options$anchor3 === void 0 ? void 0 : _options$anchor3.call(options);
14943
+ 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] : []];
14944
+ for (const node of sources) for (const root of shadowRootsOf(node)) wanted.add(root);
14945
+ for (const [root, listener] of bound) if (!wanted.has(root)) {
14946
+ listener.dispose();
14947
+ bound.delete(root);
14948
+ }
14949
+ for (const root of wanted) {
14950
+ if (bound.has(root)) continue;
14951
+ bound.set(root, addDisposableListener(root, "focusin", onFocusIn, capture));
14952
+ }
14953
+ };
14954
+ disposables.addDisposables(addDisposableListener(win, "focusin", (event) => {
14955
+ syncShadowRoots();
14956
+ onFocusIn(event);
14957
+ }, capture), { dispose: () => {
14958
+ for (const [, listener] of bound) listener.dispose();
14959
+ bound.clear();
14960
+ } });
14961
+ syncShadowRoots();
14546
14962
  }
14547
14963
  return disposables;
14548
14964
  }
@@ -14573,7 +14989,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14573
14989
  newRoot.prepend(this._element);
14574
14990
  this._root = newRoot;
14575
14991
  }
14576
- openPopover(element, position) {
14992
+ openPopover(element, position, options) {
14577
14993
  var _position$zIndex;
14578
14994
  this.close();
14579
14995
  const wrapper = this._window.document.createElement("div");
@@ -14588,14 +15004,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
14588
15004
  this._element.appendChild(wrapper);
14589
15005
  this._active = wrapper;
14590
15006
  const POINTERDOWN_GRACE_MS = 200;
14591
- this._activeDisposable.value = createDismissableLayer({
15007
+ this._activeDisposable.value = new CompositeDisposable(createDismissableLayer({
14592
15008
  window: this._window,
14593
15009
  onDismiss: () => this.close(),
14594
15010
  elements: () => this._active ? [this._active] : [],
14595
15011
  keys: ["Enter"],
14596
15012
  pointerDownGraceMs: POINTERDOWN_GRACE_MS,
14597
15013
  resize: true
14598
- });
15014
+ }), (options === null || options === void 0 ? void 0 : options.onClose) ? Disposable.from(options.onClose) : Disposable.NONE);
14599
15015
  this._window.requestAnimationFrame(() => {
14600
15016
  shiftAbsoluteElementIntoView(wrapper, this._root);
14601
15017
  });
@@ -15035,6 +15451,24 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15035
15451
  this.updateTheme(this._gap, this._defaultCollapsedSize);
15036
15452
  return view;
15037
15453
  }
15454
+ /**
15455
+ * Lay out from the shell's current size.
15456
+ *
15457
+ * The ResizeObserver above only reports asynchronously, so between
15458
+ * construction and its first callback the shell believes it has no size -
15459
+ * and any layout built in that window (panels added straight after
15460
+ * `createDockview`, say) resolves its sizes against zero and collapses to
15461
+ * minimums, permanently. Seeding the size synchronously gives that work
15462
+ * the real dimensions. Same guards as the observer: a detached or hidden
15463
+ * shell has no size worth propagating.
15464
+ */
15465
+ layoutFromElement() {
15466
+ if (!this._shellElement.offsetParent || !isInDocument(this._shellElement)) return;
15467
+ const width = Math.round(this._shellElement.clientWidth);
15468
+ const height = Math.round(this._shellElement.clientHeight);
15469
+ if (width === 0 || height === 0) return;
15470
+ this.layout(width, height);
15471
+ }
15038
15472
  layout(width, height) {
15039
15473
  this._outerSplitview.layout(width, height);
15040
15474
  this._flushPendingSizes();
@@ -15294,6 +15728,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15294
15728
 
15295
15729
  //#endregion
15296
15730
  //#region src/dockview/dockviewComponent.ts
15731
+ /**
15732
+ * An error says the most about why, so it wins; a blocked window has none, and
15733
+ * its usual cause is more useful than its name.
15734
+ */
15735
+ function logFailedPopout(failure) {
15736
+ if (failure.error) console.error("dockview: failed to create popout.", failure.error);
15737
+ else if (failure.reason === "blocked") console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
15738
+ else console.error(`dockview: failed to create popout (${failure.reason}).`);
15739
+ }
15297
15740
  function buildTabGroupColorPalette(options) {
15298
15741
  var _options$tabGroupColo;
15299
15742
  return new TabGroupColorPalette((_options$tabGroupColo = options.tabGroupColors) !== null && _options$tabGroupColo !== void 0 ? _options$tabGroupColo : DEFAULT_TAB_GROUP_COLORS, options.tabGroupAccent !== "off");
@@ -15345,6 +15788,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15345
15788
  get panels() {
15346
15789
  return this.groups.flatMap((group) => group.panels);
15347
15790
  }
15791
+ /** `dndStrategy` resolved against this device; see `DockviewApi`. */
15792
+ get dndCapabilities() {
15793
+ return resolveDndCapabilities(this.options);
15794
+ }
15348
15795
  get options() {
15349
15796
  return this._options;
15350
15797
  }
@@ -15854,9 +16301,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15854
16301
  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();
15855
16302
  }
15856
16303
  constructor(container, options) {
15857
- var _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
16304
+ var _options$proportional, _options$theme$gap, _options$theme, _options$theme$gap2, _options$theme2, _options$theme3;
15858
16305
  super(container, {
15859
- proportionalLayout: true,
16306
+ proportionalLayout: (_options$proportional = options.proportionalLayout) !== null && _options$proportional !== void 0 ? _options$proportional : true,
15860
16307
  orientation: "HORIZONTAL",
15861
16308
  styles: options.hideBorders ? { separatorBorder: "transparent" } : void 0,
15862
16309
  disableAutoResizing: options.disableAutoResizing,
@@ -15876,7 +16323,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15876
16323
  this._onWillDrop = new Emitter();
15877
16324
  this.onWillDrop = this._onWillDrop.event;
15878
16325
  this._mutationDepth = 0;
16326
+ this._syncMutationDepth = 0;
15879
16327
  this._pendingLocationChanges = /* @__PURE__ */ new Map();
16328
+ this._openingPopoutWindows = /* @__PURE__ */ new Set();
15880
16329
  this._origin = "user";
15881
16330
  this._originDepth = 0;
15882
16331
  this._onWillMutateLayout = new Emitter();
@@ -15903,6 +16352,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15903
16352
  this.onDidChangePopouts = this._onDidChangePopouts.event;
15904
16353
  this._onDidOpenPopoutWindowFail = new Emitter();
15905
16354
  this.onDidOpenPopoutWindowFail = this._onDidOpenPopoutWindowFail.event;
16355
+ this._onWillClosePopoutWindow = new Emitter();
16356
+ this.onWillClosePopoutWindow = this._onWillClosePopoutWindow.event;
15906
16357
  this._onDidStartFloatingGroupDrag = new Emitter();
15907
16358
  this.onDidStartFloatingGroupDrag = this._onDidStartFloatingGroupDrag.event;
15908
16359
  this._onDidEndFloatingGroupDrag = new Emitter();
@@ -15958,6 +16409,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
15958
16409
  });
15959
16410
  }));
15960
16411
  this.popupService = new PopupService(this.element);
16412
+ this.addDisposables(this.popupService, Disposable.from(() => {
16413
+ for (const opening of this._openingPopoutWindows) opening.dispose();
16414
+ this._openingPopoutWindows.clear();
16415
+ }));
15961
16416
  this._api = new DockviewApi(this);
15962
16417
  this.disableResizing = true;
15963
16418
  this.element.remove();
@@ -16004,7 +16459,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16004
16459
  var _this$_shellManager2;
16005
16460
  this._moduleRegistry.dispose();
16006
16461
  (_this$_shellManager2 = this._shellManager) === null || _this$_shellManager2 === void 0 || _this$_shellManager2.dispose();
16007
- }));
16462
+ }), this._onWillClosePopoutWindow);
16008
16463
  const rootDropTarget = this._rootDropTargetService;
16009
16464
  if (rootDropTarget) this.addDisposables(rootDropTarget.onWillShowOverlay((event) => {
16010
16465
  if (this.gridview.length > 0 && event.position === "center") return;
@@ -16017,6 +16472,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16017
16472
  }));
16018
16473
  }), rootDropTarget.onDrop((event) => this.dockToLayoutEdge(event.nativeEvent, event.position)));
16019
16474
  this._moduleRegistry.postConstruct(this);
16475
+ this._shellManager.layoutFromElement();
16020
16476
  }
16021
16477
  setVisible(panel, visible) {
16022
16478
  switch (panel.api.location.type) {
@@ -16086,22 +16542,42 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16086
16542
  const box = getBox();
16087
16543
  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();
16088
16544
  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;
16545
+ const popoutUrl = resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html";
16089
16546
  const _window = new PopoutWindow(`${this.id}-${groupId}`, theme !== null && theme !== void 0 ? theme : "", {
16090
- url: resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : "/popout.html",
16547
+ url: popoutUrl,
16091
16548
  left: box.left,
16092
16549
  top: box.top,
16093
16550
  width: box.width,
16094
16551
  height: box.height,
16095
16552
  onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
16096
- onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
16097
- nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce
16553
+ onWillClose: (event) => {
16554
+ var _options$onWillClose;
16555
+ options === null || options === void 0 || (_options$onWillClose = options.onWillClose) === null || _options$onWillClose === void 0 || _options$onWillClose.call(options, event);
16556
+ this._onWillClosePopoutWindow.fire(event);
16557
+ },
16558
+ nonce: (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.nonce,
16559
+ styleRoot: () => this.element.getRootNode()
16098
16560
  });
16099
16561
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
16100
16562
  popoutWindowDisposable.dispose();
16101
16563
  }));
16102
- return _window.open().then((popoutContainer) => {
16564
+ this._openingPopoutWindows.add(popoutWindowDisposable);
16565
+ const openError = getPopoutUrlError(popoutUrl);
16566
+ return (openError ? Promise.resolve(null) : _window.open()).then((popoutContainer) => {
16103
16567
  var _options$referenceGro, _options$overridePopo4;
16104
- if (_window.isDisposed) return false;
16568
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16569
+ if (this.isDisposed) {
16570
+ popoutWindowDisposable.dispose();
16571
+ return false;
16572
+ }
16573
+ if (_window.isDisposed) {
16574
+ const failure = _window.failure;
16575
+ if (failure && !this.isDisposed) {
16576
+ logFailedPopout(failure);
16577
+ this._onDidOpenPopoutWindowFail.fire(failure);
16578
+ }
16579
+ return false;
16580
+ }
16105
16581
  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;
16106
16582
  const referenceLocation = itemToPopout.api.location.type;
16107
16583
  /**
@@ -16120,11 +16596,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16120
16596
  if (popoutContainer) this._onDidAddGroup.fire(group);
16121
16597
  }
16122
16598
  if (popoutContainer === null) {
16599
+ var _window$failure;
16123
16600
  this.handleBlockedPopout({
16124
16601
  group,
16125
16602
  referenceGroup,
16126
16603
  options,
16127
- popoutWindowDisposable
16604
+ popoutWindowDisposable,
16605
+ failure: openError ? {
16606
+ reason: "url-refused",
16607
+ error: openError
16608
+ } : (_window$failure = _window.failure) !== null && _window$failure !== void 0 ? _window$failure : { reason: "blocked" }
16128
16609
  });
16129
16610
  return false;
16130
16611
  }
@@ -16282,21 +16763,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16282
16763
  for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
16283
16764
  return true;
16284
16765
  }).catch((err) => {
16766
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
16285
16767
  console.error("dockview: failed to create popout.", err);
16286
16768
  return false;
16287
16769
  });
16288
16770
  }
16289
16771
  /**
16290
- * The popout window was blocked (e.g. by the browser's popup blocker,
16291
- * common when restoring popouts on load). Fall back gracefully so the
16292
- * group(s) end up valid and visible in the main grid rather than as
16293
- * orphans that later crash clear()/remove().
16772
+ * The popout window never opened - blocked by the browser's popup blocker
16773
+ * (common when restoring popouts on load), or refused outright because its
16774
+ * URL failed the same-origin guard. Fall back gracefully so the group(s)
16775
+ * end up valid and visible in the main grid rather than as orphans that
16776
+ * render nothing and later crash clear()/remove().
16294
16777
  */
16295
16778
  handleBlockedPopout(params) {
16296
- const { group, referenceGroup, options, popoutWindowDisposable } = params;
16297
- console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
16779
+ const { group, referenceGroup, options, popoutWindowDisposable, failure } = params;
16780
+ logFailedPopout(failure);
16298
16781
  popoutWindowDisposable.dispose();
16299
- this._onDidOpenPopoutWindowFail.fire();
16782
+ this._onDidOpenPopoutWindowFail.fire(failure);
16300
16783
  if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
16301
16784
  const blockedGridview = options.overridePopoutGridview;
16302
16785
  const members = this.groups.filter((candidate) => blockedGridview.element.contains(candidate.element));
@@ -16530,12 +17013,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16530
17013
  if (group.model.size === 0) this.doRemoveGroup(group, { skipActive: true });
16531
17014
  }
16532
17015
  /**
16533
- * Build an empty gridview configured to match the main grid's styling, for
16534
- * hosting a nested layout inside a floating or popout window.
17016
+ * Build an empty gridview configured to match the main grid's styling and
17017
+ * resize behaviour, for hosting a nested layout inside a floating or popout
17018
+ * window.
16535
17019
  */
16536
17020
  createNestedGridview(orientation = "HORIZONTAL") {
16537
17021
  var _this$options$theme$g, _this$options$theme2;
16538
- 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);
17022
+ 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);
16539
17023
  }
16540
17024
  /**
16541
17025
  * Wrap a (populated) floating gridview in an overlay window: title bar /
@@ -16608,6 +17092,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16608
17092
  const newDisableDnd = this.options.disableDnd;
16609
17093
  const newDndStrategy = this.options.dndStrategy;
16610
17094
  if (oldDisableDnd !== newDisableDnd || oldDndStrategy !== newDndStrategy) this.updateDragAndDropState();
17095
+ if ("proportionalLayout" in options) {
17096
+ var _this$_popoutWindowSe9, _this$_popoutWindowSe10;
17097
+ const proportionalLayout = this.gridview.proportionalLayout;
17098
+ for (const floating of this.floatingGroups) floating.gridview.proportionalLayout = proportionalLayout;
17099
+ 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;
17100
+ }
16611
17101
  if ("theme" in options) this.updateTheme();
16612
17102
  if ("createRightHeaderActionComponent" in options || "createLeftHeaderActionComponent" in options || "createPrefixHeaderActionComponent" in options) {
16613
17103
  var _this$headerActionsSe;
@@ -16813,6 +17303,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16813
17303
  group.dispose();
16814
17304
  this._groups.delete(group.id);
16815
17305
  this._onDidRemoveGroup.fire(group);
17306
+ this.activateFallbackGroupIfRemoved(group);
16816
17307
  });
16817
17308
  }
16818
17309
  setEdgeGroupCollapsed(group, collapsed) {
@@ -16915,14 +17406,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16915
17406
  * @returns A JSON respresentation of the layout
16916
17407
  */
16917
17408
  toJSON() {
16918
- var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe9, _this$_popoutWindowSe10, _this$activeGroup2;
17409
+ var _this$_floatingGroupS3, _this$_floatingGroupS4, _this$_popoutWindowSe11, _this$_popoutWindowSe12, _this$activeGroup2;
16919
17410
  const data = this.gridview.serialize();
16920
17411
  const panels = this.panels.reduce((collection, panel) => {
16921
17412
  collection[panel.id] = panel.toJSON();
16922
17413
  return collection;
16923
17414
  }, {});
16924
17415
  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 : [];
16925
- 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 : [];
17416
+ 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 : [];
16926
17417
  const result = {
16927
17418
  grid: data,
16928
17419
  panels,
@@ -16961,8 +17452,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
16961
17452
  this.mutation("load", () => this._doFromJSON(data, options));
16962
17453
  }
16963
17454
  _doFromJSON(data, options) {
16964
- var _this$_popoutWindowSe11, _data$grid$root;
16965
- (_this$_popoutWindowSe11 = this._popoutWindowService) === null || _this$_popoutWindowSe11 === void 0 || _this$_popoutWindowSe11.cancelPendingRestorations();
17455
+ var _this$_popoutWindowSe13, _data$grid$root;
17456
+ (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 || _this$_popoutWindowSe13.cancelPendingRestorations();
16966
17457
  if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
16967
17458
  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");
16968
17459
  const existingPanels = /* @__PURE__ */ new Map();
@@ -17009,6 +17500,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17009
17500
  const record = this._groups.get(temporaryGroup.api.id);
17010
17501
  this._groups.delete(temporaryGroup.api.id);
17011
17502
  temporaryGroupDisposables.push(Disposable.from(() => {
17503
+ var _this$headerActionsSe2;
17012
17504
  /**
17013
17505
  * Reclaim the group's own resources, never its panels.
17014
17506
  * Staging is driven by the ids in `data.panels` while
@@ -17026,6 +17518,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17026
17518
  for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
17027
17519
  });
17028
17520
  record === null || record === void 0 || record.disposable.dispose();
17521
+ (_this$headerActionsSe2 = this.headerActionsService) === null || _this$headerActionsSe2 === void 0 || _this$headerActionsSe2.disposeGroup(temporaryGroup);
17029
17522
  temporaryGroup.dispose();
17030
17523
  }));
17031
17524
  return temporaryGroup;
@@ -17081,7 +17574,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17081
17574
  } else this.clear();
17082
17575
  const { grid, panels, activeGroup } = data;
17083
17576
  try {
17084
- var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
17577
+ var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe14, _this$_floatingGroupS5, _this$_watermarkServi2;
17085
17578
  const width = this.width;
17086
17579
  const height = this.height;
17087
17580
  const createGroupFromSerializedState = (data) => {
@@ -17146,7 +17639,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17146
17639
  if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
17147
17640
  this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
17148
17641
  const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
17149
- (_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
17642
+ (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 || _this$_popoutWindowSe14.finishRestoration(popoutPromises);
17150
17643
  (_this$_floatingGroupS5 = this._floatingGroupService) === null || _this$_floatingGroupS5 === void 0 || _this$_floatingGroupS5.constrainBounds();
17151
17644
  if (typeof activeGroup === "string") {
17152
17645
  const panel = this.getPanel(activeGroup);
@@ -17314,15 +17807,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17314
17807
  }
17315
17808
  }
17316
17809
  const group = grid ? members[0] : createGroup(data);
17317
- return popoutService.scheduleRestoration(index * 100, () => {
17318
- this.addPopoutGroup(group, {
17319
- position: position !== null && position !== void 0 ? position : void 0,
17320
- overridePopoutGroup: gridReferenceGroup ? group : void 0,
17321
- overridePopoutGridview,
17322
- referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17323
- popoutUrl: url
17324
- });
17325
- }, () => {
17810
+ return popoutService.scheduleRestoration(index * 100, () => this.addPopoutGroup(group, {
17811
+ position: position !== null && position !== void 0 ? position : void 0,
17812
+ overridePopoutGroup: gridReferenceGroup ? group : void 0,
17813
+ overridePopoutGridview,
17814
+ referenceGroup: gridReferenceGroup ? this.getPanel(gridReferenceGroup) : void 0,
17815
+ popoutUrl: url
17816
+ }), () => {
17326
17817
  for (const orphan of members.length > 0 ? members : [group]) if (!this.isDisposed && this._groups.has(orphan.id) && orphan.element.parentElement === null) {
17327
17818
  for (const panel of [...orphan.panels]) this.removePanel(panel, { removeEmptyGroup: false });
17328
17819
  orphan.dispose();
@@ -17557,7 +18048,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17557
18048
  * window.
17558
18049
  */
17559
18050
  detachFromNestedWindow(group) {
17560
- var _this$_floatingGroupS7, _this$_popoutWindowSe13;
18051
+ var _this$_floatingGroupS7, _this$_popoutWindowSe15;
17561
18052
  const floating = (_this$_floatingGroupS7 = this._floatingGroupService) === null || _this$_floatingGroupS7 === void 0 ? void 0 : _this$_floatingGroupS7.findByGroup(group);
17562
18053
  if (floating) {
17563
18054
  const members = this.nestedWindowMembers(group);
@@ -17566,7 +18057,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17566
18057
  if (floating.group === group) floating.setAnchorGroup(members.find((m) => m !== group));
17567
18058
  return true;
17568
18059
  }
17569
- const popout = (_this$_popoutWindowSe13 = this._popoutWindowService) === null || _this$_popoutWindowSe13 === void 0 ? void 0 : _this$_popoutWindowSe13.findByGroup(group);
18060
+ const popout = (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 ? void 0 : _this$_popoutWindowSe15.findByGroup(group);
17570
18061
  if (popout) {
17571
18062
  const members = this.nestedWindowMembers(group);
17572
18063
  if (members.length <= 1) return false;
@@ -17623,8 +18114,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17623
18114
  return group;
17624
18115
  }
17625
18116
  if (group.api.location.type === "popout") {
17626
- var _this$_popoutWindowSe14, _this$_popoutWindowSe15;
17627
- const selectedGroup = (_this$_popoutWindowSe14 = this._popoutWindowService) === null || _this$_popoutWindowSe14 === void 0 ? void 0 : _this$_popoutWindowSe14.findByGroup(group);
18117
+ var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18118
+ const selectedGroup = (_this$_popoutWindowSe16 = this._popoutWindowService) === null || _this$_popoutWindowSe16 === void 0 ? void 0 : _this$_popoutWindowSe16.findByGroup(group);
17628
18119
  if (!selectedGroup) throw new Error("dockview: failed to find popout group");
17629
18120
  if (this.detachFromNestedWindow(group)) {
17630
18121
  if (options === null || options === void 0 ? void 0 : options.skipDispose) group.model.location = { type: "grid" };
@@ -17641,7 +18132,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17641
18132
  this._groups.delete(group.id);
17642
18133
  this._onDidRemoveGroup.fire(group);
17643
18134
  }
17644
- (_this$_popoutWindowSe15 = this._popoutWindowService) === null || _this$_popoutWindowSe15 === void 0 || _this$_popoutWindowSe15.remove(selectedGroup);
18135
+ (_this$_popoutWindowSe17 = this._popoutWindowService) === null || _this$_popoutWindowSe17 === void 0 || _this$_popoutWindowSe17.remove(selectedGroup);
17645
18136
  const removedGroup = selectedGroup.disposable.dispose();
17646
18137
  if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
17647
18138
  this.doAddGroup(removedGroup, [0]);
@@ -17668,10 +18159,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17668
18159
  debouncedUpdateAllPositions() {
17669
18160
  if (this._updatePositionsFrameId !== void 0) cancelAnimationFrame(this._updatePositionsFrameId);
17670
18161
  this._updatePositionsFrameId = requestAnimationFrame(() => {
17671
- var _this$_popoutWindowSe16, _this$_popoutWindowSe17;
18162
+ var _this$_popoutWindowSe18, _this$_popoutWindowSe19;
17672
18163
  this._updatePositionsFrameId = void 0;
17673
18164
  this.overlayRenderContainer.updateAllPositions();
17674
- 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();
18165
+ 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();
17675
18166
  });
17676
18167
  }
17677
18168
  movingLock(func) {
@@ -17692,9 +18183,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17692
18183
  */
17693
18184
  mutation(kind, func) {
17694
18185
  const close = this.openMutation(kind);
18186
+ this._syncMutationDepth++;
17695
18187
  try {
17696
18188
  return func();
17697
18189
  } finally {
18190
+ this._syncMutationDepth--;
18191
+ if (this._syncMutationDepth === 0) this.releaseDisposedActiveGroup();
17698
18192
  close();
17699
18193
  }
17700
18194
  }
@@ -17741,6 +18235,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17741
18235
  return () => {
17742
18236
  this._mutationDepth--;
17743
18237
  if (this._mutationDepth === 0) {
18238
+ this.releaseDisposedActiveGroup();
17744
18239
  this.flushLocationChanges();
17745
18240
  this._onDidMutateLayout.fire({
17746
18241
  kind,
@@ -17749,6 +18244,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17749
18244
  }
17750
18245
  };
17751
18246
  }
18247
+ /** Covers removals with `skipActive` that disposed the active group. */
18248
+ releaseDisposedActiveGroup() {
18249
+ var _this$_activeGroup;
18250
+ if (!this.isDisposed && ((_this$_activeGroup = this._activeGroup) === null || _this$_activeGroup === void 0 ? void 0 : _this$_activeGroup.model.isDisposed)) this.activateFallbackGroupIfRemoved(this._activeGroup);
18251
+ }
17752
18252
  /**
17753
18253
  * Coalesce a panel's `onDidLocationChange` to the end of the enclosing
17754
18254
  * transaction, or fire it immediately when no transaction is in flight.
@@ -17886,7 +18386,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17886
18386
  skipSetActiveGroup: true
17887
18387
  }));
17888
18388
  if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
17889
- if (!options.keepEmptyGroups && sourceGroup.model.size === 0) this.doRemoveGroup(sourceGroup, { skipActive: true });
18389
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== destinationGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
17890
18390
  const isDestinationGroupEmpty = destinationGroup.model.size === 0;
17891
18391
  this.movingLock(() => {
17892
18392
  var _options$skipSetActiv;
@@ -17921,7 +18421,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17921
18421
  }
17922
18422
  }
17923
18423
  if (sourceGroup.api.location.type === "popout" && this.nestedWindowMembers(sourceGroup).length <= 1) {
17924
- var _this$_popoutWindowSe18;
18424
+ var _this$_popoutWindowSe20;
17925
18425
  /**
17926
18426
  * the source group is the only group in a popout window and
17927
18427
  * has a single panel
@@ -17936,7 +18436,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
17936
18436
  * Multi-group popout windows fall through to the generic
17937
18437
  * detach-and-re-add path so the window stays alive.
17938
18438
  */
17939
- const popoutGroup = (_this$_popoutWindowSe18 = this._popoutWindowService) === null || _this$_popoutWindowSe18 === void 0 ? void 0 : _this$_popoutWindowSe18.findByGroup(sourceGroup);
18439
+ const popoutGroup = (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 ? void 0 : _this$_popoutWindowSe20.findByGroup(sourceGroup);
17940
18440
  if (!popoutGroup) return;
17941
18441
  const removedPanel = this.movingLock(() => popoutGroup.popoutGroup.model.removePanel(popoutGroup.popoutGroup.panels[0], {
17942
18442
  skipSetActive: true,
@@ -18051,6 +18551,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18051
18551
  const from = options.from.group;
18052
18552
  const to = options.to.group;
18053
18553
  const target = options.to.position;
18554
+ if (target === "center" && from === to) return;
18054
18555
  let source = from;
18055
18556
  let mergedPanels;
18056
18557
  if (target === "center") {
@@ -18145,11 +18646,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18145
18646
  break;
18146
18647
  }
18147
18648
  case "popout": {
18148
- var _this$_popoutWindowSe19, _this$_popoutWindowSe20;
18149
- const selectedPopoutGroup = (_this$_popoutWindowSe19 = this._popoutWindowService) === null || _this$_popoutWindowSe19 === void 0 ? void 0 : _this$_popoutWindowSe19.findByGroup(from);
18649
+ var _this$_popoutWindowSe21, _this$_popoutWindowSe22;
18650
+ const selectedPopoutGroup = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.findByGroup(from);
18150
18651
  if (!selectedPopoutGroup) throw new Error("dockview: failed to find popout group");
18151
18652
  if (this.detachFromNestedWindow(from)) break;
18152
- (_this$_popoutWindowSe20 = this._popoutWindowService) === null || _this$_popoutWindowSe20 === void 0 || _this$_popoutWindowSe20.remove(selectedPopoutGroup);
18653
+ (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 || _this$_popoutWindowSe22.remove(selectedPopoutGroup);
18153
18654
  if (selectedPopoutGroup.referenceGroup) {
18154
18655
  const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
18155
18656
  if (referenceGroup && !referenceGroup.api.isVisible) this.doRemoveGroup(referenceGroup, { skipActive: true });
@@ -18314,8 +18815,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18314
18815
  * window-local containers).
18315
18816
  */
18316
18817
  setGroupLocationForRoot(group, gridview) {
18317
- var _this$_popoutWindowSe21;
18318
- const popout = (_this$_popoutWindowSe21 = this._popoutWindowService) === null || _this$_popoutWindowSe21 === void 0 ? void 0 : _this$_popoutWindowSe21.entries.find((entry) => entry.gridview === gridview);
18818
+ var _this$_popoutWindowSe23;
18819
+ const popout = (_this$_popoutWindowSe23 = this._popoutWindowService) === null || _this$_popoutWindowSe23 === void 0 ? void 0 : _this$_popoutWindowSe23.entries.find((entry) => entry.gridview === gridview);
18319
18820
  if (popout) {
18320
18821
  if (group.model.renderContainer !== popout.overlayRenderContainer) group.model.renderContainer = popout.overlayRenderContainer;
18321
18822
  group.model.dropTargetContainer = popout.dropTargetContainer;
@@ -18335,10 +18836,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18335
18836
  * the nested gridview of the floating / popout window it lives in.
18336
18837
  */
18337
18838
  getGridviewForGroup(group) {
18338
- var _this$_floatingGroupS10, _this$_popoutWindowSe22;
18839
+ var _this$_floatingGroupS10, _this$_popoutWindowSe24;
18339
18840
  const floating = (_this$_floatingGroupS10 = this._floatingGroupService) === null || _this$_floatingGroupS10 === void 0 ? void 0 : _this$_floatingGroupS10.findByGroup(group);
18340
18841
  if (floating) return floating.gridview;
18341
- const popout = (_this$_popoutWindowSe22 = this._popoutWindowService) === null || _this$_popoutWindowSe22 === void 0 ? void 0 : _this$_popoutWindowSe22.findByGroup(group);
18842
+ const popout = (_this$_popoutWindowSe24 = this._popoutWindowService) === null || _this$_popoutWindowSe24 === void 0 ? void 0 : _this$_popoutWindowSe24.findByGroup(group);
18342
18843
  if (popout) return popout.gridview;
18343
18844
  return this.gridview;
18344
18845
  }
@@ -18360,13 +18861,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18360
18861
  return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
18361
18862
  }
18362
18863
  updateTheme() {
18363
- var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18864
+ var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe25, _this$_popoutWindowSe26, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
18364
18865
  const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
18365
18866
  (_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
18366
18867
  const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
18367
18868
  this.gridview.margin = gap;
18368
18869
  for (const floating of this.floatingGroups) floating.gridview.margin = gap;
18369
- 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;
18870
+ 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;
18370
18871
  (_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);
18371
18872
  if (theme.dndOverlayBorder === void 0) {
18372
18873
  var _this$_shellManager6;
@@ -18435,6 +18936,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18435
18936
  }), this.onDidActiveChange((event) => {
18436
18937
  this._onDidActiveGroupChange.fire(event);
18437
18938
  }));
18939
+ this.layoutFromElement();
18438
18940
  }
18439
18941
  updateOptions(options) {
18440
18942
  super.updateOptions(options);
@@ -18680,6 +19182,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
18680
19182
  this._options = options;
18681
19183
  this.splitview = new Splitview(this.element, options);
18682
19184
  this.addDisposables(this._onDidAddView, this._onDidLayoutfromJSON, this._onDidRemoveView, this._onDidLayoutChange);
19185
+ this.layoutFromElement();
18683
19186
  }
18684
19187
  updateOptions(options) {
18685
19188
  if ("className" in options) {
@@ -19080,6 +19583,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
19080
19583
  const queue = [];
19081
19584
  const width = this.width;
19082
19585
  const height = this.height;
19586
+ this.paneview.dispose();
19083
19587
  this.paneview = new Paneview(this.element, {
19084
19588
  orientation: "VERTICAL",
19085
19589
  descriptor: {
@@ -19143,7 +19647,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
19143
19647
  clear() {
19144
19648
  for (const [_, value] of this._viewDisposables.entries()) value.dispose();
19145
19649
  this._viewDisposables.clear();
19650
+ const width = this.width;
19651
+ const height = this.height;
19146
19652
  this.paneview.dispose();
19653
+ this.paneview = new Paneview(this.element, { orientation: "VERTICAL" });
19654
+ this.layout(width, height);
19147
19655
  }
19148
19656
  doAddPanel(panel) {
19149
19657
  const disposable = new CompositeDisposable(panel.onDidDrop((event) => {
@@ -19361,11 +19869,13 @@ exports.createSplitview = createSplitview;
19361
19869
  exports.defineModule = defineModule;
19362
19870
  exports.directionToPosition = directionToPosition;
19363
19871
  exports.findRelativeZIndexParent = findRelativeZIndexParent;
19872
+ exports.getActiveElement = getActiveElement;
19364
19873
  exports.getDirectionOrientation = getDirectionOrientation;
19365
19874
  exports.getGridLocation = getGridLocation;
19366
19875
  exports.getLocationOrientation = getLocationOrientation;
19367
19876
  exports.getPaneData = getPaneData;
19368
19877
  exports.getPanelData = getPanelData;
19878
+ exports.getPopoutUrlError = getPopoutUrlError;
19369
19879
  exports.getRegisteredModules = getRegisteredModules;
19370
19880
  exports.getRelativeLocation = getRelativeLocation;
19371
19881
  exports.indexInParent = indexInParent;