AboutTorParent.sys.mjs (4405B)
1 import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; 2 3 const lazy = {}; 4 5 ChromeUtils.defineESModuleGetters(lazy, { 6 AboutTorMessage: "resource:///modules/AboutTorMessage.sys.mjs", 7 TorConnect: "resource://gre/modules/TorConnect.sys.mjs", 8 }); 9 10 const initializedActors = new Set(); 11 const onionizePref = "torbrowser.homepage.search.onionize"; 12 const surveyDismissVersionPref = "torbrowser.homepage.survey.dismiss_version"; 13 14 /** 15 * Actor parent class for the about:tor page. 16 */ 17 export class AboutTorParent extends JSWindowActorParent { 18 /** 19 * Whether the user has dismissed the Year End Campaign (YEC) banner this 20 * session. 21 * 22 * @type {boolean} 23 */ 24 static #dismissYEC = false; 25 26 /** 27 * Whether this instance has a preloaded browser. 28 * 29 * @type {boolean} 30 */ 31 #preloaded = false; 32 33 /** 34 * Method to be called when the browser corresponding to this actor has its 35 * preloadedState attribute removed. 36 */ 37 preloadedRemoved() { 38 if (!this.#preloaded) { 39 return; 40 } 41 this.#preloaded = false; 42 // Send in the initial data now that the page is actually going to be 43 // visible. 44 this.sendAsyncMessage( 45 "AboutTor:DelayedInitialData", 46 this.#getInitialData() 47 ); 48 } 49 50 /** 51 * Get the initial data for the page when it is about to be shown. 52 * 53 * @returns {object} - The initial data. 54 */ 55 #getInitialData() { 56 let appLocale = Services.locale.appLocaleAsBCP47; 57 if (appLocale === "ja-JP-macos") { 58 appLocale = "ja"; 59 } 60 61 return { 62 torConnectEnabled: lazy.TorConnect.enabled, 63 messageData: lazy.AboutTorMessage.getNext(), 64 isStable: AppConstants.MOZ_UPDATE_CHANNEL === "release", 65 searchOnionize: Services.prefs.getBoolPref(onionizePref, false), 66 surveyDismissVersion: Services.prefs.getIntPref( 67 surveyDismissVersionPref, 68 0 69 ), 70 appLocale, 71 dismissYEC: AboutTorParent.#dismissYEC, 72 }; 73 } 74 75 didDestroy() { 76 initializedActors.delete(this); 77 } 78 79 receiveMessage(message) { 80 switch (message.name) { 81 case "AboutTor:GetInitialData": { 82 // Track this actor to send future updates. 83 initializedActors.add(this); 84 85 const browser = this.browsingContext.top.embedderElement; 86 if (browser?.getAttribute("preloadedState") === "preloaded") { 87 // Wait until the page is actually about to be shown before sending 88 // the initial data. 89 // Otherwise the preloaded page might receive data that has expired by 90 // the time the page is shown. And it will iterate 91 // AboutTorMessage.getNext too early. See tor-browser#44314. 92 this.#preloaded = true; 93 return Promise.resolve(null); 94 } 95 return Promise.resolve(this.#getInitialData()); 96 } 97 case "AboutTor:SetSearchOnionize": 98 Services.prefs.setBoolPref(onionizePref, message.data); 99 break; 100 case "AboutTor:SurveyDismissed": 101 // The message.data contains the version of the current survey. 102 // Rather than introduce a new preference for each survey campaign we 103 // reuse the same integer preference and increase its value every time 104 // a new version of the survey is shown and dismissed by the user. 105 // I.e. if the preference value is 2, we will not show survey version 2 106 // but will show survey version 3 or higher when they are introduced. 107 // It should be safe to overwrite the value since we do not expect more 108 // than one active survey campaign at any given time, nor do we expect 109 // the version value to decrease. 110 Services.prefs.setIntPref(surveyDismissVersionPref, message.data); 111 break; 112 case "AboutTor:UserDismissedYEC": 113 AboutTorParent.#dismissYEC = true; 114 for (const actor of initializedActors) { 115 if (actor === this) { 116 // Don't send to ourselves. 117 continue; 118 } 119 // Tell all existing instances to also close the banner, if they still 120 // exist. 121 // NOTE: If the user's new tab page is `about:tor`, this may include 122 // some preloaded pages that have not been made visible yet (see 123 // NewTabPagePreloading). 124 try { 125 actor.sendAsyncMessage("AboutTor:DismissYEC"); 126 } catch {} 127 } 128 break; 129 } 130 return undefined; 131 } 132 }