richard pushed to branch tor-browser-102.11.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits: f89920b2 by Henry Wilkes at 2023-05-25T19:57:03+00:00 fixup! Bug 40597: Implement TorSettings module
Bug 41608 - Ignore tor connection errors when tor connection is cancelled by the user. This can happen if the bootstrap process is cancelled late in the process.
Also remove unused cancelAutoBootstrapping.
- - - - - 77d2560d by Henry Wilkes at 2023-05-25T19:57:03+00:00 fixup! Add TorStrings module for localization
Bug 41608 - Add new connection status strings.
- - - - - efa05015 by Henry Wilkes at 2023-05-25T19:57:03+00:00 fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
Bug 41608 - Use the torconnect icon for the onion slash.
- - - - - a71b5035 by Henry Wilkes at 2023-05-25T19:57:03+00:00 fixup! Bug 21952: Implement Onion-Location
Bug 41608 - Use the same styling for ".onion available" urlbar button as the tor-connect-urlbar-button. This also stops the button from overflowing its container like before. Also move to after the bookmark button.
- - - - - ba98c304 by Henry Wilkes at 2023-05-25T19:57:03+00:00 amend! Bug 27476: Implement about:torconnect captive portal within Tor Browser
Bug 27476: Implement about:torconnect captive portal within Tor Browser
- implements new about:torconnect page as tor-launcher replacement - adds new torconnect component to browser - tor process management functionality remains implemented in tor-launcher through the TorProtocolService module - adds warning/error box to about:preferences#tor when not connected to tor
Bug 40773: Update the about:torconnect frontend page to match additional UI flows.
Bug 41608: Add a toolbar status button and a urlbar "Connect" button.
- - - - - 702051f1 by Henry Wilkes at 2023-05-25T19:57:03+00:00 fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser
Bug 41608 and 41526 - Use KeyboardEvent.repeat to block triggering newly focused buttons in about:torconnect. The approach in tor-browser!607 prevented this by waiting for keyup, but keyup could still be triggered by a key event initialized elsewhere. E.g. when pressing Enter to close a modal dialog, the Enter's keyup event would be sent to the about:torconnect page and trigger the focused button.
- - - - -
21 changed files:
- browser/base/content/browser.js - browser/base/content/browser.xhtml - browser/base/content/navigator-toolbox.inc.xhtml - browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml - browser/components/onionservices/content/onionlocation.css - browser/components/torconnect/content/aboutTorConnect.js - − browser/components/torconnect/content/onion-slash.svg - − browser/components/torconnect/content/torBootstrapUrlbar.js - + browser/components/torconnect/content/torConnectTitlebarStatus.css - + browser/components/torconnect/content/torConnectTitlebarStatus.js - + browser/components/torconnect/content/torConnectUrlbarButton.js - − browser/components/torconnect/content/torconnect-urlbar.css - − browser/components/torconnect/content/torconnect-urlbar.inc.xhtml - browser/components/torconnect/jar.mn - browser/components/torpreferences/content/torPreferences.css - browser/modules/TorConnect.jsm - browser/modules/TorStrings.jsm - browser/themes/shared/browser-shared.css - browser/themes/shared/jar.inc.mn - + browser/themes/shared/tor-urlbar-button.css - toolkit/torbutton/chrome/locale/en-US/torConnect.properties
Changes:
===================================== browser/base/content/browser.js ===================================== @@ -80,6 +80,8 @@ XPCOMUtils.defineLazyModuleGetters(this, { TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm", TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.jsm", TorConnect: "resource:///modules/TorConnect.jsm", + TorConnectState: "resource:///modules/TorConnect.jsm", + TorConnectTopics: "resource:///modules/TorConnect.jsm", Translation: "resource:///modules/translation/TranslationParent.jsm", UITour: "resource:///modules/UITour.jsm", UpdateUtils: "resource://gre/modules/UpdateUtils.jsm", @@ -269,6 +271,16 @@ XPCOMUtils.defineLazyScriptGetter( "gSharedTabWarning", "chrome://browser/content/browser-webrtc.js" ); +XPCOMUtils.defineLazyScriptGetter( + this, + ["gTorConnectUrlbarButton"], + "chrome://browser/content/torconnect/torConnectUrlbarButton.js" +); +XPCOMUtils.defineLazyScriptGetter( + this, + ["gTorConnectTitlebarStatus"], + "chrome://browser/content/torconnect/torConnectTitlebarStatus.js" +); XPCOMUtils.defineLazyScriptGetter( this, ["gTorCircuitPanel"], @@ -1808,6 +1820,9 @@ var gBrowserInit = { // Init the OnionAuthPrompt OnionAuthPrompt.init();
+ gTorConnectUrlbarButton.init(); + gTorConnectTitlebarStatus.init(); + gTorCircuitPanel.init();
// Certain kinds of automigration rely on this notification to complete @@ -1895,8 +1910,6 @@ var gBrowserInit = { }
this._loadHandled = true; - - TorBootstrapUrlbar.init(); },
_cancelDelayedStartup() { @@ -2554,9 +2567,10 @@ var gBrowserInit = {
OnionAuthPrompt.uninit();
- gTorCircuitPanel.uninit(); + gTorConnectUrlbarButton.uninit(); + gTorConnectTitlebarStatus.uninit();
- TorBootstrapUrlbar.uninit(); + gTorCircuitPanel.uninit();
gAccessibilityServiceIndicator.uninit();
===================================== browser/base/content/browser.xhtml ===================================== @@ -37,6 +37,7 @@ <?xml-stylesheet href="chrome://browser/skin/places/editBookmark.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/content/onionservices/onionservices.css" type="text/css"?> <?xml-stylesheet href="chrome://browser/content/torCircuitPanel.css" type="text/css"?> +<?xml-stylesheet href="chrome://browser/content/torconnect/torConnectTitlebarStatus.css" type="text/css"?>
<!DOCTYPE window [ #include browser-doctype.inc @@ -123,7 +124,6 @@ Services.scriptloader.loadSubScript("chrome://browser/content/search/searchbar.js", this); Services.scriptloader.loadSubScript("chrome://browser/content/languageNotification.js", this); Services.scriptloader.loadSubScript("chrome://torbutton/content/torbutton.js", this); - Services.scriptloader.loadSubScript("chrome://browser/content/torconnect/torBootstrapUrlbar.js", this);
window.onload = gBrowserInit.onLoad.bind(gBrowserInit); window.onunload = gBrowserInit.onUnload.bind(gBrowserInit);
===================================== browser/base/content/navigator-toolbox.inc.xhtml ===================================== @@ -93,6 +93,11 @@ aria-live="polite"/> <hbox class="private-browsing-indicator"/>
+ <html:div id="tor-connect-titlebar-status" role="status"> + <html:img alt="" id="tor-connect-titlebar-status-icon" /> + <html:span id="tor-connect-titlebar-status-label"></html:span> + </html:div> + #include titlebar-items.inc.xhtml
</toolbar> @@ -335,7 +340,6 @@ data-l10n-id="urlbar-go-button"/> <hbox id="page-action-buttons" context="pageActionContextMenu"> <toolbartabstop/> -#include ../../components/torconnect/content/torconnect-urlbar.inc.xhtml <hbox id="contextual-feature-recommendation" role="button" hidden="true"> <hbox id="cfr-label-container"> <label id="cfr-label"/> @@ -363,9 +367,6 @@ onclick="FullZoom.reset(); FullZoom.resetScalingZoom();" tooltip="dynamic-shortcut-tooltip" hidden="true"/> - -#include ../../components/onionservices/content/onionlocation-urlbar.inc.xhtml - <hbox id="pageActionButton" class="urlbar-page-action" role="button" @@ -383,6 +384,15 @@ class="urlbar-icon"/> </hbox> </hbox> + + <hbox id="tor-connect-urlbar-button" + role="button" + class="tor-urlbar-button" + hidden="true"> + <label id="tor-connect-urlbar-button-label"/> + </hbox> + +#include ../../components/onionservices/content/onionlocation-urlbar.inc.xhtml </hbox> </hbox> <toolbartabstop/>
===================================== browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml ===================================== @@ -1,10 +1,10 @@ # Copyright (c) 2020, The Tor Project, Inc.
<hbox id="onion-location-box" - class="urlbar-icon-wrapper urlbar-page-action" + class="tor-urlbar-button" role="button" hidden="true" onclick="OnionLocationParent.buttonClick(event);"> <image id="onion-location-button" role="presentation"/> - <hbox id="onion-label-container"><label id="onion-label"/></hbox> + <label id="onion-label"/> </hbox>
===================================== browser/components/onionservices/content/onionlocation.css ===================================== @@ -1,44 +1,9 @@ /* Copyright (c) 2020, The Tor Project, Inc. */
-#onion-location-box { - background-color: var(--purple-60); - -moz-context-properties: fill; - fill: white; -} - -#onion-location-box:hover { - background-color: var(--purple-70); -} - -#onion-location-box:active { - background-color: var(--purple-80); -} - -@media (prefers-color-scheme: dark) { - #onion-location-box { - background-color: var(--purple-50); - } - - #onion-location-box:hover { - background-color: var(--purple-60); - } - - #onion-location-box:active { - background-color: var(--purple-70); - } -} - #onion-location-button { list-style-image: url(chrome://browser/content/onionservices/onionlocation.svg); - padding-inline-start: 0.5em; -} - -label#onion-label { - margin: 0; - padding-block: 0; - padding-inline: 0.5em; - color: white; - font-weight: normal; + -moz-context-properties: fill; + fill: currentColor; }
.onionlocation-notification-icon {
===================================== browser/components/torconnect/content/aboutTorConnect.js ===================================== @@ -769,26 +769,29 @@ class AboutTorConnect { } });
- // Delay the "Enter" activation of the given button from "keydown" to - // "keyup". + // Prevent repeat triggering on keydown when the Enter key is held down. // - // Without this, holding down Enter will continue to trigger the button - // until the user stops holding. This means that a user can accidentally - // re-trigger a button several times. This is particularly bad when the - // focus gets moved to a new button, and the new button can get triggered - // immediately. E.g. when the "Connect" button is triggered it disappears - // and focus moves to the "Cancel" button. + // Without this, holding down Enter will continue to trigger the button's + // click event until the user stops holding. This means that a user can + // accidentally re-trigger a button several times. And if focus moves to a + // new button it can also get triggered, despite not receiving the initial + // keydown event. + // + // E.g. If the user presses down Enter on the "Connect" button it will + // trigger and focus will move to the "Cancel" button. This should prevent + // the user accidentally triggering the "Cancel" button if they hold down + // Enter for a little bit too long. for (const button of document.body.querySelectorAll("button")) { button.addEventListener("keydown", event => { - if (event.key === "Enter") { + // If the keydown is a repeating Enter event, ignore it. + // NOTE: If firefox uses wayland display (rather than xwayland), the + // "repeat" event is always "false" so this will not work. + // See bugzilla bug 1784438. Also see bugzilla bug 1594003. + // Currently tor browser uses xwayland by default on linux. + if (event.key === "Enter" && event.repeat) { event.preventDefault(); } }); - button.addEventListener("keyup", event => { - if (event.key === "Enter") { - button.click(); - } - }); } }
===================================== browser/components/torconnect/content/onion-slash.svg deleted ===================================== @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg viewBox="0 0 16 16" width="16" height="16" xmlns="http://www.w3.org/2000/svg"> - <path d="m14.1161 15.6245c-.0821.0001-.1634-.016-.2393-.0474-.0758-.0314-.1447-.0775-.2027-.1356l-12.749984-12.749c-.109266-.11882-.168406-.27526-.165071-.43666.003335-.16139.068886-.31525.182967-.42946.114078-.11421.267868-.17994.429258-.18345.16139-.00352.3179.05544.43685.16457l12.74998 12.75c.1168.1176.1824.2767.1824.4425s-.0656.3249-.1824.4425c-.058.058-.1269.1039-.2028.1352-.0759.0312-.1571.0471-.2392.0468z" fill-opacity="context-fill-opacity" fill="#ff0039" /> - <path d="m 8,0.5000002 c -1.61963,0 -3.1197431,0.5137987 -4.3457031,1.3867188 l 0.84375,0.8417968 0.7792969,0.78125 0.8613281,0.8613282 0.8164062,0.8164062 0.9863281,0.984375 h 0.058594 c 1.00965,0 1.828125,0.818485 1.828125,1.828125 0,0.01968 6.2e-4,0.039074 0,0.058594 L 10.8125,9.0449221 C 10.9334,8.7195921 11,8.3674002 11,8.0000002 c 0,-1.65685 -1.34314,-3 -3,-3 v -1.078125 c 2.25231,0 4.078125,1.825845 4.078125,4.078125 0,0.67051 -0.162519,1.3033281 -0.449219,1.8613281 l 0.861328,0.8613277 C 12.972434,9.9290067 13.25,8.9965102 13.25,8.0000002 c 0,-2.89949 -2.35049,-5.25 -5.25,-5.25 v -1.078125 c 3.4949,0 6.328125,2.833195 6.328125,6.328125 0,1.29533 -0.388841,2.4990528 -1.056641,3.5019528 l 0.841797,0.84375 C 14.986181,11.119703 15.5,9.6196302 15.5,8.0000002 c 0,-4.14214 -3.3579,-7.5 -7.5,-7.5 z m -6.1113281,3.15625 C 1.0154872,4.8821451 0.5,6.3803304 0.5,8.0000002 0.5,12.1421 3.85786,15.5 8,15.5 c 1.6198027,0 3.117896,-0.515441 4.34375,-1.388672 L 11.501953,13.269531 C 10.498787,13.937828 9.295838,14.328125 8,14.328125 V 13.25 c 0.9967306,0 1.9287093,-0.277621 2.722656,-0.759766 L 9.859375,11.626953 C 9.3016226,11.913918 8.6705338,12.078125 8,12.078125 V 11 C 8.3664751,11 8.716425,10.93088 9.0410156,10.810547 6.6639891,8.4300416 4.2743195,6.0418993 1.8886719,3.6562502 Z" fill-opacity="context-fill-opacity" fill="context-fill"/> -</svg>
===================================== browser/components/torconnect/content/torBootstrapUrlbar.js deleted ===================================== @@ -1,95 +0,0 @@ -// Copyright (c) 2021, The Tor Project, Inc. - -"use strict"; - -const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import( - "resource:///modules/TorConnect.jsm" -); -const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm"); - -/* globals browser, gURLBar, Services */ - -var TorBootstrapUrlbar = { - selectors: Object.freeze({ - torConnect: { - box: "hbox#torconnect-box", - label: "label#torconnect-label", - }, - }), - - elements: null, - - updateTorConnectBox(state) { - switch (state) { - case TorConnectState.Initial: - case TorConnectState.Configuring: - case TorConnectState.AutoConfiguring: - case TorConnectState.Error: - case TorConnectState.FatalError: { - this.elements.torConnectBox.removeAttribute("hidden"); - this.elements.torConnectLabel.textContent = - TorStrings.torConnect.torNotConnectedConcise; - this.elements.inputContainer.setAttribute("torconnect", "offline"); - break; - } - case TorConnectState.Bootstrapping: { - this.elements.torConnectBox.removeAttribute("hidden"); - this.elements.torConnectLabel.textContent = - TorStrings.torConnect.torConnectingConcise; - this.elements.inputContainer.setAttribute("torconnect", "connecting"); - break; - } - case TorConnectState.Bootstrapped: { - this.elements.torConnectBox.removeAttribute("hidden"); - this.elements.torConnectLabel.textContent = - TorStrings.torConnect.torConnectedConcise; - this.elements.inputContainer.setAttribute("torconnect", "connected"); - // hide torconnect box after 5 seconds - setTimeout(() => { - this.elements.torConnectBox.setAttribute("hidden", "true"); - }, 5000); - break; - } - case TorConnectState.Disabled: { - this.elements.torConnectBox.setAttribute("hidden", "true"); - break; - } - default: - break; - } - }, - - observe(aSubject, aTopic, aData) { - if (aTopic === TorConnectTopics.StateChange) { - const obj = aSubject?.wrappedJSObject; - this.updateTorConnectBox(obj?.state); - } - }, - - init() { - if (TorConnect.shouldShowTorConnect) { - // browser isn't populated until init - this.elements = Object.freeze({ - torConnectBox: browser.ownerGlobal.document.querySelector( - this.selectors.torConnect.box - ), - torConnectLabel: browser.ownerGlobal.document.querySelector( - this.selectors.torConnect.label - ), - inputContainer: gURLBar._inputContainer, - }); - this.elements.torConnectBox.addEventListener("click", () => { - TorConnect.openTorConnect(); - }); - Services.obs.addObserver(this, TorConnectTopics.StateChange); - this.observing = true; - this.updateTorConnectBox(TorConnect.state); - } - }, - - uninit() { - if (this.observing) { - Services.obs.removeObserver(this, TorConnectTopics.StateChange); - } - }, -};
===================================== browser/components/torconnect/content/torConnectTitlebarStatus.css ===================================== @@ -0,0 +1,38 @@ +#tor-connect-titlebar-status:not([hidden]) { + display: flex; + align-items: center; + /* Want same as #private-browsing-indicator-with-label */ + margin-inline: 7px; +} + +#tor-connect-titlebar-status-label { + margin-inline: 6px; + white-space: nowrap; +} + +#tor-connect-titlebar-status-icon { + -moz-context-properties: fill; + fill: currentColor; + width: 16px; + height: 16px; +} + +#tor-connect-titlebar-status-icon.tor-connect-status-connected { + fill: var(--purple-60); +} + +@media (prefers-color-scheme: dark) { + #tor-connect-titlebar-status-icon.tor-connect-status-connected { + fill: var(--purple-30); + } +} + +#tor-connect-titlebar-status-icon.tor-connect-status-potentially-blocked { + fill: #c50042; +} + +@media (prefers-color-scheme: dark) { + #tor-connect-titlebar-status-icon.tor-connect-status-potentially-blocked { + fill: #ff9aa2; + } +}
===================================== browser/components/torconnect/content/torConnectTitlebarStatus.js ===================================== @@ -0,0 +1,115 @@ +/* eslint-env mozilla/browser-window */ + +/** + * A TorConnect status shown in the application title bar. + */ +var gTorConnectTitlebarStatus = { + /** + * The status element in the title bar. + * + * @type {Element} + */ + node: null, + /** + * The status label. + * + * @type {Element} + */ + label: null, + /** + * The status icon. + * + * @type {Element} + */ + icon: null, + + /** + * Initialize the component. + */ + init() { + const { TorStrings } = ChromeUtils.import( + "resource:///modules/TorStrings.jsm" + ); + + this._strings = TorStrings.torConnect; + + this.node = document.getElementById("tor-connect-titlebar-status"); + this.icon = document.getElementById("tor-connect-titlebar-status-icon"); + this.label = document.getElementById("tor-connect-titlebar-status-label"); + // The title also acts as an accessible name for the role="status". + this.node.setAttribute("title", this._strings.titlebarStatusName); + + this._observeTopic = TorConnectTopics.StateChange; + this._stateListener = { + observe: (subject, topic, data) => { + if (topic !== this._observeTopic) { + return; + } + this._torConnectStateChanged(); + }, + }; + Services.obs.addObserver(this._stateListener, this._observeTopic); + + this._torConnectStateChanged(); + }, + + /** + * De-initialize the component. + */ + deinit() { + Services.obs.removeObserver(this._stateListener, this._observeTopic); + }, + + /** + * Callback for when the TorConnect state changes. + */ + _torConnectStateChanged() { + let textId; + let connected = false; + let potentiallyBlocked = false; + switch (TorConnect.state) { + case TorConnectState.Disabled: + // Hide immediately. + this.node.hidden = true; + return; + case TorConnectState.Bootstrapped: + this._startHiding(); + textId = "titlebarStatusConnected"; + connected = true; + break; + case TorConnectState.Bootstrapping: + case TorConnectState.AutoBootstrapping: + textId = "titlebarStatusConnecting"; + break; + default: + if (TorConnect.potentiallyBlocked) { + textId = "titlebarStatusPotentiallyBlocked"; + potentiallyBlocked = true; + } else { + textId = "titlebarStatusNotConnected"; + } + break; + } + this.label.textContent = this._strings[textId]; + this.icon.setAttribute( + "src", + connected + ? "chrome://browser/content/torconnect/onion.svg" + : "chrome://browser/content/torconnect/onion-slash-fillable.svg" + ); + this.icon.classList.toggle("tor-connect-status-connected", connected); + this.icon.classList.toggle( + "tor-connect-status-potentially-blocked", + potentiallyBlocked + ); + }, + + /** + * Mark the component to be hidden after some delay. + */ + _startHiding() { + setTimeout(() => { + this.node.hidden = true; + }, 5000); + }, +};
===================================== browser/components/torconnect/content/torConnectUrlbarButton.js ===================================== @@ -0,0 +1,155 @@ +/* eslint-env mozilla/browser-window */ + +/** + * A "Connect" button shown in the urlbar when not connected to tor and in tabs + * other than about:torconnect. + */ +var gTorConnectUrlbarButton = { + /** + * The urlbar button node. + * + * @type {Element} + */ + button: null, + /** + * Whether we are active. + * + * @type {boolean} + */ + _isActive: false, + /** + * Whether we are in the "about:torconnect" tab. + * + * @type {boolean} + */ + // We init to "true" so that the button can only appear after the first page + // load. + _inAboutTorConnectTab: true, + + /** + * Initialize the button. + */ + init() { + if (this._isActive) { + return; + } + this._isActive = true; + + const { TorStrings } = ChromeUtils.import( + "resource:///modules/TorStrings.jsm" + ); + + this.button = document.getElementById("tor-connect-urlbar-button"); + document.getElementById("tor-connect-urlbar-button-label").value = + TorStrings.torConnect.torConnectButton; + this.button.addEventListener("click", event => { + if (event.button !== 0) { + return; + } + this.connect(); + }); + this.button.addEventListener("keydown", event => { + if (event.key !== "Enter" && event.key !== " ") { + return; + } + this.connect(); + }); + + this._observeTopic = TorConnectTopics.StateChange; + this._stateListener = { + observe: (subject, topic, data) => { + if (topic !== this._observeTopic) { + return; + } + this._torConnectStateChanged(); + }, + }; + Services.obs.addObserver(this._stateListener, this._observeTopic); + + this._locationListener = { + onLocationChange: (webProgress, request, locationURI, flags) => { + if ( + webProgress.isTopLevel && + !(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) + ) { + this._inAboutTorConnectTab = gBrowser.selectedBrowser.currentURI?.spec.startsWith( + "about:torconnect" + ); + this._updateButtonVisibility(); + } + }, + }; + // Notified of new locations for the currently selected browser (tab) *and* + // switching selected browser. + gBrowser.addProgressListener(this._locationListener); + + this._torConnectStateChanged(); + }, + + /** + * Deactivate and de-initialize the button. + */ + deinit() { + if (!this._isActive) { + return; + } + this._isActive = false; + + Services.obs.removeObserver(this._stateListener, this._observeTopic); + gBrowser.removeProgressListener(this._locationListener); + this._updateButtonVisibility(); + }, + + /** + * Begin the tor connection bootstrapping process. + */ + connect() { + TorConnect.openTorConnect({ beginBootstrap: true }); + }, + + /** + * Callback for when the TorConnect state changes. + */ + _torConnectStateChanged() { + if ( + TorConnect.state === TorConnectState.Bootstrapped || + TorConnect.state === TorConnectState.Disabled + ) { + this.deinit(); + return; + } + this._updateButtonVisibility(); + }, + + /** + * Callback when the TorConnect state, current browser location, or activation + * state changes. + */ + _updateButtonVisibility() { + if (!this.button) { + return; + } + // NOTE: We do not manage focus when hiding the button. We only expect to + // move from "not hidden" to "hidden" when: + // + switching tabs to "about:torconnect", or + // + starting bootstrapping. + // + // When switching tabs, the normal tab switching logic will eventually move + // focus to the new tab or url bar, so whilst the focus may be lost + // temporarily when we hide the button, it will be re-established quickly on + // tab switch. + // + // And we don't expect bootstrapping to start whilst outside of the + // "about:torconnect", and the automatic bootstrapping should only trigger + // at the initial start. + this.button.hidden = + !this._isActive || + this._inAboutTorConnectTab || + !TorConnect.enabled || + !TorConnect.canBeginBootstrap; + this.button.classList.toggle( + "tor-urlbar-button-plain", + TorConnect.potentiallyBlocked + ); + }, +};
===================================== browser/components/torconnect/content/torconnect-urlbar.css deleted ===================================== @@ -1,37 +0,0 @@ -/* - ensure our torconnect button is always visible (same rule as for the bookmark button) -*/ -label#torconnect-label { - margin: 0; - opacity: 0.6; - padding: 0 0.5em; -} - -hbox.urlbar-page-action#torconnect-box { - display: -moz-inline-box!important; -} - -/* hide when hidden attribute is set */ -hbox.urlbar-page-action#torconnect-box[hidden="true"], -/* hide when user is typing in URL bar */ -#urlbar[usertyping] > #urlbar-input-container > #page-action-buttons > #torconnect-box { - display: none!important; -} - -/* hide urlbar's placeholder text when not connectd to tor */ -hbox#urlbar-input-container[torconnect="offline"] input#urlbar-input::placeholder, -hbox#urlbar-input-container[torconnect="connecting"] input#urlbar-input::placeholder { - opacity: 0; -} - -/* hide search suggestions when not connected to tor */ -hbox#urlbar-input-container[torconnect="offline"] + vbox.urlbarView, -hbox#urlbar-input-container[torconnect="connecting"] + vbox.urlbarView { - display: none!important; -} - -/* hide search icon when we are not connected to tor */ -hbox#urlbar-input-container[torconnect="offline"] > #identity-box[pageproxystate="invalid"] > #identity-icon, -hbox#urlbar-input-container[torconnect="connecting"] > #identity-box[pageproxystate="invalid"] > #identity-icon { - display: none!important; -}
===================================== browser/components/torconnect/content/torconnect-urlbar.inc.xhtml deleted ===================================== @@ -1,11 +0,0 @@ -# Copyright (c) 2021, The Tor Project, Inc. - -<hbox id="torconnect-box" - class="urlbar-icon-wrapper urlbar-page-action" - role="status" - align="center" - hidden="true"> - <hbox id="torconnect-container"> - <label id="torconnect-label"/> - </hbox> -</hbox> \ No newline at end of file
===================================== browser/components/torconnect/jar.mn ===================================== @@ -1,5 +1,7 @@ browser.jar: - content/browser/torconnect/torBootstrapUrlbar.js (content/torBootstrapUrlbar.js) + content/browser/torconnect/torConnectUrlbarButton.js (content/torConnectUrlbarButton.js) + content/browser/torconnect/torConnectTitlebarStatus.js (content/torConnectTitlebarStatus.js) + content/browser/torconnect/torConnectTitlebarStatus.css (content/torConnectTitlebarStatus.css) content/browser/torconnect/aboutTorConnect.css (content/aboutTorConnect.css) * content/browser/torconnect/aboutTorConnect.xhtml (content/aboutTorConnect.xhtml) content/browser/torconnect/aboutTorConnect.js (content/aboutTorConnect.js) @@ -8,6 +10,4 @@ browser.jar: content/browser/torconnect/connection-failure.svg (content/connection-failure.svg) content/browser/torconnect/connection-location.svg (content/connection-location.svg) content/browser/torconnect/onion.svg (content/onion.svg) - content/browser/torconnect/onion-slash.svg (content/onion-slash.svg) content/browser/torconnect/onion-slash-fillable.svg (content/onion-slash-fillable.svg) - skin/classic/browser/torconnect-urlbar.css (content/torconnect-urlbar.css)
===================================== browser/components/torpreferences/content/torPreferences.css ===================================== @@ -58,7 +58,7 @@ html:dir(rtl) input[type="checkbox"].toggle-button::before {
#torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-icon { - mask: url("chrome://browser/skin/onion-slash.svg"); + mask: url("chrome://browser/content/torconnect/onion-slash-fillable.svg"); background-color: white; }
===================================== browser/modules/TorConnect.jsm ===================================== @@ -99,7 +99,7 @@ const TorConnectState = Object.freeze({ └─┼─────▶ │ │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ ▲ │ - │ │ beginAutoBootstrap() │ cancelAutoBootstrap() │ + │ │ beginAutoBootstrap() │ cancelBootstrap() │ │ ▼ │ │ │ ┌───────────────────────┐ │ │ └────── │ AutoBootstrapping │ ─┘ │ @@ -464,6 +464,7 @@ const TorConnect = (() => {
const tbr = new TorBootstrapRequest(); const internetTest = new InternetTest(); + let cancelled = false;
let bootstrapError = ""; let bootstrapErrorDetails = ""; @@ -506,6 +507,7 @@ const TorConnect = (() => { this.on_transition = async nextState => { if (nextState === TorConnectState.Configuring) { // stop bootstrap process if user cancelled + cancelled = true; internetTest.cancel(); await tbr.cancel(); } @@ -520,6 +522,19 @@ const TorConnect = (() => { TorConnect._changeState(TorConnectState.Bootstrapped); }; tbr.onbootstraperror = (message, details) => { + if (cancelled) { + // We ignore this error since it occurred after cancelling (by + // the user). We assume the error is just a side effect of the + // cancelling. + // E.g. If the cancelling is triggered late in the process, we + // get "Building circuits: Establishing a Tor circuit failed". + // TODO: Maybe move this logic deeper in the process to know + // when to filter out such errors triggered by cancelling. + console.log( + `TorConnect: Post-cancel error => ${message}; ${details}` + ); + return; + } // We have to wait for the Internet test to finish before sending the bootstrap error bootstrapError = message; bootstrapErrorDetails = details; @@ -1023,11 +1038,6 @@ const TorConnect = (() => { this._changeState(TorConnectState.AutoBootstrapping, countryCode); },
- cancelAutoBootstrap() { - console.log("TorConnect: cancelAutoBootstrap()"); - this._changeState(TorConnectState.Configuring); - }, - /* Further external commands and helper methods */
===================================== browser/modules/TorStrings.jsm ===================================== @@ -207,10 +207,6 @@ const Loader = {
torConnecting: "Establishing a Connection",
- torNotConnectedConcise: "Not Connected", - - torConnectingConcise: "Connecting…", - tryingAgain: "Trying again…",
noInternet: "Tor Browser couldn’t reach the Internet", @@ -250,8 +246,6 @@ const Loader = {
torConnected: "Connected to the Tor network",
- torConnectedConcise: "Connected", - tryAgain: "Try Again",
// tor connect strings for message box in about:preferences#connection @@ -275,6 +269,13 @@ const Loader = { autoBootstrappingAllFailed: "None of the configurations we tried worked", cannotDetermineCountry: "Unable to determine user country", noSettingsForCountry: "No settings available for your location", + + // Titlebar status. + titlebarStatusName: "Tor connection", + titlebarStatusNotConnected: "Not connected", + titlebarStatusConnecting: "Connecting…", + titlebarStatusPotentiallyBlocked: "Potentially blocked", + titlebarStatusConnected: "Connected", };
const tsb = new TorPropertyStringBundle(
===================================== browser/themes/shared/browser-shared.css ===================================== @@ -23,8 +23,8 @@ @import url("chrome://browser/skin/UITour.css"); @import url("chrome://browser/skin/browser-colors.css"); @import url("chrome://branding/content/tor-styles.css"); -@import url("chrome://browser/skin/torconnect-urlbar.css"); @import url("chrome://browser/skin/onionlocation.css"); +@import url("chrome://browser/skin/tor-urlbar-button.css");
@namespace html url("http://www.w3.org/1999/xhtml");
===================================== browser/themes/shared/jar.inc.mn ===================================== @@ -32,6 +32,7 @@ skin/classic/browser/tabs.css (../shared/tabs.css) skin/classic/browser/toolbarbuttons.css (../shared/toolbarbuttons.css) skin/classic/browser/toolbarbutton-icons.css (../shared/toolbarbutton-icons.css) + skin/classic/browser/tor-urlbar-button.css (../shared/tor-urlbar-button.css) skin/classic/browser/urlbar-dynamic-results.css (../shared/urlbar-dynamic-results.css) skin/classic/browser/urlbar-searchbar.css (../shared/urlbar-searchbar.css) skin/classic/browser/urlbarView.css (../shared/urlbarView.css)
===================================== browser/themes/shared/tor-urlbar-button.css ===================================== @@ -0,0 +1,107 @@ +.tor-urlbar-button:not([hidden]) { + --tor-urlbar-button-background-color: var(--purple-60); + background-color: var(--tor-urlbar-button-background-color); + /* FIXME: Use different colors for light and dark theme, rather than "white". + * See tor-browser#41787 */ + color: white; + display: flex; + align-items: center; + gap: 0.5em; + border-radius: var(--urlbar-icon-border-radius); + --tor-urlbar-button-inline-padding: 8px; + padding-inline: var(--tor-urlbar-button-inline-padding); + margin: 0; +} + +.tor-urlbar-button > * { + flex: 0 0 auto; + margin: 0; +} + +.tor-urlbar-button:focus-visible { + /* This button lies within the urlbar, so if the outline extends beyond the + * button's boundary, it will be clipped by the urlbar. + * Most button's in the urlbar get around this by using --focus-outline-inset, + * but our button has a purple background, which does not contrast well with + * the focus outline. + * Therefore, we use an offset outline rather than an inset outline, and + * compensate by shrinking the button's width and height so that the outline + * fits within the non-focused button boundary. Essentially, this has a + * similar effect to using an inset outline that matches the color of the + * urlbar background, but we keep the rounded corners. */ + outline: var(--focus-outline); + outline-offset: var(--focus-outline-offset); + /* Use the background color for the outline, same as in-content buttons. */ + outline-color: var(--tor-urlbar-button-background-color); + /* Calculate the difference between the button's border area and the outline + * area. */ + --tor-urlbar-focus-outline-difference: calc( + var(--focus-outline-offset) + + var(--focus-outline-width) + ); + /* For the inline direction, we shrink the padding by the difference, and + * increase the margin by the same amount so that the button text remains in + * the same position. + * For the block direction, the height of the button is flexibly sized with + * the urlbar height, so we should only need to increase the margin. */ + padding-inline: calc( + var(--tor-urlbar-button-inline-padding) + - var(--tor-urlbar-focus-outline-difference) + ); + margin: var(--tor-urlbar-focus-outline-difference); +} + +.tor-urlbar-button:focus-visible > * { + /* Negate the margin that would be added on focus to ensure the button does + * not grow in height. + * Ideally, this should not change anything noticeable, otherwise the text + * could be clipped when focused. */ + margin-block: calc(-1 * var(--tor-urlbar-focus-outline-difference)); +} + +#urlbar[usertyping] .tor-urlbar-button { + /* Hide whilst the user is typing in the url bar. */ + display: none; +} + +.tor-urlbar-button:hover { + --tor-urlbar-button-background-color: var(--purple-70); +} + +.tor-urlbar-button:hover:active { + --tor-urlbar-button-background-color: var(--purple-80); +} + +@media (prefers-color-scheme: dark) { + .tor-urlbar-button { + --tor-urlbar-button-background-color: var(--purple-50); + } + + .tor-urlbar-button:hover { + --tor-urlbar-button-background-color: var(--purple-60); + } + + .tor-urlbar-button:hover:active { + --tor-urlbar-button-background-color: var(--purple-70); + } +} + +/* Make the button look plain like the identity #urlbar-label-box. */ +.tor-urlbar-button.tor-urlbar-button-plain { + --tor-urlbar-button-background-color: var(--urlbar-box-bgcolor); + color: var(--urlbar-box-text-color); +} + +.tor-urlbar-button.tor-urlbar-button-plain:focus-visible { + outline-color: var(--focus-outline-color); +} + +.tor-urlbar-button.tor-urlbar-button-plain:hover { + --tor-urlbar-button-background-color: var(--urlbar-box-hover-bgcolor); + color: var(--urlbar-box-hover-text-color); +} + +.tor-urlbar-button.tor-urlbar-button-plain:hover:active { + --tor-urlbar-button-background-color: var(--urlbar-box-active-bgcolor); + color: var(--urlbar-box-hover-text-color); +}
===================================== toolkit/torbutton/chrome/locale/en-US/torConnect.properties ===================================== @@ -3,10 +3,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+torConnect.titlebarStatusName=Tor connection +torConnect.titlebarStatusNotConnected=Not connected +torConnect.titlebarStatusConnecting=Connecting… +torConnect.titlebarStatusPotentiallyBlocked=Potentially blocked +torConnect.titlebarStatusConnected=Connected + torConnect.torConnect=Connect to Tor torConnect.torConnecting=Establishing a Connection -torConnect.torNotConnectedConcise=Not Connected -torConnect.torConnectingConcise=Connecting… torConnect.tryingAgain=Trying again… torConnect.noInternet=Tor Browser couldn’t reach the Internet torConnect.noInternetDescription=This could be due to a connection issue rather than Tor being blocked. Check your Internet connection, proxy and firewall settings before trying again. @@ -35,7 +39,6 @@ torConnect.viewLog=View logs… torConnect.torConnectButton=Connect torConnect.cancel=Cancel torConnect.torConnected=Connected to the Tor network! -torConnect.torConnectedConcise=Connected torConnect.tryAgain=Try Again torConnect.connectMessage=Changes to Tor Settings will not take effect until you connect torConnect.tryAgainMessage=Tor Browser has failed to establish a connection to the Tor Network @@ -51,3 +54,8 @@ torConnect.autoBootstrappingFailed=Automatic configuration failed torConnect.autoBootstrappingAllFailed=None of the configurations we tried worked torConnect.cannotDetermineCountry=Unable to determine user country torConnect.noSettingsForCountry=No settings available for your location + +# Urlbar strings used up to 12.0 - TODO: remove when 12.5 becomes stable: +torConnect.torNotConnectedConcise=Not Connected +torConnect.torConnectingConcise=Connecting… +torConnect.torConnectedConcise=Connected
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/dbec6cf...
tor-commits@lists.torproject.org