DownloadsTorWarning.sys.mjs (3765B)
1 /* import-globals-from /browser/base/content/utilityOverlay.js */ 2 3 const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning"; 4 5 /** 6 * Manages an instance of a tor warning. 7 */ 8 export class DownloadsTorWarning { 9 /** 10 * Observer for showing or hiding the warning. 11 * 12 * @type {function} 13 */ 14 #torWarningPrefObserver; 15 16 /** 17 * Whether the warning is active. 18 * 19 * @type {boolean} 20 */ 21 #active = false; 22 23 /** 24 * The moz-message-bar element that should show the warning. 25 * 26 * @type {MozMessageBar} 27 */ 28 #warningElement; 29 30 /** 31 * The dismiss button for the warning. 32 * 33 * @type {HTMLButton} 34 */ 35 #dismissButton; 36 37 /** 38 * Attach to an instance of the tor warning. 39 * 40 * @param {MozMessageBar} warningElement - The warning element to initialize 41 * and attach to. 42 * @param {boolean} isChrome - Whether the element belongs to the chrome. 43 * Otherwise it belongs to content. 44 * @param {function} moveFocus - Callback to move the focus out of the warning 45 * when it is hidden. 46 * @param {function} [onLinkClick] - Callback that is called when a link is 47 * about to open. 48 */ 49 constructor(warningElement, isChrome, moveFocus, onLinkClick) { 50 const doc = warningElement.ownerDocument; 51 this.#warningElement = warningElement; 52 warningElement.setAttribute( 53 "data-l10n-id", 54 "downloads-tor-warning-message-bar" 55 ); 56 warningElement.setAttribute("data-l10n-attrs", "heading, message"); 57 58 // Observe changes to the tor warning pref. 59 this.#torWarningPrefObserver = () => { 60 if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) { 61 warningElement.hidden = false; 62 } else { 63 const hadFocus = warningElement.contains(doc.activeElement); 64 warningElement.hidden = true; 65 if (hadFocus) { 66 moveFocus(); 67 } 68 } 69 }; 70 71 const tailsLink = doc.createElement("a"); 72 tailsLink.setAttribute("slot", "support-link"); 73 tailsLink.href = "https://tails.net/"; 74 tailsLink.target = "_blank"; 75 tailsLink.setAttribute("data-l10n-id", "downloads-tor-warning-tails-link"); 76 if (isChrome) { 77 // Intercept clicks on the tails link. 78 tailsLink.addEventListener("click", event => { 79 event.preventDefault(); 80 onLinkClick?.(); 81 doc.defaultView.openWebLinkIn(tailsLink.href, "tab"); 82 }); 83 } 84 85 const dismissButton = doc.createElement("button"); 86 dismissButton.setAttribute("slot", "actions"); 87 dismissButton.setAttribute( 88 "data-l10n-id", 89 "downloads-tor-warning-dismiss-button" 90 ); 91 if (isChrome) { 92 dismissButton.classList.add("footer-button"); 93 } 94 95 dismissButton.addEventListener("click", () => { 96 Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false); 97 }); 98 99 warningElement.append(tailsLink); 100 warningElement.append(dismissButton); 101 102 this.#dismissButton = dismissButton; 103 } 104 105 /** 106 * Whether the warning is hidden by the preference. 107 * 108 * @type {boolean} 109 */ 110 get hidden() { 111 return this.#warningElement.hidden; 112 } 113 114 /** 115 * The dismiss button for the warning. 116 * 117 * @type {HTMLButton} 118 */ 119 get dismissButton() { 120 return this.#dismissButton; 121 } 122 123 /** 124 * Activate the instance. 125 */ 126 activate() { 127 if (this.#active) { 128 return; 129 } 130 this.#active = true; 131 Services.prefs.addObserver( 132 PREF_SHOW_DOWNLOAD_WARNING, 133 this.#torWarningPrefObserver 134 ); 135 // Initialize. 136 this.#torWarningPrefObserver(); 137 } 138 139 /** 140 * Deactivate the instance. 141 */ 142 deactivate() { 143 if (!this.#active) { 144 return; 145 } 146 this.#active = false; 147 Services.prefs.removeObserver( 148 PREF_SHOW_DOWNLOAD_WARNING, 149 this.#torWarningPrefObserver 150 ); 151 } 152 }