@ai-ecoverse/slicc-spectrum 1.62.1 → 1.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/slicc-ui.js CHANGED
@@ -13845,13 +13845,16 @@ function table(rows) {
13845
13845
  var done = (result, note = "") => result.code === 0 ? { stdout: `${result.message}${note}
13846
13846
  `, stderr: "", code: 0 } : { stdout: "", stderr: `panel: ${result.message}
13847
13847
  `, code: result.code };
13848
+ function closedWhen(ago2) {
13849
+ return ago2 < 5e3 ? "just now" : `${Math.round(ago2 / 1e3)} s ago`;
13850
+ }
13848
13851
  function act(scope, parsed) {
13849
13852
  const { panels, reachable: reachable2, cone } = scope;
13850
13853
  if (parsed.verb === "reset") {
13851
13854
  const recent = scope.agent ? panels.recentClose() : null;
13852
13855
  if (recent)
13853
13856
  return refusedOutput(
13854
- `the user closed ${recent.id} ${Math.round(recent.ago / 1e3)} s ago; ask before resetting the layout`
13857
+ `the user closed ${recent.id} ${closedWhen(recent.ago)}; ask before resetting the layout`
13855
13858
  );
13856
13859
  return done(panels.reset());
13857
13860
  }
@@ -13867,9 +13870,7 @@ function act(scope, parsed) {
13867
13870
  if (parsed.verb === "close") return done(panels.close(id));
13868
13871
  const ago2 = scope.agent && !panels.find(id)?.open ? panels.closedAgo(id) : null;
13869
13872
  if (ago2 !== null)
13870
- return refusedOutput(
13871
- `the user closed ${id} ${Math.round(ago2 / 1e3)} s ago; ask before opening it again`
13872
- );
13873
+ return refusedOutput(`the user closed ${id} ${closedWhen(ago2)}; ask before opening it again`);
13873
13874
  if (parsed.verb === "move") return done(panels.move(id, place3));
13874
13875
  const options = { place: place3, section: parsed.section };
13875
13876
  if (parsed.verb === "open") return done(panels.open(id, options));
@@ -14081,6 +14082,20 @@ function deepActive(root2) {
14081
14082
  }
14082
14083
  var scrollback = 1 << 18;
14083
14084
  var laid = ({ width, height }) => width > 0 && height > 0;
14085
+ function settled(element2) {
14086
+ return new Promise((resolve2) => {
14087
+ let last = "";
14088
+ const frame = () => {
14089
+ if (!element2.isConnected) return;
14090
+ const { width, height } = element2.getBoundingClientRect();
14091
+ const size4 = `${width}x${height}`;
14092
+ if (laid({ width, height }) && size4 === last) return resolve2();
14093
+ last = size4;
14094
+ requestAnimationFrame(frame);
14095
+ };
14096
+ requestAnimationFrame(frame);
14097
+ });
14098
+ }
14084
14099
  var ended = { write() {
14085
14100
  }, resize() {
14086
14101
  }, close() {
@@ -14286,7 +14301,7 @@ var SliccTerminalPanel = class extends ThemedElement {
14286
14301
  const backend = keep(model.terminals, info.id);
14287
14302
  terminal.backend = {
14288
14303
  open: async (sink) => {
14289
- await this.#placed(info.id);
14304
+ await this.#placed(info.id, terminal);
14290
14305
  terminal.fit();
14291
14306
  return backend.open(sink, { cols: terminal.cols, rows: terminal.rows });
14292
14307
  }
@@ -14306,17 +14321,18 @@ var SliccTerminalPanel = class extends ThemedElement {
14306
14321
  );
14307
14322
  return terminal;
14308
14323
  }
14309
- #placed(id) {
14324
+ #placed(id, screen) {
14310
14325
  const host4 = this.getRootNode().host;
14311
14326
  const panel = host4?.localName === "slicc-dock" ? host4.api.getPanel(terminalPanel(id)) : void 0;
14312
- if (!panel || laid(panel.api)) return Promise.resolve();
14313
- return new Promise((resolve2) => {
14327
+ if (!panel) return Promise.resolve();
14328
+ const sized = laid(panel.api) ? Promise.resolve() : new Promise((resolve2) => {
14314
14329
  const watch = panel.api.onDidDimensionsChange((size4) => {
14315
14330
  if (!laid(size4)) return;
14316
14331
  watch.dispose();
14317
14332
  resolve2();
14318
14333
  });
14319
14334
  });
14335
+ return sized.then(() => settled(screen));
14320
14336
  }
14321
14337
  #request() {
14322
14338
  this.dispatchEvent(new CustomEvent("new-terminal", { bubbles: true, composed: true }));
@@ -20482,6 +20498,16 @@ function body(call, color) {
20482
20498
  }
20483
20499
  return b`<pre class="input">${call.input}</pre>`;
20484
20500
  }
20501
+ var severityWords = {
20502
+ error: "Error: ",
20503
+ warn: "Warning: ",
20504
+ info: "Note: "
20505
+ };
20506
+ function notes(list5) {
20507
+ return b`<ul class="notes">${list5.map(
20508
+ (note) => b`<li data-note data-severity=${note.severity}>${note.severity === "info" ? b`<swc-icon-info-circle size="s" aria-hidden="true"></swc-icon-info-circle>` : b`<swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>`}<span><span class="sr">${severityWords[note.severity]}</span>${note.text}</span></li>`
20509
+ )}</ul>`;
20510
+ }
20485
20511
  function tool(call, color = "light") {
20486
20512
  const kind = toolKind(call.name);
20487
20513
  return b`<details class="tool" data-status=${call.status} data-tool=${call.name} data-kind=${kind.id}>
@@ -20499,6 +20525,7 @@ function tool(call, color = "light") {
20499
20525
  <div class="call">
20500
20526
  ${body(call, color)}
20501
20527
  ${call.output ? b`<pre class="output">${call.output}</pre>` : A}
20528
+ ${call.notes?.length ? notes(call.notes) : A}
20502
20529
  ${call.image ? b`<img class="shot" src=${call.image} alt=${call.title} />` : A}
20503
20530
  </div>
20504
20531
  </details>`;
@@ -21153,6 +21180,33 @@ var messageCss = i`
21153
21180
  max-block-size: calc(var(--swc-spacing-1000) * 2.5);
21154
21181
  overflow: auto;
21155
21182
  }
21183
+ .call > pre {
21184
+ white-space: pre-wrap;
21185
+ overflow-wrap: anywhere;
21186
+ }
21187
+ .notes {
21188
+ display: flex;
21189
+ flex-direction: column;
21190
+ gap: var(--swc-spacing-75);
21191
+ margin: var(--swc-spacing-100) 0 0;
21192
+ padding: 0;
21193
+ list-style: none;
21194
+ color: var(--swc-neutral-subdued-content-color-default);
21195
+ }
21196
+ .notes li {
21197
+ display: flex;
21198
+ align-items: flex-start;
21199
+ gap: var(--swc-spacing-75);
21200
+ overflow-wrap: anywhere;
21201
+ }
21202
+ .notes swc-icon-alert-triangle,
21203
+ .notes swc-icon-info-circle {
21204
+ flex: none;
21205
+ margin-block-start: var(--swc-spacing-50);
21206
+ }
21207
+ .notes [data-severity='error'] {
21208
+ color: var(--swc-negative-content-color-default);
21209
+ }
21156
21210
  .call > pre.input:has(+ pre.output) {
21157
21211
  margin-block-end: calc(-1 * var(--swc-spacing-100));
21158
21212
  border-block-end: 0;
@@ -21440,7 +21494,8 @@ var messageCss = i`
21440
21494
  .lick[data-severity='warn'] {
21441
21495
  --severity: var(--swc-notice-visual-color);
21442
21496
  }
21443
- .lick .sr {
21497
+ .lick .sr,
21498
+ .notes .sr {
21444
21499
  position: absolute;
21445
21500
  inline-size: 1px;
21446
21501
  block-size: 1px;
@@ -21534,7 +21589,7 @@ function requiresText(item2, all2) {
21534
21589
  return parts2.length ? parts2.join("; ") : null;
21535
21590
  }
21536
21591
  var snapshot = (items) => new Map(items.map(({ id, state: state3, error }) => [id, { state: state3, error }]));
21537
- function settled(failures, before, after) {
21592
+ function settled2(failures, before, after) {
21538
21593
  return new Map(
21539
21594
  [...failures].filter(([id]) => {
21540
21595
  const was = before.get(id);
@@ -21843,7 +21898,7 @@ var SliccUpdates = class extends ModelElement {
21843
21898
  const subscriptions = [
21844
21899
  port.on("items", (items) => {
21845
21900
  const next = snapshot(items);
21846
- this.failures = settled(this.failures, previous, next);
21901
+ this.failures = settled2(this.failures, previous, next);
21847
21902
  previous = next;
21848
21903
  this.requestUpdate();
21849
21904
  })
@@ -21854,7 +21909,7 @@ var SliccUpdates = class extends ModelElement {
21854
21909
  ...subscriptions,
21855
21910
  port.on("packages", (items) => {
21856
21911
  const next = snapshot(items);
21857
- this.problems = settled(this.problems, packages, next);
21912
+ this.problems = settled2(this.problems, packages, next);
21858
21913
  packages = next;
21859
21914
  this.requestUpdate();
21860
21915
  })
@@ -27731,11 +27786,13 @@ function attention(section) {
27731
27786
  var SliccMonitor = class extends ModelElement {
27732
27787
  static properties = {
27733
27788
  ...ModelElement.properties,
27734
- expanded: { state: true }
27789
+ expanded: { state: true },
27790
+ copied: { state: true }
27735
27791
  };
27736
27792
  constructor() {
27737
27793
  super();
27738
27794
  this.expanded = {};
27795
+ this.copied = null;
27739
27796
  }
27740
27797
  static styles = [
27741
27798
  shared,
@@ -27835,6 +27892,36 @@ var SliccMonitor = class extends ModelElement {
27835
27892
  display: block;
27836
27893
  color: var(--swc-neutral-subdued-content-color-default);
27837
27894
  }
27895
+ .alert > div {
27896
+ min-width: 0;
27897
+ }
27898
+ .alert .command {
27899
+ display: flex;
27900
+ align-items: center;
27901
+ gap: var(--swc-spacing-100);
27902
+ margin-block-start: var(--swc-spacing-75);
27903
+ padding-inline-start: var(--swc-spacing-100);
27904
+ border-radius: var(--swc-corner-radius-medium-default);
27905
+ background: var(--swc-background-layer-1-color);
27906
+ }
27907
+ .alert code {
27908
+ flex: 1;
27909
+ min-width: 0;
27910
+ overflow-x: auto;
27911
+ white-space: nowrap;
27912
+ font-family: var(--swc-code-font-family-stack);
27913
+ font-size: var(--swc-font-size-75);
27914
+ color: var(--swc-code-color);
27915
+ }
27916
+ .alert .lead {
27917
+ display: block;
27918
+ margin-block-start: var(--swc-spacing-75);
27919
+ color: var(--swc-neutral-subdued-content-color-default);
27920
+ }
27921
+ .alert .uncopied {
27922
+ display: block;
27923
+ color: var(--swc-negative-content-color-default);
27924
+ }
27838
27925
  .sections {
27839
27926
  display: grid;
27840
27927
  margin: 0;
@@ -27959,9 +28046,16 @@ var SliccMonitor = class extends ModelElement {
27959
28046
  const error = alert.severity === "error";
27960
28047
  return b`<li class="alert" data-severity=${alert.severity}>
27961
28048
  ${error ? b`<swc-icon-alert-diamond size="s" aria-hidden="true"></swc-icon-alert-diamond>` : b`<swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>`}
27962
- <div><span class="sr">${error ? "Error: " : "Warning: "}</span><strong>${alert.title}</strong><span class="detail">${alert.detail}</span></div>
28049
+ <div><span class="sr">${error ? "Error: " : "Warning: "}</span><strong>${alert.title}</strong><span class="detail">${alert.detail}</span>${alert.command ? this.#command(alert.id, alert.command, alert.commandLabel ?? "Run") : A}</div>
27963
28050
  </li>`;
27964
28051
  }
28052
+ #command(id, text2, label) {
28053
+ const copied = this.copied?.id === id && this.copied.text === text2 ? this.copied : null;
28054
+ return b`<span class="lead">${label}:</span><div class="command" data-command><code>${text2}</code><swc-action-button size="s" quiet data-action="copy-command" accessible-label=${copied?.done ? "Copied" : "Copy command"} @click=${() => this.#copy(id, text2)}><swc-icon-copy slot="icon"></swc-icon-copy>${copied?.done ? "Copied" : "Copy"}</swc-action-button></div>${copied && !copied.done ? b`<span class="uncopied" role="alert" data-error="copy">Couldn’t copy. Select the command and copy it.</span>` : A}`;
28055
+ }
28056
+ async #copy(id, text2) {
28057
+ this.copied = { id, text: text2, done: await copyText(text2) };
28058
+ }
27965
28059
  #open(id) {
27966
28060
  this.dispatchEvent(
27967
28061
  new CustomEvent("show-surface", { detail: { id }, bubbles: true, composed: true })
@@ -55121,16 +55215,24 @@ var OverflowObserver = class extends CompositeDisposable {
55121
55215
  }
55122
55216
  };
55123
55217
  function watchElementResize(element2, cb) {
55218
+ const pendingFrames = /* @__PURE__ */ new Set();
55124
55219
  const observer = new ResizeObserver((entires) => {
55125
- requestAnimationFrame(() => {
55220
+ let ran = false;
55221
+ let frame;
55222
+ frame = requestAnimationFrame(() => {
55223
+ ran = true;
55224
+ if (frame !== void 0) pendingFrames.delete(frame);
55126
55225
  const firstEntry = entires[0];
55127
55226
  cb(firstEntry);
55128
55227
  });
55228
+ if (!ran) pendingFrames.add(frame);
55129
55229
  });
55130
55230
  observer.observe(element2);
55131
55231
  return { dispose: () => {
55132
55232
  observer.unobserve(element2);
55133
55233
  observer.disconnect();
55234
+ for (const frame of pendingFrames) cancelAnimationFrame(frame);
55235
+ pendingFrames.clear();
55134
55236
  } };
55135
55237
  }
55136
55238
  var removeClasses = (element2, ...classes) => {
@@ -63603,16 +63705,21 @@ var TabsContainer = class extends CompositeDisposable {
63603
63705
  y: event2.clientY,
63604
63706
  zIndex: (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0
63605
63707
  };
63606
- const context = this.createOverflowRenderContext(root2, anchor);
63708
+ const { context, rowRenderers } = this.createOverflowRenderContext(root2, anchor);
63607
63709
  const advancedOverflow = this.accessor.advancedOverflowService;
63608
- if (advancedOverflow) advancedOverflow.renderOverflow({
63609
- group: this.group,
63610
- overflowTabs: [...this._overflowTabs],
63611
- overflowTabGroups: [...this._overflowTabGroups],
63612
- pinnedOverflowTabs: [...this._overflowPinnedTabs],
63613
- context
63614
- });
63615
- else context.open(this.renderFreeOverflowList(context));
63710
+ try {
63711
+ if (advancedOverflow) advancedOverflow.renderOverflow({
63712
+ group: this.group,
63713
+ overflowTabs: [...this._overflowTabs],
63714
+ overflowTabGroups: [...this._overflowTabGroups],
63715
+ pinnedOverflowTabs: [...this._overflowPinnedTabs],
63716
+ context
63717
+ });
63718
+ else context.open(this.renderFreeOverflowList(context));
63719
+ } catch (err) {
63720
+ rowRenderers.dispose();
63721
+ throw err;
63722
+ }
63616
63723
  }));
63617
63724
  }
63618
63725
  /**
@@ -63633,6 +63740,7 @@ var TabsContainer = class extends CompositeDisposable {
63633
63740
  if (overflowGroupSet.has(tg.id)) for (const pid of tg.panelIds) panelToGroup.set(pid, tg);
63634
63741
  }
63635
63742
  const popup2 = () => this.accessor.getPopupServiceForGroup(this.group);
63743
+ const rowRenderers = new CompositeDisposable();
63636
63744
  const buildGroupHeader = (tg) => {
63637
63745
  const groupHeader = document.createElement("div");
63638
63746
  groupHeader.className = "dv-tabs-overflow-group-header";
@@ -63662,69 +63770,87 @@ var TabsContainer = class extends CompositeDisposable {
63662
63770
  return groupHeader;
63663
63771
  };
63664
63772
  return {
63665
- overflowGroupIdForPanel: (panelId) => {
63666
- var _panelToGroup$get;
63667
- return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
63668
- },
63669
- buildGroupHeader: (tabGroupId) => {
63670
- const tg = groupById.get(tabGroupId);
63671
- if (!tg || !overflowGroupSet.has(tg.id)) return;
63672
- return buildGroupHeader(tg);
63673
- },
63674
- buildPinnedHeader: () => {
63675
- const header = document.createElement("div");
63676
- header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
63677
- const glyph = createPinButton();
63678
- glyph.classList.add("dv-tabs-overflow-pinned-icon");
63679
- header.appendChild(glyph);
63680
- const labelSpan = document.createElement("span");
63681
- labelSpan.className = "dv-tabs-overflow-group-label";
63682
- labelSpan.textContent = "Pinned";
63683
- header.appendChild(labelSpan);
63684
- return header;
63685
- },
63686
- buildRow: (panelId) => {
63687
- const panel = this.group.panels.find((p17) => p17.id === panelId);
63688
- if (!panel) return;
63689
- const tab = this.tabs.tabs.find((t88) => t88.panel.id === panelId);
63690
- const tg = panelToGroup.get(panelId);
63691
- const child = panel.view.createTabRenderer("headerOverflow").element;
63692
- const wrapper = document.createElement("div");
63693
- toggleClass(wrapper, "dv-tab", true);
63694
- toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
63695
- toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
63696
- if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
63697
- const doActivate = () => {
63698
- if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
63699
- tab === null || tab === void 0 || tab.element.scrollIntoView({
63700
- block: "nearest",
63701
- inline: "nearest"
63773
+ context: {
63774
+ overflowGroupIdForPanel: (panelId) => {
63775
+ var _panelToGroup$get;
63776
+ return (_panelToGroup$get = panelToGroup.get(panelId)) === null || _panelToGroup$get === void 0 ? void 0 : _panelToGroup$get.id;
63777
+ },
63778
+ buildGroupHeader: (tabGroupId) => {
63779
+ const tg = groupById.get(tabGroupId);
63780
+ if (!tg || !overflowGroupSet.has(tg.id)) return;
63781
+ return buildGroupHeader(tg);
63782
+ },
63783
+ buildPinnedHeader: () => {
63784
+ const header = document.createElement("div");
63785
+ header.className = "dv-tabs-overflow-group-header dv-tabs-overflow-pinned-header";
63786
+ const glyph = createPinButton();
63787
+ glyph.classList.add("dv-tabs-overflow-pinned-icon");
63788
+ header.appendChild(glyph);
63789
+ const labelSpan = document.createElement("span");
63790
+ labelSpan.className = "dv-tabs-overflow-group-label";
63791
+ labelSpan.textContent = "Pinned";
63792
+ header.appendChild(labelSpan);
63793
+ return header;
63794
+ },
63795
+ buildRow: (panelId) => {
63796
+ const panel = this.group.panels.find((p17) => p17.id === panelId);
63797
+ if (!panel) return;
63798
+ const tab = this.tabs.tabs.find((t88) => t88.panel.id === panelId);
63799
+ const tg = panelToGroup.get(panelId);
63800
+ const tabComponent = panel.view.createTabRenderer("headerOverflow");
63801
+ let rowDisposed = false;
63802
+ const disposeRow = Disposable.from(() => {
63803
+ if (!rowDisposed) {
63804
+ var _tabComponent$dispose;
63805
+ rowDisposed = true;
63806
+ (_tabComponent$dispose = tabComponent.dispose) === null || _tabComponent$dispose === void 0 || _tabComponent$dispose.call(tabComponent);
63807
+ }
63702
63808
  });
63703
- this.accessor.withOrigin("user", () => panel.api.setActive());
63704
- };
63705
- wrapper.addEventListener("click", (event2) => {
63706
- popup2().close();
63707
- if (event2.defaultPrevented) return;
63708
- doActivate();
63709
- });
63710
- wrapper.appendChild(child);
63711
- return {
63712
- element: wrapper,
63713
- panel,
63714
- activate: () => {
63809
+ if (rowRenderers.isDisposed) disposeRow.dispose();
63810
+ else rowRenderers.addDisposables(disposeRow);
63811
+ const child = tabComponent.element;
63812
+ const wrapper = document.createElement("div");
63813
+ toggleClass(wrapper, "dv-tab", true);
63814
+ toggleClass(wrapper, "dv-active-tab", panel.api.isActive);
63815
+ toggleClass(wrapper, "dv-inactive-tab", !panel.api.isActive);
63816
+ if (tg) toggleClass(wrapper, "dv-tab--grouped", true);
63817
+ const doActivate = () => {
63818
+ if (tg === null || tg === void 0 ? void 0 : tg.collapsed) tg.expand();
63819
+ tab === null || tab === void 0 || tab.element.scrollIntoView({
63820
+ block: "nearest",
63821
+ inline: "nearest"
63822
+ });
63823
+ this.accessor.withOrigin("user", () => panel.api.setActive());
63824
+ };
63825
+ wrapper.addEventListener("click", (event2) => {
63715
63826
  popup2().close();
63827
+ if (event2.defaultPrevented) return;
63716
63828
  doActivate();
63717
- }
63718
- };
63719
- },
63720
- open: (body4) => {
63721
- popup2().openPopover(body4, anchor);
63829
+ });
63830
+ wrapper.appendChild(child);
63831
+ return {
63832
+ element: wrapper,
63833
+ panel,
63834
+ activate: () => {
63835
+ popup2().close();
63836
+ doActivate();
63837
+ },
63838
+ dispose: () => {
63839
+ rowRenderers.removeDisposable(disposeRow);
63840
+ disposeRow.dispose();
63841
+ }
63842
+ };
63843
+ },
63844
+ open: (body4) => {
63845
+ popup2().openPopover(body4, anchor, { onClose: () => rowRenderers.dispose() });
63846
+ },
63847
+ close: () => popup2().close(),
63848
+ focusTrigger: () => {
63849
+ root2.tabIndex = -1;
63850
+ root2.focus();
63851
+ }
63722
63852
  },
63723
- close: () => popup2().close(),
63724
- focusTrigger: () => {
63725
- root2.tabIndex = -1;
63726
- root2.focus();
63727
- }
63853
+ rowRenderers
63728
63854
  };
63729
63855
  }
63730
63856
  /**
@@ -64638,6 +64764,7 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
64638
64764
  this.tabsContainer.setRightActionsElement(element2);
64639
64765
  }
64640
64766
  setActive(isGroupActive, force = false) {
64767
+ if (this.isDisposed) return;
64641
64768
  if (!force && this.isActive === isGroupActive) return;
64642
64769
  this._isGroupActive = isGroupActive;
64643
64770
  toggleClass(this.container, "dv-active-group", isGroupActive);
@@ -67291,13 +67418,14 @@ var ContextMenuController = class {
67291
67418
  * menu passes the `tabGroup`. No-op when no renderer could be created (no
67292
67419
  * factory configured, or the factory declined the component).
67293
67420
  */
67294
- appendComponentItem(menuEl, item2, identity, group, close) {
67421
+ appendComponentItem(menuEl, item2, identity, group, close, renderers) {
67295
67422
  var _this$accessor$option4, _this$accessor$option5;
67296
67423
  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, {
67297
67424
  id: nextContextMenuItemId(),
67298
67425
  component: item2.component
67299
67426
  });
67300
67427
  if (!renderer) return;
67428
+ renderers.addDisposables(renderer);
67301
67429
  renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
67302
67430
  group,
67303
67431
  api: this.accessor.api,
@@ -67357,9 +67485,9 @@ var ContextMenuController = class {
67357
67485
  * default row; an item carrying none of the three renders nothing. Shared
67358
67486
  * by both menus, which differ only in `identity`.
67359
67487
  */
67360
- appendConfigItem(menuEl, item2, identity, group, close) {
67488
+ appendConfigItem(menuEl, item2, identity, group, close, renderers) {
67361
67489
  if (item2.element) menuEl.appendChild(item2.element);
67362
- else if (item2.component) this.appendComponentItem(menuEl, item2, identity, group, close);
67490
+ else if (item2.component) this.appendComponentItem(menuEl, item2, identity, group, close, renderers);
67363
67491
  else if (item2.label) menuEl.appendChild(buildItem(item2.label, close, () => {
67364
67492
  var _item$action;
67365
67493
  return (_item$action = item2.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item2);
@@ -67371,22 +67499,28 @@ var ContextMenuController = class {
67371
67499
  event2.preventDefault();
67372
67500
  const popupService = this.accessor.getPopupServiceForGroup(group);
67373
67501
  const close = () => popupService.close();
67502
+ const renderers = new CompositeDisposable();
67374
67503
  const menuEl = document.createElement("div");
67375
67504
  menuEl.className = "dv-context-menu";
67376
67505
  menuEl.setAttribute("role", "menu");
67377
- for (const item2 of items) {
67378
- if (isItemConfig(item2)) {
67379
- this.appendConfigItem(menuEl, item2, { panel }, group, close);
67380
- continue;
67506
+ try {
67507
+ for (const item2 of items) {
67508
+ if (isItemConfig(item2)) {
67509
+ this.appendConfigItem(menuEl, item2, { panel }, group, close, renderers);
67510
+ continue;
67511
+ }
67512
+ const el = this.buildBuiltInTabItem(item2, panel, group, close);
67513
+ if (el) menuEl.appendChild(el);
67381
67514
  }
67382
- const el = this.buildBuiltInTabItem(item2, panel, group, close);
67383
- if (el) menuEl.appendChild(el);
67515
+ } catch (err) {
67516
+ renderers.dispose();
67517
+ throw err;
67384
67518
  }
67385
67519
  popupService.openPopover(menuEl, {
67386
67520
  x: event2.clientX,
67387
67521
  y: event2.clientY,
67388
67522
  zIndex: popoverZIndexFor(event2.target, group)
67389
- });
67523
+ }, { onClose: () => renderers.dispose() });
67390
67524
  }
67391
67525
  showForChip(tabGroup, group, event2) {
67392
67526
  if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
@@ -67400,22 +67534,28 @@ var ContextMenuController = class {
67400
67534
  event2.preventDefault();
67401
67535
  const popupService = this.accessor.getPopupServiceForGroup(group);
67402
67536
  const close = () => popupService.close();
67537
+ const renderers = new CompositeDisposable();
67403
67538
  const menuEl = document.createElement("div");
67404
67539
  menuEl.className = "dv-context-menu";
67405
67540
  menuEl.setAttribute("role", "menu");
67406
- for (const item2 of items) if (item2 === "separator") menuEl.appendChild(buildSeparator());
67407
- else if (item2 === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
67408
- else if (item2 === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
67409
- else if (item2 === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
67410
- else if (item2 === "close") menuEl.appendChild(buildItem("Close All", close, () => {
67411
- group.panels.filter((p17) => tabGroup.containsPanel(p17.id)).forEach((p17) => p17.api.close());
67412
- }));
67413
- else if (isItemConfig(item2)) this.appendConfigItem(menuEl, item2, { tabGroup }, group, close);
67541
+ try {
67542
+ for (const item2 of items) if (item2 === "separator") menuEl.appendChild(buildSeparator());
67543
+ else if (item2 === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
67544
+ else if (item2 === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
67545
+ else if (item2 === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
67546
+ else if (item2 === "close") menuEl.appendChild(buildItem("Close All", close, () => {
67547
+ group.panels.filter((p17) => tabGroup.containsPanel(p17.id)).forEach((p17) => p17.api.close());
67548
+ }));
67549
+ else if (isItemConfig(item2)) this.appendConfigItem(menuEl, item2, { tabGroup }, group, close, renderers);
67550
+ } catch (err) {
67551
+ renderers.dispose();
67552
+ throw err;
67553
+ }
67414
67554
  popupService.openPopover(menuEl, {
67415
67555
  x: event2.clientX,
67416
67556
  y: event2.clientY,
67417
67557
  zIndex: popoverZIndexFor(event2.target, group)
67418
- });
67558
+ }, { onClose: () => renderers.dispose() });
67419
67559
  }
67420
67560
  };
67421
67561
  var ContextMenuModule = defineModule({
@@ -67633,6 +67773,7 @@ var OverlayRenderContainer = class extends CompositeDisposable {
67633
67773
  const observerDisposable = new MutableDisposable();
67634
67774
  const correctLayerPosition = () => {
67635
67775
  if (panel.api.location.type === "floating") queueMicrotask(() => {
67776
+ if (disposable.isDisposed) return;
67636
67777
  const floatingGroup = this.accessor.getFloatingWindowForGroup(panel.api.group);
67637
67778
  if (!floatingGroup) return;
67638
67779
  const element2 = floatingGroup.overlay.element;
@@ -67831,7 +67972,7 @@ var PopupService = class extends CompositeDisposable {
67831
67972
  newRoot.prepend(this._element);
67832
67973
  this._root = newRoot;
67833
67974
  }
67834
- openPopover(element2, position) {
67975
+ openPopover(element2, position, options) {
67835
67976
  var _position$zIndex;
67836
67977
  this.close();
67837
67978
  const wrapper = this._window.document.createElement("div");
@@ -67846,14 +67987,14 @@ var PopupService = class extends CompositeDisposable {
67846
67987
  this._element.appendChild(wrapper);
67847
67988
  this._active = wrapper;
67848
67989
  const POINTERDOWN_GRACE_MS = 200;
67849
- this._activeDisposable.value = createDismissableLayer({
67990
+ this._activeDisposable.value = new CompositeDisposable(createDismissableLayer({
67850
67991
  window: this._window,
67851
67992
  onDismiss: () => this.close(),
67852
67993
  elements: () => this._active ? [this._active] : [],
67853
67994
  keys: ["Enter"],
67854
67995
  pointerDownGraceMs: POINTERDOWN_GRACE_MS,
67855
67996
  resize: true
67856
- });
67997
+ }), (options === null || options === void 0 ? void 0 : options.onClose) ? Disposable.from(options.onClose) : Disposable.NONE);
67857
67998
  this._window.requestAnimationFrame(() => {
67858
67999
  shiftAbsoluteElementIntoView(wrapper, this._root);
67859
68000
  });
@@ -69142,7 +69283,9 @@ var DockviewComponent = class extends BaseGrid {
69142
69283
  this._onWillDrop = new Emitter2();
69143
69284
  this.onWillDrop = this._onWillDrop.event;
69144
69285
  this._mutationDepth = 0;
69286
+ this._syncMutationDepth = 0;
69145
69287
  this._pendingLocationChanges = /* @__PURE__ */ new Map();
69288
+ this._openingPopoutWindows = /* @__PURE__ */ new Set();
69146
69289
  this._origin = "user";
69147
69290
  this._originDepth = 0;
69148
69291
  this._onWillMutateLayout = new Emitter2();
@@ -69226,6 +69369,10 @@ var DockviewComponent = class extends BaseGrid {
69226
69369
  });
69227
69370
  }));
69228
69371
  this.popupService = new PopupService(this.element);
69372
+ this.addDisposables(this.popupService, Disposable.from(() => {
69373
+ for (const opening2 of this._openingPopoutWindows) opening2.dispose();
69374
+ this._openingPopoutWindows.clear();
69375
+ }));
69229
69376
  this._api = new DockviewApi(this);
69230
69377
  this.disableResizing = true;
69231
69378
  this.element.remove();
@@ -69370,9 +69517,15 @@ var DockviewComponent = class extends BaseGrid {
69370
69517
  const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
69371
69518
  popoutWindowDisposable.dispose();
69372
69519
  }));
69520
+ this._openingPopoutWindows.add(popoutWindowDisposable);
69373
69521
  const openError = getPopoutUrlError(popoutUrl);
69374
69522
  return (openError ? Promise.resolve(null) : _window.open()).then((popoutContainer) => {
69375
69523
  var _options$referenceGro, _options$overridePopo4;
69524
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
69525
+ if (this.isDisposed) {
69526
+ popoutWindowDisposable.dispose();
69527
+ return false;
69528
+ }
69376
69529
  if (_window.isDisposed) {
69377
69530
  const failure2 = _window.failure;
69378
69531
  if (failure2 && !this.isDisposed) {
@@ -69556,6 +69709,7 @@ var DockviewComponent = class extends BaseGrid {
69556
69709
  for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
69557
69710
  return true;
69558
69711
  }).catch((err) => {
69712
+ this._openingPopoutWindows.delete(popoutWindowDisposable);
69559
69713
  console.error("dockview: failed to create popout.", err);
69560
69714
  return false;
69561
69715
  });
@@ -70079,6 +70233,7 @@ var DockviewComponent = class extends BaseGrid {
70079
70233
  group.dispose();
70080
70234
  this._groups.delete(group.id);
70081
70235
  this._onDidRemoveGroup.fire(group);
70236
+ this.activateFallbackGroupIfRemoved(group);
70082
70237
  });
70083
70238
  }
70084
70239
  setEdgeGroupCollapsed(group, collapsed) {
@@ -70251,10 +70406,12 @@ var DockviewComponent = class extends BaseGrid {
70251
70406
  const record = this._groups.get(temporaryGroup.api.id);
70252
70407
  this._groups.delete(temporaryGroup.api.id);
70253
70408
  temporaryGroupDisposables.push(Disposable.from(() => {
70409
+ var _this$headerActionsSe2;
70254
70410
  this.movingLock(() => {
70255
70411
  for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
70256
70412
  });
70257
70413
  record === null || record === void 0 || record.disposable.dispose();
70414
+ (_this$headerActionsSe2 = this.headerActionsService) === null || _this$headerActionsSe2 === void 0 || _this$headerActionsSe2.disposeGroup(temporaryGroup);
70258
70415
  temporaryGroup.dispose();
70259
70416
  }));
70260
70417
  return temporaryGroup;
@@ -70873,9 +71030,12 @@ var DockviewComponent = class extends BaseGrid {
70873
71030
  */
70874
71031
  mutation(kind, func) {
70875
71032
  const close = this.openMutation(kind);
71033
+ this._syncMutationDepth++;
70876
71034
  try {
70877
71035
  return func();
70878
71036
  } finally {
71037
+ this._syncMutationDepth--;
71038
+ if (this._syncMutationDepth === 0) this.releaseDisposedActiveGroup();
70879
71039
  close();
70880
71040
  }
70881
71041
  }
@@ -70922,6 +71082,7 @@ var DockviewComponent = class extends BaseGrid {
70922
71082
  return () => {
70923
71083
  this._mutationDepth--;
70924
71084
  if (this._mutationDepth === 0) {
71085
+ this.releaseDisposedActiveGroup();
70925
71086
  this.flushLocationChanges();
70926
71087
  this._onDidMutateLayout.fire({
70927
71088
  kind,
@@ -70930,6 +71091,11 @@ var DockviewComponent = class extends BaseGrid {
70930
71091
  }
70931
71092
  };
70932
71093
  }
71094
+ /** Covers removals with `skipActive` that disposed the active group. */
71095
+ releaseDisposedActiveGroup() {
71096
+ var _this$_activeGroup;
71097
+ if (!this.isDisposed && ((_this$_activeGroup = this._activeGroup) === null || _this$_activeGroup === void 0 ? void 0 : _this$_activeGroup.model.isDisposed)) this.activateFallbackGroupIfRemoved(this._activeGroup);
71098
+ }
70933
71099
  /**
70934
71100
  * Coalesce a panel's `onDidLocationChange` to the end of the enclosing
70935
71101
  * transaction, or fire it immediately when no transaction is in flight.
@@ -71058,7 +71224,7 @@ var DockviewComponent = class extends BaseGrid {
71058
71224
  skipSetActiveGroup: true
71059
71225
  }));
71060
71226
  if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
71061
- if (!options.keepEmptyGroups && sourceGroup.model.size === 0) this.doRemoveGroup(sourceGroup, { skipActive: true });
71227
+ if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== destinationGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
71062
71228
  const isDestinationGroupEmpty = destinationGroup.model.size === 0;
71063
71229
  this.movingLock(() => {
71064
71230
  var _options$skipSetActiv;
@@ -71192,6 +71358,7 @@ var DockviewComponent = class extends BaseGrid {
71192
71358
  const from = options.from.group;
71193
71359
  const to = options.to.group;
71194
71360
  const target = options.to.position;
71361
+ if (target === "center" && from === to) return;
71195
71362
  let source = from;
71196
71363
  let mergedPanels;
71197
71364
  if (target === "center") {
@@ -81176,7 +81343,7 @@ lit-html/static.js:
81176
81343
  dockview-core/dist/package/main.esm.mjs:
81177
81344
  (**
81178
81345
  * dockview-core
81179
- * @version 8.4.0
81346
+ * @version 8.4.1
81180
81347
  * @link https://github.com/dockview/dockview
81181
81348
  * @license MIT
81182
81349
  *)