mirror of https://github.com/garrytan/gstack.git
fix(browse): closeTab loses last-tab auto-create when 'close' event wins the race
The page 'close' event handler can run while page.close() is awaited and reassign activeTabId before closeTab's post-close active check, so the last-tab auto-create branch never ran and the manager was left with zero tabs. Capture wasActive before close(); only reassign activeTabId when it no longer points at a live tab. Event-dispatch order varies across Playwright/Chromium versions, which is why this raced on some machines only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
82a6778185
commit
383814366b
|
|
@ -798,19 +798,31 @@ export class BrowserManager {
|
||||||
const page = this.pages.get(tabId);
|
const page = this.pages.get(tabId);
|
||||||
if (!page) throw new Error(`Tab ${tabId} not found`);
|
if (!page) throw new Error(`Tab ${tabId} not found`);
|
||||||
|
|
||||||
|
// Capture BEFORE close(): the page 'close' event handler wired in
|
||||||
|
// wirePageEvents() can fire while page.close() is awaited. It removes
|
||||||
|
// the tab from the maps and reassigns activeTabId (to 0 when no tabs
|
||||||
|
// remain), so a post-close `tabId === this.activeTabId` check is
|
||||||
|
// order-dependent — whether the event dispatches before or after
|
||||||
|
// close() resolves varies across Playwright/Chromium versions and
|
||||||
|
// machines, and losing the race means the last-tab auto-create below
|
||||||
|
// never runs, leaving the manager with zero tabs.
|
||||||
|
const wasActive = tabId === this.activeTabId;
|
||||||
|
|
||||||
await page.close();
|
await page.close();
|
||||||
this.pages.delete(tabId);
|
this.pages.delete(tabId);
|
||||||
this.tabSessions.delete(tabId);
|
this.tabSessions.delete(tabId);
|
||||||
this.tabOwnership.delete(tabId);
|
this.tabOwnership.delete(tabId);
|
||||||
|
|
||||||
// Switch to another tab if we closed the active one
|
// Switch to another tab if we closed the active one
|
||||||
if (tabId === this.activeTabId) {
|
if (wasActive) {
|
||||||
const remaining = [...this.pages.keys()];
|
const remaining = [...this.pages.keys()];
|
||||||
if (remaining.length > 0) {
|
if (remaining.length === 0) {
|
||||||
this.activeTabId = remaining[remaining.length - 1];
|
|
||||||
} else {
|
|
||||||
// No tabs left — create a new blank one
|
// No tabs left — create a new blank one
|
||||||
await this.newTab();
|
await this.newTab();
|
||||||
|
} else if (!this.pages.has(this.activeTabId)) {
|
||||||
|
// The 'close' handler may have already switched to a valid tab;
|
||||||
|
// only reassign when activeTabId no longer points at a live tab.
|
||||||
|
this.activeTabId = remaining[remaining.length - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue