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 { ASRouter } from "resource:///modules/asrouter/ASRouter.sys.mjs";
6 import { BrowserUtils } from "resource://gre/modules/BrowserUtils.sys.mjs";
7 import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
9 const SHOWN_PREF = "browser.search.separatePrivateDefault.ui.banner.shown";
11 XPCOMUtils.defineLazyPreferenceGetter(
13 "MAX_SEARCH_BANNER_SHOW_COUNT",
14 "browser.search.separatePrivateDefault.ui.banner.max",
18 XPCOMUtils.defineLazyPreferenceGetter(
20 "isPrivateSearchUIEnabled",
21 "browser.search.separatePrivateDefault.ui.enabled",
25 ChromeUtils.defineESModuleGetters(lazy, {
26 SpecialMessageActions:
27 "resource://messaging-system/lib/SpecialMessageActions.sys.mjs",
30 // We only show the private search banner once per browser session.
31 let gSearchBannerShownThisSession;
33 export class AboutPrivateBrowsingParent extends JSWindowActorParent {
36 Services.telemetry.setEventRecordingEnabled("aboutprivatebrowsing", true);
39 static setShownThisSession(shown) {
40 gSearchBannerShownThisSession = shown;
43 receiveMessage(aMessage) {
44 let browser = this.browsingContext.top.embedderElement;
49 let win = browser.ownerGlobal;
51 switch (aMessage.name) {
52 case "OpenPrivateWindow": {
53 win.OpenBrowserWindow({ private: true });
56 case "OpenSearchPreferences": {
57 win.openPreferences("search", { origin: "about-privatebrowsing" });
60 case "SearchHandoff": {
61 let urlBar = win.gURLBar;
62 let searchEngine = Services.search.defaultPrivateEngine;
63 let isFirstChange = true;
65 if (!aMessage.data || !aMessage.data.text) {
66 urlBar.setHiddenFocus();
68 // Pass the provided text to the awesomebar
69 urlBar.handoff(aMessage.data.text, searchEngine);
70 isFirstChange = false;
73 let checkFirstChange = () => {
74 // Check if this is the first change since we hidden focused. If it is,
75 // remove hidden focus styles, prepend the search alias and hide the
78 isFirstChange = false;
79 urlBar.removeHiddenFocus(true);
80 urlBar.handoff("", searchEngine);
81 this.sendAsyncMessage("DisableSearch");
82 urlBar.removeEventListener("compositionstart", checkFirstChange);
83 urlBar.removeEventListener("paste", checkFirstChange);
87 let onKeydown = ev => {
88 // Check if the keydown will cause a value change.
89 if (ev.key.length === 1 && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
92 // If the Esc button is pressed, we are done. Show in-content search and cleanup.
93 if (ev.key === "Escape") {
99 // We are done. Show in-content search again and cleanup.
100 this.sendAsyncMessage("ShowSearch");
102 const forceSuppressFocusBorder = ev?.type === "mousedown";
103 urlBar.removeHiddenFocus(forceSuppressFocusBorder);
105 urlBar.removeEventListener("keydown", onKeydown);
106 urlBar.removeEventListener("mousedown", onDone);
107 urlBar.removeEventListener("blur", onDone);
108 urlBar.removeEventListener("compositionstart", checkFirstChange);
109 urlBar.removeEventListener("paste", checkFirstChange);
112 urlBar.addEventListener("keydown", onKeydown);
113 urlBar.addEventListener("mousedown", onDone);
114 urlBar.addEventListener("blur", onDone);
115 urlBar.addEventListener("compositionstart", checkFirstChange);
116 urlBar.addEventListener("paste", checkFirstChange);
119 case "ShouldShowSearchBanner": {
120 // If this is a pre-loaded private browsing new tab, then we don't want
121 // to display the banner - it might never get displayed to the user
122 // and we won't know, or it might get displayed at the wrong time.
123 // This has the minor downside of not displaying the banner if
124 // you go into private browsing via opening a link, and then opening
125 // a new tab, we won't display the banner, for now, that's ok.
126 if (browser.getAttribute("preloadedState") === "preloaded") {
130 if (!lazy.isPrivateSearchUIEnabled || gSearchBannerShownThisSession) {
133 gSearchBannerShownThisSession = true;
134 const shownTimes = Services.prefs.getIntPref(SHOWN_PREF, 0);
135 if (shownTimes >= lazy.MAX_SEARCH_BANNER_SHOW_COUNT) {
138 Services.prefs.setIntPref(SHOWN_PREF, shownTimes + 1);
139 return new Promise(resolve => {
140 Services.search.getDefaultPrivate().then(engine => {
141 resolve(engine.name);
145 case "SearchBannerDismissed": {
146 Services.prefs.setIntPref(
148 lazy.MAX_SEARCH_BANNER_SHOW_COUNT
152 case "ShouldShowPromo": {
153 return BrowserUtils.shouldShowPromo(
154 BrowserUtils.PromoType[aMessage.data.type]
157 case "SpecialMessageActionDispatch": {
158 lazy.SpecialMessageActions.handleAction(aMessage.data, browser);
161 case "IsPromoBlocked": {
162 return !ASRouter.isUnblockedMessage(aMessage.data);