fuck this shit bro (add tabs.onReplaced notification)

This commit is contained in:
wuggy 2026-09-19 04:40:20 -07:00
commit 5ac0d5acc3
6 changed files with 108 additions and 7 deletions

View file

@ -2920,6 +2920,18 @@
// Finish tearing down the tab that's going away.
remoteBrowser._endRemoveTab(aOtherTab);
// Notify WebExtensions when one tab is replaced by another. Tab
// adoption uses this same swap internally, but represents a move
// and is marked below so it does not generate a replacement event.
if (!aOurTab._adoptingTab) {
let event = new CustomEvent("TabReplaced", {
bubbles: true,
detail: {addedTab: aOurTab, removedTab: aOtherTab},
});
aOurTab.dispatchEvent(event);
}
delete aOurTab._adoptingTab;
if (isBusy)
this.setTabTitleLoading(aOurTab);
else
@ -3359,6 +3371,7 @@
params.userContextId = aTab.getAttribute("usercontextid");
}
let newTab = this.addTab("about:blank", params);
newTab._adoptingTab = aTab;
let newBrowser = this.getBrowserForTab(newTab);
let newURL = aTab.linkedBrowser.currentURI.spec;

View file

@ -103,6 +103,7 @@ let tabListener = {
AllWindowEvents.addListener("TabClose", this);
AllWindowEvents.addListener("TabOpen", this);
AllWindowEvents.addListener("TabReplaced", this);
WindowListManager.addOpenListener(this.handleWindowOpen);
WindowListManager.addCloseListener(this.handleWindowClose);
@ -138,6 +139,10 @@ let tabListener = {
this.emitRemoved(tab, false);
}
break;
case "TabReplaced":
this.emitReplaced(event.detail.addedTab, event.detail.removedTab);
break;
}
},
@ -220,6 +225,13 @@ let tabListener = {
}, Ci.nsIThread.DISPATCH_NORMAL);
},
emitReplaced(addedTab, removedTab) {
this.emit("tab-replaced", {
addedTabId: TabManager.getId(addedTab),
removedTabId: TabManager.getId(removedTab),
});
},
tabReadyInitialized: false,
tabReadyPromises: new WeakMap(),
initializingTabs: new WeakSet(),
@ -347,7 +359,15 @@ extensions.registerSchemaAPI("tabs", "addon_parent", context => {
};
}).api(),
onReplaced: ignoreEvent(context, "tabs.onReplaced"),
onReplaced: new EventManager(context, "tabs.onReplaced", fire => {
let listener = (eventName, event) => {
fire(event.addedTabId, event.removedTabId);
};
tabListener.on("tab-replaced", listener);
return () => {
tabListener.off("tab-replaced", listener);
};
}).api(),
onMoved: new EventManager(context, "tabs.onMoved", fire => {
// There are certain circumstances where we need to ignore a move event.