Bug 1733622 [wpt PR 31061] - Allow 'transform' to be 'none' while animating., a=testonly
[gecko.git] / browser / actors / AboutPrivateBrowsingParent.jsm
blobc066a833c77bfb85dff5a61e97e4ac2d61d5d786
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 "use strict";
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(
16   this,
17   "MAX_SEARCH_BANNER_SHOW_COUNT",
18   "browser.search.separatePrivateDefault.ui.banner.max",
19   0
22 XPCOMUtils.defineLazyPreferenceGetter(
23   this,
24   "isPrivateSearchUIEnabled",
25   "browser.search.separatePrivateDefault.ui.enabled",
26   false
29 XPCOMUtils.defineLazyModuleGetters(this, {
30   Region: "resource://gre/modules/Region.jsm",
31   UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
32 });
34 // We only show the private search banner once per browser session.
35 let gSearchBannerShownThisSession;
37 class AboutPrivateBrowsingParent extends JSWindowActorParent {
38   constructor() {
39     super();
40     Services.telemetry.setEventRecordingEnabled("aboutprivatebrowsing", true);
41   }
42   // Used by tests
43   static setShownThisSession(shown) {
44     gSearchBannerShownThisSession = shown;
45   }
47   receiveMessage(aMessage) {
48     let browser = this.browsingContext.top.embedderElement;
49     if (!browser) {
50       return undefined;
51     }
53     let win = browser.ownerGlobal;
55     switch (aMessage.name) {
56       case "OpenPrivateWindow": {
57         win.OpenBrowserWindow({ private: true });
58         break;
59       }
60       case "OpenSearchPreferences": {
61         win.openPreferences("search", { origin: "about-privatebrowsing" });
62         break;
63       }
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();
71         } else {
72           // Pass the provided text to the awesomebar
73           urlBar.handoff(aMessage.data.text, searchEngine);
74           isFirstChange = false;
75         }
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
80           // in-content search.
81           if (isFirstChange) {
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);
88           }
89         };
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) {
94             checkFirstChange();
95           }
96           // If the Esc button is pressed, we are done. Show in-content search and cleanup.
97           if (ev.key === "Escape") {
98             onDone();
99           }
100         };
102         let onDone = ev => {
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);
114         };
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);
121         break;
122       }
123       case "ShouldShowSearch": {
124         let engineName = Services.prefs.getStringPref(
125           "browser.urlbar.placeholderName.private",
126           ""
127         );
128         let shouldHandOffToSearchMode = UrlbarPrefs.get(
129           "shouldHandOffToSearchMode"
130         );
131         return [engineName, shouldHandOffToSearchMode];
132       }
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") {
141           return null;
142         }
144         if (!isPrivateSearchUIEnabled || gSearchBannerShownThisSession) {
145           return null;
146         }
147         gSearchBannerShownThisSession = true;
148         const shownTimes = Services.prefs.getIntPref(SHOWN_PREF, 0);
149         if (shownTimes >= MAX_SEARCH_BANNER_SHOW_COUNT) {
150           return null;
151         }
152         Services.prefs.setIntPref(SHOWN_PREF, shownTimes + 1);
153         return new Promise(resolve => {
154           Services.search.getDefaultPrivate().then(engine => {
155             resolve(engine.name);
156           });
157         });
158       }
159       case "SearchBannerDismissed": {
160         Services.prefs.setIntPref(SHOWN_PREF, MAX_SEARCH_BANNER_SHOW_COUNT);
161         break;
162       }
163       case "ShouldShowVPNPromo": {
164         const homeRegion = Region.home || "";
165         const currentRegion = Region.current || "";
166         return (
167           homeRegion.toLowerCase() !== "cn" &&
168           currentRegion.toLowerCase() !== "cn" &&
169           Services.policies.status !== Services.policies.ACTIVE
170         );
171       }
172     }
174     return undefined;
175   }