1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
9 ChromeUtils.defineESModuleGetters(lazy, {
10 AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
13 XPCOMUtils.defineLazyModuleGetters(lazy, {
14 ASRouter: "resource://activity-stream/lib/ASRouter.jsm",
17 // A mapping of loaded new tab pages, where the mapping is:
18 // browser -> { actor, browser, browsingContext, portID, url, loaded }
19 let gLoadedTabs = new Map();
21 export class AboutNewTabParent extends JSWindowActorParent {
22 static get loadedTabs() {
26 getTabDetails(message) {
27 let browsingContext = message.target.browsingContext;
28 let browser = browsingContext.top.embedderElement;
29 return browser ? gLoadedTabs.get(browser) : null;
33 if (event.type == "SwapDocShells") {
34 let oldBrowser = this.browsingContext.top.embedderElement;
35 let newBrowser = event.detail;
37 let tabDetails = gLoadedTabs.get(oldBrowser);
39 tabDetails.browser = newBrowser;
40 gLoadedTabs.delete(oldBrowser);
41 gLoadedTabs.set(newBrowser, tabDetails);
43 oldBrowser.removeEventListener("SwapDocShells", this);
44 newBrowser.addEventListener("SwapDocShells", this);
49 async receiveMessage(message) {
50 switch (message.name) {
51 case "AboutNewTabVisible":
52 await lazy.ASRouter.waitForInitialized;
53 lazy.ASRouter.sendTriggerMessage({
54 browser: this.browsingContext.top.embedderElement,
55 // triggerId and triggerContext
56 id: "defaultBrowserCheck",
57 context: { source: "newtab" },
62 let actor = message.target;
63 let browsingContext = actor.browsingContext;
64 let browser = browsingContext.top.embedderElement;
73 portID: message.data.portID,
74 url: message.data.url,
76 gLoadedTabs.set(browser, tabDetails);
78 browser.addEventListener("SwapDocShells", this);
79 browser.addEventListener("EndSwapDocShells", this);
81 this.notifyActivityStreamChannel("onNewTabInit", message, tabDetails);
86 this.notifyActivityStreamChannel("onNewTabLoad", message);
90 let tabDetails = this.getTabDetails(message);
92 // When closing a tab, the embedderElement can already be disconnected, so
93 // an a backup, look up the tab details by browsing context.
94 tabDetails = this.getByBrowsingContext(
95 message.target.browsingContext
103 tabDetails.browser.removeEventListener("EndSwapDocShells", this);
105 gLoadedTabs.delete(tabDetails.browser);
107 this.notifyActivityStreamChannel("onNewTabUnload", message, tabDetails);
111 case "ActivityStream:ContentToMain":
112 this.notifyActivityStreamChannel("onMessage", message);
117 notifyActivityStreamChannel(name, message, tabDetails) {
119 tabDetails = this.getTabDetails(message);
125 let channel = this.getChannel();
130 let messageToSend = {
131 target: message.target,
132 data: message.data || {},
135 channel[name](messageToSend, tabDetails);
138 getByBrowsingContext(expectedBrowsingContext) {
139 for (let tabDetails of AboutNewTabParent.loadedTabs.values()) {
140 if (tabDetails.browsingContext === expectedBrowsingContext) {
149 return lazy.AboutNewTab.activityStream?.store?.getMessageChannel();