fix: satisfy browser tab landing guards

This commit is contained in:
Shakker
2026-08-11 15:38:24 +02:00
parent 6aab02e6a5
commit 2bfb44ea2e
3 changed files with 24 additions and 15 deletions
@@ -663,7 +663,7 @@ describe("BrowserPanelController capture and input ownership", () => {
const previousUrl = "https://example.test/previous";
const { client, request } = createBrowserClient(async (envelope) => {
if (envelope.path === "/act") {
const fn = String(envelope.body?.fn ?? "");
const fn = typeof envelope.body?.fn === "string" ? envelope.body.fn : "";
return fn.includes("history.go")
? { result: true }
: createBrowserPanelTestMetrics(previousUrl, "Previous");
@@ -37,6 +37,7 @@ import {
paintBrowserPanelOverlay,
type BrowserPanelView,
} from "./browser-panel-surface.ts";
import { reconcileCapturedTab } from "./browser-panel-tabs.ts";
import { normalizeBrowserUrlDraft } from "./browser-url.ts";
const INSPECT_THROTTLE_MS = 120;
@@ -223,19 +224,9 @@ export class BrowserPanelController implements ReactiveController {
shot.url && observedMetrics?.url && shot.url !== observedMetrics.url
? null
: observedMetrics;
const tabIndex = this.tabs.findIndex((tab) => tab.id === targetId);
const tab = this.tabs[tabIndex];
if (tab) {
// Tab snapshots can lag history and in-page navigation. Keep the active
// tab's stable identity aligned with the document this capture owns.
const url = metrics?.url || shot.url || tab.url;
const title = metrics ? metrics.title : tab.title;
if (url !== tab.url || title !== tab.title) {
const tabs = [...this.tabs];
tabs[tabIndex] = { ...tab, title, url };
this.setState("tabs", tabs);
}
}
// Tab snapshots can lag history and in-page navigation. Keep the stable
// identity aligned with the document this capture owns.
this.setState("tabs", reconcileCapturedTab(this.tabs, targetId, metrics, shot.url));
this.setState("view", { targetId, dataUrl, image, url: shot.url, metrics });
if (!this.urlDraftEditing && shot.url) {
this.setState("urlDraft", shot.url);
@@ -1,6 +1,24 @@
import { t } from "../../i18n/index.ts";
import { renderPanelTabStrip, type PanelTabStripTab } from "../panel-tab-strip.ts";
import type { BrowserPanelTab } from "./browser-client.ts";
import type { BrowserPageMetrics, BrowserPanelTab } from "./browser-client.ts";
export function reconcileCapturedTab(
tabs: BrowserPanelTab[],
targetId: string,
metrics: BrowserPageMetrics | null,
screenshotUrl: string,
): BrowserPanelTab[] {
const tab = tabs.find((entry) => entry.id === targetId);
if (!tab) {
return tabs;
}
const title = metrics?.title ?? tab.title;
const url = metrics?.url || screenshotUrl || tab.url;
if (title === tab.title && url === tab.url) {
return tabs;
}
return tabs.map((entry) => (entry.id === targetId ? { ...entry, title, url } : entry));
}
function tabLabel(tab: BrowserPanelTab): string {
if (tab.title.trim()) {