ma1 pushed to branch tor-browser-102.12.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
787ac906
by Dan Ballard at 2023-06-06T20:52:51+00:00
11 changed files:
- browser/components/downloads/content/allDownloadsView.js
- browser/components/downloads/content/contentAreaDownloadsView.js
- browser/components/downloads/content/contentAreaDownloadsView.xhtml
- browser/components/downloads/content/downloads.css
- browser/components/downloads/content/downloads.js
- browser/components/downloads/content/downloadsPanel.inc.xhtml
- browser/components/places/content/places.css
- browser/components/places/content/places.js
- browser/components/places/content/places.xhtml
- browser/themes/shared/customizableui/panelUI-shared.css
- browser/themes/shared/downloads/contentAreaDownloadsView.css
Changes:
... | ... | @@ -212,6 +212,7 @@ var DownloadsView = { |
212 | 212 | */
|
213 | 213 | function DownloadsPlacesView(
|
214 | 214 | aRichListBox,
|
215 | + torWarningMessageBar,
|
|
215 | 216 | aActive = true,
|
216 | 217 | aSuppressionFlag = DownloadsCommon.SUPPRESS_ALL_DOWNLOADS_OPEN
|
217 | 218 | ) {
|
... | ... | @@ -241,6 +242,46 @@ function DownloadsPlacesView( |
241 | 242 | ).attentionSuppressed |= aSuppressionFlag;
|
242 | 243 | }
|
243 | 244 | |
245 | + // Tor browser warning message/alert shown above the list.
|
|
246 | + |
|
247 | + const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning";
|
|
248 | + // Observe changes to the tor warning pref.
|
|
249 | + const torWarningPrefObserver = () => {
|
|
250 | + if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) {
|
|
251 | + torWarningMessageBar.hidden = false;
|
|
252 | + } else {
|
|
253 | + // Re-assign focus if it is about to be lost.
|
|
254 | + if (torWarningMessageBar.contains(document.activeElement)) {
|
|
255 | + // Try and focus the downloads list.
|
|
256 | + // NOTE: If #downloadsListBox is still hidden, this will do nothing.
|
|
257 | + // But in this case there are no other focusable targets within the
|
|
258 | + // view, so we just leave it up to the focus handler.
|
|
259 | + this._richlistbox.focus({ preventFocusRing: true });
|
|
260 | + }
|
|
261 | + torWarningMessageBar.hidden = true;
|
|
262 | + }
|
|
263 | + };
|
|
264 | + |
|
265 | + Services.prefs.addObserver(
|
|
266 | + PREF_SHOW_DOWNLOAD_WARNING,
|
|
267 | + torWarningPrefObserver
|
|
268 | + );
|
|
269 | + // Initialize.
|
|
270 | + torWarningPrefObserver();
|
|
271 | + |
|
272 | + window.addEventListener("unload", () => {
|
|
273 | + Services.prefs.removeObserver(
|
|
274 | + PREF_SHOW_DOWNLOAD_WARNING,
|
|
275 | + torWarningPrefObserver
|
|
276 | + );
|
|
277 | + });
|
|
278 | + |
|
279 | + torWarningMessageBar
|
|
280 | + .querySelector(".downloads-tor-warning-dismiss-button")
|
|
281 | + .addEventListener("click", event => {
|
|
282 | + Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
|
|
283 | + });
|
|
284 | + |
|
244 | 285 | // Make sure to unregister the view if the window is closed.
|
245 | 286 | window.addEventListener(
|
246 | 287 | "unload",
|
... | ... | @@ -10,6 +10,9 @@ const { PrivateBrowsingUtils } = ChromeUtils.import( |
10 | 10 | |
11 | 11 | var ContentAreaDownloadsView = {
|
12 | 12 | init() {
|
13 | + const torWarningMessage = document.getElementById(
|
|
14 | + "aboutDownloadsTorWarning"
|
|
15 | + );
|
|
13 | 16 | let box = document.getElementById("downloadsListBox");
|
14 | 17 | let suppressionFlag = DownloadsCommon.SUPPRESS_CONTENT_AREA_DOWNLOADS_OPEN;
|
15 | 18 | box.addEventListener(
|
... | ... | @@ -17,9 +20,22 @@ var ContentAreaDownloadsView = { |
17 | 20 | () => {
|
18 | 21 | // Set focus to Downloads list once it is created
|
19 | 22 | // And prevent it from showing the focus ring around the richlistbox (Bug 1702694)
|
20 | - document
|
|
21 | - .getElementById("downloadsListBox")
|
|
22 | - .focus({ preventFocusRing: true });
|
|
23 | + // Prevent focusing the list whilst the tor browser warning is shown.
|
|
24 | + // Some screen readers (tested with Orca and NVDA) will not read out
|
|
25 | + // alerts if they are already present on page load. In that case, a
|
|
26 | + // screen reader user may not be aware of the warning before they
|
|
27 | + // interact with the downloads list, which we do not want.
|
|
28 | + // Some hacky workarounds were tested with Orca to get it to read back
|
|
29 | + // the alert before the focus is read, but this was inconsistent and the
|
|
30 | + // experience was bad.
|
|
31 | + // Without auto-focusing the downloads list, a screen reader should not
|
|
32 | + // skip beyond the alert's content.
|
|
33 | + if (torWarningMessage.hidden) {
|
|
34 | + document
|
|
35 | + .getElementById("downloadsListBox")
|
|
36 | + .focus({ preventFocusRing: true });
|
|
37 | + }
|
|
38 | + |
|
23 | 39 | // Pause the indicator if the browser is active.
|
24 | 40 | if (document.visibilityState === "visible") {
|
25 | 41 | DownloadsCommon.getIndicatorData(
|
... | ... | @@ -29,7 +45,12 @@ var ContentAreaDownloadsView = { |
29 | 45 | },
|
30 | 46 | { once: true }
|
31 | 47 | );
|
32 | - let view = new DownloadsPlacesView(box, true, suppressionFlag);
|
|
48 | + let view = new DownloadsPlacesView(
|
|
49 | + box,
|
|
50 | + torWarningMessage,
|
|
51 | + true,
|
|
52 | + suppressionFlag
|
|
53 | + );
|
|
33 | 54 | document.addEventListener("visibilitychange", aEvent => {
|
34 | 55 | let indicator = DownloadsCommon.getIndicatorData(window);
|
35 | 56 | if (document.visibilityState === "visible") {
|
... | ... | @@ -42,6 +63,53 @@ var ContentAreaDownloadsView = { |
42 | 63 | if (!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
|
43 | 64 | view.place = "place:transition=7&sort=4";
|
44 | 65 | }
|
66 | + |
|
67 | + torWarningMessage.querySelector(
|
|
68 | + ".downloads-tor-warning-title"
|
|
69 | + ).textContent = this._getTorString("torbutton.download.warning.title");
|
|
70 | + |
|
71 | + const tailsLink = document.createElement("a");
|
|
72 | + tailsLink.href = "https://tails.boum.org/";
|
|
73 | + tailsLink.target = "_blank";
|
|
74 | + tailsLink.textContent = this._getTorString(
|
|
75 | + "torbutton.download.warning.tails_brand_name"
|
|
76 | + );
|
|
77 | + |
|
78 | + const [beforeLink, afterLink] = this._getTorString(
|
|
79 | + "torbutton.download.warning.description"
|
|
80 | + ).split("%S");
|
|
81 | + |
|
82 | + torWarningMessage
|
|
83 | + .querySelector(".downloads-tor-warning-description")
|
|
84 | + .append(beforeLink, tailsLink, afterLink);
|
|
85 | + |
|
86 | + torWarningMessage.querySelector(
|
|
87 | + ".downloads-tor-warning-dismiss-button"
|
|
88 | + ).textContent = this._getTorString("torbutton.download.warning.dismiss");
|
|
89 | + },
|
|
90 | + |
|
91 | + /**
|
|
92 | + * Get a string from the properties bundle.
|
|
93 | + *
|
|
94 | + * @param {string} name - The string name.
|
|
95 | + *
|
|
96 | + * @return {string} The string.
|
|
97 | + */
|
|
98 | + _getTorString(name) {
|
|
99 | + if (!this._stringBundle) {
|
|
100 | + this._stringBundle = Services.strings.createBundle(
|
|
101 | + "chrome://torbutton/locale/torbutton.properties"
|
|
102 | + );
|
|
103 | + }
|
|
104 | + try {
|
|
105 | + return this._stringBundle.GetStringFromName(name);
|
|
106 | + } catch {}
|
|
107 | + if (!this._fallbackStringBundle) {
|
|
108 | + this._fallbackStringBundle = Services.strings.createBundle(
|
|
109 | + "resource://torbutton/locale/en-US/torbutton.properties"
|
|
110 | + );
|
|
111 | + }
|
|
112 | + return this._fallbackStringBundle.GetStringFromName(name);
|
|
45 | 113 | },
|
46 | 114 | };
|
47 | 115 |
... | ... | @@ -39,6 +39,23 @@ |
39 | 39 | </keyset>
|
40 | 40 | #endif
|
41 | 41 | |
42 | + <html:message-bar id="aboutDownloadsTorWarning"
|
|
43 | + class="downloads-tor-warning-message-bar"
|
|
44 | + role="alert"
|
|
45 | + aria-labelledby="aboutDownloadsTorWarningTitle"
|
|
46 | + aria-describedby="aboutDownloadsTorWarningDescription">
|
|
47 | + <html:div class="downloads-tor-warning-grid">
|
|
48 | + <html:p id="aboutDownloadsTorWarningTitle"
|
|
49 | + class="downloads-tor-warning-title">
|
|
50 | + </html:p>
|
|
51 | + <html:p id="aboutDownloadsTorWarningDescription"
|
|
52 | + class="downloads-tor-warning-description">
|
|
53 | + </html:p>
|
|
54 | + <html:button class="downloads-tor-warning-dismiss-button">
|
|
55 | + </html:button>
|
|
56 | + </html:div>
|
|
57 | + </html:message-bar>
|
|
58 | + |
|
42 | 59 | <richlistbox flex="1"
|
43 | 60 | seltype="multiple"
|
44 | 61 | id="downloadsListBox"
|
... | ... | @@ -104,18 +104,52 @@ |
104 | 104 | flex-direction: column;
|
105 | 105 | }
|
106 | 106 | |
107 | -#downloadsWarning p {
|
|
108 | - padding-inline: 8px;
|
|
109 | - margin-block-start: 8px;
|
|
110 | - margin-block-end: 0;
|
|
107 | +.downloads-tor-warning-grid {
|
|
108 | + display: grid;
|
|
109 | + grid-template:
|
|
110 | + "title button" min-content
|
|
111 | + "description button" auto
|
|
112 | + / 1fr max-content;
|
|
113 | + gap: 8px;
|
|
114 | + margin-block: 8px;
|
|
115 | + /* Some extra space between the text and the icon. */
|
|
116 | + margin-inline-start: 8px;
|
|
117 | +}
|
|
118 | + |
|
119 | +.downloads-tor-warning-grid .downloads-tor-warning-title {
|
|
120 | + grid-area: title;
|
|
121 | + margin: 0;
|
|
122 | +}
|
|
123 | + |
|
124 | +.downloads-tor-warning-grid .downloads-tor-warning-description {
|
|
125 | + grid-area: description;
|
|
126 | + margin: 0;
|
|
127 | +}
|
|
128 | + |
|
129 | +.downloads-tor-warning-grid .downloads-tor-warning-dismiss-button {
|
|
130 | + grid-area: button;
|
|
131 | + align-self: center;
|
|
132 | +}
|
|
133 | + |
|
134 | +.downloads-tor-warning-description,
|
|
135 | +.downloads-tor-warning-title {
|
|
111 | 136 | line-height: 1.4;
|
112 | 137 | }
|
113 | 138 | |
114 | -#downloadsWarningHeaderTitle {
|
|
139 | +.downloads-tor-warning-title {
|
|
115 | 140 | font-weight: bold;
|
116 | 141 | }
|
117 | 142 | |
118 | -#downloadsWarningDescription {
|
|
143 | +#downloadsPanelTorWarning :is(
|
|
144 | + .downloads-tor-warning-description,
|
|
145 | + .downloads-tor-warning-title
|
|
146 | +) {
|
|
147 | + padding-inline: 8px;
|
|
148 | + margin-block-start: 8px;
|
|
149 | + margin-block-end: 0;
|
|
150 | +}
|
|
151 | + |
|
152 | +#downloadsPanelTorWarningDescription {
|
|
119 | 153 | /* Make sure we wrap the text rather than request the default max-content
|
120 | 154 | * width from the parent XUL -moz-box. */
|
121 | 155 | width: 0;
|
... | ... | @@ -33,8 +33,6 @@ |
33 | 33 | |
34 | 34 | const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning";
|
35 | 35 | |
36 | -const TAILS_URI = "https://tails.boum.org/";
|
|
37 | - |
|
38 | 36 | var { XPCOMUtils } = ChromeUtils.import(
|
39 | 37 | "resource://gre/modules/XPCOMUtils.jsm"
|
40 | 38 | );
|
... | ... | @@ -143,13 +141,28 @@ var DownloadsPanel = { |
143 | 141 | );
|
144 | 142 | }
|
145 | 143 | |
146 | - let showDownloadWarning = Services.prefs.getBoolPref(
|
|
147 | - PREF_SHOW_DOWNLOAD_WARNING
|
|
144 | + const torWarningMessage = document.getElementById(
|
|
145 | + "downloadsPanelTorWarning"
|
|
148 | 146 | );
|
149 | - if (!showDownloadWarning) {
|
|
150 | - document.getElementById("downloadsWarning").hidden = true;
|
|
151 | - } else {
|
|
152 | - document.getElementById("downloadsWarning").hidden = false;
|
|
147 | + if (!this._torWarningPrefObserver) {
|
|
148 | + // Observe changes to the tor warning pref.
|
|
149 | + this._torWarningPrefObserver = () => {
|
|
150 | + if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) {
|
|
151 | + torWarningMessage.hidden = false;
|
|
152 | + } else {
|
|
153 | + // Re-assign focus if it is about to be lost.
|
|
154 | + if (torWarningMessage.contains(document.activeElement)) {
|
|
155 | + this._focusPanel(true);
|
|
156 | + }
|
|
157 | + torWarningMessage.hidden = true;
|
|
158 | + }
|
|
159 | + };
|
|
160 | + Services.prefs.addObserver(
|
|
161 | + PREF_SHOW_DOWNLOAD_WARNING,
|
|
162 | + this._torWarningPrefObserver
|
|
163 | + );
|
|
164 | + // Initialize
|
|
165 | + this._torWarningPrefObserver();
|
|
153 | 166 | }
|
154 | 167 | |
155 | 168 | if (this._state != this.kStateUninitialized) {
|
... | ... | @@ -175,42 +188,40 @@ var DownloadsPanel = { |
175 | 188 | DownloadsSummary
|
176 | 189 | );
|
177 | 190 | |
178 | - if (this._torWarningInitialized == 0) {
|
|
179 | - document.getElementById(
|
|
180 | - "downloadsWarningHeaderTitle"
|
|
181 | - ).textContent = this._getString("torbutton.download.warning.title");
|
|
182 | - let tailsBrandName = this._getString(
|
|
183 | - "torbutton.download.warning.tails_brand_name"
|
|
184 | - );
|
|
191 | + if (!this._torWarningInitialized) {
|
|
192 | + torWarningMessage.querySelector(
|
|
193 | + ".downloads-tor-warning-title"
|
|
194 | + ).textContent = this._getTorString("torbutton.download.warning.title");
|
|
185 | 195 | |
186 | - let warningDescriptionText = this._getString(
|
|
187 | - "torbutton.download.warning.description"
|
|
188 | - );
|
|
189 | - let [head, rest] = warningDescriptionText.split("%S");
|
|
190 | 196 | const tailsLink = document.createElement("a");
|
191 | - tailsLink.setAttribute("href", TAILS_URI);
|
|
192 | - tailsLink.textContent = tailsBrandName.trim();
|
|
197 | + tailsLink.href = "https://tails.boum.org/";
|
|
198 | + tailsLink.textContent = this._getTorString(
|
|
199 | + "torbutton.download.warning.tails_brand_name"
|
|
200 | + );
|
|
193 | 201 | tailsLink.addEventListener("click", event => {
|
194 | 202 | event.preventDefault();
|
195 | 203 | this.hidePanel();
|
196 | - openWebLinkIn(TAILS_URI, "tab");
|
|
204 | + openWebLinkIn(tailsLink.href, "tab");
|
|
197 | 205 | });
|
198 | 206 | |
199 | - let downloadsWarningDescription = document.getElementById(
|
|
200 | - "downloadsWarningDescription"
|
|
201 | - );
|
|
202 | - downloadsWarningDescription.append(head, tailsLink, rest);
|
|
207 | + const [beforeLink, afterLink] = this._getTorString(
|
|
208 | + "torbutton.download.warning.description"
|
|
209 | + ).split("%S");
|
|
210 | + |
|
211 | + torWarningMessage
|
|
212 | + .querySelector(".downloads-tor-warning-description")
|
|
213 | + .append(beforeLink, tailsLink, afterLink);
|
|
203 | 214 | |
204 | - let dismissBtn = document.getElementById(
|
|
205 | - "downloadWarningDismiss"
|
|
215 | + let dismissButton = torWarningMessage.querySelector(
|
|
216 | + ".downloads-tor-warning-dismiss-button"
|
|
206 | 217 | );
|
207 | - dismissBtn.textContent = this._getString("torbutton.download.warning.dismiss");
|
|
208 | - dismissBtn.addEventListener("click", event => {
|
|
218 | + dismissButton.textContent = this._getTorString(
|
|
219 | + "torbutton.download.warning.dismiss"
|
|
220 | + );
|
|
221 | + dismissButton.addEventListener("click", event => {
|
|
209 | 222 | Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
|
210 | - document.getElementById("downloadsWarning").hidden = true;
|
|
211 | - this._focusPanel(true);
|
|
212 | 223 | });
|
213 | - this._torWarningInitialized = 1;
|
|
224 | + this._torWarningInitialized = true;
|
|
214 | 225 | }
|
215 | 226 | |
216 | 227 | DownloadsCommon.log(
|
... | ... | @@ -254,6 +265,14 @@ var DownloadsPanel = { |
254 | 265 | );
|
255 | 266 | }
|
256 | 267 | |
268 | + if (this._torWarningPrefObserver) {
|
|
269 | + Services.prefs.removeObserver(
|
|
270 | + PREF_SHOW_DOWNLOAD_WARNING,
|
|
271 | + this._torWarningPrefObserver
|
|
272 | + );
|
|
273 | + delete this._torWarningPrefObserver;
|
|
274 | + }
|
|
275 | + |
|
257 | 276 | this._state = this.kStateUninitialized;
|
258 | 277 | |
259 | 278 | DownloadsSummary.active = false;
|
... | ... | @@ -591,14 +610,17 @@ var DownloadsPanel = { |
591 | 610 | *
|
592 | 611 | * @param {bool} [forceFocus=false] - Whether to force move the focus.
|
593 | 612 | */
|
594 | - _focusPanel(forceFocus=false) {
|
|
613 | + _focusPanel(forceFocus = false) {
|
|
595 | 614 | if (!forceFocus) {
|
596 | 615 | // We may be invoked while the panel is still waiting to be shown.
|
597 | 616 | if (this._state != this.kStateShown) {
|
598 | 617 | return;
|
599 | 618 | }
|
600 | 619 | |
601 | - if (document.activeElement && this.panel.contains(document.activeElement)) {
|
|
620 | + if (
|
|
621 | + document.activeElement &&
|
|
622 | + this.panel.contains(document.activeElement)
|
|
623 | + ) {
|
|
602 | 624 | return;
|
603 | 625 | }
|
604 | 626 | }
|
... | ... | @@ -729,7 +751,7 @@ var DownloadsPanel = { |
729 | 751 | *
|
730 | 752 | * @return {string} The string.
|
731 | 753 | */
|
732 | - _getString(name) {
|
|
754 | + _getTorString(name) {
|
|
733 | 755 | if (!this._stringBundle) {
|
734 | 756 | this._stringBundle = Services.strings.createBundle(
|
735 | 757 | "chrome://torbutton/locale/torbutton.properties"
|
... | ... | @@ -124,16 +124,19 @@ |
124 | 124 | disablekeynav="true">
|
125 | 125 | |
126 | 126 | <panelview id="downloadsPanel-mainView">
|
127 | - <vbox id="downloadsWarning">
|
|
127 | + <vbox id="downloadsPanelTorWarning">
|
|
128 | 128 | <vbox role="alert"
|
129 | - aria-labelledby="downloadsWarningHeaderTitle"
|
|
130 | - aria-describedby="downloadsWarningDescription">
|
|
131 | - <html:p id="downloadsWarningHeaderTitle"></html:p>
|
|
132 | - <html:p id="downloadsWarningDescription">
|
|
129 | + aria-labelledby="downloadsPanelTorWarningTitle"
|
|
130 | + aria-describedby="downloadsPanelTorWarningDescription">
|
|
131 | + <html:p id="downloadsPanelTorWarningTitle"
|
|
132 | + class="downloads-tor-warning-title">
|
|
133 | + </html:p>
|
|
134 | + <html:p id="downloadsPanelTorWarningDescription"
|
|
135 | + class="downloads-tor-warning-description">
|
|
133 | 136 | </html:p>
|
134 | 137 | |
135 | 138 | <html:div class="panel-footer">
|
136 | - <html:button id="downloadWarningDismiss">
|
|
139 | + <html:button class="downloads-tor-warning-dismiss-button">
|
|
137 | 140 | </html:button>
|
138 | 141 | </html:div>
|
139 | 142 | </vbox>
|
... | ... | @@ -126,3 +126,7 @@ tree[is="places-tree"] > treechildren::-moz-tree-cell { |
126 | 126 | margin: 2px 4px;
|
127 | 127 | color: currentColor;
|
128 | 128 | }
|
129 | + |
|
130 | +#placesDownloadsTorWarning:not(.downloads-visible) {
|
|
131 | + display: none;
|
|
132 | +} |
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | /* import-globals-from instantEditBookmark.js */
|
7 | 7 | /* import-globals-from /toolkit/content/contentAreaUtils.js */
|
8 | 8 | /* import-globals-from /browser/components/downloads/content/allDownloadsView.js */
|
9 | +/* import-globals-from /browser/base/content/utilityOverlay.js */
|
|
9 | 10 | |
10 | 11 | /* Shared Places Import - change other consumers if you change this: */
|
11 | 12 | var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
... | ... | @@ -164,11 +165,15 @@ var PlacesOrganizer = { |
164 | 165 | "&sort=" +
|
165 | 166 | Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING;
|
166 | 167 | |
168 | + const torWarningMessage = document.getElementById(
|
|
169 | + "placesDownloadsTorWarning"
|
|
170 | + );
|
|
167 | 171 | ContentArea.setContentViewForQueryString(
|
168 | 172 | DOWNLOADS_QUERY,
|
169 | 173 | () =>
|
170 | 174 | new DownloadsPlacesView(
|
171 | 175 | document.getElementById("downloadsListBox"),
|
176 | + torWarningMessage,
|
|
172 | 177 | false
|
173 | 178 | ),
|
174 | 179 | {
|
... | ... | @@ -178,6 +183,33 @@ var PlacesOrganizer = { |
178 | 183 | }
|
179 | 184 | );
|
180 | 185 | |
186 | + // Initialize tor warning text content.
|
|
187 | + torWarningMessage.querySelector(
|
|
188 | + ".downloads-tor-warning-title"
|
|
189 | + ).textContent = this._getTorString("torbutton.download.warning.title");
|
|
190 | + |
|
191 | + const tailsLink = document.createElement("a");
|
|
192 | + tailsLink.href = "https://tails.boum.org/";
|
|
193 | + tailsLink.textContent = this._getTorString(
|
|
194 | + "torbutton.download.warning.tails_brand_name"
|
|
195 | + );
|
|
196 | + tailsLink.addEventListener("click", event => {
|
|
197 | + event.preventDefault();
|
|
198 | + openWebLinkIn(tailsLink.href, "tab");
|
|
199 | + });
|
|
200 | + |
|
201 | + const [beforeLink, afterLink] = this._getTorString(
|
|
202 | + "torbutton.download.warning.description"
|
|
203 | + ).split("%S");
|
|
204 | + |
|
205 | + torWarningMessage
|
|
206 | + .querySelector(".downloads-tor-warning-description")
|
|
207 | + .append(beforeLink, tailsLink, afterLink);
|
|
208 | + |
|
209 | + torWarningMessage.querySelector(
|
|
210 | + ".downloads-tor-warning-dismiss-button"
|
|
211 | + ).textContent = this._getTorString("torbutton.download.warning.dismiss");
|
|
212 | + |
|
181 | 213 | ContentArea.init();
|
182 | 214 | |
183 | 215 | this._places = document.getElementById("placesList");
|
... | ... | @@ -246,6 +278,30 @@ var PlacesOrganizer = { |
246 | 278 | ContentArea.focus();
|
247 | 279 | },
|
248 | 280 | |
281 | + /**
|
|
282 | + * Get a string from the properties bundle.
|
|
283 | + *
|
|
284 | + * @param {string} name - The string name.
|
|
285 | + *
|
|
286 | + * @returns {string} The string.
|
|
287 | + */
|
|
288 | + _getTorString(name) {
|
|
289 | + if (!this._stringBundle) {
|
|
290 | + this._stringBundle = Services.strings.createBundle(
|
|
291 | + "chrome://torbutton/locale/torbutton.properties"
|
|
292 | + );
|
|
293 | + }
|
|
294 | + try {
|
|
295 | + return this._stringBundle.GetStringFromName(name);
|
|
296 | + } catch {}
|
|
297 | + if (!this._fallbackStringBundle) {
|
|
298 | + this._fallbackStringBundle = Services.strings.createBundle(
|
|
299 | + "resource://torbutton/locale/en-US/torbutton.properties"
|
|
300 | + );
|
|
301 | + }
|
|
302 | + return this._fallbackStringBundle.GetStringFromName(name);
|
|
303 | + },
|
|
304 | + |
|
249 | 305 | QueryInterface: ChromeUtils.generateQI([]),
|
250 | 306 | |
251 | 307 | handleEvent: function PO_handleEvent(aEvent) {
|
... | ... | @@ -1386,9 +1442,20 @@ var ContentArea = { |
1386 | 1442 | oldView.associatedElement.hidden = true;
|
1387 | 1443 | aNewView.associatedElement.hidden = false;
|
1388 | 1444 | |
1445 | + const isDownloads = aNewView.associatedElement.id === "downloadsListBox";
|
|
1446 | + const torWarningMessage = document.getElementById(
|
|
1447 | + "placesDownloadsTorWarning"
|
|
1448 | + );
|
|
1449 | + const torWarningLoosingFocus =
|
|
1450 | + torWarningMessage.contains(document.activeElement) && !isDownloads;
|
|
1451 | + torWarningMessage.classList.toggle("downloads-visible", isDownloads);
|
|
1452 | + |
|
1389 | 1453 | // If the content area inactivated view was focused, move focus
|
1390 | 1454 | // to the new view.
|
1391 | - if (document.activeElement == oldView.associatedElement) {
|
|
1455 | + if (
|
|
1456 | + document.activeElement == oldView.associatedElement ||
|
|
1457 | + torWarningLoosingFocus
|
|
1458 | + ) {
|
|
1392 | 1459 | aNewView.associatedElement.focus();
|
1393 | 1460 | }
|
1394 | 1461 | }
|
... | ... | @@ -345,6 +345,21 @@ |
345 | 345 | </tree>
|
346 | 346 | <splitter collapse="none" persist="state"></splitter>
|
347 | 347 | <vbox id="contentView" flex="4">
|
348 | + <html:message-bar id="placesDownloadsTorWarning"
|
|
349 | + role="alert"
|
|
350 | + aria-labelledby="placesDownloadsTorWarningTitle"
|
|
351 | + aria-describedby="placesDownloadsTorWarningDescription">
|
|
352 | + <html:div class="downloads-tor-warning-grid">
|
|
353 | + <html:p id="placesDownloadsTorWarningTitle"
|
|
354 | + class="downloads-tor-warning-title">
|
|
355 | + </html:p>
|
|
356 | + <html:p id="placesDownloadsTorWarningDescription"
|
|
357 | + class="downloads-tor-warning-description">
|
|
358 | + </html:p>
|
|
359 | + <html:button class="downloads-tor-warning-dismiss-button">
|
|
360 | + </html:button>
|
|
361 | + </html:div>
|
|
362 | + </html:message-bar>
|
|
348 | 363 | <vbox id="placesViewsBox" flex="1">
|
349 | 364 | <tree id="placeContent"
|
350 | 365 | class="plain placesTree"
|
... | ... | @@ -1324,7 +1324,7 @@ panelview .toolbarbutton-1 { |
1324 | 1324 | #downloadsFooterButtons > toolbarseparator,
|
1325 | 1325 | .cui-widget-panelview menuseparator,
|
1326 | 1326 | .cui-widget-panel toolbarseparator,
|
1327 | -#downloadsWarning toolbarseparator,
|
|
1327 | +#downloadsPanelTorWarning toolbarseparator,
|
|
1328 | 1328 | #securityLevel-panel toolbarseparator {
|
1329 | 1329 | appearance: none;
|
1330 | 1330 | min-height: 0;
|
... | ... | @@ -25,3 +25,7 @@ |
25 | 25 | text-align: center;
|
26 | 26 | color: var(--in-content-deemphasized-text);
|
27 | 27 | }
|
28 | + |
|
29 | +#aboutDownloadsTorWarning {
|
|
30 | + margin-block-end: 8px;
|
|
31 | +} |