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
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:
| ... | ... | @@ -36,9 +36,6 @@ class BuiltinBridgeDialog { |
| 36 | 36 | "#torPreferences-builtinBridge-description"
|
| 37 | 37 | ).textContent = TorStrings.settings.builtinBridgeDescription2;
|
| 38 | 38 | |
| 39 | - this._acceptButton = dialog.getButton("accept");
|
|
| 40 | - this.onTorStateChange();
|
|
| 41 | - |
|
| 42 | 39 | const radioGroup = dialog.querySelector(
|
| 43 | 40 | "#torPreferences-builtinBridge-typeSelection"
|
| 44 | 41 | );
|
| ... | ... | @@ -102,20 +99,26 @@ class BuiltinBridgeDialog { |
| 102 | 99 | dialog.style.minWidth = "0";
|
| 103 | 100 | dialog.style.minHeight = "0";
|
| 104 | 101 | |
| 102 | + this._acceptButton = dialog.getButton("accept");
|
|
| 103 | + |
|
| 105 | 104 | Services.obs.addObserver(this, TorConnectTopics.StateChange);
|
| 105 | + this.onAcceptStateChange();
|
|
| 106 | 106 | }
|
| 107 | 107 | |
| 108 | - onTorStateChange() {
|
|
| 109 | - if (TorConnect.canBeginBootstrap) {
|
|
| 110 | - this._acceptButton.setAttribute(
|
|
| 111 | - "label",
|
|
| 112 | - TorStrings.settings.bridgeButtonConnect
|
|
| 113 | - );
|
|
| 114 | - } else {
|
|
| 115 | - this._acceptButton.setAttribute(
|
|
| 116 | - "label",
|
|
| 117 | - TorStrings.settings.bridgeButtonAccept
|
|
| 118 | - );
|
|
| 108 | + onAcceptStateChange() {
|
|
| 109 | + this._acceptButton.setAttribute(
|
|
| 110 | + "label",
|
|
| 111 | + TorConnect.canBeginBootstrap
|
|
| 112 | + ? TorStrings.settings.bridgeButtonConnect
|
|
| 113 | + : TorStrings.settings.bridgeButtonAccept
|
|
| 114 | + );
|
|
| 115 | + }
|
|
| 116 | + |
|
| 117 | + observe(subject, topic, data) {
|
|
| 118 | + switch (topic) {
|
|
| 119 | + case TorConnectTopics.StateChange:
|
|
| 120 | + this.onAcceptStateChange();
|
|
| 121 | + break;
|
|
| 119 | 122 | }
|
| 120 | 123 | }
|
| 121 | 124 | |
| ... | ... | @@ -126,16 +129,8 @@ class BuiltinBridgeDialog { |
| 126 | 129 | }, 0);
|
| 127 | 130 | }
|
| 128 | 131 | |
| 129 | - observe(subject, topic, data) {
|
|
| 130 | - switch (topic) {
|
|
| 131 | - case TorConnectTopics.StateChange:
|
|
| 132 | - this.onTorStateChange();
|
|
| 133 | - break;
|
|
| 134 | - }
|
|
| 135 | - }
|
|
| 136 | - |
|
| 137 | 132 | close() {
|
| 138 | - // unregister our observer topics
|
|
| 133 | + // Unregister our observer topics.
|
|
| 139 | 134 | Services.obs.removeObserver(this, TorConnectTopics.StateChange);
|
| 140 | 135 | }
|
| 141 | 136 |
| ... | ... | @@ -1047,9 +1047,47 @@ const gConnectionPane = (function() { |
| 1047 | 1047 | });
|
| 1048 | 1048 | },
|
| 1049 | 1049 | |
| 1050 | + /**
|
|
| 1051 | + * Save and apply settings, then optionally open about:torconnect and start
|
|
| 1052 | + * bootstrapping.
|
|
| 1053 | + *
|
|
| 1054 | + * @param {boolean} connect - Whether to open about:torconnect and start
|
|
| 1055 | + * bootstrapping if possible.
|
|
| 1056 | + */
|
|
| 1057 | + async saveBridgeSettings(connect) {
|
|
| 1058 | + TorSettings.saveToPrefs();
|
|
| 1059 | + // FIXME: This can throw if the user adds a bridge manually with invalid
|
|
| 1060 | + // content. Should be addressed by tor-browser#40552.
|
|
| 1061 | + await TorSettings.applySettings();
|
|
| 1062 | + |
|
| 1063 | + this._populateBridgeCards();
|
|
| 1064 | + |
|
| 1065 | + if (!connect) {
|
|
| 1066 | + return;
|
|
| 1067 | + }
|
|
| 1068 | + |
|
| 1069 | + // The bridge dialog button is "connect" when Tor is not bootstrapped,
|
|
| 1070 | + // so do the connect.
|
|
| 1071 | + |
|
| 1072 | + // Start Bootstrapping, which should use the configured bridges.
|
|
| 1073 | + // NOTE: We do this regardless of any previous TorConnect Error.
|
|
| 1074 | + if (TorConnect.canBeginBootstrap) {
|
|
| 1075 | + TorConnect.beginBootstrap();
|
|
| 1076 | + }
|
|
| 1077 | + // Open "about:torconnect".
|
|
| 1078 | + // FIXME: If there has been a previous bootstrapping error then
|
|
| 1079 | + // "about:torconnect" will be trying to get the user to use
|
|
| 1080 | + // AutoBootstrapping. It is not set up to handle a forced direct
|
|
| 1081 | + // entry to plain Bootstrapping from this dialog so the UI will not
|
|
| 1082 | + // be aligned. In particular the
|
|
| 1083 | + // AboutTorConnect.uiState.bootstrapCause will be aligned to
|
|
| 1084 | + // whatever was shown previously in "about:torconnect" instead.
|
|
| 1085 | + TorConnect.openTorConnect();
|
|
| 1086 | + },
|
|
| 1087 | + |
|
| 1050 | 1088 | onAddBuiltinBridge() {
|
| 1051 | 1089 | const builtinBridgeDialog = new BuiltinBridgeDialog(
|
| 1052 | - async (bridgeType, connect) => {
|
|
| 1090 | + (bridgeType, connect) => {
|
|
| 1053 | 1091 | if (!bridgeType) {
|
| 1054 | 1092 | TorSettings.bridges.enabled = false;
|
| 1055 | 1093 | TorSettings.bridges.builtin_type = "";
|
| ... | ... | @@ -1058,29 +1096,8 @@ const gConnectionPane = (function() { |
| 1058 | 1096 | TorSettings.bridges.source = TorBridgeSource.BuiltIn;
|
| 1059 | 1097 | TorSettings.bridges.builtin_type = bridgeType;
|
| 1060 | 1098 | }
|
| 1061 | - TorSettings.saveToPrefs();
|
|
| 1062 | - await TorSettings.applySettings();
|
|
| 1063 | - |
|
| 1064 | - this._populateBridgeCards();
|
|
| 1065 | 1099 | |
| 1066 | - // The bridge dialog button is "connect" when Tor is not bootstrapped,
|
|
| 1067 | - // so do the connect.
|
|
| 1068 | - if (connect) {
|
|
| 1069 | - // Start Bootstrapping, which should use the configured bridges.
|
|
| 1070 | - // NOTE: We do this regardless of any previous TorConnect Error.
|
|
| 1071 | - if (TorConnect.canBeginBootstrap) {
|
|
| 1072 | - TorConnect.beginBootstrap();
|
|
| 1073 | - }
|
|
| 1074 | - // Open "about:torconnect".
|
|
| 1075 | - // FIXME: If there has been a previous bootstrapping error then
|
|
| 1076 | - // "about:torconnect" will be trying to get the user to use
|
|
| 1077 | - // AutoBootstrapping. It is not set up to handle a forced direct
|
|
| 1078 | - // entry to plain Bootstrapping from this dialog so the UI will not
|
|
| 1079 | - // be aligned. In particular the
|
|
| 1080 | - // AboutTorConnect.uiState.bootstrapCause will be aligned to
|
|
| 1081 | - // whatever was shown previously in "about:torconnect" instead.
|
|
| 1082 | - TorConnect.openTorConnect();
|
|
| 1083 | - }
|
|
| 1100 | + this.saveBridgeSettings(connect);
|
|
| 1084 | 1101 | }
|
| 1085 | 1102 | );
|
| 1086 | 1103 | builtinBridgeDialog.openDialog(gSubDialog);
|
| ... | ... | @@ -1088,37 +1105,38 @@ const gConnectionPane = (function() { |
| 1088 | 1105 | |
| 1089 | 1106 | // called when the request bridge button is activated
|
| 1090 | 1107 | onRequestBridge() {
|
| 1091 | - const requestBridgeDialog = new RequestBridgeDialog(aBridges => {
|
|
| 1092 | - if (aBridges.length) {
|
|
| 1108 | + const requestBridgeDialog = new RequestBridgeDialog(
|
|
| 1109 | + (aBridges, connect) => {
|
|
| 1110 | + if (!aBridges.length) {
|
|
| 1111 | + return;
|
|
| 1112 | + }
|
|
| 1093 | 1113 | const bridgeStrings = aBridges.join("\n");
|
| 1094 | 1114 | TorSettings.bridges.enabled = true;
|
| 1095 | 1115 | TorSettings.bridges.source = TorBridgeSource.BridgeDB;
|
| 1096 | 1116 | TorSettings.bridges.bridge_strings = bridgeStrings;
|
| 1097 | - TorSettings.saveToPrefs();
|
|
| 1098 | - TorSettings.applySettings().then(result => {
|
|
| 1099 | - this._populateBridgeCards();
|
|
| 1100 | - });
|
|
| 1117 | + |
|
| 1118 | + this.saveBridgeSettings(connect);
|
|
| 1101 | 1119 | }
|
| 1102 | - });
|
|
| 1120 | + );
|
|
| 1103 | 1121 | requestBridgeDialog.openDialog(gSubDialog);
|
| 1104 | 1122 | },
|
| 1105 | 1123 | |
| 1106 | 1124 | onAddBridgeManually() {
|
| 1107 | - const provideBridgeDialog = new ProvideBridgeDialog(aBridgeString => {
|
|
| 1108 | - if (aBridgeString.length) {
|
|
| 1109 | - TorSettings.bridges.enabled = true;
|
|
| 1110 | - TorSettings.bridges.source = TorBridgeSource.UserProvided;
|
|
| 1111 | - TorSettings.bridges.bridge_strings = aBridgeString;
|
|
| 1112 | - } else {
|
|
| 1113 | - TorSettings.bridges.enabled = false;
|
|
| 1114 | - TorSettings.bridges.source = TorBridgeSource.Invalid;
|
|
| 1115 | - TorSettings.bridges.bridge_strings = "";
|
|
| 1125 | + const provideBridgeDialog = new ProvideBridgeDialog(
|
|
| 1126 | + (aBridgeString, connect) => {
|
|
| 1127 | + if (aBridgeString) {
|
|
| 1128 | + TorSettings.bridges.enabled = true;
|
|
| 1129 | + TorSettings.bridges.source = TorBridgeSource.UserProvided;
|
|
| 1130 | + TorSettings.bridges.bridge_strings = aBridgeString;
|
|
| 1131 | + } else {
|
|
| 1132 | + TorSettings.bridges.enabled = false;
|
|
| 1133 | + TorSettings.bridges.source = TorBridgeSource.Invalid;
|
|
| 1134 | + TorSettings.bridges.bridge_strings = "";
|
|
| 1135 | + }
|
|
| 1136 | + |
|
| 1137 | + this.saveBridgeSettings(connect);
|
|
| 1116 | 1138 | }
|
| 1117 | - TorSettings.saveToPrefs();
|
|
| 1118 | - TorSettings.applySettings().then(result => {
|
|
| 1119 | - this._populateBridgeCards();
|
|
| 1120 | - });
|
|
| 1121 | - });
|
|
| 1139 | + );
|
|
| 1122 | 1140 | provideBridgeDialog.openDialog(gSubDialog);
|
| 1123 | 1141 | },
|
| 1124 | 1142 |
| ... | ... | @@ -2,17 +2,24 @@ |
| 2 | 2 | |
| 3 | 3 | var EXPORTED_SYMBOLS = ["ProvideBridgeDialog"];
|
| 4 | 4 | |
| 5 | +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
| 6 | + |
|
| 5 | 7 | const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
|
| 6 | 8 | |
| 7 | 9 | const { TorSettings, TorBridgeSource } = ChromeUtils.import(
|
| 8 | 10 | "resource:///modules/TorSettings.jsm"
|
| 9 | 11 | );
|
| 10 | 12 | |
| 13 | +const { TorConnect, TorConnectTopics } = ChromeUtils.import(
|
|
| 14 | + "resource:///modules/TorConnect.jsm"
|
|
| 15 | +);
|
|
| 16 | + |
|
| 11 | 17 | class ProvideBridgeDialog {
|
| 12 | 18 | constructor(onSubmit) {
|
| 13 | 19 | this.onSubmit = onSubmit;
|
| 14 | 20 | this._dialog = null;
|
| 15 | 21 | this._textarea = null;
|
| 22 | + this._acceptButton = null;
|
|
| 16 | 23 | }
|
| 17 | 24 | |
| 18 | 25 | static get selectors() {
|
| ... | ... | @@ -49,14 +56,43 @@ class ProvideBridgeDialog { |
| 49 | 56 | "placeholder",
|
| 50 | 57 | TorStrings.settings.provideBridgePlaceholder
|
| 51 | 58 | );
|
| 59 | + this._textarea.addEventListener("input", () => {
|
|
| 60 | + this.onAcceptStateChange();
|
|
| 61 | + });
|
|
| 52 | 62 | if (TorSettings.bridges.source == TorBridgeSource.UserProvided) {
|
| 53 | 63 | this._textarea.value = TorSettings.bridges.bridge_strings.join("\n");
|
| 54 | 64 | }
|
| 55 | 65 | |
| 56 | 66 | this._dialog.addEventListener("dialogaccept", e => {
|
| 57 | - this.onSubmit(this._textarea.value);
|
|
| 67 | + let value = this._textarea.value;
|
|
| 68 | + if (!value.trim()) {
|
|
| 69 | + value = null;
|
|
| 70 | + }
|
|
| 71 | + this.onSubmit(value, value && TorConnect.canBeginBootstrap);
|
|
| 58 | 72 | });
|
| 59 | 73 | this._dialog.addEventListener("dialoghelp", openHelp);
|
| 74 | + |
|
| 75 | + this._acceptButton = this._dialog.getButton("accept");
|
|
| 76 | + |
|
| 77 | + Services.obs.addObserver(this, TorConnectTopics.StateChange);
|
|
| 78 | + this.onAcceptStateChange();
|
|
| 79 | + }
|
|
| 80 | + |
|
| 81 | + onAcceptStateChange() {
|
|
| 82 | + this._acceptButton.setAttribute(
|
|
| 83 | + "label",
|
|
| 84 | + this._textarea.value.trim() && TorConnect.canBeginBootstrap
|
|
| 85 | + ? TorStrings.settings.bridgeButtonConnect
|
|
| 86 | + : TorStrings.settings.bridgeButtonAccept
|
|
| 87 | + );
|
|
| 88 | + }
|
|
| 89 | + |
|
| 90 | + observe(subject, topic, data) {
|
|
| 91 | + switch (topic) {
|
|
| 92 | + case TorConnectTopics.StateChange:
|
|
| 93 | + this.onAcceptStateChange();
|
|
| 94 | + break;
|
|
| 95 | + }
|
|
| 60 | 96 | }
|
| 61 | 97 | |
| 62 | 98 | init(window, aDialog) {
|
| ... | ... | @@ -66,10 +102,20 @@ class ProvideBridgeDialog { |
| 66 | 102 | }, 0);
|
| 67 | 103 | }
|
| 68 | 104 | |
| 105 | + close() {
|
|
| 106 | + // Unregister our observer topics.
|
|
| 107 | + Services.obs.removeObserver(this, TorConnectTopics.StateChange);
|
|
| 108 | + }
|
|
| 109 | + |
|
| 69 | 110 | openDialog(gSubDialog) {
|
| 70 | 111 | gSubDialog.open(
|
| 71 | 112 | "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
|
| 72 | - { features: "resizable=yes" },
|
|
| 113 | + {
|
|
| 114 | + features: "resizable=yes",
|
|
| 115 | + closingCallback: () => {
|
|
| 116 | + this.close();
|
|
| 117 | + },
|
|
| 118 | + },
|
|
| 73 | 119 | this
|
| 74 | 120 | );
|
| 75 | 121 | }
|
| ... | ... | @@ -2,9 +2,15 @@ |
| 2 | 2 | |
| 3 | 3 | var EXPORTED_SYMBOLS = ["RequestBridgeDialog"];
|
| 4 | 4 | |
| 5 | +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
| 6 | + |
|
| 5 | 7 | const { BridgeDB } = ChromeUtils.import("resource:///modules/BridgeDB.jsm");
|
| 6 | 8 | const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
|
| 7 | 9 | |
| 10 | +const { TorConnect, TorConnectTopics } = ChromeUtils.import(
|
|
| 11 | + "resource:///modules/TorConnect.jsm"
|
|
| 12 | +);
|
|
| 13 | + |
|
| 8 | 14 | class RequestBridgeDialog {
|
| 9 | 15 | constructor(onSubmit) {
|
| 10 | 16 | this.onSubmit = onSubmit;
|
| ... | ... | @@ -20,8 +26,6 @@ class RequestBridgeDialog { |
| 20 | 26 | |
| 21 | 27 | static get selectors() {
|
| 22 | 28 | return {
|
| 23 | - submitButton:
|
|
| 24 | - "accept" /* not really a selector but a key for dialog's getButton */,
|
|
| 25 | 29 | dialogHeader: "h3#torPreferences-requestBridge-header",
|
| 26 | 30 | captchaImage: "image#torPreferences-requestBridge-captchaImage",
|
| 27 | 31 | captchaEntryTextbox: "input#torPreferences-requestBridge-captchaTextbox",
|
| ... | ... | @@ -57,8 +61,7 @@ class RequestBridgeDialog { |
| 57 | 61 | }
|
| 58 | 62 | });
|
| 59 | 63 | |
| 60 | - this._submitButton = this._dialog.getButton(selectors.submitButton);
|
|
| 61 | - this._submitButton.setAttribute("label", TorStrings.settings.submitCaptcha);
|
|
| 64 | + this._submitButton = this._dialog.getButton("accept");
|
|
| 62 | 65 | this._submitButton.disabled = true;
|
| 63 | 66 | this._dialog.addEventListener("dialogaccept", e => {
|
| 64 | 67 | e.preventDefault();
|
| ... | ... | @@ -110,7 +113,25 @@ class RequestBridgeDialog { |
| 110 | 113 | TorStrings.settings.incorrectCaptcha
|
| 111 | 114 | );
|
| 112 | 115 | |
| 113 | - return true;
|
|
| 116 | + Services.obs.addObserver(this, TorConnectTopics.StateChange);
|
|
| 117 | + this.onAcceptStateChange();
|
|
| 118 | + }
|
|
| 119 | + |
|
| 120 | + onAcceptStateChange() {
|
|
| 121 | + this._submitButton.setAttribute(
|
|
| 122 | + "label",
|
|
| 123 | + TorConnect.canBeginBootstrap
|
|
| 124 | + ? TorStrings.settings.bridgeButtonConnect
|
|
| 125 | + : TorStrings.settings.submitCaptcha
|
|
| 126 | + );
|
|
| 127 | + }
|
|
| 128 | + |
|
| 129 | + observe(subject, topic, data) {
|
|
| 130 | + switch (topic) {
|
|
| 131 | + case TorConnectTopics.StateChange:
|
|
| 132 | + this.onAcceptStateChange();
|
|
| 133 | + break;
|
|
| 134 | + }
|
|
| 114 | 135 | }
|
| 115 | 136 | |
| 116 | 137 | _setcaptchaImage(uri) {
|
| ... | ... | @@ -142,6 +163,8 @@ class RequestBridgeDialog { |
| 142 | 163 | |
| 143 | 164 | close() {
|
| 144 | 165 | BridgeDB.close();
|
| 166 | + // Unregister our observer topics.
|
|
| 167 | + Services.obs.removeObserver(this, TorConnectTopics.StateChange);
|
|
| 145 | 168 | }
|
| 146 | 169 | |
| 147 | 170 | /*
|
| ... | ... | @@ -161,7 +184,7 @@ class RequestBridgeDialog { |
| 161 | 184 | BridgeDB.submitCaptchaGuess(captchaText)
|
| 162 | 185 | .then(aBridges => {
|
| 163 | 186 | if (aBridges) {
|
| 164 | - this.onSubmit(aBridges);
|
|
| 187 | + this.onSubmit(aBridges, TorConnect.canBeginBootstrap);
|
|
| 165 | 188 | this._submitButton.disabled = false;
|
| 166 | 189 | // This was successful, but use cancelDialog() to close, since
|
| 167 | 190 | // we intercept the `dialogaccept` event.
|