Bug 1845017 - Disable the TestPHCExhaustion test r=glandium
[gecko.git] / browser / actors / AboutNewTabParent.sys.mjs
blobbb1a0b6f7141a5d909d5c04c816c2ad549f8899b
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";
7 const lazy = {};
9 ChromeUtils.defineESModuleGetters(lazy, {
10   AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
11 });
13 XPCOMUtils.defineLazyModuleGetters(lazy, {
14   ASRouter: "resource://activity-stream/lib/ASRouter.jsm",
15 });
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() {
23     return gLoadedTabs;
24   }
26   getTabDetails(message) {
27     let browsingContext = message.target.browsingContext;
28     let browser = browsingContext.top.embedderElement;
29     return browser ? gLoadedTabs.get(browser) : null;
30   }
32   handleEvent(event) {
33     if (event.type == "SwapDocShells") {
34       let oldBrowser = this.browsingContext.top.embedderElement;
35       let newBrowser = event.detail;
37       let tabDetails = gLoadedTabs.get(oldBrowser);
38       if (tabDetails) {
39         tabDetails.browser = newBrowser;
40         gLoadedTabs.delete(oldBrowser);
41         gLoadedTabs.set(newBrowser, tabDetails);
43         oldBrowser.removeEventListener("SwapDocShells", this);
44         newBrowser.addEventListener("SwapDocShells", this);
45       }
46     }
47   }
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" },
58         });
59         break;
61       case "Init": {
62         let actor = message.target;
63         let browsingContext = actor.browsingContext;
64         let browser = browsingContext.top.embedderElement;
65         if (!browser) {
66           return;
67         }
69         let tabDetails = {
70           actor,
71           browser,
72           browsingContext,
73           portID: message.data.portID,
74           url: message.data.url,
75         };
76         gLoadedTabs.set(browser, tabDetails);
78         browser.addEventListener("SwapDocShells", this);
79         browser.addEventListener("EndSwapDocShells", this);
81         this.notifyActivityStreamChannel("onNewTabInit", message, tabDetails);
82         break;
83       }
85       case "Load":
86         this.notifyActivityStreamChannel("onNewTabLoad", message);
87         break;
89       case "Unload": {
90         let tabDetails = this.getTabDetails(message);
91         if (!tabDetails) {
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
96           );
97         }
99         if (!tabDetails) {
100           return;
101         }
103         tabDetails.browser.removeEventListener("EndSwapDocShells", this);
105         gLoadedTabs.delete(tabDetails.browser);
107         this.notifyActivityStreamChannel("onNewTabUnload", message, tabDetails);
108         break;
109       }
111       case "ActivityStream:ContentToMain":
112         this.notifyActivityStreamChannel("onMessage", message);
113         break;
114     }
115   }
117   notifyActivityStreamChannel(name, message, tabDetails) {
118     if (!tabDetails) {
119       tabDetails = this.getTabDetails(message);
120       if (!tabDetails) {
121         return;
122       }
123     }
125     let channel = this.getChannel();
126     if (!channel) {
127       return;
128     }
130     let messageToSend = {
131       target: message.target,
132       data: message.data || {},
133     };
135     channel[name](messageToSend, tabDetails);
136   }
138   getByBrowsingContext(expectedBrowsingContext) {
139     for (let tabDetails of AboutNewTabParent.loadedTabs.values()) {
140       if (tabDetails.browsingContext === expectedBrowsingContext) {
141         return tabDetails;
142       }
143     }
145     return null;
146   }
148   getChannel() {
149     return lazy.AboutNewTab.activityStream?.store?.getMessageChannel();
150   }