ma1 pushed to branch tor-browser-102.12.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits: 338b3317 by Henry Wilkes at 2023-06-07T19:58:06+00:00 fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
Bug 41810 - Add "Connect" button instead of the "Submit" and "OK" button in the bridge request dialog and the manual bridge dialog, respectively.
- - - - -
4 changed files:
- browser/components/torpreferences/content/builtinBridgeDialog.jsm - browser/components/torpreferences/content/connectionPane.js - browser/components/torpreferences/content/provideBridgeDialog.jsm - browser/components/torpreferences/content/requestBridgeDialog.jsm
Changes:
===================================== browser/components/torpreferences/content/builtinBridgeDialog.jsm ===================================== @@ -36,9 +36,6 @@ class BuiltinBridgeDialog { "#torPreferences-builtinBridge-description" ).textContent = TorStrings.settings.builtinBridgeDescription2;
- this._acceptButton = dialog.getButton("accept"); - this.onTorStateChange(); - const radioGroup = dialog.querySelector( "#torPreferences-builtinBridge-typeSelection" ); @@ -102,20 +99,26 @@ class BuiltinBridgeDialog { dialog.style.minWidth = "0"; dialog.style.minHeight = "0";
+ this._acceptButton = dialog.getButton("accept"); + Services.obs.addObserver(this, TorConnectTopics.StateChange); + this.onAcceptStateChange(); }
- onTorStateChange() { - if (TorConnect.canBeginBootstrap) { - this._acceptButton.setAttribute( - "label", - TorStrings.settings.bridgeButtonConnect - ); - } else { - this._acceptButton.setAttribute( - "label", - TorStrings.settings.bridgeButtonAccept - ); + onAcceptStateChange() { + this._acceptButton.setAttribute( + "label", + TorConnect.canBeginBootstrap + ? TorStrings.settings.bridgeButtonConnect + : TorStrings.settings.bridgeButtonAccept + ); + } + + observe(subject, topic, data) { + switch (topic) { + case TorConnectTopics.StateChange: + this.onAcceptStateChange(); + break; } }
@@ -126,16 +129,8 @@ class BuiltinBridgeDialog { }, 0); }
- observe(subject, topic, data) { - switch (topic) { - case TorConnectTopics.StateChange: - this.onTorStateChange(); - break; - } - } - close() { - // unregister our observer topics + // Unregister our observer topics. Services.obs.removeObserver(this, TorConnectTopics.StateChange); }
===================================== browser/components/torpreferences/content/connectionPane.js ===================================== @@ -1047,9 +1047,47 @@ const gConnectionPane = (function() { }); },
+ /** + * Save and apply settings, then optionally open about:torconnect and start + * bootstrapping. + * + * @param {boolean} connect - Whether to open about:torconnect and start + * bootstrapping if possible. + */ + async saveBridgeSettings(connect) { + TorSettings.saveToPrefs(); + // FIXME: This can throw if the user adds a bridge manually with invalid + // content. Should be addressed by tor-browser#40552. + await TorSettings.applySettings(); + + this._populateBridgeCards(); + + if (!connect) { + return; + } + + // The bridge dialog button is "connect" when Tor is not bootstrapped, + // so do the connect. + + // Start Bootstrapping, which should use the configured bridges. + // NOTE: We do this regardless of any previous TorConnect Error. + if (TorConnect.canBeginBootstrap) { + TorConnect.beginBootstrap(); + } + // Open "about:torconnect". + // FIXME: If there has been a previous bootstrapping error then + // "about:torconnect" will be trying to get the user to use + // AutoBootstrapping. It is not set up to handle a forced direct + // entry to plain Bootstrapping from this dialog so the UI will not + // be aligned. In particular the + // AboutTorConnect.uiState.bootstrapCause will be aligned to + // whatever was shown previously in "about:torconnect" instead. + TorConnect.openTorConnect(); + }, + onAddBuiltinBridge() { const builtinBridgeDialog = new BuiltinBridgeDialog( - async (bridgeType, connect) => { + (bridgeType, connect) => { if (!bridgeType) { TorSettings.bridges.enabled = false; TorSettings.bridges.builtin_type = ""; @@ -1058,29 +1096,8 @@ const gConnectionPane = (function() { TorSettings.bridges.source = TorBridgeSource.BuiltIn; TorSettings.bridges.builtin_type = bridgeType; } - TorSettings.saveToPrefs(); - await TorSettings.applySettings(); - - this._populateBridgeCards();
- // The bridge dialog button is "connect" when Tor is not bootstrapped, - // so do the connect. - if (connect) { - // Start Bootstrapping, which should use the configured bridges. - // NOTE: We do this regardless of any previous TorConnect Error. - if (TorConnect.canBeginBootstrap) { - TorConnect.beginBootstrap(); - } - // Open "about:torconnect". - // FIXME: If there has been a previous bootstrapping error then - // "about:torconnect" will be trying to get the user to use - // AutoBootstrapping. It is not set up to handle a forced direct - // entry to plain Bootstrapping from this dialog so the UI will not - // be aligned. In particular the - // AboutTorConnect.uiState.bootstrapCause will be aligned to - // whatever was shown previously in "about:torconnect" instead. - TorConnect.openTorConnect(); - } + this.saveBridgeSettings(connect); } ); builtinBridgeDialog.openDialog(gSubDialog); @@ -1088,37 +1105,38 @@ const gConnectionPane = (function() {
// called when the request bridge button is activated onRequestBridge() { - const requestBridgeDialog = new RequestBridgeDialog(aBridges => { - if (aBridges.length) { + const requestBridgeDialog = new RequestBridgeDialog( + (aBridges, connect) => { + if (!aBridges.length) { + return; + } const bridgeStrings = aBridges.join("\n"); TorSettings.bridges.enabled = true; TorSettings.bridges.source = TorBridgeSource.BridgeDB; TorSettings.bridges.bridge_strings = bridgeStrings; - TorSettings.saveToPrefs(); - TorSettings.applySettings().then(result => { - this._populateBridgeCards(); - }); + + this.saveBridgeSettings(connect); } - }); + ); requestBridgeDialog.openDialog(gSubDialog); },
onAddBridgeManually() { - const provideBridgeDialog = new ProvideBridgeDialog(aBridgeString => { - if (aBridgeString.length) { - TorSettings.bridges.enabled = true; - TorSettings.bridges.source = TorBridgeSource.UserProvided; - TorSettings.bridges.bridge_strings = aBridgeString; - } else { - TorSettings.bridges.enabled = false; - TorSettings.bridges.source = TorBridgeSource.Invalid; - TorSettings.bridges.bridge_strings = ""; + const provideBridgeDialog = new ProvideBridgeDialog( + (aBridgeString, connect) => { + if (aBridgeString) { + TorSettings.bridges.enabled = true; + TorSettings.bridges.source = TorBridgeSource.UserProvided; + TorSettings.bridges.bridge_strings = aBridgeString; + } else { + TorSettings.bridges.enabled = false; + TorSettings.bridges.source = TorBridgeSource.Invalid; + TorSettings.bridges.bridge_strings = ""; + } + + this.saveBridgeSettings(connect); } - TorSettings.saveToPrefs(); - TorSettings.applySettings().then(result => { - this._populateBridgeCards(); - }); - }); + ); provideBridgeDialog.openDialog(gSubDialog); },
===================================== browser/components/torpreferences/content/provideBridgeDialog.jsm ===================================== @@ -2,17 +2,24 @@
var EXPORTED_SYMBOLS = ["ProvideBridgeDialog"];
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
const { TorSettings, TorBridgeSource } = ChromeUtils.import( "resource:///modules/TorSettings.jsm" );
+const { TorConnect, TorConnectTopics } = ChromeUtils.import( + "resource:///modules/TorConnect.jsm" +); + class ProvideBridgeDialog { constructor(onSubmit) { this.onSubmit = onSubmit; this._dialog = null; this._textarea = null; + this._acceptButton = null; }
static get selectors() { @@ -49,14 +56,43 @@ class ProvideBridgeDialog { "placeholder", TorStrings.settings.provideBridgePlaceholder ); + this._textarea.addEventListener("input", () => { + this.onAcceptStateChange(); + }); if (TorSettings.bridges.source == TorBridgeSource.UserProvided) { this._textarea.value = TorSettings.bridges.bridge_strings.join("\n"); }
this._dialog.addEventListener("dialogaccept", e => { - this.onSubmit(this._textarea.value); + let value = this._textarea.value; + if (!value.trim()) { + value = null; + } + this.onSubmit(value, value && TorConnect.canBeginBootstrap); }); this._dialog.addEventListener("dialoghelp", openHelp); + + this._acceptButton = this._dialog.getButton("accept"); + + Services.obs.addObserver(this, TorConnectTopics.StateChange); + this.onAcceptStateChange(); + } + + onAcceptStateChange() { + this._acceptButton.setAttribute( + "label", + this._textarea.value.trim() && TorConnect.canBeginBootstrap + ? TorStrings.settings.bridgeButtonConnect + : TorStrings.settings.bridgeButtonAccept + ); + } + + observe(subject, topic, data) { + switch (topic) { + case TorConnectTopics.StateChange: + this.onAcceptStateChange(); + break; + } }
init(window, aDialog) { @@ -66,10 +102,20 @@ class ProvideBridgeDialog { }, 0); }
+ close() { + // Unregister our observer topics. + Services.obs.removeObserver(this, TorConnectTopics.StateChange); + } + openDialog(gSubDialog) { gSubDialog.open( "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml", - { features: "resizable=yes" }, + { + features: "resizable=yes", + closingCallback: () => { + this.close(); + }, + }, this ); }
===================================== browser/components/torpreferences/content/requestBridgeDialog.jsm ===================================== @@ -2,9 +2,15 @@
var EXPORTED_SYMBOLS = ["RequestBridgeDialog"];
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + const { BridgeDB } = ChromeUtils.import("resource:///modules/BridgeDB.jsm"); const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+const { TorConnect, TorConnectTopics } = ChromeUtils.import( + "resource:///modules/TorConnect.jsm" +); + class RequestBridgeDialog { constructor(onSubmit) { this.onSubmit = onSubmit; @@ -20,8 +26,6 @@ class RequestBridgeDialog {
static get selectors() { return { - submitButton: - "accept" /* not really a selector but a key for dialog's getButton */, dialogHeader: "h3#torPreferences-requestBridge-header", captchaImage: "image#torPreferences-requestBridge-captchaImage", captchaEntryTextbox: "input#torPreferences-requestBridge-captchaTextbox", @@ -57,8 +61,7 @@ class RequestBridgeDialog { } });
- this._submitButton = this._dialog.getButton(selectors.submitButton); - this._submitButton.setAttribute("label", TorStrings.settings.submitCaptcha); + this._submitButton = this._dialog.getButton("accept"); this._submitButton.disabled = true; this._dialog.addEventListener("dialogaccept", e => { e.preventDefault(); @@ -110,7 +113,25 @@ class RequestBridgeDialog { TorStrings.settings.incorrectCaptcha );
- return true; + Services.obs.addObserver(this, TorConnectTopics.StateChange); + this.onAcceptStateChange(); + } + + onAcceptStateChange() { + this._submitButton.setAttribute( + "label", + TorConnect.canBeginBootstrap + ? TorStrings.settings.bridgeButtonConnect + : TorStrings.settings.submitCaptcha + ); + } + + observe(subject, topic, data) { + switch (topic) { + case TorConnectTopics.StateChange: + this.onAcceptStateChange(); + break; + } }
_setcaptchaImage(uri) { @@ -142,6 +163,8 @@ class RequestBridgeDialog {
close() { BridgeDB.close(); + // Unregister our observer topics. + Services.obs.removeObserver(this, TorConnectTopics.StateChange); }
/* @@ -161,7 +184,7 @@ class RequestBridgeDialog { BridgeDB.submitCaptchaGuess(captchaText) .then(aBridges => { if (aBridges) { - this.onSubmit(aBridges); + this.onSubmit(aBridges, TorConnect.canBeginBootstrap); this._submitButton.disabled = false; // This was successful, but use cancelDialog() to close, since // we intercept the `dialogaccept` event.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/338b3317...