[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-102.12.0esr-12.5-1] amend! Bug 40701: Add in pane security warning when downloading a file
ma1 (@ma1)
git at gitlab.torproject.org
Tue Jun 6 20:54:35 UTC 2023
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
amend! Bug 40701: Add in pane security warning when downloading a file
Bug 40701: Add security warning when downloading a file
Shown in the downloads panel, about:downloads and places.xhtml.
- - - - -
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:
=====================================
browser/components/downloads/content/allDownloadsView.js
=====================================
@@ -212,6 +212,7 @@ var DownloadsView = {
*/
function DownloadsPlacesView(
aRichListBox,
+ torWarningMessageBar,
aActive = true,
aSuppressionFlag = DownloadsCommon.SUPPRESS_ALL_DOWNLOADS_OPEN
) {
@@ -241,6 +242,46 @@ function DownloadsPlacesView(
).attentionSuppressed |= aSuppressionFlag;
}
+ // Tor browser warning message/alert shown above the list.
+
+ const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning";
+ // Observe changes to the tor warning pref.
+ const torWarningPrefObserver = () => {
+ if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) {
+ torWarningMessageBar.hidden = false;
+ } else {
+ // Re-assign focus if it is about to be lost.
+ if (torWarningMessageBar.contains(document.activeElement)) {
+ // Try and focus the downloads list.
+ // NOTE: If #downloadsListBox is still hidden, this will do nothing.
+ // But in this case there are no other focusable targets within the
+ // view, so we just leave it up to the focus handler.
+ this._richlistbox.focus({ preventFocusRing: true });
+ }
+ torWarningMessageBar.hidden = true;
+ }
+ };
+
+ Services.prefs.addObserver(
+ PREF_SHOW_DOWNLOAD_WARNING,
+ torWarningPrefObserver
+ );
+ // Initialize.
+ torWarningPrefObserver();
+
+ window.addEventListener("unload", () => {
+ Services.prefs.removeObserver(
+ PREF_SHOW_DOWNLOAD_WARNING,
+ torWarningPrefObserver
+ );
+ });
+
+ torWarningMessageBar
+ .querySelector(".downloads-tor-warning-dismiss-button")
+ .addEventListener("click", event => {
+ Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
+ });
+
// Make sure to unregister the view if the window is closed.
window.addEventListener(
"unload",
=====================================
browser/components/downloads/content/contentAreaDownloadsView.js
=====================================
@@ -10,6 +10,9 @@ const { PrivateBrowsingUtils } = ChromeUtils.import(
var ContentAreaDownloadsView = {
init() {
+ const torWarningMessage = document.getElementById(
+ "aboutDownloadsTorWarning"
+ );
let box = document.getElementById("downloadsListBox");
let suppressionFlag = DownloadsCommon.SUPPRESS_CONTENT_AREA_DOWNLOADS_OPEN;
box.addEventListener(
@@ -17,9 +20,22 @@ var ContentAreaDownloadsView = {
() => {
// Set focus to Downloads list once it is created
// And prevent it from showing the focus ring around the richlistbox (Bug 1702694)
- document
- .getElementById("downloadsListBox")
- .focus({ preventFocusRing: true });
+ // Prevent focusing the list whilst the tor browser warning is shown.
+ // Some screen readers (tested with Orca and NVDA) will not read out
+ // alerts if they are already present on page load. In that case, a
+ // screen reader user may not be aware of the warning before they
+ // interact with the downloads list, which we do not want.
+ // Some hacky workarounds were tested with Orca to get it to read back
+ // the alert before the focus is read, but this was inconsistent and the
+ // experience was bad.
+ // Without auto-focusing the downloads list, a screen reader should not
+ // skip beyond the alert's content.
+ if (torWarningMessage.hidden) {
+ document
+ .getElementById("downloadsListBox")
+ .focus({ preventFocusRing: true });
+ }
+
// Pause the indicator if the browser is active.
if (document.visibilityState === "visible") {
DownloadsCommon.getIndicatorData(
@@ -29,7 +45,12 @@ var ContentAreaDownloadsView = {
},
{ once: true }
);
- let view = new DownloadsPlacesView(box, true, suppressionFlag);
+ let view = new DownloadsPlacesView(
+ box,
+ torWarningMessage,
+ true,
+ suppressionFlag
+ );
document.addEventListener("visibilitychange", aEvent => {
let indicator = DownloadsCommon.getIndicatorData(window);
if (document.visibilityState === "visible") {
@@ -42,6 +63,53 @@ var ContentAreaDownloadsView = {
if (!PrivateBrowsingUtils.isContentWindowPrivate(window)) {
view.place = "place:transition=7&sort=4";
}
+
+ torWarningMessage.querySelector(
+ ".downloads-tor-warning-title"
+ ).textContent = this._getTorString("torbutton.download.warning.title");
+
+ const tailsLink = document.createElement("a");
+ tailsLink.href = "https://tails.boum.org/";
+ tailsLink.target = "_blank";
+ tailsLink.textContent = this._getTorString(
+ "torbutton.download.warning.tails_brand_name"
+ );
+
+ const [beforeLink, afterLink] = this._getTorString(
+ "torbutton.download.warning.description"
+ ).split("%S");
+
+ torWarningMessage
+ .querySelector(".downloads-tor-warning-description")
+ .append(beforeLink, tailsLink, afterLink);
+
+ torWarningMessage.querySelector(
+ ".downloads-tor-warning-dismiss-button"
+ ).textContent = this._getTorString("torbutton.download.warning.dismiss");
+ },
+
+ /**
+ * Get a string from the properties bundle.
+ *
+ * @param {string} name - The string name.
+ *
+ * @return {string} The string.
+ */
+ _getTorString(name) {
+ if (!this._stringBundle) {
+ this._stringBundle = Services.strings.createBundle(
+ "chrome://torbutton/locale/torbutton.properties"
+ );
+ }
+ try {
+ return this._stringBundle.GetStringFromName(name);
+ } catch {}
+ if (!this._fallbackStringBundle) {
+ this._fallbackStringBundle = Services.strings.createBundle(
+ "resource://torbutton/locale/en-US/torbutton.properties"
+ );
+ }
+ return this._fallbackStringBundle.GetStringFromName(name);
},
};
=====================================
browser/components/downloads/content/contentAreaDownloadsView.xhtml
=====================================
@@ -39,6 +39,23 @@
</keyset>
#endif
+ <html:message-bar id="aboutDownloadsTorWarning"
+ class="downloads-tor-warning-message-bar"
+ role="alert"
+ aria-labelledby="aboutDownloadsTorWarningTitle"
+ aria-describedby="aboutDownloadsTorWarningDescription">
+ <html:div class="downloads-tor-warning-grid">
+ <html:p id="aboutDownloadsTorWarningTitle"
+ class="downloads-tor-warning-title">
+ </html:p>
+ <html:p id="aboutDownloadsTorWarningDescription"
+ class="downloads-tor-warning-description">
+ </html:p>
+ <html:button class="downloads-tor-warning-dismiss-button">
+ </html:button>
+ </html:div>
+ </html:message-bar>
+
<richlistbox flex="1"
seltype="multiple"
id="downloadsListBox"
=====================================
browser/components/downloads/content/downloads.css
=====================================
@@ -104,18 +104,52 @@
flex-direction: column;
}
-#downloadsWarning p {
- padding-inline: 8px;
- margin-block-start: 8px;
- margin-block-end: 0;
+.downloads-tor-warning-grid {
+ display: grid;
+ grid-template:
+ "title button" min-content
+ "description button" auto
+ / 1fr max-content;
+ gap: 8px;
+ margin-block: 8px;
+ /* Some extra space between the text and the icon. */
+ margin-inline-start: 8px;
+}
+
+.downloads-tor-warning-grid .downloads-tor-warning-title {
+ grid-area: title;
+ margin: 0;
+}
+
+.downloads-tor-warning-grid .downloads-tor-warning-description {
+ grid-area: description;
+ margin: 0;
+}
+
+.downloads-tor-warning-grid .downloads-tor-warning-dismiss-button {
+ grid-area: button;
+ align-self: center;
+}
+
+.downloads-tor-warning-description,
+.downloads-tor-warning-title {
line-height: 1.4;
}
-#downloadsWarningHeaderTitle {
+.downloads-tor-warning-title {
font-weight: bold;
}
-#downloadsWarningDescription {
+#downloadsPanelTorWarning :is(
+ .downloads-tor-warning-description,
+ .downloads-tor-warning-title
+) {
+ padding-inline: 8px;
+ margin-block-start: 8px;
+ margin-block-end: 0;
+}
+
+#downloadsPanelTorWarningDescription {
/* Make sure we wrap the text rather than request the default max-content
* width from the parent XUL -moz-box. */
width: 0;
=====================================
browser/components/downloads/content/downloads.js
=====================================
@@ -33,8 +33,6 @@
const PREF_SHOW_DOWNLOAD_WARNING = "browser.download.showTorWarning";
-const TAILS_URI = "https://tails.boum.org/";
-
var { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
@@ -143,13 +141,28 @@ var DownloadsPanel = {
);
}
- let showDownloadWarning = Services.prefs.getBoolPref(
- PREF_SHOW_DOWNLOAD_WARNING
+ const torWarningMessage = document.getElementById(
+ "downloadsPanelTorWarning"
);
- if (!showDownloadWarning) {
- document.getElementById("downloadsWarning").hidden = true;
- } else {
- document.getElementById("downloadsWarning").hidden = false;
+ if (!this._torWarningPrefObserver) {
+ // Observe changes to the tor warning pref.
+ this._torWarningPrefObserver = () => {
+ if (Services.prefs.getBoolPref(PREF_SHOW_DOWNLOAD_WARNING)) {
+ torWarningMessage.hidden = false;
+ } else {
+ // Re-assign focus if it is about to be lost.
+ if (torWarningMessage.contains(document.activeElement)) {
+ this._focusPanel(true);
+ }
+ torWarningMessage.hidden = true;
+ }
+ };
+ Services.prefs.addObserver(
+ PREF_SHOW_DOWNLOAD_WARNING,
+ this._torWarningPrefObserver
+ );
+ // Initialize
+ this._torWarningPrefObserver();
}
if (this._state != this.kStateUninitialized) {
@@ -175,42 +188,40 @@ var DownloadsPanel = {
DownloadsSummary
);
- if (this._torWarningInitialized == 0) {
- document.getElementById(
- "downloadsWarningHeaderTitle"
- ).textContent = this._getString("torbutton.download.warning.title");
- let tailsBrandName = this._getString(
- "torbutton.download.warning.tails_brand_name"
- );
+ if (!this._torWarningInitialized) {
+ torWarningMessage.querySelector(
+ ".downloads-tor-warning-title"
+ ).textContent = this._getTorString("torbutton.download.warning.title");
- let warningDescriptionText = this._getString(
- "torbutton.download.warning.description"
- );
- let [head, rest] = warningDescriptionText.split("%S");
const tailsLink = document.createElement("a");
- tailsLink.setAttribute("href", TAILS_URI);
- tailsLink.textContent = tailsBrandName.trim();
+ tailsLink.href = "https://tails.boum.org/";
+ tailsLink.textContent = this._getTorString(
+ "torbutton.download.warning.tails_brand_name"
+ );
tailsLink.addEventListener("click", event => {
event.preventDefault();
this.hidePanel();
- openWebLinkIn(TAILS_URI, "tab");
+ openWebLinkIn(tailsLink.href, "tab");
});
- let downloadsWarningDescription = document.getElementById(
- "downloadsWarningDescription"
- );
- downloadsWarningDescription.append(head, tailsLink, rest);
+ const [beforeLink, afterLink] = this._getTorString(
+ "torbutton.download.warning.description"
+ ).split("%S");
+
+ torWarningMessage
+ .querySelector(".downloads-tor-warning-description")
+ .append(beforeLink, tailsLink, afterLink);
- let dismissBtn = document.getElementById(
- "downloadWarningDismiss"
+ let dismissButton = torWarningMessage.querySelector(
+ ".downloads-tor-warning-dismiss-button"
);
- dismissBtn.textContent = this._getString("torbutton.download.warning.dismiss");
- dismissBtn.addEventListener("click", event => {
+ dismissButton.textContent = this._getTorString(
+ "torbutton.download.warning.dismiss"
+ );
+ dismissButton.addEventListener("click", event => {
Services.prefs.setBoolPref(PREF_SHOW_DOWNLOAD_WARNING, false);
- document.getElementById("downloadsWarning").hidden = true;
- this._focusPanel(true);
});
- this._torWarningInitialized = 1;
+ this._torWarningInitialized = true;
}
DownloadsCommon.log(
@@ -254,6 +265,14 @@ var DownloadsPanel = {
);
}
+ if (this._torWarningPrefObserver) {
+ Services.prefs.removeObserver(
+ PREF_SHOW_DOWNLOAD_WARNING,
+ this._torWarningPrefObserver
+ );
+ delete this._torWarningPrefObserver;
+ }
+
this._state = this.kStateUninitialized;
DownloadsSummary.active = false;
@@ -591,14 +610,17 @@ var DownloadsPanel = {
*
* @param {bool} [forceFocus=false] - Whether to force move the focus.
*/
- _focusPanel(forceFocus=false) {
+ _focusPanel(forceFocus = false) {
if (!forceFocus) {
// We may be invoked while the panel is still waiting to be shown.
if (this._state != this.kStateShown) {
return;
}
- if (document.activeElement && this.panel.contains(document.activeElement)) {
+ if (
+ document.activeElement &&
+ this.panel.contains(document.activeElement)
+ ) {
return;
}
}
@@ -729,7 +751,7 @@ var DownloadsPanel = {
*
* @return {string} The string.
*/
- _getString(name) {
+ _getTorString(name) {
if (!this._stringBundle) {
this._stringBundle = Services.strings.createBundle(
"chrome://torbutton/locale/torbutton.properties"
=====================================
browser/components/downloads/content/downloadsPanel.inc.xhtml
=====================================
@@ -124,16 +124,19 @@
disablekeynav="true">
<panelview id="downloadsPanel-mainView">
- <vbox id="downloadsWarning">
+ <vbox id="downloadsPanelTorWarning">
<vbox role="alert"
- aria-labelledby="downloadsWarningHeaderTitle"
- aria-describedby="downloadsWarningDescription">
- <html:p id="downloadsWarningHeaderTitle"></html:p>
- <html:p id="downloadsWarningDescription">
+ aria-labelledby="downloadsPanelTorWarningTitle"
+ aria-describedby="downloadsPanelTorWarningDescription">
+ <html:p id="downloadsPanelTorWarningTitle"
+ class="downloads-tor-warning-title">
+ </html:p>
+ <html:p id="downloadsPanelTorWarningDescription"
+ class="downloads-tor-warning-description">
</html:p>
<html:div class="panel-footer">
- <html:button id="downloadWarningDismiss">
+ <html:button class="downloads-tor-warning-dismiss-button">
</html:button>
</html:div>
</vbox>
=====================================
browser/components/places/content/places.css
=====================================
@@ -126,3 +126,7 @@ tree[is="places-tree"] > treechildren::-moz-tree-cell {
margin: 2px 4px;
color: currentColor;
}
+
+#placesDownloadsTorWarning:not(.downloads-visible) {
+ display: none;
+}
=====================================
browser/components/places/content/places.js
=====================================
@@ -6,6 +6,7 @@
/* import-globals-from instantEditBookmark.js */
/* import-globals-from /toolkit/content/contentAreaUtils.js */
/* import-globals-from /browser/components/downloads/content/allDownloadsView.js */
+/* import-globals-from /browser/base/content/utilityOverlay.js */
/* Shared Places Import - change other consumers if you change this: */
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
@@ -164,11 +165,15 @@ var PlacesOrganizer = {
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING;
+ const torWarningMessage = document.getElementById(
+ "placesDownloadsTorWarning"
+ );
ContentArea.setContentViewForQueryString(
DOWNLOADS_QUERY,
() =>
new DownloadsPlacesView(
document.getElementById("downloadsListBox"),
+ torWarningMessage,
false
),
{
@@ -178,6 +183,33 @@ var PlacesOrganizer = {
}
);
+ // Initialize tor warning text content.
+ torWarningMessage.querySelector(
+ ".downloads-tor-warning-title"
+ ).textContent = this._getTorString("torbutton.download.warning.title");
+
+ const tailsLink = document.createElement("a");
+ tailsLink.href = "https://tails.boum.org/";
+ tailsLink.textContent = this._getTorString(
+ "torbutton.download.warning.tails_brand_name"
+ );
+ tailsLink.addEventListener("click", event => {
+ event.preventDefault();
+ openWebLinkIn(tailsLink.href, "tab");
+ });
+
+ const [beforeLink, afterLink] = this._getTorString(
+ "torbutton.download.warning.description"
+ ).split("%S");
+
+ torWarningMessage
+ .querySelector(".downloads-tor-warning-description")
+ .append(beforeLink, tailsLink, afterLink);
+
+ torWarningMessage.querySelector(
+ ".downloads-tor-warning-dismiss-button"
+ ).textContent = this._getTorString("torbutton.download.warning.dismiss");
+
ContentArea.init();
this._places = document.getElementById("placesList");
@@ -246,6 +278,30 @@ var PlacesOrganizer = {
ContentArea.focus();
},
+ /**
+ * Get a string from the properties bundle.
+ *
+ * @param {string} name - The string name.
+ *
+ * @returns {string} The string.
+ */
+ _getTorString(name) {
+ if (!this._stringBundle) {
+ this._stringBundle = Services.strings.createBundle(
+ "chrome://torbutton/locale/torbutton.properties"
+ );
+ }
+ try {
+ return this._stringBundle.GetStringFromName(name);
+ } catch {}
+ if (!this._fallbackStringBundle) {
+ this._fallbackStringBundle = Services.strings.createBundle(
+ "resource://torbutton/locale/en-US/torbutton.properties"
+ );
+ }
+ return this._fallbackStringBundle.GetStringFromName(name);
+ },
+
QueryInterface: ChromeUtils.generateQI([]),
handleEvent: function PO_handleEvent(aEvent) {
@@ -1386,9 +1442,20 @@ var ContentArea = {
oldView.associatedElement.hidden = true;
aNewView.associatedElement.hidden = false;
+ const isDownloads = aNewView.associatedElement.id === "downloadsListBox";
+ const torWarningMessage = document.getElementById(
+ "placesDownloadsTorWarning"
+ );
+ const torWarningLoosingFocus =
+ torWarningMessage.contains(document.activeElement) && !isDownloads;
+ torWarningMessage.classList.toggle("downloads-visible", isDownloads);
+
// If the content area inactivated view was focused, move focus
// to the new view.
- if (document.activeElement == oldView.associatedElement) {
+ if (
+ document.activeElement == oldView.associatedElement ||
+ torWarningLoosingFocus
+ ) {
aNewView.associatedElement.focus();
}
}
=====================================
browser/components/places/content/places.xhtml
=====================================
@@ -345,6 +345,21 @@
</tree>
<splitter collapse="none" persist="state"></splitter>
<vbox id="contentView" flex="4">
+ <html:message-bar id="placesDownloadsTorWarning"
+ role="alert"
+ aria-labelledby="placesDownloadsTorWarningTitle"
+ aria-describedby="placesDownloadsTorWarningDescription">
+ <html:div class="downloads-tor-warning-grid">
+ <html:p id="placesDownloadsTorWarningTitle"
+ class="downloads-tor-warning-title">
+ </html:p>
+ <html:p id="placesDownloadsTorWarningDescription"
+ class="downloads-tor-warning-description">
+ </html:p>
+ <html:button class="downloads-tor-warning-dismiss-button">
+ </html:button>
+ </html:div>
+ </html:message-bar>
<vbox id="placesViewsBox" flex="1">
<tree id="placeContent"
class="plain placesTree"
=====================================
browser/themes/shared/customizableui/panelUI-shared.css
=====================================
@@ -1324,7 +1324,7 @@ panelview .toolbarbutton-1 {
#downloadsFooterButtons > toolbarseparator,
.cui-widget-panelview menuseparator,
.cui-widget-panel toolbarseparator,
-#downloadsWarning toolbarseparator,
+#downloadsPanelTorWarning toolbarseparator,
#securityLevel-panel toolbarseparator {
appearance: none;
min-height: 0;
=====================================
browser/themes/shared/downloads/contentAreaDownloadsView.css
=====================================
@@ -25,3 +25,7 @@
text-align: center;
color: var(--in-content-deemphasized-text);
}
+
+#aboutDownloadsTorWarning {
+ margin-block-end: 8px;
+}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/787ac9062bc132ac6c05564c295845f4d6c91c68
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/787ac9062bc132ac6c05564c295845f4d6c91c68
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230606/70ca68b9/attachment-0001.htm>
More information about the tbb-commits
mailing list