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/. */
7 var EXPORTED_SYMBOLS = ["AboutPrivateBrowsingParent"];
9 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
10 const { XPCOMUtils } = ChromeUtils.import(
11 "resource://gre/modules/XPCOMUtils.jsm"
14 const SHOWN_PREF = "browser.search.separatePrivateDefault.ui.banner.shown";
15 XPCOMUtils.defineLazyPreferenceGetter(
17 "MAX_SEARCH_BANNER_SHOW_COUNT",
18 "browser.search.separatePrivateDefault.ui.banner.max",
22 XPCOMUtils.defineLazyPreferenceGetter(
24 "isPrivateSearchUIEnabled",
25 "browser.search.separatePrivateDefault.ui.enabled",
29 XPCOMUtils.defineLazyModuleGetters(this, {
30 Region: "resource://gre/modules/Region.jsm",
31 UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
34 // We only show the private search banner once per browser session.
35 let gSearchBannerShownThisSession;
37 class AboutPrivateBrowsingParent extends JSWindowActorParent {
40 Services.telemetry.setEventRecordingEnabled("aboutprivatebrowsing", true);
43 static setShownThisSession(shown) {
44 gSearchBannerShownThisSession = shown;
47 receiveMessage(aMessage) {
48 let browser = this.browsingContext.top.embedderElement;
53 let win = browser.ownerGlobal;
55 switch (aMessage.name) {
56 case "OpenPrivateWindow": {
57 win.OpenBrowserWindow({ private: true });
60 case "OpenSearchPreferences": {
61 win.openPreferences("search", { origin: "about-privatebrowsing" });
64 case "SearchHandoff": {
65 let urlBar = win.gURLBar;
66 let searchEngine = Services.search.defaultPrivateEngine;
67 let isFirstChange = true;
69 if (!aMessage.data || !aMessage.data.text) {
70 urlBar.setHiddenFocus();
72 // Pass the provided text to the awesomebar
73 urlBar.handoff(aMessage.data.text, searchEngine);
74 isFirstChange = false;
77 let checkFirstChange = () => {
78 // Check if this is the first change since we hidden focused. If it is,
79 // remove hidden focus styles, prepend the search alias and hide the
82 isFirstChange = false;
83 urlBar.removeHiddenFocus(true);
84 urlBar.handoff("", searchEngine);
85 this.sendAsyncMessage("DisableSearch");
86 urlBar.removeEventListener("compositionstart", checkFirstChange);
87 urlBar.removeEventListener("paste", checkFirstChange);
91 let onKeydown = ev => {
92 // Check if the keydown will cause a value change.
93 if (ev.key.length === 1 && !ev.altKey && !ev.ctrlKey && !ev.metaKey) {
96 // If the Esc button is pressed, we are done. Show in-content search and cleanup.
97 if (ev.key === "Escape") {
103 // We are done. Show in-content search again and cleanup.
104 this.sendAsyncMessage("ShowSearch");
106 const forceSuppressFocusBorder = ev?.type === "mousedown";
107 urlBar.removeHiddenFocus(forceSuppressFocusBorder);
109 urlBar.removeEventListener("keydown", onKeydown);
110 urlBar.removeEventListener("mousedown", onDone);
111 urlBar.removeEventListener("blur", onDone);
112 urlBar.removeEventListener("compositionstart", checkFirstChange);
113 urlBar.removeEventListener("paste", checkFirstChange);
116 urlBar.addEventListener("keydown", onKeydown);
117 urlBar.addEventListener("mousedown", onDone);
118 urlBar.addEventListener("blur", onDone);
119 urlBar.addEventListener("compositionstart", checkFirstChange);
120 urlBar.addEventListener("paste", checkFirstChange);
123 case "ShouldShowSearch": {
124 let engineName = Services.prefs.getStringPref(
125 "browser.urlbar.placeholderName.private",
128 let shouldHandOffToSearchMode = UrlbarPrefs.get(
129 "shouldHandOffToSearchMode"
131 return [engineName, shouldHandOffToSearchMode];
133 case "ShouldShowSearchBanner": {
134 // If this is a pre-loaded private browsing new tab, then we don't want
135 // to display the banner - it might never get displayed to the user
136 // and we won't know, or it might get displayed at the wrong time.
137 // This has the minor downside of not displaying the banner if
138 // you go into private browsing via opening a link, and then opening
139 // a new tab, we won't display the banner, for now, that's ok.
140 if (browser.getAttribute("preloadedState") === "preloaded") {
144 if (!isPrivateSearchUIEnabled || gSearchBannerShownThisSession) {
147 gSearchBannerShownThisSession = true;
148 const shownTimes = Services.prefs.getIntPref(SHOWN_PREF, 0);
149 if (shownTimes >= MAX_SEARCH_BANNER_SHOW_COUNT) {
152 Services.prefs.setIntPref(SHOWN_PREF, shownTimes + 1);
153 return new Promise(resolve => {
154 Services.search.getDefaultPrivate().then(engine => {
155 resolve(engine.name);
159 case "SearchBannerDismissed": {
160 Services.prefs.setIntPref(SHOWN_PREF, MAX_SEARCH_BANNER_SHOW_COUNT);
163 case "ShouldShowVPNPromo": {
164 const homeRegion = Region.home || "";
165 const currentRegion = Region.current || "";
167 homeRegion.toLowerCase() !== "cn" &&
168 currentRegion.toLowerCase() !== "cn"