Commits:
-
8a68fba1
by Henry Wilkes at 2024-08-21T19:22:49+00:00
fixup! Bug 40701: Add security warning when downloading a file
Bug 41820: Convert downloads warning to moz-message-bar.
Move the logic to DownloadsTorWarning.sys.mjs so it remains in one
place.
-
49c2f08e
by Henry Wilkes at 2024-08-21T19:22:49+00:00
fixup! Tor Browser strings
Bug 41820: Use moz-message-bar for the downloads warning.
-
04d6d341
by Henry Wilkes at 2024-08-21T19:22:49+00:00
fixup! Tor Browser localization migration scripts.
Bug 41820: Use moz-message-bar for the downloads warning.
We add a migration to convert the old string values into the new value.
13 changed files:
Changes:
browser/components/downloads/DownloadsTorWarning.sys.mjs
|
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
|
+} |
browser/components/downloads/content/allDownloadsView.js
... |
... |
@@ -213,7 +213,6 @@ var DownloadsView = { |
213
|
213
|
*/
|
214
|
214
|
function DownloadsPlacesView(
|
215
|
215
|
aRichListBox,
|
216
|
|
- torWarningMessageBar,
|
217
|
216
|
aActive = true,
|
218
|
217
|
aSuppressionFlag = DownloadsCommon.SUPPRESS_ALL_DOWNLOADS_OPEN
|
219
|
218
|
) {
|
... |
... |
@@ -242,46 +241,6 @@ function DownloadsPlacesView( |
242
|
241
|
aSuppressionFlag;
|
243
|
242
|
}
|
244
|
243
|
|
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", () => {
|
282
|
|
- Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
|
283
|
|
- });
|
284
|
|
-
|
285
|
244
|
// Make sure to unregister the view if the window is closed.
|
286
|
245
|
window.addEventListener(
|
287
|
246
|
"unload",
|
browser/components/downloads/content/contentAreaDownloadsView.js
... |
... |
@@ -8,12 +8,30 @@ const { PrivateBrowsingUtils } = ChromeUtils.importESModule( |
8
|
8
|
"resource://gre/modules/PrivateBrowsingUtils.sys.mjs"
|
9
|
9
|
);
|
10
|
10
|
|
|
11
|
+const { DownloadsTorWarning } = ChromeUtils.importESModule(
|
|
12
|
+ "resource:///modules/DownloadsTorWarning.sys.mjs"
|
|
13
|
+);
|
|
14
|
+
|
11
|
15
|
var ContentAreaDownloadsView = {
|
12
|
16
|
init() {
|
13
|
|
- const torWarningMessage = document.getElementById(
|
14
|
|
- "aboutDownloadsTorWarning"
|
15
|
|
- );
|
16
|
17
|
let box = document.getElementById("downloadsListBox");
|
|
18
|
+
|
|
19
|
+ const torWarning = new DownloadsTorWarning(
|
|
20
|
+ document.getElementById("aboutDownloadsTorWarning"),
|
|
21
|
+ false,
|
|
22
|
+ () => {
|
|
23
|
+ // Try and focus the downloads list.
|
|
24
|
+ // NOTE: If #downloadsListBox is still hidden, this will do nothing.
|
|
25
|
+ // But in this case there are no other focusable targets within the
|
|
26
|
+ // view, so we just leave it up to the focus handler.
|
|
27
|
+ box.focus({ preventFocusRing: true });
|
|
28
|
+ }
|
|
29
|
+ );
|
|
30
|
+ torWarning.activate();
|
|
31
|
+ window.addEventListener("unload", () => {
|
|
32
|
+ torWarning.deactivate();
|
|
33
|
+ });
|
|
34
|
+
|
17
|
35
|
let suppressionFlag = DownloadsCommon.SUPPRESS_CONTENT_AREA_DOWNLOADS_OPEN;
|
18
|
36
|
box.addEventListener(
|
19
|
37
|
"InitialDownloadsLoaded",
|
... |
... |
@@ -30,7 +48,7 @@ var ContentAreaDownloadsView = { |
30
|
48
|
// experience was bad.
|
31
|
49
|
// Without auto-focusing the downloads list, a screen reader should not
|
32
|
50
|
// skip beyond the alert's content.
|
33
|
|
- if (torWarningMessage.hidden) {
|
|
51
|
+ if (torWarning.hidden) {
|
34
|
52
|
document
|
35
|
53
|
.getElementById("downloadsListBox")
|
36
|
54
|
.focus({ focusVisible: false });
|
... |
... |
@@ -44,12 +62,7 @@ var ContentAreaDownloadsView = { |
44
|
62
|
},
|
45
|
63
|
{ once: true }
|
46
|
64
|
);
|
47
|
|
- let view = new DownloadsPlacesView(
|
48
|
|
- box,
|
49
|
|
- torWarningMessage,
|
50
|
|
- true,
|
51
|
|
- suppressionFlag
|
52
|
|
- );
|
|
65
|
+ let view = new DownloadsPlacesView(box, true, suppressionFlag);
|
53
|
66
|
document.addEventListener("visibilitychange", () => {
|
54
|
67
|
let indicator = DownloadsCommon.getIndicatorData(window);
|
55
|
68
|
if (document.visibilityState === "visible") {
|
browser/components/downloads/content/contentAreaDownloadsView.xhtml
... |
... |
@@ -49,36 +49,7 @@ |
49
|
49
|
</keyset>
|
50
|
50
|
#endif
|
51
|
51
|
|
52
|
|
- <html:message-bar
|
53
|
|
- id="aboutDownloadsTorWarning"
|
54
|
|
- class="downloads-tor-warning-message-bar"
|
55
|
|
- role="alert"
|
56
|
|
- aria-labelledby="aboutDownloadsTorWarningTitle"
|
57
|
|
- aria-describedby="aboutDownloadsTorWarningDescription"
|
58
|
|
- >
|
59
|
|
- <html:div class="downloads-tor-warning-grid">
|
60
|
|
- <html:p
|
61
|
|
- id="aboutDownloadsTorWarningTitle"
|
62
|
|
- class="downloads-tor-warning-title"
|
63
|
|
- data-l10n-id="downloads-tor-warning-title"
|
64
|
|
- ></html:p>
|
65
|
|
- <html:p
|
66
|
|
- id="aboutDownloadsTorWarningDescription"
|
67
|
|
- class="downloads-tor-warning-description"
|
68
|
|
- data-l10n-id="downloads-tor-warning-description"
|
69
|
|
- >
|
70
|
|
- <html:a
|
71
|
|
- href="https://tails.net/"
|
72
|
|
- target="_blank"
|
73
|
|
- data-l10n-name="tails-link"
|
74
|
|
- ></html:a>
|
75
|
|
- </html:p>
|
76
|
|
- <html:button
|
77
|
|
- class="downloads-tor-warning-dismiss-button"
|
78
|
|
- data-l10n-id="downloads-tor-warning-dismiss-button"
|
79
|
|
- ></html:button>
|
80
|
|
- </html:div>
|
81
|
|
- </html:message-bar>
|
|
52
|
+ <html:moz-message-bar id="aboutDownloadsTorWarning"></html:moz-message-bar>
|
82
|
53
|
|
83
|
54
|
<richlistbox flex="1"
|
84
|
55
|
seltype="multiple"
|
browser/components/downloads/content/downloads.css
... |
... |
@@ -92,63 +92,13 @@ |
92
|
92
|
#downloadsPanel-mainView {
|
93
|
93
|
min-width: 37em;
|
94
|
94
|
padding: 0.62em;
|
95
|
|
- /* If we don't set a width, #downloadsPanelTorWarningDescription will request
|
|
95
|
+ /* If we don't set a width, #downloadsPanelTorWarning will request
|
96
|
96
|
* its max-content width. */
|
97
|
97
|
width: 37em;
|
98
|
98
|
}
|
99
|
99
|
|
100
|
|
-#downloadsPanel-mainView {
|
101
|
|
- /* Fix the layout to ensure the #downloadsWarningDescription is given enough
|
102
|
|
- * vertical space. For tor-browser#40701.
|
103
|
|
- * TODO: May no longer be necessary after esr 115 due to bugzilla bug 1816455.
|
104
|
|
- */
|
105
|
|
- display: flex;
|
106
|
|
- flex-direction: column;
|
107
|
|
-}
|
108
|
|
-
|
109
|
|
-.downloads-tor-warning-grid {
|
110
|
|
- display: grid;
|
111
|
|
- grid-template:
|
112
|
|
- "title button" min-content
|
113
|
|
- "description button" auto
|
114
|
|
- / 1fr max-content;
|
115
|
|
- gap: 8px;
|
116
|
|
- margin-block: 8px;
|
117
|
|
- /* Some extra space between the text and the icon. */
|
118
|
|
- margin-inline-start: 8px;
|
119
|
|
-}
|
120
|
|
-
|
121
|
|
-.downloads-tor-warning-grid .downloads-tor-warning-title {
|
122
|
|
- grid-area: title;
|
123
|
|
- margin: 0;
|
124
|
|
-}
|
125
|
|
-
|
126
|
|
-.downloads-tor-warning-grid .downloads-tor-warning-description {
|
127
|
|
- grid-area: description;
|
128
|
|
- margin: 0;
|
129
|
|
-}
|
130
|
|
-
|
131
|
|
-.downloads-tor-warning-grid .downloads-tor-warning-dismiss-button {
|
132
|
|
- grid-area: button;
|
133
|
|
- align-self: center;
|
134
|
|
-}
|
135
|
|
-
|
136
|
|
-.downloads-tor-warning-description,
|
137
|
|
-.downloads-tor-warning-title {
|
138
|
|
- line-height: 1.4;
|
139
|
|
-}
|
140
|
|
-
|
141
|
|
-.downloads-tor-warning-title {
|
142
|
|
- font-weight: bold;
|
143
|
|
-}
|
144
|
|
-
|
145
|
|
-#downloadsPanelTorWarning :is(
|
146
|
|
- .downloads-tor-warning-description,
|
147
|
|
- .downloads-tor-warning-title
|
148
|
|
-) {
|
149
|
|
- padding-inline: 8px;
|
150
|
|
- margin-block-start: 8px;
|
151
|
|
- margin-block-end: 0;
|
|
100
|
+#downloadsPanelTorWarning {
|
|
101
|
+ margin-block-end: var(--arrowpanel-menuitem-padding-block);
|
152
|
102
|
}
|
153
|
103
|
|
154
|
104
|
#downloadsHistory,
|
browser/components/downloads/content/downloads.js
... |
... |
@@ -31,8 +31,6 @@ |
31
|
31
|
|
32
|
32
|
"use strict";
|
33
|
33
|
|
34
|
|
-const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning";
|
35
|
|
-
|
36
|
34
|
var { XPCOMUtils } = ChromeUtils.importESModule(
|
37
|
35
|
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
38
|
36
|
);
|
... |
... |
@@ -42,6 +40,7 @@ ChromeUtils.defineESModuleGetters(this, { |
42
|
40
|
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
|
43
|
41
|
NetUtil: "resource://gre/modules/NetUtil.sys.mjs",
|
44
|
42
|
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
|
43
|
+ DownloadsTorWarning: "resource:///modules/DownloadsTorWarning.sys.mjs",
|
45
|
44
|
});
|
46
|
45
|
|
47
|
46
|
const { Integration } = ChromeUtils.importESModule(
|
... |
... |
@@ -76,11 +75,11 @@ var DownloadsPanel = { |
76
|
75
|
_waitingDataForOpen: false,
|
77
|
76
|
|
78
|
77
|
/**
|
79
|
|
- * State of tor's download warning. It should only be initialized once (text assigned,
|
80
|
|
- * button commands assigned). This tracks if that has been performed and prevents
|
81
|
|
- * repeats.
|
|
78
|
+ * Tracks whether to show the tor warning or not.
|
|
79
|
+ *
|
|
80
|
+ * @type {?DownloadsTorWarning}
|
82
|
81
|
*/
|
83
|
|
- _torWarningInitialized: false,
|
|
82
|
+ _torWarning: null,
|
84
|
83
|
|
85
|
84
|
/**
|
86
|
85
|
* Starts loading the download data in background, without opening the panel.
|
... |
... |
@@ -98,30 +97,20 @@ var DownloadsPanel = { |
98
|
97
|
);
|
99
|
98
|
}
|
100
|
99
|
|
101
|
|
- const torWarningMessage = document.getElementById(
|
102
|
|
- "downloadsPanelTorWarning"
|
103
|
|
- );
|
104
|
|
- if (!this._torWarningPrefObserver) {
|
105
|
|
- // Observe changes to the tor warning pref.
|
106
|
|
- this._torWarningPrefObserver = () => {
|
107
|
|
- if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) {
|
108
|
|
- torWarningMessage.hidden = false;
|
109
|
|
- } else {
|
110
|
|
- const hadFocus = torWarningMessage.contains(document.activeElement);
|
111
|
|
- torWarningMessage.hidden = true;
|
|
100
|
+ if (!this._torWarning) {
|
|
101
|
+ this._torWarning = new DownloadsTorWarning(
|
|
102
|
+ document.getElementById("downloadsPanelTorWarning"),
|
|
103
|
+ true,
|
|
104
|
+ () => {
|
112
|
105
|
// Re-assign focus that was lost.
|
113
|
|
- if (hadFocus) {
|
114
|
|
- this._focusPanel(true);
|
115
|
|
- }
|
|
106
|
+ this._focusPanel(true);
|
|
107
|
+ },
|
|
108
|
+ () => {
|
|
109
|
+ this.hidePanel();
|
116
|
110
|
}
|
117
|
|
- };
|
118
|
|
- Services.prefs.addObserver(
|
119
|
|
- PREF_SHOW_DOWNLOAD_WARNING,
|
120
|
|
- this._torWarningPrefObserver
|
121
|
111
|
);
|
122
|
|
- // Initialize
|
123
|
|
- this._torWarningPrefObserver();
|
124
|
112
|
}
|
|
113
|
+ this._torWarning.activate();
|
125
|
114
|
|
126
|
115
|
if (this._initialized) {
|
127
|
116
|
DownloadsCommon.log("DownloadsPanel is already initialized.");
|
... |
... |
@@ -149,33 +138,6 @@ var DownloadsPanel = { |
149
|
138
|
DownloadsSummary
|
150
|
139
|
);
|
151
|
140
|
|
152
|
|
- if (!this._torWarningInitialized) {
|
153
|
|
- // Intercept clicks on the tails link.
|
154
|
|
- // NOTE: We listen for clicks on the parent instead of the
|
155
|
|
- // <a data-l10n-name="tails-link"> element because the latter may be
|
156
|
|
- // swapped for a new instance by Fluent when refreshing the parent.
|
157
|
|
- torWarningMessage
|
158
|
|
- .querySelector(".downloads-tor-warning-description")
|
159
|
|
- .addEventListener("click", event => {
|
160
|
|
- const tailsLink = event.target.closest(
|
161
|
|
- ".downloads-tor-warning-tails-link"
|
162
|
|
- );
|
163
|
|
- if (!tailsLink) {
|
164
|
|
- return;
|
165
|
|
- }
|
166
|
|
- event.preventDefault();
|
167
|
|
- this.hidePanel();
|
168
|
|
- openWebLinkIn(tailsLink.href, "tab");
|
169
|
|
- });
|
170
|
|
-
|
171
|
|
- torWarningMessage
|
172
|
|
- .querySelector(".downloads-tor-warning-dismiss-button")
|
173
|
|
- .addEventListener("click", () => {
|
174
|
|
- Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
|
175
|
|
- });
|
176
|
|
- this._torWarningInitialized = true;
|
177
|
|
- }
|
178
|
|
-
|
179
|
141
|
DownloadsCommon.log(
|
180
|
142
|
"DownloadsView attached - the panel for this window",
|
181
|
143
|
"should now see download items come in."
|
... |
... |
@@ -218,13 +180,7 @@ var DownloadsPanel = { |
218
|
180
|
DownloadIntegration.downloadSpamProtection.unregister(window);
|
219
|
181
|
}
|
220
|
182
|
|
221
|
|
- if (this._torWarningPrefObserver) {
|
222
|
|
- Services.prefs.removeObserver(
|
223
|
|
- PREF_SHOW_DOWNLOAD_WARNING,
|
224
|
|
- this._torWarningPrefObserver
|
225
|
|
- );
|
226
|
|
- delete this._torWarningPrefObserver;
|
227
|
|
- }
|
|
183
|
+ this._torWarning?.deactivate();
|
228
|
184
|
|
229
|
185
|
this._initialized = false;
|
230
|
186
|
|
... |
... |
@@ -582,13 +538,8 @@ var DownloadsPanel = { |
582
|
538
|
// Focus the "Got it" button if it is visible.
|
583
|
539
|
// This should ensure that the alert is read aloud by Orca when the
|
584
|
540
|
// downloads panel is opened. See tor-browser#42642.
|
585
|
|
- const torWarningMessage = document.getElementById(
|
586
|
|
- "downloadsPanelTorWarning"
|
587
|
|
- );
|
588
|
|
- if (!torWarningMessage.hidden) {
|
589
|
|
- torWarningMessage
|
590
|
|
- .querySelector(".downloads-tor-warning-dismiss-button")
|
591
|
|
- .focus(focusOptions);
|
|
541
|
+ if (!this._torWarning?.hidden) {
|
|
542
|
+ this._torWarning.dismissButton.focus(focusOptions);
|
592
|
543
|
return;
|
593
|
544
|
}
|
594
|
545
|
|
browser/components/downloads/content/downloadsPanel.inc.xhtml
... |
... |
@@ -104,37 +104,8 @@ |
104
|
104
|
disablekeynav="true">
|
105
|
105
|
|
106
|
106
|
<panelview id="downloadsPanel-mainView">
|
107
|
|
- <vbox id="downloadsPanelTorWarning">
|
108
|
|
- <vbox
|
109
|
|
- role="alert"
|
110
|
|
- aria-labelledby="downloadsPanelTorWarningTitle"
|
111
|
|
- aria-describedby="downloadsPanelTorWarningDescription"
|
112
|
|
- >
|
113
|
|
- <html:p
|
114
|
|
- id="downloadsPanelTorWarningTitle"
|
115
|
|
- class="downloads-tor-warning-title"
|
116
|
|
- data-l10n-id="downloads-tor-warning-title"
|
117
|
|
- ></html:p>
|
118
|
|
- <html:p
|
119
|
|
- id="downloadsPanelTorWarningDescription"
|
120
|
|
- class="downloads-tor-warning-description"
|
121
|
|
- data-l10n-id="downloads-tor-warning-description"
|
122
|
|
- >
|
123
|
|
- <html:a
|
124
|
|
- href="">"https://tails.net/"
|
125
|
|
- data-l10n-name="tails-link"
|
126
|
|
- class="downloads-tor-warning-tails-link"
|
127
|
|
- ></html:a>
|
128
|
|
- </html:p>
|
129
|
|
- <html:moz-button-group class="panel-footer">
|
130
|
|
- <html:button
|
131
|
|
- class="footer-button downloads-tor-warning-dismiss-button"
|
132
|
|
- data-l10n-id="downloads-tor-warning-dismiss-button"
|
133
|
|
- ></html:button>
|
134
|
|
- </html:moz-button-group>
|
135
|
|
- </vbox>
|
136
|
|
- <toolbarseparator />
|
137
|
|
- </vbox>
|
|
107
|
+ <html:moz-message-bar id="downloadsPanelTorWarning">
|
|
108
|
+ </html:moz-message-bar>
|
138
|
109
|
<vbox class="panel-view-body-unscrollable">
|
139
|
110
|
<richlistbox id="downloadsListBox"
|
140
|
111
|
data-l10n-id="downloads-panel-items"
|
browser/components/downloads/moz.build
... |
... |
@@ -15,6 +15,7 @@ EXTRA_JS_MODULES += [ |
15
|
15
|
"DownloadsCommon.sys.mjs",
|
16
|
16
|
"DownloadSpamProtection.sys.mjs",
|
17
|
17
|
"DownloadsTaskbar.sys.mjs",
|
|
18
|
+ "DownloadsTorWarning.sys.mjs",
|
18
|
19
|
"DownloadsViewableInternally.sys.mjs",
|
19
|
20
|
"DownloadsViewUI.sys.mjs",
|
20
|
21
|
]
|
browser/components/places/content/places.js
... |
... |
@@ -6,7 +6,6 @@ |
6
|
6
|
/* import-globals-from editBookmark.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 */
|
10
|
9
|
|
11
|
10
|
/* Shared Places Import - change other consumers if you change this: */
|
12
|
11
|
var { XPCOMUtils } = ChromeUtils.importESModule(
|
... |
... |
@@ -18,6 +17,7 @@ ChromeUtils.defineESModuleGetters(this, { |
18
|
17
|
PlacesBackups: "resource://gre/modules/PlacesBackups.sys.mjs",
|
19
|
18
|
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
20
|
19
|
DownloadUtils: "resource://gre/modules/DownloadUtils.sys.mjs",
|
|
20
|
+ DownloadsTorWarning: "resource:///modules/DownloadsTorWarning.sys.mjs",
|
21
|
21
|
});
|
22
|
22
|
XPCOMUtils.defineLazyScriptGetter(
|
23
|
23
|
this,
|
... |
... |
@@ -158,15 +158,25 @@ var PlacesOrganizer = { |
158
|
158
|
"&sort=" +
|
159
|
159
|
Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING;
|
160
|
160
|
|
161
|
|
- const torWarningMessage = document.getElementById(
|
162
|
|
- "placesDownloadsTorWarning"
|
|
161
|
+ const torWarning = new DownloadsTorWarning(
|
|
162
|
+ document.getElementById("placesDownloadsTorWarning"),
|
|
163
|
+ true,
|
|
164
|
+ () => {
|
|
165
|
+ document
|
|
166
|
+ .getElementById("downloadsListBox")
|
|
167
|
+ .focus({ preventFocusRing: true });
|
|
168
|
+ }
|
163
|
169
|
);
|
|
170
|
+ torWarning.activate();
|
|
171
|
+ window.addEventListener("unload", () => {
|
|
172
|
+ torWarning.deactivate();
|
|
173
|
+ });
|
|
174
|
+
|
164
|
175
|
ContentArea.setContentViewForQueryString(
|
165
|
176
|
DOWNLOADS_QUERY,
|
166
|
177
|
() =>
|
167
|
178
|
new DownloadsPlacesView(
|
168
|
179
|
document.getElementById("downloadsListBox"),
|
169
|
|
- torWarningMessage,
|
170
|
180
|
false
|
171
|
181
|
),
|
172
|
182
|
{
|
... |
... |
@@ -176,23 +186,6 @@ var PlacesOrganizer = { |
176
|
186
|
}
|
177
|
187
|
);
|
178
|
188
|
|
179
|
|
- // Intercept clicks on the tor warning tails link.
|
180
|
|
- // NOTE: We listen for clicks on the parent instead of the
|
181
|
|
- // <a data-l10n-name="tails-link"> element because the latter may be
|
182
|
|
- // swapped for a new instance by Fluent when refreshing the parent.
|
183
|
|
- document
|
184
|
|
- .querySelector(".downloads-tor-warning-description")
|
185
|
|
- .addEventListener("click", event => {
|
186
|
|
- const tailsLink = event.target.closest(
|
187
|
|
- ".downloads-tor-warning-tails-link"
|
188
|
|
- );
|
189
|
|
- if (!tailsLink) {
|
190
|
|
- return;
|
191
|
|
- }
|
192
|
|
- event.preventDefault();
|
193
|
|
- openWebLinkIn(tailsLink.href, "tab");
|
194
|
|
- });
|
195
|
|
-
|
196
|
189
|
ContentArea.init();
|
197
|
190
|
|
198
|
191
|
this._places = document.getElementById("placesList");
|
... |
... |
@@ -1432,6 +1425,7 @@ var ContentArea = { |
1432
|
1425
|
oldView.associatedElement.hidden = true;
|
1433
|
1426
|
aNewView.associatedElement.hidden = false;
|
1434
|
1427
|
|
|
1428
|
+ // Hide the Tor warning when not in the downloads view.
|
1435
|
1429
|
const isDownloads = aNewView.associatedElement.id === "downloadsListBox";
|
1436
|
1430
|
const torWarningMessage = document.getElementById(
|
1437
|
1431
|
"placesDownloadsTorWarning"
|
browser/components/places/content/places.xhtml
... |
... |
@@ -363,35 +363,8 @@ |
363
|
363
|
</tree>
|
364
|
364
|
<splitter collapse="none" persist="state"></splitter>
|
365
|
365
|
<vbox id="contentView">
|
366
|
|
- <html:message-bar
|
367
|
|
- id="placesDownloadsTorWarning"
|
368
|
|
- role="alert"
|
369
|
|
- aria-labelledby="placesDownloadsTorWarningTitle"
|
370
|
|
- aria-describedby="placesDownloadsTorWarningDescription"
|
371
|
|
- >
|
372
|
|
- <html:div class="downloads-tor-warning-grid">
|
373
|
|
- <html:p
|
374
|
|
- id="placesDownloadsTorWarningTitle"
|
375
|
|
- class="downloads-tor-warning-title"
|
376
|
|
- data-l10n-id="downloads-tor-warning-title"
|
377
|
|
- ></html:p>
|
378
|
|
- <html:p
|
379
|
|
- id="placesDownloadsTorWarningDescription"
|
380
|
|
- class="downloads-tor-warning-description"
|
381
|
|
- data-l10n-id="downloads-tor-warning-description"
|
382
|
|
- >
|
383
|
|
- <html:a
|
384
|
|
- href="https://tails.net/"
|
385
|
|
- class="downloads-tor-warning-tails-link"
|
386
|
|
- data-l10n-name="tails-link"
|
387
|
|
- ></html:a>
|
388
|
|
- </html:p>
|
389
|
|
- <html:button
|
390
|
|
- class="downloads-tor-warning-dismiss-button"
|
391
|
|
- data-l10n-id="downloads-tor-warning-dismiss-button"
|
392
|
|
- ></html:button>
|
393
|
|
- </html:div>
|
394
|
|
- </html:message-bar>
|
|
366
|
+ <html:moz-message-bar id="placesDownloadsTorWarning">
|
|
367
|
+ </html:moz-message-bar>
|
395
|
368
|
<vbox id="placesViewsBox" flex="1">
|
396
|
369
|
<tree id="placeContent"
|
397
|
370
|
class="placesTree"
|
browser/themes/shared/downloads/downloads.inc.css
... |
... |
@@ -252,7 +252,6 @@ |
252
|
252
|
}
|
253
|
253
|
|
254
|
254
|
/*** Toolbarseparator ***/
|
255
|
|
-#downloadsPanelTorWarning toolbarseparator,
|
256
|
255
|
#downloadsFooterButtons > toolbarseparator {
|
257
|
256
|
margin-inline: 0;
|
258
|
257
|
} |
toolkit/locales/en-US/toolkit/global/tor-browser.ftl
... |
... |
@@ -559,9 +559,13 @@ crypto-safety-prompt-dismiss-button = Dismiss Warning |
559
|
559
|
## Downloads warning.
|
560
|
560
|
## Shown in downloads panel, about:downloads and Library window.
|
561
|
561
|
|
562
|
|
-downloads-tor-warning-title = Be careful opening downloads
|
563
|
|
-# "Tails" is the brand name for the Tails operating system and should be localized appropriately, and will be a link to its website. The name should be wrapped in '<a data-l10n-name="tails-link">' and '</a>'.
|
564
|
|
-downloads-tor-warning-description = Some files may connect to the internet when opened without using Tor. To be safe, open the files while offline or use a portable operating system like <a data-l10n-name="tails-link">Tails</a>.
|
|
562
|
+# "Tails" is the brand name for the Tails operating system and should be localized appropriately.
|
|
563
|
+downloads-tor-warning-message-bar =
|
|
564
|
+ .heading = Be careful opening downloads
|
|
565
|
+ .message = Some files may connect to the internet when opened without using Tor. To be safe, open the files while offline or use a portable operating system like Tails.
|
|
566
|
+# This will be a link to the Tails operating system website.
|
|
567
|
+# "Tails" is the brand name for the Tails operating system and should be localized appropriately.
|
|
568
|
+downloads-tor-warning-tails-link= Learn more about Tails
|
565
|
569
|
# Button to dismiss the warning forever.
|
566
|
570
|
downloads-tor-warning-dismiss-button = Got it
|
567
|
571
|
|
tools/torbrowser/l10n/migrations/bug-41820-moz-message-bar-download-warning.py
|
1
|
+import re
|
|
2
|
+
|
|
3
|
+import fluent.syntax.ast as FTL
|
|
4
|
+from fluent.migrate.transforms import COPY_PATTERN, FluentSource
|
|
5
|
+from fluent.syntax.visitor import Visitor
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+class RemoveAnchorVisitor(Visitor):
|
|
9
|
+ """Class to remove <a> and </a> wrappers from a Fluent TextElement."""
|
|
10
|
+
|
|
11
|
+ def __init__(self):
|
|
12
|
+ # Good enough regex for our needs that will match starting and ending
|
|
13
|
+ # tags.
|
|
14
|
+ self._anchor_regex = re.compile(r"<\/?[aA](| [^>]*)>")
|
|
15
|
+ super().__init__()
|
|
16
|
+
|
|
17
|
+ def visit_TextElement(self, node):
|
|
18
|
+ node.value = self._anchor_regex.sub("", node.value)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+class RemoveAnchorTransform(FluentSource):
|
|
22
|
+ """Class to remove <a> and </a> wrappers from a Fluent source."""
|
|
23
|
+
|
|
24
|
+ def __call__(self, ctx):
|
|
25
|
+ pattern = ctx.get_fluent_source_pattern(self.path, self.key).clone()
|
|
26
|
+ # Visit every node in the pattern, replacing each TextElement's content.
|
|
27
|
+ RemoveAnchorVisitor().visit(pattern)
|
|
28
|
+ return pattern
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+def migrate(ctx):
|
|
32
|
+ # Convert
|
|
33
|
+ #
|
|
34
|
+ # downloads-tor-warning-title = A
|
|
35
|
+ # downloads-tor-warning-description = B<a data-l10n-name="tails-link">C</a>D
|
|
36
|
+ #
|
|
37
|
+ # to
|
|
38
|
+ #
|
|
39
|
+ # downloads-tor-warning-message-bar =
|
|
40
|
+ # .heading = A
|
|
41
|
+ # .message = BCD
|
|
42
|
+ ctx.add_transforms(
|
|
43
|
+ "tor-browser.ftl",
|
|
44
|
+ "tor-browser.ftl",
|
|
45
|
+ [
|
|
46
|
+ FTL.Message(
|
|
47
|
+ id=FTL.Identifier("downloads-tor-warning-message-bar"),
|
|
48
|
+ value=None,
|
|
49
|
+ attributes=[
|
|
50
|
+ FTL.Attribute(
|
|
51
|
+ id=FTL.Identifier("heading"),
|
|
52
|
+ value=COPY_PATTERN(
|
|
53
|
+ "tor-browser.ftl",
|
|
54
|
+ "downloads-tor-warning-title",
|
|
55
|
+ ),
|
|
56
|
+ ),
|
|
57
|
+ FTL.Attribute(
|
|
58
|
+ id=FTL.Identifier("message"),
|
|
59
|
+ value=RemoveAnchorTransform(
|
|
60
|
+ "tor-browser.ftl",
|
|
61
|
+ "downloads-tor-warning-description",
|
|
62
|
+ ),
|
|
63
|
+ ),
|
|
64
|
+ ],
|
|
65
|
+ ),
|
|
66
|
+ ],
|
|
67
|
+ ) |
|