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.
|