commit 782b1abb8a3509e51371aef10867e60501420ce9
parent 1f74f55b43b518287525819030f372d6efbe695d
Author: Rob Wu <rob@robwu.nl>
Date: Mon, 29 Dec 2025 22:17:05 +0000
Bug 2002643 - Preserve custom tab value when tab is adopted r=sessionstore-reviewers,sthompson
Differential Revision: https://phabricator.services.mozilla.com/D277566
Diffstat:
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/browser/components/extensions/test/browser/browser_ext_sessions_window_tab_value.js b/browser/components/extensions/test/browser/browser_ext_sessions_window_tab_value.js
@@ -226,6 +226,47 @@ add_task(async function test_sessions_tab_value_persistence() {
await extension.unload();
});
+// Regression test for https://bugzilla.mozilla.org/show_bug.cgi?id=2002643
+add_task(async function test_sessions_tab_value_persists_across_adoption() {
+ async function background() {
+ const tab = await browser.tabs.create({ url: "about:blank" });
+
+ await browser.sessions.setTabValue(tab.id, "my key", "tab value");
+
+ await browser.windows.create({ tabId: tab.id });
+
+ browser.test.assertEq(
+ await browser.sessions.getTabValue(tab.id, "my key"),
+ "tab value",
+ "setTabValue sticks to tab when tab is adopted in new window"
+ );
+
+ const win = await browser.windows.create({});
+ await browser.tabs.group({
+ createProperties: { windowId: win.id },
+ tabIds: [tab.id],
+ });
+
+ browser.test.assertEq(
+ await browser.sessions.getTabValue(tab.id, "my key"),
+ "tab value",
+ "setTabValue sticks to tab when tab is adopted in group in other window"
+ );
+
+ await browser.windows.remove(win.id);
+ browser.test.sendMessage("testComplete");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: { permissions: ["sessions"] },
+ background,
+ });
+
+ await extension.startup();
+ await extension.awaitMessage("testComplete");
+ await extension.unload();
+});
+
add_task(async function test_sessions_window_value() {
info("Testing set/get/deleteWindowValue.");
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
@@ -1904,6 +1904,9 @@ var SessionStoreInternal = {
switch (aEvent.type) {
case "TabOpen":
this.onTabAdd(win);
+ if (aEvent.detail.adoptedTab) {
+ this.moveCustomTabValue(aEvent.detail.adoptedTab, target);
+ }
break;
case "TabBrowserInserted":
this.onTabBrowserInserted(win, target);
@@ -1912,6 +1915,7 @@ var SessionStoreInternal = {
// `adoptedBy` will be set if the tab was closed because it is being
// moved to a new window.
if (aEvent.detail.adoptedBy) {
+ this.moveCustomTabValue(target, aEvent.detail.adoptedBy);
this.onMoveToNewWindow(
target.linkedBrowser,
aEvent.detail.adoptedBy.linkedBrowser
@@ -4962,6 +4966,17 @@ var SessionStoreInternal = {
}
},
+ moveCustomTabValue(aFromTab, aToTab) {
+ let state = TAB_CUSTOM_VALUES.get(aFromTab);
+ if (state) {
+ TAB_CUSTOM_VALUES.set(aToTab, state);
+ TAB_CUSTOM_VALUES.delete(aFromTab);
+ // No saveStateDelayed calls for either window here, because the callers
+ // of moveCustomTabValue already call saveStateDelayed for both windows
+ // as needed, from onTabAdd and onTabRemove.
+ }
+ },
+
/**
* Retrieves data specific to lazy-browser tabs. If tab is not lazy,
* will return undefined.