tor-commits
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2019
- 22 participants
- 4142 discussions
[translation/torbutton-browseronboardingproperties] https://gitweb.torproject.org/translation.git/commit/?h=torbutton-browseronboardingproperties
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit 582d608fba6dad3e88ca6a7a3899be5898121b61
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 13:21:40 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=torbutton-browseron…
---
is/browserOnboarding.properties | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/is/browserOnboarding.properties b/is/browserOnboarding.properties
index 656b8ae50..2b89ac456 100644
--- a/is/browserOnboarding.properties
+++ b/is/browserOnboarding.properties
@@ -16,7 +16,7 @@ onboarding.tour-tor-network=Tor-netið
onboarding.tour-tor-network.title=Farðu um ómiðstýrt netkerfi.
onboarding.tour-tor-network.description=Tor-vafrinn tengir þig við Tor-netið sem rekið er af þúsundum sjálfboðaliða um víða veröld. Ólíkt VPN, þá er enginn einn punktur sem getur brugðist eða miðlægt fyrirbæri sem þú þarft að treysta til að geta notað netið án afskipta annarra.
onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.action-button=Aðlagaðu þínar netkerfisstillingar fyrir Tor
onboarding.tour-tor-network.button=Fara í birtingu rása
onboarding.tour-tor-circuit-display=Birting rása
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Nýtt
onboarding.tour-tor-update.prefix-updated=Uppfært
onboarding.tour-tor-toolbar=Verkfærastika
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
+onboarding.tour-tor-toolbar-update-9.0.title=Bless gamli laukhnappur.
+onboarding.tour-tor-toolbar-update-9.0.description=Við viljum að upplifun þín með Tor sé að fullu innbyggð í Tor-vafrann.
onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.button=Hvernig á að biðja um nýtt auðkenni
onboarding.tour-tor-toolbar-update-9.0.next-button=Fara á Tor-netið
# Circuit Display onboarding.
1
0
[tor-browser/tor-browser-68.1.0esr-9.0-2] Update Torbutton to latest master for 9.0a8
by gk@torproject.org 12 Oct '19
by gk@torproject.org 12 Oct '19
12 Oct '19
commit 661fc1772b12fb7745224f97a3c6bd79ce78fc13
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Oct 12 13:20:07 2019 +0000
Update Torbutton to latest master for 9.0a8
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index e54639aab0c6..a1fe61ca5e14 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit e54639aab0c60274c14809cd9129b534bb79f92c
+Subproject commit a1fe61ca5e14e166617c516f2af449b043a3ef1c
1
0
[translation/tails-misc_release] https://gitweb.torproject.org/translation.git/commit/?h=tails-misc_release
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit 6994960544bae07259b034aa1428b9cc1c0a0a31
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 13:18:20 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tails-misc_release
---
is.po | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/is.po b/is.po
index 23c7814f7..0c2da2a3c 100644
--- a/is.po
+++ b/is.po
@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: Tor Project\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-05 16:50+0200\n"
-"PO-Revision-Date: 2019-10-06 02:05+0000\n"
-"Last-Translator: carolyn <carolyn(a)anhalt.org>\n"
+"PO-Revision-Date: 2019-10-12 13:14+0000\n"
+"Last-Translator: Sveinn í Felli <sv1(a)fellsnet.is>\n"
"Language-Team: Icelandic (http://www.transifex.com/otf/torproject/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
1
0
[tor-browser/tor-browser-68.1.0esr-9.0-2] fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#tor
by gk@torproject.org 12 Oct '19
by gk@torproject.org 12 Oct '19
12 Oct '19
commit 109c1defa853ec6364c66a72b3554ea05304dd3f
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Oct 12 13:17:35 2019 +0000
fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#tor
---
browser/modules/BridgeDB.jsm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/browser/modules/BridgeDB.jsm b/browser/modules/BridgeDB.jsm
index 16bf02e6c688..2caa26b4e2e0 100644
--- a/browser/modules/BridgeDB.jsm
+++ b/browser/modules/BridgeDB.jsm
@@ -1,4 +1,4 @@
-"use strict;";
+"use strict";
var EXPORTED_SYMBOLS = ["BridgeDB"];
1
0
[translation/tails-misc] https://gitweb.torproject.org/translation.git/commit/?h=tails-misc
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit 1f01b77600777a63584f3f98391af5d18951a325
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 13:17:17 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=tails-misc
---
is.po | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/is.po b/is.po
index 51eed4c0f..ab720953d 100644
--- a/is.po
+++ b/is.po
@@ -9,8 +9,8 @@ msgstr ""
"Project-Id-Version: Tor Project\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-10-05 16:50+0200\n"
-"PO-Revision-Date: 2019-10-06 02:05+0000\n"
-"Last-Translator: carolyn <carolyn(a)anhalt.org>\n"
+"PO-Revision-Date: 2019-10-12 13:14+0000\n"
+"Last-Translator: Sveinn í Felli <sv1(a)fellsnet.is>\n"
"Language-Team: Icelandic (http://www.transifex.com/otf/torproject/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -80,7 +80,7 @@ msgstr "Varanleg geymsla gagna er óvirk í Electrum"
msgid ""
"When you reboot Tails, all of Electrum's data will be lost, including your Bitcoin wallet.\n"
"It is strongly recommended to only run Electrum when its persistence feature is activated."
-msgstr ""
+msgstr "Þegar þú endurræsir Tails, tapast öll gögn í Electrum, þar með talið Bitcoin-veskið.\nSterklega er mælt með því að keyra Electrum einungis þegar varanleg gagnageymsla er virk."
#: config/chroot_local-includes/usr/local/bin/electrum:65
msgid "Do you want to start Electrum anyway?"
1
0
[translation/snowflakeaddon-messages.json] https://gitweb.torproject.org/translation.git/commit/?h=snowflakeaddon-messages.json
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit e94505890aba6e523a77b0abc2b24e52bbd553d7
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 13:16:59 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=snowflakeaddon-mess…
---
is/messages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/is/messages.json b/is/messages.json
index 0327b8ab9..8c168d55c 100644
--- a/is/messages.json
+++ b/is/messages.json
@@ -21,7 +21,7 @@
"message": "WebRTC-eiginleikinn fannst ekki."
},
"popupBridgeUnreachable": {
- "message": "Could not connect to the bridge."
+ "message": "Tókst ekki að tengjast brúnni."
},
"popupDescOn": {
"message": "Fjöldi notenda sem Snowflake-tilvikið þitt hefur hjálpað við að komast framhjá ritskoðun á síðustu 24 klukkustundum: $1"
1
0
[tor-browser/tor-browser-68.1.0esr-9.0-2] Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#tor
by gk@torproject.org 12 Oct '19
by gk@torproject.org 12 Oct '19
12 Oct '19
commit bd4082f2f1db8a1f1c135d6d1689242f7c659a19
Author: Richard Pospesel <richard(a)torproject.org>
Date: Mon Sep 16 15:25:39 2019 -0700
Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#tor
This patch adds a new about:preferences#tor page which allows modifying
bridge, proxy, and firewall settings from within Tor Browser. All of the
functionality present in tor-launcher's Network Configuration panel is
present:
- Setting built-in bridges
- Requesting bridges from BridgeDB via moat
- Using user-provided bridges
- Configuring SOCKS4, SOCKS5, and HTTP/HTTPS proxies
- Setting firewall ports
- Viewing and Copying Tor's logs
In addition the following changes have been made:
- The Networking Settings in General preferences has been removed
- TorStrings has been removed from the SecurityLevel component and
moved into a common shared module also used by about:preferences#tor
---
browser/components/moz.build | 1 +
browser/components/preferences/in-content/main.js | 15 -
browser/components/preferences/in-content/main.xul | 56 --
.../preferences/in-content/preferences.js | 2 +
.../preferences/in-content/preferences.xul | 5 +
.../components/preferences/in-content/privacy.js | 1 +
.../securitylevel/content/securityLevel.js | 155 +---
.../torpreferences/content/parseFunctions.jsm | 76 ++
.../torpreferences/content/requestBridgeDialog.jsm | 220 ++++++
.../torpreferences/content/requestBridgeDialog.xul | 35 +
.../torpreferences/content/torBridgeSettings.jsm | 325 +++++++++
.../torpreferences/content/torCategory.inc.xul | 8 +
.../torpreferences/content/torFirewallSettings.jsm | 72 ++
.../torpreferences/content/torLogDialog.jsm | 65 ++
.../torpreferences/content/torLogDialog.xul | 22 +
.../components/torpreferences/content/torPane.js | 802 +++++++++++++++++++++
.../components/torpreferences/content/torPane.xul | 119 +++
.../torpreferences/content/torPreferences.css | 63 ++
.../torpreferences/content/torPreferencesIcon.svg | 5 +
.../torpreferences/content/torProxySettings.jsm | 245 +++++++
browser/components/torpreferences/jar.mn | 14 +
browser/components/torpreferences/moz.build | 1 +
browser/modules/BridgeDB.jsm | 110 +++
browser/modules/TorProtocolService.jsm | 203 ++++++
browser/modules/TorStrings.jsm | 326 +++++++++
browser/modules/moz.build | 3 +
26 files changed, 2755 insertions(+), 194 deletions(-)
diff --git a/browser/components/moz.build b/browser/components/moz.build
index 111794a7532c..c0c9629cac65 100644
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -56,6 +56,7 @@ DIRS += [
'syncedtabs',
'uitour',
'urlbar',
+ 'torpreferences',
'translation',
]
diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js
index 845ef2f61e30..98c73c5ac119 100644
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -365,16 +365,6 @@ var gMainPane = {
});
this.updatePerformanceSettingsBox({ duringChangeEvent: false });
- let connectionSettingsLink = document.getElementById(
- "connectionSettingsLearnMore"
- );
- let connectionSettingsUrl =
- Services.urlFormatter.formatURLPref("app.support.baseURL") +
- "prefs-connection-settings";
- connectionSettingsLink.setAttribute("href", connectionSettingsUrl);
- this.updateProxySettingsUI();
- initializeProxyUI(gMainPane);
-
if (Services.prefs.getBoolPref("intl.multilingual.enabled")) {
gMainPane.initBrowserLocale();
}
@@ -464,11 +454,6 @@ var gMainPane = {
gMainPane.updateHardwareAcceleration.bind(gMainPane)
);
setEventListener(
- "connectionSettings",
- "command",
- gMainPane.showConnections
- );
- setEventListener(
"browserContainersCheckbox",
"command",
gMainPane.checkBrowserContainers
diff --git a/browser/components/preferences/in-content/main.xul b/browser/components/preferences/in-content/main.xul
index 83d64f26a62d..85a219ff783b 100644
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -669,60 +669,4 @@
<label id="cfrFeaturesLearnMore" class="learnMore" data-l10n-id="browsing-cfr-recommendations-learn-more" is="text-link"/>
</hbox>
</groupbox>
-
-<hbox id="networkProxyCategory"
- class="subcategory"
- hidden="true"
- data-category="paneGeneral">
- <html:h1 data-l10n-id="network-settings-title"/>
-</hbox>
-
-<!-- Network Settings-->
-<groupbox id="connectionGroup" data-category="paneGeneral" hidden="true">
- <label class="search-header" hidden="true"><html:h2 data-l10n-id="network-settings-title"/></label>
-
- <hbox align="center">
- <hbox align="center" flex="1">
- <description id="connectionSettingsDescription" control="connectionSettings"/>
- <spacer width="5"/>
- <label id="connectionSettingsLearnMore" class="learnMore" is="text-link"
- data-l10n-id="network-proxy-connection-learn-more">
- </label>
- <separator orient="vertical"/>
- </hbox>
-
- <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
- <hbox>
- <button id="connectionSettings"
- is="highlightable-button"
- class="accessory-button"
- icon="network"
- data-l10n-id="network-proxy-connection-settings"
- searchkeywords="doh trr"
- search-l10n-ids="
- connection-window.title,
- connection-proxy-option-no.label,
- connection-proxy-option-auto.label,
- connection-proxy-option-system.label,
- connection-proxy-option-manual.label,
- connection-proxy-http,
- connection-proxy-ssl,
- connection-proxy-ftp,
- connection-proxy-http-port,
- connection-proxy-socks,
- connection-proxy-socks4,
- connection-proxy-socks5,
- connection-proxy-noproxy,
- connection-proxy-noproxy-desc,
- connection-proxy-http-share.label,
- connection-proxy-autotype.label,
- connection-proxy-reload.label,
- connection-proxy-autologin.label,
- connection-proxy-socks-remote-dns.label,
- connection-dns-over-https.label,
- connection-dns-over-https-url-custom.label,
- " />
- </hbox>
- </hbox>
-</groupbox>
</html:template>
diff --git a/browser/components/preferences/in-content/preferences.js b/browser/components/preferences/in-content/preferences.js
index d2851f20d2ca..b5b5f87af459 100644
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -13,6 +13,7 @@
/* import-globals-from findInPage.js */
/* import-globals-from ../../../base/content/utilityOverlay.js */
/* import-globals-from ../../../../toolkit/content/preferencesBindings.js */
+/* import-globals-from ../../torpreferences/content/torPane.js */
/* global MozXULElement */
"use strict";
@@ -92,6 +93,7 @@ function init_all() {
document.getElementById("template-paneSync").remove();
}
register_module("paneSearchResults", gSearchResultsPane);
+ register_module("paneTor", gTorPane);
gSearchResultsPane.init();
gMainPane.preInit();
diff --git a/browser/components/preferences/in-content/preferences.xul b/browser/components/preferences/in-content/preferences.xul
index 3b07e4596907..7a01443ab048 100644
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -16,6 +16,7 @@
<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/containers.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/privacy.css"?>
<?xml-stylesheet href="chrome://browser/content/securitylevel/securityLevelPreferences.css"?>
+<?xml-stylesheet href="chrome://browser/content/torpreferences/torPreferences.css"?>
<!DOCTYPE page [
<!ENTITY % aboutTorDTD SYSTEM "chrome://torbutton/locale/aboutTor.dtd">
@@ -138,6 +139,9 @@
<image class="category-icon"/>
<label class="category-name" flex="1" data-l10n-id="pane-sync-title2"></label>
</richlistitem>
+
+#include ../../torpreferences/content/torCategory.inc.xul
+
</richlistbox>
<spacer flex="1"/>
@@ -195,6 +199,7 @@
#include privacy.xul
#include containers.xul
#include sync.xul
+#include ../../torpreferences/content/torPane.xul
</vbox>
</vbox>
</vbox>
diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js
index e9112a2c467e..297d07fadf1f 100644
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -62,6 +62,7 @@ XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function() {
}
});
+// TODO: module import via ChromeUtils.defineModuleGetter
XPCOMUtils.defineLazyScriptGetter(
this,
["SecurityLevelPreferences"],
diff --git a/browser/components/securitylevel/content/securityLevel.js b/browser/components/securitylevel/content/securityLevel.js
index 9965046a7d15..7f307c5df43a 100644
--- a/browser/components/securitylevel/content/securityLevel.js
+++ b/browser/components/securitylevel/content/securityLevel.js
@@ -8,102 +8,11 @@ XPCOMUtils.defineLazyModuleGetters(this, {
PanelMultiView: "resource:///modules/PanelMultiView.jsm",
});
-XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]);
-XPCOMUtils.defineLazyGetter(this, "domParser", () => {
- const parser = new DOMParser();
- parser.forceEnableDTD();
- return parser;
-});
-
-/*
- Security Level Strings
-
- Strings loaded from torbutton, but en-US defaults provided in case torbutton addon not enabled
-*/
-XPCOMUtils.defineLazyGetter(this, "SecurityLevelStrings", function() {
- // copied from testing/marionette/l10n.js
- let localizeEntity = function(urls, id) {
- // Build a string which contains all possible entity locations
- let locations = [];
- urls.forEach((url, index) => {
- locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`);
- });
-
- // Use the DOM parser to resolve the entity and extract its real value
- let header = `<?xml version="1.0"?><!DOCTYPE elem [${locations.join("")}]>`;
- let elem = `<elem id="elementID">&${id};</elem>`;
- let doc = domParser.parseFromString(header + elem, "text/xml");
- let element = doc.querySelector("elem[id='elementID']");
-
- if (element === null) {
- throw new Error(`Entity with id='${id}' hasn't been found`);
- }
-
- return element.textContent;
- };
-
- let getString = function(key, fallback) {
- try {
- return localizeEntity(
- ['chrome://torbutton/locale/torbutton.dtd'],
- `torbutton.prefs.sec_${key}`
- );
- } catch (e) { }
- return fallback;
- };
-
- // read localized strings from torbutton; but use hard-coded en-US strings as fallbacks in case of error
- let retval = {
- securityLevel : getString("caption", "Security Level"),
- customWarning : getString("custom_warning", "Custom"),
- overview : getString("overview", "Disable certain web features that can be used to attack your security and anonymity."),
- standard : {
- level : getString("standard_label", "Standard"),
- tooltip : getString("standard_tooltip", "Security Level : Standard"),
- summary : getString("standard_description", "All Tor Browser and website features are enabled."),
- },
- safer : {
- level : getString("safer_label", "Safer"),
- tooltip : getString("safer_tooltip", "Security Level : Safer"),
- summary : getString("safer_description", "Disables website features that are often dangerous, causing some sites to lose functionality."),
- description1 : getString("js_on_https_sites_only", "JavaScript is disabled on non-HTTPS sites."),
- description2 : getString("limit_typography", "Some fonts and math symbols are disabled."),
- description3 : getString("click_to_play_media", "Audio and video (HTML5 media), and WebGL are click-to-play."),
- },
- safest : {
- level : getString("safest_label", "Safest"),
- tooltip : getString("safest_tooltip", "Security Level : Safest"),
- summary : getString("safest_description", "Only allows website features required for static sites and basic services. These changes affect images, media, and scripts."),
- description1 : getString("js_disabled", "JavaScript is disabled by default on all sites."),
- description2 : getString("limit_graphics_and_typography", "Some fonts, icons, math symbols, and images are disabled."),
- description3 : getString("click_to_play_media", "Audio and video (HTML5 media), and WebGL are click-to-play."),
- },
- custom : {
- summary : getString("custom_summary", "Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels."),
- },
- learnMore : getString("learn_more_label", "Learn more"),
- learnMoreURL : function() {
- let locale = "";
- try {
- let { getLocale } =
- Cu.import("resource://torbutton/modules/utils.js", {});
- locale = getLocale();
- } catch(e) {}
-
- if (locale == "") {
- locale = "en-US";
- }
-
- return "https://tb-manual.torproject.org/" + locale + "/security-settings/";
- }(),
- restoreDefaults : getString("restore_defaults", "Restore Defaults"),
- advancedSecuritySettings : getString("advanced_security_settings", "Advanced Security Settings\u2026"),
- };
-
-
- return retval;
-});
-
+ChromeUtils.defineModuleGetter(
+ this,
+ "TorStrings",
+ "resource:///modules/TorStrings.jsm"
+);
/*
Security Level Prefs
@@ -158,8 +67,8 @@ const SecurityLevelButton = {
_populateXUL : function(securityLevelButton) {
if (securityLevelButton != null) {
- securityLevelButton.setAttribute("tooltiptext", SecurityLevelStrings.securityLevel);
- securityLevelButton.setAttribute("label", SecurityLevelStrings.securityLevel);
+ securityLevelButton.setAttribute("tooltiptext", TorStrings.securityLevel.securityLevel);
+ securityLevelButton.setAttribute("label", TorStrings.securityLevel.securityLevel);
}
},
@@ -171,15 +80,15 @@ const SecurityLevelButton = {
switch(securitySlider) {
case 4:
classList.add("standard");
- securityLevelButton.setAttribute("tooltiptext", SecurityLevelStrings.standard.tooltip);
+ securityLevelButton.setAttribute("tooltiptext", TorStrings.securityLevel.standard.tooltip);
break;
case 2:
classList.add("safer");
- securityLevelButton.setAttribute("tooltiptext", SecurityLevelStrings.safer.tooltip);
+ securityLevelButton.setAttribute("tooltiptext", TorStrings.securityLevel.safer.tooltip);
break;
case 1:
classList.add("safest");
- securityLevelButton.setAttribute("tooltiptext", SecurityLevelStrings.safest.tooltip);
+ securityLevelButton.setAttribute("tooltiptext", TorStrings.securityLevel.safest.tooltip);
break;
}
}
@@ -294,12 +203,12 @@ const SecurityLevelPanel = {
let buttonRestoreDefaults = panelview.querySelector("#securityLevel-restoreDefaults");
let buttonAdvancedSecuritySettings = panelview.querySelector("#securityLevel-advancedSecuritySettings");
- labelHeader.setAttribute("value", SecurityLevelStrings.securityLevel);
- labelCustomWarning.setAttribute("value", SecurityLevelStrings.customWarning);
- labelLearnMore.setAttribute("value", SecurityLevelStrings.learnMore);
- labelLearnMore.setAttribute("href", SecurityLevelStrings.learnMoreURL);
- buttonRestoreDefaults.setAttribute("label", SecurityLevelStrings.restoreDefaults);
- buttonAdvancedSecuritySettings.setAttribute("label", SecurityLevelStrings.advancedSecuritySettings);
+ labelHeader.setAttribute("value", TorStrings.securityLevel.securityLevel);
+ labelCustomWarning.setAttribute("value", TorStrings.securityLevel.customWarning);
+ labelLearnMore.setAttribute("value", TorStrings.securityLevel.learnMore);
+ labelLearnMore.setAttribute("href", TorStrings.securityLevel.learnMoreURL);
+ buttonRestoreDefaults.setAttribute("label", TorStrings.securityLevel.restoreDefaults);
+ buttonAdvancedSecuritySettings.setAttribute("label", TorStrings.securityLevel.advancedSecuritySettings);
// rest of the XUL is set based on security prefs
this._configUIFromPrefs();
@@ -328,24 +237,24 @@ const SecurityLevelPanel = {
switch(securitySlider) {
// standard
case 4:
- labelLevel.setAttribute("value", SecurityLevelStrings.standard.level);
- summary.textContent = SecurityLevelStrings.standard.summary;
+ labelLevel.setAttribute("value", TorStrings.securityLevel.standard.level);
+ summary.textContent = TorStrings.securityLevel.standard.summary;
break;
// safer
case 2:
- labelLevel.setAttribute("value", SecurityLevelStrings.safer.level);
- summary.textContent = SecurityLevelStrings.safer.summary;
+ labelLevel.setAttribute("value", TorStrings.securityLevel.safer.level);
+ summary.textContent = TorStrings.securityLevel.safer.summary;
break;
// safest
case 1:
- labelLevel.setAttribute("value", SecurityLevelStrings.safest.level);
- summary.textContent = SecurityLevelStrings.safest.summary;
+ labelLevel.setAttribute("value", TorStrings.securityLevel.safest.level);
+ summary.textContent = TorStrings.securityLevel.safest.summary;
break;
}
// override the summary text with custom warning
if (securityCustom) {
- summary.textContent = SecurityLevelStrings.custom.summary;
+ summary.textContent = TorStrings.securityLevel.custom.summary;
}
},
@@ -425,14 +334,14 @@ const SecurityLevelPreferences =
let groupbox = document.getElementById("securityLevel-groupbox");
let labelHeader = groupbox.querySelector("#securityLevel-header");
- labelHeader.setAttribute("value", SecurityLevelStrings.securityLevel);
+ labelHeader.setAttribute("value", TorStrings.securityLevel.securityLevel);
let spanOverview = groupbox.querySelector("#securityLevel-overview");
- spanOverview.textContent = SecurityLevelStrings.overview;
+ spanOverview.textContent = TorStrings.securityLevel.overview;
let labelLearnMore = groupbox.querySelector("#securityLevel-learnMore");
- labelLearnMore.setAttribute("value", SecurityLevelStrings.learnMore);
- labelLearnMore.setAttribute("href", SecurityLevelStrings.learnMoreURL);
+ labelLearnMore.setAttribute("value", TorStrings.securityLevel.learnMore);
+ labelLearnMore.setAttribute("href", TorStrings.securityLevel.learnMoreURL);
let populateRadioElements = function(vboxQuery, stringStruct) {
let vbox = groupbox.querySelector(vboxQuery);
@@ -441,13 +350,13 @@ const SecurityLevelPreferences =
radio.setAttribute("label", stringStruct.level);
let customWarning = vbox.querySelector("#securityLevel-customWarning");
- customWarning.setAttribute("value", SecurityLevelStrings.customWarning);
+ customWarning.setAttribute("value", TorStrings.securityLevel.customWarning);
let labelSummary = vbox.querySelector("#securityLevel-summary");
labelSummary.textContent = stringStruct.summary;
let labelRestoreDefaults = vbox.querySelector("#securityLevel-restoreDefaults");
- labelRestoreDefaults.setAttribute("value", SecurityLevelStrings.restoreDefaults);
+ labelRestoreDefaults.setAttribute("value", TorStrings.securityLevel.restoreDefaults);
let description1 = vbox.querySelector("#securityLevel-description1");
if (description1) {
@@ -463,9 +372,9 @@ const SecurityLevelPreferences =
}
};
- populateRadioElements("#securityLevel-vbox-standard", SecurityLevelStrings.standard);
- populateRadioElements("#securityLevel-vbox-safer", SecurityLevelStrings.safer);
- populateRadioElements("#securityLevel-vbox-safest", SecurityLevelStrings.safest);
+ populateRadioElements("#securityLevel-vbox-standard", TorStrings.securityLevel.standard);
+ populateRadioElements("#securityLevel-vbox-safer", TorStrings.securityLevel.safer);
+ populateRadioElements("#securityLevel-vbox-safest", TorStrings.securityLevel.safest);
},
_configUIFromPrefs : function() {
diff --git a/browser/components/torpreferences/content/parseFunctions.jsm b/browser/components/torpreferences/content/parseFunctions.jsm
new file mode 100644
index 000000000000..a6e6c554ca63
--- /dev/null
+++ b/browser/components/torpreferences/content/parseFunctions.jsm
@@ -0,0 +1,76 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = [
+ "parsePort",
+ "parseAddrPort",
+ "parseUsernamePassword",
+ "parseAddrPortList",
+ "parseBridgeStrings",
+ "parsePortList",
+];
+
+// expects a string representation of an integer from 1 to 65535
+let parsePort = function(aPort) {
+ // ensure port string is a valid positive integer
+ const validIntRegex = /^[0-9]+$/;
+ if (!validIntRegex.test(aPort)) {
+ throw new Error(`Invalid PORT string : '${aPort}'`);
+ }
+
+ // ensure port value is on valid range
+ let port = Number.parseInt(aPort);
+ if (port < 1 || port > 65535) {
+ throw new Error(
+ `Invalid PORT value, needs to be on range [1,65535] : '${port}'`
+ );
+ }
+
+ return port;
+};
+// expects a string in the format: "ADDRESS:PORT"
+let parseAddrPort = function(aAddrColonPort) {
+ let tokens = aAddrColonPort.split(":");
+ if (tokens.length != 2) {
+ throw new Error(`Invalid ADDRESS:PORT string : '${aAddrColonPort}'`);
+ }
+ let address = tokens[0];
+ let port = parsePort(tokens[1]);
+ return [address, port];
+};
+
+// expects a string in the format: "USERNAME:PASSWORD"
+// split on the first colon and any subsequent go into password
+let parseUsernamePassword = function(aUsernameColonPassword) {
+ let colonIndex = aUsernameColonPassword.indexOf(":");
+ if (colonIndex < 0) {
+ // we don't log the contents of the potentially password containing string
+ throw new Error("Invalid USERNAME:PASSWORD string");
+ }
+
+ let username = aUsernameColonPassword.substring(0, colonIndex);
+ let password = aUsernameColonPassword.substring(colonIndex + 1);
+
+ return [username, password];
+};
+
+// expects tring in the format: ADDRESS:PORT,ADDRESS:PORT,...
+// returns array of ports (as ints)
+let parseAddrPortList = function(aAddrPortList) {
+ let addrPorts = aAddrPortList.split(",");
+ // parse ADDRESS:PORT string and only keep the port (second element in returned array)
+ let retval = addrPorts.map(addrPort => parseAddrPort(addrPort)[1]);
+ return retval;
+};
+
+// expects a '/n' delimited string of bridge string, which we split and trim
+let parseBridgeStrings = function(aBridgeStrings) {
+ let splitStrings = aBridgeStrings.split("\n");
+ return splitStrings.map(val => val.trim());
+};
+
+// expecting a ',' delimited list of ints with possible white space between
+// returns an array of ints
+let parsePortList = function(aPortListString) {
+ let splitStrings = aPortListString.split(",");
+ return splitStrings.map(val => parsePort(val.trim()));
+};
diff --git a/browser/components/torpreferences/content/requestBridgeDialog.jsm b/browser/components/torpreferences/content/requestBridgeDialog.jsm
new file mode 100644
index 000000000000..b66272edf880
--- /dev/null
+++ b/browser/components/torpreferences/content/requestBridgeDialog.jsm
@@ -0,0 +1,220 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["RequestBridgeDialog"];
+
+const { BridgeDB } = ChromeUtils.import("resource:///modules/BridgeDB.jsm");
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+
+class RequestBridgeDialog {
+ constructor() {
+ this._dialog = null;
+ this._submitCommand = null;
+ this._submitButton = null;
+ this._dialogDescription = null;
+ this._captchaImage = null;
+ this._captchaEntryTextbox = null;
+ this._captchaRefreshCommand = null;
+ this._captchaRefreshButton = null;
+ this._incorrectCaptchaHbox = null;
+ this._incorrectCaptchaLabel = null;
+ this._bridges = [];
+ this._proxyURI = null;
+ }
+
+ static get selectors() {
+ return {
+ submitButton:
+ "accept" /* not really a selector but a key for dialog's getButton */,
+ dialogDescription: "description#torPreferences-requestBridge-description",
+ submitCommand: "command#torPreferences-requestBridge-submitCommand",
+ captchaImage: "image#torPreferences-requestBridge-captchaImage",
+ captchaEntryTextbox:
+ "textbox#torPreferences-requestBridge-captchaTextbox",
+ refreshCaptchaCommand:
+ "command#torPreferences-requestBridge-refreshCaptchaCommand",
+ refreshCaptchaButton:
+ "button#torPreferences-requestBridge-refreshCaptchaButton",
+ incorrectCaptchaHbox:
+ "hbox#torPreferences-requestBridge-incorrectCaptchaHbox",
+ incorrectCaptchaLabel:
+ "label#torPreferences-requestBridge-incorrectCaptchaError",
+ };
+ }
+
+ _populateXUL(dialog) {
+ const selectors = RequestBridgeDialog.selectors;
+
+ this._dialog = dialog;
+ this._dialog.setAttribute(
+ "title",
+ TorStrings.settings.requestBridgeDialogTitle
+ );
+ // user may have opened a Request Bridge dialog in another tab, so update the
+ // CAPTCHA image or close out the dialog if we have a bridge list
+ this._dialog.addEventListener("focusin", () => {
+ const uri = BridgeDB.currentCaptchaImage;
+ const bridges = BridgeDB.currentBridges;
+
+ // new captcha image
+ if (uri) {
+ this._setcaptchaImage(uri);
+ } else if (bridges) {
+ this._bridges = bridges;
+ this._submitButton.disabled = false;
+ this._dialog.acceptDialog();
+ }
+ });
+
+ this._submitCommand = this._dialog.querySelector(selectors.submitCommand);
+
+ this._submitButton = this._dialog.getButton(selectors.submitButton);
+ this._submitButton.setAttribute("label", TorStrings.settings.submitCaptcha);
+ this._submitButton.setAttribute("command", this._submitCommand.id);
+ this._submitButton.disabled = true;
+
+ this._dialogDescription = this._dialog.querySelector(
+ selectors.dialogDescription
+ );
+ this._dialogDescription.textContent =
+ TorStrings.settings.contactingBridgeDB;
+
+ this._captchaImage = this._dialog.querySelector(selectors.captchaImage);
+
+ // request captcha from bridge db
+ BridgeDB.requestNewCaptchaImage(this._proxyURI).then(uri => {
+ this._setcaptchaImage(uri);
+ });
+
+ this._captchaEntryTextbox = this._dialog.querySelector(
+ selectors.captchaEntryTextbox
+ );
+ this._captchaEntryTextbox.setAttribute(
+ "placeholder",
+ TorStrings.settings.captchaTextboxPlaceholder
+ );
+ this._captchaEntryTextbox.disabled = true;
+ this._captchaEntryTextbox.onkeypress = evt => {
+ const ENTER_KEY = 13;
+ if (evt.keyCode == ENTER_KEY) {
+ // logically same as pressing the 'submit' button of the parent dialog
+ this.onSubmitCaptcha();
+ return false;
+ }
+ return true;
+ };
+ // disable submit if entry textbox is empty
+ this._captchaEntryTextbox.oninput = () => {
+ this._submitButton.disabled = this._captchaEntryTextbox.value == "";
+ };
+
+ this._captchaRefreshCommand = this._dialog.querySelector(
+ selectors.refreshCaptchaCommand
+ );
+ this._captchaRefreshButton = this._dialog.querySelector(
+ selectors.refreshCaptchaButton
+ );
+ this._captchaRefreshButton.setAttribute(
+ "command",
+ this._captchaRefreshCommand.id
+ );
+ this._captchaRefreshButton.disabled = true;
+
+ this._incorrectCaptchaHbox = this._dialog.querySelector(
+ selectors.incorrectCaptchaHbox
+ );
+ this._incorrectCaptchaLabel = this._dialog.querySelector(
+ selectors.incorrectCaptchaLabel
+ );
+ this._incorrectCaptchaLabel.setAttribute(
+ "value",
+ TorStrings.settings.incorrectCaptcha
+ );
+
+ return true;
+ }
+
+ _setcaptchaImage(uri) {
+ if (uri != this._captchaImage.src) {
+ this._captchaImage.src = uri;
+ this._dialogDescription.textContent = TorStrings.settings.solveTheCaptcha;
+ this._setUIDisabled(false);
+ this._captchaEntryTextbox.focus();
+ this._captchaEntryTextbox.select();
+ }
+ }
+
+ _setUIDisabled(disabled) {
+ this._submitButton.disabled = this._captchaGuessIsEmpty() || disabled;
+ this._captchaEntryTextbox.disabled = disabled;
+ this._captchaRefreshButton.disabled = disabled;
+ }
+
+ _captchaGuessIsEmpty() {
+ return this._captchaEntryTextbox.value == "";
+ }
+
+ init(window, dialog) {
+ // defer to later until firefox has populated the dialog with all our elements
+ window.setTimeout(() => {
+ this._populateXUL(dialog);
+ }, 0);
+ }
+
+ close() {
+ BridgeDB.close();
+ }
+
+ /*
+ Event Handlers
+ */
+ onSubmitCaptcha() {
+ let captchaText = this._captchaEntryTextbox.value.trim();
+ // noop if the field is empty
+ if (captchaText == "") {
+ return;
+ }
+
+ // freeze ui while we make request
+ this._setUIDisabled(true);
+ this._incorrectCaptchaHbox.style.visibility = "hidden";
+
+ BridgeDB.submitCaptchaGuess(captchaText)
+ .then(aBridges => {
+ this._bridges = aBridges;
+
+ this._submitButton.disabled = false;
+ this._dialog.acceptDialog();
+ })
+ .catch(aError => {
+ this._bridges = [];
+ this._setUIDisabled(false);
+ this._incorrectCaptchaHbox.style.visibility = "visible";
+ });
+ }
+
+ onRefreshCaptcha() {
+ this._setUIDisabled(true);
+ this._captchaImage.src = "";
+ this._dialogDescription.textContent =
+ TorStrings.settings.contactingBridgeDB;
+ this._captchaEntryTextbox.value = "";
+ this._incorrectCaptchaHbox.style.visibility = "hidden";
+
+ BridgeDB.requestNewCaptchaImage(this._proxyURI).then(uri => {
+ this._setcaptchaImage(uri);
+ });
+ }
+
+ openDialog(gSubDialog, aProxyURI, aCloseCallback) {
+ this._proxyURI = aProxyURI;
+ gSubDialog.open(
+ "chrome://browser/content/torpreferences/requestBridgeDialog.xul",
+ "resizable=yes",
+ this,
+ () => {
+ this.close();
+ aCloseCallback(this._bridges);
+ }
+ );
+ }
+}
diff --git a/browser/components/torpreferences/content/requestBridgeDialog.xul b/browser/components/torpreferences/content/requestBridgeDialog.xul
new file mode 100644
index 000000000000..67cae40b9a48
--- /dev/null
+++ b/browser/components/torpreferences/content/requestBridgeDialog.xul
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
+<?xml-stylesheet href="chrome://browser/content/torpreferences/torPreferences.css"?>
+
+<dialog id="torPreferences-requestBridge-dialog" type="child" class="prefwindow"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ title="Request Bridge"
+ buttons="cancel,accept"
+ role="dialog">
+ <command id="torPreferences-requestBridge-submitCommand" oncommand="requestBridgeDialog.onSubmitCaptcha();"/>
+ <!-- ok, so ​ is a zero-width space. We need to have *something* in the innerText so that XUL knows how tall the
+ description node is so that it can determine how large to make the dialog element's inner draw area. If we have
+ nothing in the innerText, then it collapse to 0 height, and the contents of the dialog ends up partially hidden >:( -->
+ <description id="torPreferences-requestBridge-description">​</description>
+ <!-- init to transparent 400x125 png -->
+ <image id="torPreferences-requestBridge-captchaImage" flex="1"/>
+ <hbox id="torPreferences-requestBridge-inputHbox">
+ <textbox id="torPreferences-requestBridge-captchaTextbox" flex="1" />
+ <command id="torPreferences-requestBridge-refreshCaptchaCommand" oncommand="requestBridgeDialog.onRefreshCaptcha();"/>
+ <button id="torPreferences-requestBridge-refreshCaptchaButton" image="chrome://browser/skin/reload.svg"/>
+ </hbox>
+ <hbox id="torPreferences-requestBridge-incorrectCaptchaHbox" align="center">
+ <image id="torPreferences-requestBridge-errorIcon" />
+ <label id="torPreferences-requestBridge-incorrectCaptchaError" flex="1"/>
+ </hbox>
+ <script type="application/javascript"><![CDATA[
+ "use strict";
+
+ let requestBridgeDialog = window.arguments[0];
+ let dialog = document.getElementById("torPreferences-requestBridge-dialog");
+ requestBridgeDialog.init(window, dialog);
+ ]]></script>
+</dialog>
\ No newline at end of file
diff --git a/browser/components/torpreferences/content/torBridgeSettings.jsm b/browser/components/torpreferences/content/torBridgeSettings.jsm
new file mode 100644
index 000000000000..ceb61d3ec972
--- /dev/null
+++ b/browser/components/torpreferences/content/torBridgeSettings.jsm
@@ -0,0 +1,325 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = [
+ "TorBridgeSource",
+ "TorBridgeSettings",
+ "makeTorBridgeSettingsNone",
+ "makeTorBridgeSettingsBuiltin",
+ "makeTorBridgeSettingsBridgeDB",
+ "makeTorBridgeSettingsUserProvided",
+];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+
+const TorBridgeSource = {
+ NONE: "NONE",
+ BUILTIN: "BUILTIN",
+ BRIDGEDB: "BRIDGEDB",
+ USERPROVIDED: "USERPROVIDED",
+};
+
+class TorBridgeSettings {
+ constructor() {
+ this._bridgeSource = TorBridgeSource.NONE;
+ this._selectedDefaultBridgeType = null;
+ this._bridgeStrings = [];
+ }
+
+ get selectedDefaultBridgeType() {
+ if (this._bridgeSource == TorBridgeSource.BUILTIN) {
+ return this._selectedDefaultBridgeType;
+ }
+ return undefined;
+ }
+
+ get bridgeSource() {
+ return this._bridgeSource;
+ }
+
+ // for display
+ get bridgeStrings() {
+ return this._bridgeStrings.join("\n");
+ }
+
+ // raw
+ get bridgeStringsArray() {
+ return this._bridgeStrings;
+ }
+
+ static get defaultBridgeTypes() {
+ if (TorBridgeSettings._defaultBridgeTypes) {
+ return TorBridgeSettings._defaultBridgeTypes;
+ }
+
+ let bridgeListBranch = Services.prefs.getBranch(
+ TorStrings.preferenceBranches.defaultBridge
+ );
+ let bridgePrefs = bridgeListBranch.getChildList("", {});
+
+ // an unordered set for shoving bridge types into
+ let bridgeTypes = new Set();
+ // look for keys ending in ".N" and treat string before that as the bridge type
+ const pattern = /\.[0-9]+$/;
+ for (const key of bridgePrefs) {
+ const offset = key.search(pattern);
+ if (offset != -1) {
+ const bt = key.substring(0, offset);
+ bridgeTypes.add(bt);
+ }
+ }
+
+ // recommended bridge type goes first in the list
+ let recommendedBridgeType = Services.prefs.getCharPref(
+ TorStrings.preferenceKeys.recommendedBridgeType,
+ null
+ );
+
+ let retval = [];
+ if (recommendedBridgeType && bridgeTypes.has(recommendedBridgeType)) {
+ retval.push(recommendedBridgeType);
+ }
+
+ for (const bridgeType of bridgeTypes.values()) {
+ if (bridgeType != recommendedBridgeType) {
+ retval.push(bridgeType);
+ }
+ }
+
+ // cache off
+ TorBridgeSettings._defaultBridgeTypes = retval;
+ return retval;
+ }
+
+ _readDefaultBridges(aBridgeType) {
+ let bridgeBranch = Services.prefs.getBranch(
+ TorStrings.preferenceBranches.defaultBridge
+ );
+ let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
+
+ let retval = [];
+
+ // regex matches against strings ending in ".N" where N is a positive integer
+ let pattern = /\.[0-9]+$/;
+ for (const key of bridgeBranchPrefs) {
+ // verify the location of the match is the correct offset required for aBridgeType
+ // to fit, and that the string begins with aBridgeType
+ if (
+ key.search(pattern) == aBridgeType.length &&
+ key.startsWith(aBridgeType)
+ ) {
+ let bridgeStr = bridgeBranch.getCharPref(key);
+ retval.push(bridgeStr);
+ }
+ }
+
+ // fisher-yates shuffle
+ // shuffle so that Tor Browser users don't all try the built-in bridges in the same order
+ for (let i = retval.length - 1; i > 0; --i) {
+ // number n such that 0.0 <= n < 1.0
+ const n = Math.random();
+ // integer j such that 0 <= j <= i
+ const j = Math.floor(n * (i + 1));
+
+ // swap values at indices i and j
+ const tmp = retval[i];
+ retval[i] = retval[j];
+ retval[j] = tmp;
+ }
+
+ return retval;
+ }
+
+ _readBridgeDBBridges() {
+ let bridgeBranch = Services.prefs.getBranch(
+ `${TorStrings.preferenceBranches.bridgeDBBridges}`
+ );
+ let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
+ // the child prefs do not come in any particular order so sort the keys
+ // so the values can be compared to what we get out off torrc
+ bridgeBranchPrefs.sort();
+
+ // just assume all of the prefs under the parent point to valid bridge string
+ let retval = bridgeBranchPrefs.map(key =>
+ bridgeBranch.getCharPref(key).trim()
+ );
+
+ return retval;
+ }
+
+ _readTorrcBridges() {
+ let bridgeList = TorProtocolService.readStringArraySetting(
+ TorStrings.configKeys.bridgeList
+ );
+
+ let retval = [];
+ for (const line of bridgeList) {
+ let trimmedLine = line.trim();
+ if (trimmedLine) {
+ retval.push(trimmedLine);
+ }
+ }
+
+ return retval;
+ }
+
+ // analagous to initBridgeSettings()
+ readSettings() {
+ // restore to defaults
+ this._bridgeSource = TorBridgeSource.NONE;
+ this._selectedDefaultBridgeType = null;
+ this._bridgeStrings = [];
+
+ // So the way tor-launcher determines the origin of the configured bridges is a bit
+ // weird and depends on inferring our scenario based on some firefox prefs and the
+ // relationship between the saved list of bridges in about:config vs the list saved in torrc
+
+ // first off, if "extensions.torlauncher.default_bridge_type" is set to one of our
+ // builtin default types (obfs4, meek-azure, snowflake, etc) then we provide the
+ // bridges in "extensions.torlauncher.default_bridge.*" (filtered by our default_bridge_type)
+
+ // next, we compare the list of bridges saved in torrc to the bridges stored in the
+ // "extensions.torlauncher.bridgedb_bridge."" branch. If they match *exactly* then we assume
+ // the bridges were retrieved from BridgeDB and use those. If the torrc list is empty then we know
+ // we have no bridge settings
+
+ // finally, if none of the previous conditions are not met, it is assumed the bridges stored in
+ // torrc are user-provided
+
+ // what we should(?) do once we excise tor-launcher entirely is explicitly store an int/enum in
+ // about:config that tells us which scenario we are in so we don't have to guess
+
+ let defaultBridgeType = Services.prefs.getCharPref(
+ TorStrings.preferenceKeys.defaultBridgeType,
+ null
+ );
+
+ // check if source is BUILTIN
+ if (defaultBridgeType) {
+ this._bridgeStrings = this._readDefaultBridges(defaultBridgeType);
+ this._bridgeSource = TorBridgeSource.BUILTIN;
+ this._selectedDefaultBridgeType = defaultBridgeType;
+ return;
+ }
+
+ let torrcBridges = this._readTorrcBridges();
+
+ // no stored bridges means no bridge is in use
+ if (torrcBridges.length == 0) {
+ this._bridgeStrings = [];
+ this._bridgeSource = TorBridgeSource.NONE;
+ return;
+ }
+
+ let bridgedbBridges = this._readBridgeDBBridges();
+
+ // if these two lists are equal then we got our bridges from bridgedb
+ // ie: same element in identical order
+ let arraysEqual = (left, right) => {
+ if (left.length != right.length) {
+ return false;
+ }
+ const length = left.length;
+ for (let i = 0; i < length; ++i) {
+ if (left[i] != right[i]) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ // agreement between prefs and torrc means bridgedb bridges
+ if (arraysEqual(torrcBridges, bridgedbBridges)) {
+ this._bridgeStrings = torrcBridges;
+ this._bridgeSource = TorBridgeSource.BRIDGEDB;
+ return;
+ }
+
+ // otherwise they must be user provided
+ this._bridgeStrings = torrcBridges;
+ this._bridgeSource = TorBridgeSource.USERPROVIDED;
+ }
+
+ writeSettings() {
+ let settingsObject = new Map();
+
+ // init tor bridge settings to null
+ settingsObject.set(TorStrings.configKeys.useBridges, null);
+ settingsObject.set(TorStrings.configKeys.bridgeList, null);
+
+ // clear bridge related firefox prefs
+ Services.prefs.setCharPref(TorStrings.preferenceKeys.defaultBridgeType, "");
+ let bridgeBranch = Services.prefs.getBranch(
+ `${TorStrings.preferenceBranches.bridgeDBBridges}`
+ );
+ let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
+ for (const pref of bridgeBranchPrefs) {
+ Services.prefs.clearUserPref(
+ `${TorStrings.preferenceBranches.bridgeDBBridges}${pref}`
+ );
+ }
+
+ switch (this._bridgeSource) {
+ case TorBridgeSource.BUILTIN:
+ // set builtin bridge type to use in prefs
+ Services.prefs.setCharPref(
+ TorStrings.preferenceKeys.defaultBridgeType,
+ this._selectedDefaultBridgeType
+ );
+ break;
+ case TorBridgeSource.BRIDGEDB:
+ // save bridges off to prefs
+ for (let i = 0; i < this.bridgeStringsArray.length; ++i) {
+ Services.prefs.setCharPref(
+ `${TorStrings.preferenceBranches.bridgeDBBridges}${i}`,
+ this.bridgeStringsArray[i]
+ );
+ }
+ break;
+ }
+
+ // write over our bridge list if bridges are enabled
+ if (this._bridgeSource != TorBridgeSource.NONE) {
+ settingsObject.set(TorStrings.configKeys.useBridges, true);
+ settingsObject.set(
+ TorStrings.configKeys.bridgeList,
+ this.bridgeStringsArray
+ );
+ }
+ TorProtocolService.writeSettings(settingsObject);
+ }
+}
+
+function makeTorBridgeSettingsNone() {
+ return new TorBridgeSettings();
+}
+
+function makeTorBridgeSettingsBuiltin(aBridgeType) {
+ let retval = new TorBridgeSettings();
+ retval._bridgeSource = TorBridgeSource.BUILTIN;
+ retval._selectedDefaultBridgeType = aBridgeType;
+ retval._bridgeStrings = retval._readDefaultBridges(aBridgeType);
+
+ return retval;
+}
+
+function makeTorBridgeSettingsBridgeDB(aBridges) {
+ let retval = new TorBridgeSettings();
+ retval._bridgeSource = TorBridgeSource.BRIDGEDB;
+ retval._selectedDefaultBridgeType = null;
+ retval._bridgeStrings = aBridges;
+
+ return retval;
+}
+
+function makeTorBridgeSettingsUserProvided(aBridges) {
+ let retval = new TorBridgeSettings();
+ retval._bridgeSource = TorBridgeSource.USERPROVIDED;
+ retval._selectedDefaultBridgeType = null;
+ retval._bridgeStrings = aBridges;
+
+ return retval;
+}
diff --git a/browser/components/torpreferences/content/torCategory.inc.xul b/browser/components/torpreferences/content/torCategory.inc.xul
new file mode 100644
index 000000000000..746059358d5f
--- /dev/null
+++ b/browser/components/torpreferences/content/torCategory.inc.xul
@@ -0,0 +1,8 @@
+<richlistitem id="category-tor"
+ class="category"
+ value="paneTor"
+ helpTopic="prefs-tor"
+ align="center">
+ <image class="category-icon"/>
+ <label id="torPreferences-labelCategory" class="category-name" flex="1" value="Tor"/>
+</richlistitem>
diff --git a/browser/components/torpreferences/content/torFirewallSettings.jsm b/browser/components/torpreferences/content/torFirewallSettings.jsm
new file mode 100644
index 000000000000..e77f18ef2fae
--- /dev/null
+++ b/browser/components/torpreferences/content/torFirewallSettings.jsm
@@ -0,0 +1,72 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = [
+ "TorFirewallSettings",
+ "makeTorFirewallSettingsNone",
+ "makeTorFirewallSettingsCustom",
+];
+
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+const { parseAddrPortList } = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/parseFunctions.jsm"
+);
+
+class TorFirewallSettings {
+ constructor() {
+ this._allowedPorts = [];
+ }
+
+ get portsConfigurationString() {
+ let portStrings = this._allowedPorts.map(port => `*:${port}`);
+ return portStrings.join(",");
+ }
+
+ get commaSeparatedListString() {
+ return this._allowedPorts.join(",");
+ }
+
+ get hasPorts() {
+ return this._allowedPorts.length > 0;
+ }
+
+ readSettings() {
+ let addressPortList = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.reachableAddresses
+ );
+
+ let allowedPorts = [];
+ if (addressPortList) {
+ allowedPorts = parseAddrPortList(addressPortList);
+ }
+ this._allowedPorts = allowedPorts;
+ }
+
+ writeSettings() {
+ let settingsObject = new Map();
+
+ // init to null so Tor daemon resets if no ports
+ settingsObject.set(TorStrings.configKeys.reachableAddresses, null);
+
+ if (this._allowedPorts.length > 0) {
+ settingsObject.set(
+ TorStrings.configKeys.reachableAddresses,
+ this.portsConfigurationString
+ );
+ }
+
+ TorProtocolService.writeSettings(settingsObject);
+ }
+}
+
+function makeTorFirewallSettingsNone() {
+ return new TorFirewallSettings();
+}
+
+function makeTorFirewallSettingsCustom(aPortsList) {
+ let retval = new TorFirewallSettings();
+ retval._allowedPorts = aPortsList;
+ return retval;
+}
diff --git a/browser/components/torpreferences/content/torLogDialog.jsm b/browser/components/torpreferences/content/torLogDialog.jsm
new file mode 100644
index 000000000000..13a8c42884d2
--- /dev/null
+++ b/browser/components/torpreferences/content/torLogDialog.jsm
@@ -0,0 +1,65 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorLogDialog"];
+
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+
+class TorLogDialog {
+ constructor() {
+ this._dialog = null;
+ this._logTextarea = null;
+ this._copyLogButton = null;
+ }
+
+ static get selectors() {
+ return {
+ copyLogButton: "extra1",
+ logTextarea: "textarea#torPreferences-torDialog-textarea",
+ };
+ }
+
+ _populateXUL(aDialog) {
+ this._dialog = aDialog;
+ this._dialog.setAttribute("title", TorStrings.settings.torLogDialogTitle);
+
+ this._logTextarea = this._dialog.querySelector(
+ TorLogDialog.selectors.logTextarea
+ );
+
+ this._copyLogButton = this._dialog.getButton(
+ TorLogDialog.selectors.copyLogButton
+ );
+ this._copyLogButton.setAttribute("label", TorStrings.settings.copyLog);
+ this._copyLogButton.addEventListener("command", () => {
+ this.copyTorLog();
+ });
+
+ this._logTextarea.value = TorProtocolService.getLog();
+ }
+
+ init(window, aDialog) {
+ // defer to later until firefox has populated the dialog with all our elements
+ window.setTimeout(() => {
+ this._populateXUL(aDialog);
+ }, 0);
+ }
+
+ copyTorLog() {
+ // Copy tor log messages to the system clipboard.
+ let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
+ Ci.nsIClipboardHelper
+ );
+ clipboard.copyString(this._logTextarea.value);
+ }
+
+ openDialog(gSubDialog) {
+ gSubDialog.open(
+ "chrome://browser/content/torpreferences/torLogDialog.xul",
+ "resizable=yes",
+ this
+ );
+ }
+}
diff --git a/browser/components/torpreferences/content/torLogDialog.xul b/browser/components/torpreferences/content/torLogDialog.xul
new file mode 100644
index 000000000000..ae0f4b294204
--- /dev/null
+++ b/browser/components/torpreferences/content/torLogDialog.xul
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
+<?xml-stylesheet href="chrome://browser/content/torpreferences/torPreferences.css"?>
+
+<dialog id="torPreferences-torLog-dialog" type="child" class="prefwindow"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ buttons="accept,extra1"
+ role="dialog">
+ <html:textarea
+ id="torPreferences-torDialog-textarea"
+ multiline="true"
+ readonly="true"/>
+ <script type="application/javascript"><![CDATA[
+ "use strict";
+
+ let torLogDialog = window.arguments[0];
+ let dialog = document.getElementById("torPreferences-torLog-dialog");
+ torLogDialog.init(window, dialog);
+ ]]></script>
+</dialog>
\ No newline at end of file
diff --git a/browser/components/torpreferences/content/torPane.js b/browser/components/torpreferences/content/torPane.js
new file mode 100644
index 000000000000..08de0613e1d4
--- /dev/null
+++ b/browser/components/torpreferences/content/torPane.js
@@ -0,0 +1,802 @@
+"use strict";
+
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+
+const {
+ TorBridgeSource,
+ TorBridgeSettings,
+ makeTorBridgeSettingsNone,
+ makeTorBridgeSettingsBuiltin,
+ makeTorBridgeSettingsBridgeDB,
+ makeTorBridgeSettingsUserProvided,
+} = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/torBridgeSettings.jsm"
+);
+
+const {
+ TorProxyType,
+ TorProxySettings,
+ makeTorProxySettingsNone,
+ makeTorProxySettingsSocks4,
+ makeTorProxySettingsSocks5,
+ makeTorProxySettingsHTTPS,
+} = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/torProxySettings.jsm"
+);
+const {
+ TorFirewallSettings,
+ makeTorFirewallSettingsNone,
+ makeTorFirewallSettingsCustom,
+} = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/torFirewallSettings.jsm"
+);
+
+const { TorLogDialog } = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/torLogDialog.jsm"
+);
+
+const { RequestBridgeDialog } = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/requestBridgeDialog.jsm"
+);
+
+ChromeUtils.defineModuleGetter(
+ this,
+ "TorStrings",
+ "resource:///modules/TorStrings.jsm"
+);
+
+const { parsePort, parseBridgeStrings, parsePortList } = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/parseFunctions.jsm"
+);
+
+/*
+ Tor Pane
+
+ Code for populating the XUL in about:preferences#tor, handling input events, interfacing with tor-launcher
+*/
+const gTorPane = (function() {
+ /* CSS selectors for all of the Tor Network DOM elements we need to access */
+ const selectors = {
+ category: {
+ title: "label#torPreferences-labelCategory",
+ },
+ torPreferences: {
+ header: "h1#torPreferences-header",
+ description: "span#torPreferences-description",
+ learnMore: "label#torPreferences-learnMore",
+ },
+ bridges: {
+ header: "h2#torPreferences-bridges-header",
+ description: "span#torPreferences-bridges-description",
+ learnMore: "label#torPreferences-bridges-learnMore",
+ useBridgeCheckbox: "checkbox#torPreferences-bridges-toggle",
+ bridgeSelectionRadiogroup:
+ "radiogroup#torPreferences-bridges-bridgeSelection",
+ builtinBridgeOption: "radio#torPreferences-bridges-radioBuiltin",
+ builtinBridgeList: "menulist#torPreferences-bridges-builtinList",
+ requestBridgeOption: "radio#torPreferences-bridges-radioRequestBridge",
+ requestBridgeButton: "button#torPreferences-bridges-buttonRequestBridge",
+ requestBridgeTextarea:
+ "textarea#torPreferences-bridges-textareaRequestBridge",
+ provideBridgeOption: "radio#torPreferences-bridges-radioProvideBridge",
+ provideBridgeDescription:
+ "description#torPreferences-bridges-descriptionProvideBridge",
+ provideBridgeTextarea:
+ "textarea#torPreferences-bridges-textareaProvideBridge",
+ },
+ advanced: {
+ header: "h2#torPreferences-advanced-header",
+ description: "span#torPreferences-advanced-description",
+ learnMore: "label#torPreferences-advanced-learnMore",
+ useProxyCheckbox: "checkbox#torPreferences-advanced-toggleProxy",
+ proxyTypeLabel: "label#torPreferences-localProxy-type",
+ proxyTypeList: "menulist#torPreferences-localProxy-builtinList",
+ proxyAddressLabel: "label#torPreferences-localProxy-address",
+ proxyAddressTextbox: "textbox#torPreferences-localProxy-textboxAddress",
+ proxyPortLabel: "label#torPreferences-localProxy-port",
+ proxyPortTextbox: "input#torPreferences-localProxy-textboxPort",
+ proxyUsernameLabel: "label#torPreferences-localProxy-username",
+ proxyUsernameTextbox: "textbox#torPreferences-localProxy-textboxUsername",
+ proxyPasswordLabel: "label#torPreferences-localProxy-password",
+ proxyPasswordTextbox: "textbox#torPreferences-localProxy-textboxPassword",
+ useFirewallCheckbox: "checkbox#torPreferences-advanced-toggleFirewall",
+ firewallAllowedPortsLabel: "label#torPreferences-advanced-allowedPorts",
+ firewallAllowedPortsTextbox:
+ "textbox#torPreferences-advanced-textboxAllowedPorts",
+ torLogsLabel: "label#torPreferences-torLogs",
+ torLogsButton: "button#torPreferences-buttonTorLogs",
+ },
+ }; /* selectors */
+
+ let retval = {
+ // cached frequently accessed DOM elements
+ _useBridgeCheckbox: null,
+ _bridgeSelectionRadiogroup: null,
+ _builtinBridgeOption: null,
+ _builtinBridgeMenulist: null,
+ _requestBridgeOption: null,
+ _requestBridgeButton: null,
+ _requestBridgeTextarea: null,
+ _provideBridgeOption: null,
+ _provideBridgeTextarea: null,
+ _useProxyCheckbox: null,
+ _proxyTypeLabel: null,
+ _proxyTypeMenulist: null,
+ _proxyAddressLabel: null,
+ _proxyAddressTextbox: null,
+ _proxyPortLabel: null,
+ _proxyPortTextbox: null,
+ _proxyUsernameLabel: null,
+ _proxyUsernameTextbox: null,
+ _proxyPasswordLabel: null,
+ _proxyPasswordTextbox: null,
+ _useFirewallCheckbox: null,
+ _allowedPortsLabel: null,
+ _allowedPortsTextbox: null,
+
+ // tor network settings
+ _bridgeSettings: null,
+ _proxySettings: null,
+ _firewallSettings: null,
+
+ // disables the provided list of elements
+ _setElementsDisabled(elements, disabled) {
+ for (let currentElement of elements) {
+ currentElement.disabled = disabled;
+ }
+ },
+
+ // populate xul with strings and cache the relevant elements
+ _populateXUL() {
+ // saves tor settings to disk when navigate away from about:preferences
+ window.addEventListener("blur", val => {
+ TorProtocolService.flushSettings();
+ });
+
+ document
+ .querySelector(selectors.category.title)
+ .setAttribute("value", TorStrings.settings.categoryTitle);
+
+ let prefpane = document.getElementById("mainPrefPane");
+
+ // Heading
+ prefpane.querySelector(selectors.torPreferences.header).innerText =
+ TorStrings.settings.torPreferencesHeading;
+ prefpane.querySelector(selectors.torPreferences.description).textContent =
+ TorStrings.settings.torPreferencesDescription;
+ {
+ let learnMore = prefpane.querySelector(
+ selectors.torPreferences.learnMore
+ );
+ learnMore.setAttribute("value", TorStrings.settings.learnMore);
+ learnMore.setAttribute(
+ "href",
+ TorStrings.settings.learnMoreTorBrowserURL
+ );
+ }
+
+ // Bridge setup
+ prefpane.querySelector(selectors.bridges.header).innerText =
+ TorStrings.settings.bridgesHeading;
+ prefpane.querySelector(selectors.bridges.description).textContent =
+ TorStrings.settings.bridgesDescription;
+ {
+ let learnMore = prefpane.querySelector(selectors.bridges.learnMore);
+ learnMore.setAttribute("value", TorStrings.settings.learnMore);
+ learnMore.setAttribute("href", TorStrings.settings.learnMoreBridgesURL);
+ }
+
+ this._useBridgeCheckbox = prefpane.querySelector(
+ selectors.bridges.useBridgeCheckbox
+ );
+ this._useBridgeCheckbox.setAttribute(
+ "label",
+ TorStrings.settings.useBridge
+ );
+ this._bridgeSelectionRadiogroup = prefpane.querySelector(
+ selectors.bridges.bridgeSelectionRadiogroup
+ );
+ this._bridgeSelectionRadiogroup.value = TorBridgeSource.BUILTIN;
+
+ // Builtin bridges
+ this._builtinBridgeOption = prefpane.querySelector(
+ selectors.bridges.builtinBridgeOption
+ );
+ this._builtinBridgeOption.setAttribute(
+ "label",
+ TorStrings.settings.selectBridge
+ );
+ this._builtinBridgeOption.setAttribute("value", TorBridgeSource.BUILTIN);
+ this._builtinBridgeMenulist = prefpane.querySelector(
+ selectors.bridges.builtinBridgeList
+ );
+
+ // Request bridge
+ this._requestBridgeOption = prefpane.querySelector(
+ selectors.bridges.requestBridgeOption
+ );
+ this._requestBridgeOption.setAttribute(
+ "label",
+ TorStrings.settings.requestBridgeFromTorProject
+ );
+ this._requestBridgeOption.setAttribute("value", TorBridgeSource.BRIDGEDB);
+ this._requestBridgeButton = prefpane.querySelector(
+ selectors.bridges.requestBridgeButton
+ );
+ this._requestBridgeButton.setAttribute(
+ "label",
+ TorStrings.settings.requestNewBridge
+ );
+ this._requestBridgeTextarea = prefpane.querySelector(
+ selectors.bridges.requestBridgeTextarea
+ );
+
+ // Provide a bridge
+ this._provideBridgeOption = prefpane.querySelector(
+ selectors.bridges.provideBridgeOption
+ );
+ this._provideBridgeOption.setAttribute(
+ "label",
+ TorStrings.settings.provideBridge
+ );
+ this._provideBridgeOption.setAttribute(
+ "value",
+ TorBridgeSource.USERPROVIDED
+ );
+ prefpane.querySelector(
+ selectors.bridges.provideBridgeDescription
+ ).textContent = TorStrings.settings.provideBridgeDirections;
+ this._provideBridgeTextarea = prefpane.querySelector(
+ selectors.bridges.provideBridgeTextarea
+ );
+ this._provideBridgeTextarea.setAttribute(
+ "placeholder",
+ TorStrings.settings.provideBridgePlaceholder
+ );
+
+ // Advanced setup
+ prefpane.querySelector(selectors.advanced.header).innerText =
+ TorStrings.settings.advancedHeading;
+ prefpane.querySelector(selectors.advanced.description).textContent =
+ TorStrings.settings.advancedDescription;
+ {
+ let learnMore = prefpane.querySelector(selectors.advanced.learnMore);
+ learnMore.setAttribute("value", TorStrings.settings.learnMore);
+ learnMore.setAttribute(
+ "href",
+ TorStrings.settings.learnMoreNetworkSettingsURL
+ );
+ }
+
+ // Local Proxy
+ this._useProxyCheckbox = prefpane.querySelector(
+ selectors.advanced.useProxyCheckbox
+ );
+ this._useProxyCheckbox.setAttribute(
+ "label",
+ TorStrings.settings.useLocalProxy
+ );
+ this._proxyTypeLabel = prefpane.querySelector(
+ selectors.advanced.proxyTypeLabel
+ );
+ this._proxyTypeLabel.setAttribute("value", TorStrings.settings.proxyType);
+
+ let mockProxies = [
+ {
+ value: TorProxyType.SOCKS4,
+ label: TorStrings.settings.proxyTypeSOCKS4,
+ },
+ {
+ value: TorProxyType.SOCKS5,
+ label: TorStrings.settings.proxyTypeSOCKS5,
+ },
+ { value: TorProxyType.HTTPS, label: TorStrings.settings.proxyTypeHTTP },
+ ];
+ this._proxyTypeMenulist = prefpane.querySelector(
+ selectors.advanced.proxyTypeList
+ );
+ for (let currentProxy of mockProxies) {
+ let menuEntry = document.createElement("menuitem");
+ menuEntry.setAttribute("value", currentProxy.value);
+ menuEntry.setAttribute("label", currentProxy.label);
+ this._proxyTypeMenulist.querySelector("menupopup").append(menuEntry);
+ }
+
+ this._proxyAddressLabel = prefpane.querySelector(
+ selectors.advanced.proxyAddressLabel
+ );
+ this._proxyAddressLabel.setAttribute(
+ "value",
+ TorStrings.settings.proxyAddress
+ );
+ this._proxyAddressTextbox = prefpane.querySelector(
+ selectors.advanced.proxyAddressTextbox
+ );
+ this._proxyAddressTextbox.setAttribute(
+ "placeholder",
+ TorStrings.settings.proxyAddressPlaceholder
+ );
+ this._proxyPortLabel = prefpane.querySelector(
+ selectors.advanced.proxyPortLabel
+ );
+ this._proxyPortLabel.setAttribute("value", TorStrings.settings.proxyPort);
+ this._proxyPortTextbox = prefpane.querySelector(
+ selectors.advanced.proxyPortTextbox
+ );
+ this._proxyUsernameLabel = prefpane.querySelector(
+ selectors.advanced.proxyUsernameLabel
+ );
+ this._proxyUsernameLabel.setAttribute(
+ "value",
+ TorStrings.settings.proxyUsername
+ );
+ this._proxyUsernameTextbox = prefpane.querySelector(
+ selectors.advanced.proxyUsernameTextbox
+ );
+ this._proxyUsernameTextbox.setAttribute(
+ "placeholder",
+ TorStrings.settings.proxyUsernamePasswordPlaceholder
+ );
+ this._proxyPasswordLabel = prefpane.querySelector(
+ selectors.advanced.proxyPasswordLabel
+ );
+ this._proxyPasswordLabel.setAttribute(
+ "value",
+ TorStrings.settings.proxyPassword
+ );
+ this._proxyPasswordTextbox = prefpane.querySelector(
+ selectors.advanced.proxyPasswordTextbox
+ );
+ this._proxyPasswordTextbox.setAttribute(
+ "placeholder",
+ TorStrings.settings.proxyUsernamePasswordPlaceholder
+ );
+
+ // Local firewall
+ this._useFirewallCheckbox = prefpane.querySelector(
+ selectors.advanced.useFirewallCheckbox
+ );
+ this._useFirewallCheckbox.setAttribute(
+ "label",
+ TorStrings.settings.useFirewall
+ );
+ this._allowedPortsLabel = prefpane.querySelector(
+ selectors.advanced.firewallAllowedPortsLabel
+ );
+ this._allowedPortsLabel.setAttribute(
+ "value",
+ TorStrings.settings.allowedPorts
+ );
+ this._allowedPortsTextbox = prefpane.querySelector(
+ selectors.advanced.firewallAllowedPortsTextbox
+ );
+ this._allowedPortsTextbox.setAttribute(
+ "placeholder",
+ TorStrings.settings.allowedPortsPlaceholder
+ );
+
+ // Tor logs
+ prefpane
+ .querySelector(selectors.advanced.torLogsLabel)
+ .setAttribute("value", TorStrings.settings.showTorDaemonLogs);
+ prefpane
+ .querySelector(selectors.advanced.torLogsButton)
+ .setAttribute("label", TorStrings.settings.showLogs);
+
+ // Disable all relevant elements by default
+ this._setElementsDisabled(
+ [
+ this._builtinBridgeOption,
+ this._builtinBridgeMenulist,
+ this._requestBridgeOption,
+ this._requestBridgeButton,
+ this._requestBridgeTextarea,
+ this._provideBridgeOption,
+ this._provideBridgeTextarea,
+ this._proxyTypeLabel,
+ this._proxyTypeMenulist,
+ this._proxyAddressLabel,
+ this._proxyAddressTextbox,
+ this._proxyPortLabel,
+ this._proxyPortTextbox,
+ this._proxyUsernameLabel,
+ this._proxyUsernameTextbox,
+ this._proxyPasswordLabel,
+ this._proxyPasswordTextbox,
+ this._allowedPortsLabel,
+ this._allowedPortsTextbox,
+ ],
+ true
+ );
+
+ // load bridge settings
+ let torBridgeSettings = new TorBridgeSettings();
+ torBridgeSettings.readSettings();
+
+ // populate the bridge list
+ for (let currentBridge of TorBridgeSettings.defaultBridgeTypes) {
+ let menuEntry = document.createElement("menuitem");
+ menuEntry.setAttribute("value", currentBridge);
+ menuEntry.setAttribute("label", currentBridge);
+ this._builtinBridgeMenulist
+ .querySelector("menupopup")
+ .append(menuEntry);
+ }
+
+ this.onSelectBridgeOption(torBridgeSettings.bridgeSource);
+ this.onToggleBridge(
+ torBridgeSettings.bridgeSource != TorBridgeSource.NONE
+ );
+ switch (torBridgeSettings.bridgeSource) {
+ case TorBridgeSource.NONE:
+ break;
+ case TorBridgeSource.BUILTIN:
+ this._builtinBridgeMenulist.value =
+ torBridgeSettings.selectedDefaultBridgeType;
+ break;
+ case TorBridgeSource.BRIDGEDB:
+ this._requestBridgeTextarea.value = torBridgeSettings.bridgeStrings;
+ break;
+ case TorBridgeSource.USERPROVIDED:
+ this._provideBridgeTextarea.value = torBridgeSettings.bridgeStrings;
+ break;
+ }
+
+ this._bridgeSettings = torBridgeSettings;
+
+ // load proxy settings
+ let torProxySettings = new TorProxySettings();
+ torProxySettings.readSettings();
+
+ if (torProxySettings.type != TorProxyType.NONE) {
+ this.onToggleProxy(true);
+ this.onSelectProxyType(torProxySettings.type);
+ this._proxyAddressTextbox.value = torProxySettings.address;
+ this._proxyPortTextbox.value = torProxySettings.port;
+ this._proxyUsernameTextbox.value = torProxySettings.username;
+ this._proxyPasswordTextbox.value = torProxySettings.password;
+ }
+
+ this._proxySettings = torProxySettings;
+
+ // load firewall settings
+ let torFirewallSettings = new TorFirewallSettings();
+ torFirewallSettings.readSettings();
+
+ if (torFirewallSettings.hasPorts) {
+ this.onToggleFirewall(true);
+ this._allowedPortsTextbox.value =
+ torFirewallSettings.commaSeparatedListString;
+ }
+
+ this._firewallSettings = torFirewallSettings;
+ },
+
+ init() {
+ this._populateXUL();
+ },
+
+ //
+ // Callbacks
+ //
+
+ // callback when using bridges toggled
+ onToggleBridge(enabled) {
+ this._useBridgeCheckbox.checked = enabled;
+ let disabled = !enabled;
+
+ // first disable all the bridge related elements
+ this._setElementsDisabled(
+ [
+ this._builtinBridgeOption,
+ this._builtinBridgeMenulist,
+ this._requestBridgeOption,
+ this._requestBridgeButton,
+ this._requestBridgeTextarea,
+ this._provideBridgeOption,
+ this._provideBridgeTextarea,
+ ],
+ disabled
+ );
+
+ // and selectively re-enable based on the radiogroup's current value
+ if (enabled) {
+ this.onSelectBridgeOption(this._bridgeSelectionRadiogroup.value);
+ } else {
+ this.onSelectBridgeOption(TorBridgeSource.NONE);
+ }
+ return this;
+ },
+
+ // callback when a bridge option is selected
+ onSelectBridgeOption(source) {
+ // disable all of the bridge elements under radio buttons
+ this._setElementsDisabled(
+ [
+ this._builtinBridgeMenulist,
+ this._requestBridgeButton,
+ this._requestBridgeTextarea,
+ this._provideBridgeTextarea,
+ ],
+ true
+ );
+
+ if (source != TorBridgeSource.NONE) {
+ this._bridgeSelectionRadiogroup.value = source;
+ }
+
+ switch (source) {
+ case TorBridgeSource.BUILTIN: {
+ this._setElementsDisabled([this._builtinBridgeMenulist], false);
+ break;
+ }
+ case TorBridgeSource.BRIDGEDB: {
+ this._setElementsDisabled(
+ [this._requestBridgeButton, this._requestBridgeTextarea],
+ false
+ );
+ break;
+ }
+ case TorBridgeSource.USERPROVIDED: {
+ this._setElementsDisabled([this._provideBridgeTextarea], false);
+ break;
+ }
+ }
+ return this;
+ },
+
+ // called when the request brige button is activated
+ onRequestBridge() {
+ let requestBridgeDialog = new RequestBridgeDialog();
+ requestBridgeDialog.openDialog(
+ gSubDialog,
+ this._proxySettings.proxyURI,
+ aBridges => {
+ if (aBridges.length > 0) {
+ let bridgeSettings = makeTorBridgeSettingsBridgeDB(aBridges);
+ bridgeSettings.writeSettings();
+ this._bridgeSettings = bridgeSettings;
+
+ this._requestBridgeTextarea.value = bridgeSettings.bridgeStrings;
+ }
+ }
+ );
+ return this;
+ },
+
+ // pushes bridge settings from UI to tor
+ onUpdateBridgeSettings() {
+ let bridgeSettings = null;
+
+ let source = this._useBridgeCheckbox.checked
+ ? this._bridgeSelectionRadiogroup.value
+ : TorBridgeSource.NONE;
+ switch (source) {
+ case TorBridgeSource.NONE: {
+ bridgeSettings = makeTorBridgeSettingsNone();
+ break;
+ }
+ case TorBridgeSource.BUILTIN: {
+ // if there is a built-in bridge already selected, use that
+ let bridgeType = this._builtinBridgeMenulist.value;
+ if (bridgeType) {
+ bridgeSettings = makeTorBridgeSettingsBuiltin(bridgeType);
+ } else {
+ bridgeSettings = makeTorBridgeSettingsNone();
+ }
+ break;
+ }
+ case TorBridgeSource.BRIDGEDB: {
+ // if there are bridgedb bridges saved in the text area, use them
+ let bridgeStrings = this._requestBridgeTextarea.value;
+ if (bridgeStrings) {
+ let bridgeStringList = parseBridgeStrings(bridgeStrings);
+ bridgeSettings = makeTorBridgeSettingsBridgeDB(bridgeStringList);
+ } else {
+ bridgeSettings = makeTorBridgeSettingsNone();
+ }
+ break;
+ }
+ case TorBridgeSource.USERPROVIDED: {
+ // if bridges already exist in the text area, use them
+ let bridgeStrings = this._provideBridgeTextarea.value;
+ if (bridgeStrings) {
+ let bridgeStringList = parseBridgeStrings(bridgeStrings);
+ bridgeSettings = makeTorBridgeSettingsUserProvided(
+ bridgeStringList
+ );
+ } else {
+ bridgeSettings = makeTorBridgeSettingsNone();
+ }
+ break;
+ }
+ }
+ bridgeSettings.writeSettings();
+ this._bridgeSettings = bridgeSettings;
+ return this;
+ },
+
+ // callback when proxy is toggled
+ onToggleProxy(enabled) {
+ this._useProxyCheckbox.checked = enabled;
+ let disabled = !enabled;
+
+ this._setElementsDisabled(
+ [
+ this._proxyTypeLabel,
+ this._proxyTypeMenulist,
+ this._proxyAddressLabel,
+ this._proxyAddressTextbox,
+ this._proxyPortLabel,
+ this._proxyPortTextbox,
+ this._proxyUsernameLabel,
+ this._proxyUsernameTextbox,
+ this._proxyPasswordLabel,
+ this._proxyPasswordTextbox,
+ ],
+ disabled
+ );
+ this.onSelectProxyType(this._proxyTypeMenulist.value);
+ return this;
+ },
+
+ // callback when proxy type is changed
+ onSelectProxyType(value) {
+ if (value == "") {
+ value = TorProxyType.NONE;
+ }
+ this._proxyTypeMenulist.value = value;
+ switch (value) {
+ case TorProxyType.NONE: {
+ this._setElementsDisabled(
+ [
+ this._proxyAddressLabel,
+ this._proxyAddressTextbox,
+ this._proxyPortLabel,
+ this._proxyPortTextbox,
+ this._proxyUsernameLabel,
+ this._proxyUsernameTextbox,
+ this._proxyPasswordLabel,
+ this._proxyPasswordTextbox,
+ ],
+ true
+ ); // DISABLE
+
+ this._proxyAddressTextbox.value = "";
+ this._proxyPortTextbox.value = "";
+ this._proxyUsernameTextbox.value = "";
+ this._proxyPasswordTextbox.value = "";
+ break;
+ }
+ case TorProxyType.SOCKS4: {
+ this._setElementsDisabled(
+ [
+ this._proxyAddressLabel,
+ this._proxyAddressTextbox,
+ this._proxyPortLabel,
+ this._proxyPortTextbox,
+ ],
+ false
+ ); // ENABLE
+ this._setElementsDisabled(
+ [
+ this._proxyUsernameLabel,
+ this._proxyUsernameTextbox,
+ this._proxyPasswordLabel,
+ this._proxyPasswordTextbox,
+ ],
+ true
+ ); // DISABLE
+
+ this._proxyUsernameTextbox.value = "";
+ this._proxyPasswordTextbox.value = "";
+ break;
+ }
+ case TorProxyType.SOCKS5:
+ case TorProxyType.HTTPS: {
+ this._setElementsDisabled(
+ [
+ this._proxyAddressLabel,
+ this._proxyAddressTextbox,
+ this._proxyPortLabel,
+ this._proxyPortTextbox,
+ this._proxyUsernameLabel,
+ this._proxyUsernameTextbox,
+ this._proxyPasswordLabel,
+ this._proxyPasswordTextbox,
+ ],
+ false
+ ); // ENABLE
+ break;
+ }
+ }
+ return this;
+ },
+
+ // pushes proxy settings from UI to tor
+ onUpdateProxySettings() {
+ const proxyType = this._useProxyCheckbox.checked
+ ? this._proxyTypeMenulist.value
+ : TorProxyType.NONE;
+ const addressString = this._proxyAddressTextbox.value;
+ const portString = this._proxyPortTextbox.value;
+ const usernameString = this._proxyUsernameTextbox.value;
+ const passwordString = this._proxyPasswordTextbox.value;
+
+ let proxySettings = null;
+
+ switch (proxyType) {
+ case TorProxyType.NONE:
+ proxySettings = makeTorProxySettingsNone();
+ break;
+ case TorProxyType.SOCKS4:
+ proxySettings = makeTorProxySettingsSocks4(
+ addressString,
+ parsePort(portString)
+ );
+ break;
+ case TorProxyType.SOCKS5:
+ proxySettings = makeTorProxySettingsSocks5(
+ addressString,
+ parsePort(portString),
+ usernameString,
+ passwordString
+ );
+ break;
+ case TorProxyType.HTTPS:
+ proxySettings = makeTorProxySettingsHTTPS(
+ addressString,
+ parsePort(portString),
+ usernameString,
+ passwordString
+ );
+ break;
+ }
+
+ proxySettings.writeSettings();
+ this._proxySettings = proxySettings;
+ return this;
+ },
+
+ // callback when firewall proxy is toggled
+ onToggleFirewall(enabled) {
+ this._useFirewallCheckbox.checked = enabled;
+ let disabled = !enabled;
+
+ this._setElementsDisabled(
+ [this._allowedPortsLabel, this._allowedPortsTextbox],
+ disabled
+ );
+
+ return this;
+ },
+
+ // pushes firewall settings from UI to tor
+ onUpdateFirewallSettings() {
+ let portListString = this._useFirewallCheckbox.checked
+ ? this._allowedPortsTextbox.value
+ : "";
+ let firewallSettings = null;
+
+ if (portListString) {
+ firewallSettings = makeTorFirewallSettingsCustom(
+ parsePortList(portListString)
+ );
+ } else {
+ firewallSettings = makeTorFirewallSettingsNone();
+ }
+
+ firewallSettings.writeSettings();
+ this._firewallSettings = firewallSettings;
+ return this;
+ },
+
+ onViewTorLogs() {
+ let torLogDialog = new TorLogDialog();
+ torLogDialog.openDialog(gSubDialog);
+ },
+ };
+ return retval;
+})(); /* gTorPane */
diff --git a/browser/components/torpreferences/content/torPane.xul b/browser/components/torpreferences/content/torPane.xul
new file mode 100644
index 000000000000..298c148bcbf2
--- /dev/null
+++ b/browser/components/torpreferences/content/torPane.xul
@@ -0,0 +1,119 @@
+<!-- Tor panel -->
+
+<script type="application/javascript"
+ src="chrome://browser/content/torpreferences/torPane.js"/>
+
+<hbox id="torPreferencesCategory"
+ class="subcategory"
+ hidden="true"
+ data-category="paneTor">
+ <html:h1 id="torPreferences-header"/>
+</hbox>
+
+<groupbox data-category="paneTor" >
+ <description flex="1">
+ <html:span id="torPreferences-description" class="tail-with-learn-more"/>
+ <label id="torPreferences-learnMore" class="learnMore text-link" is="text-link"/>
+ </description>
+</groupbox>
+
+<!-- Bridges -->
+<groupbox id="torPreferences-bridges-group" data-category="paneTor" >
+ <html:h2 id="torPreferences-bridges-header"/>
+ <description flex="1">
+ <html:span id="torPreferences-bridges-description" class="tail-with-learn-more"/>
+ <label id="torPreferences-bridges-learnMore" class="learnMore text-link" is="text-link"/>
+ </description>
+ <checkbox id="torPreferences-bridges-toggle" oncommand="gTorPane.onToggleBridge(this.checked).onUpdateBridgeSettings();"/>
+ <radiogroup id="torPreferences-bridges-bridgeSelection"
+ oncommand="gTorPane.onSelectBridgeOption(this.value).onUpdateBridgeSettings();">
+ <hbox class="indent">
+ <radio id="torPreferences-bridges-radioBuiltin"/>
+ <spacer flex="1"/>
+ <menulist id="torPreferences-bridges-builtinList" class="torMarginFix" oncommand="gTorPane.onUpdateBridgeSettings();">
+ <menupopup/>
+ </menulist>
+ </hbox>
+ <vbox class="indent">
+ <hbox>
+ <radio id="torPreferences-bridges-radioRequestBridge"/>
+ <space flex="1"/>
+ <button id="torPreferences-bridges-buttonRequestBridge" class="torMarginFix" oncommand="gTorPane.onRequestBridge();"/>
+ </hbox>
+ <html:textarea
+ id="torPreferences-bridges-textareaRequestBridge"
+ class="indent torMarginFix"
+ multiline="true"
+ rows="3"
+ readonly="true"/>
+ </vbox>
+ <hbox class="indent" flex="1">
+ <vbox flex="1">
+ <radio id="torPreferences-bridges-radioProvideBridge"/>
+ <description id="torPreferences-bridges-descriptionProvideBridge" class="indent"/>
+ <html:textarea
+ id="torPreferences-bridges-textareaProvideBridge"
+ class="indent torMarginFix"
+ multiline="true"
+ rows="3"
+ onblur="gTorPane.onUpdateBridgeSettings();"/>
+ </vbox>
+ </hbox>
+ </radiogroup>
+</groupbox>
+
+<!-- Advanced -->
+<groupbox id="torPreferences-advanced-group" data-category="paneTor">
+ <html:h2 id="torPreferences-advanced-header"/>
+ <description flex="1">
+ <html:span id="torPreferences-advanced-description" class="tail-with-learn-more"/>
+ <label id="torPreferences-advanced-learnMore" class="learnMore text-link" is="text-link"/>
+ </description>
+ <grid flex="1">
+ <columns>
+ <column flex="0"/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <!-- Local Proxy -->
+ <checkbox id="torPreferences-advanced-toggleProxy" oncommand="gTorPane.onToggleProxy(this.checked).onUpdateProxySettings();"/>
+ <row class="indent" align="center">
+ <label id="torPreferences-localProxy-type"/>
+ <hbox>
+ <spacer flex="1"/>
+ <menulist id="torPreferences-localProxy-builtinList" class="torMarginFix" oncommand="gTorPane.onSelectProxyType(this.value).onUpdateProxySettings();">
+ <menupopup/>
+ </menulist>
+ </hbox>
+ </row>
+ <row class="indent" align="center">
+ <label id="torPreferences-localProxy-address"/>
+ <hbox align="center">
+ <textbox id="torPreferences-localProxy-textboxAddress" class="torMarginFix" flex="4" onblur="gTorPane.onUpdateProxySettings();"/>
+ <label id="torPreferences-localProxy-port"/>
+ <!-- proxy-port-input class style pulled from preferences.css and used in the vanilla proxy setup menu -->
+ <html:input id="torPreferences-localProxy-textboxPort" class="proxy-port-input torMarginFix" hidespinbuttons="true" type="number" min="0" max="65535" maxlength="5" onblur="gTorPane.onUpdateProxySettings();"/>
+ </hbox>
+ </row>
+ <row class="indent" align="center">
+ <label id="torPreferences-localProxy-username"/>
+ <hbox align="center">
+ <textbox id="torPreferences-localProxy-textboxUsername" class="torMarginFix" flex="1" onblur="gTorPane.onUpdateProxySettings();"/>
+ <label id="torPreferences-localProxy-password"/>
+ <textbox id="torPreferences-localProxy-textboxPassword" class="torMarginFix" type="password" flex="1" onblur="gTorPane.onUpdateProxySettings();"/>
+ </hbox>
+ </row>
+ <!-- Firewall -->
+ <checkbox id="torPreferences-advanced-toggleFirewall" oncommand="gTorPane.onToggleFirewall(this.checked).onUpdateFirewallSettings();"/>
+ <row class="indent" align="center">
+ <label id="torPreferences-advanced-allowedPorts"/>
+ <textbox id="torPreferences-advanced-textboxAllowedPorts" class="torMarginFix" value="80,443" onblur="gTorPane.onUpdateFirewallSettings();"/>
+ </row>
+ </rows>
+ </grid>
+ <hbox id="torPreferences-torDaemon-hbox" align="center">
+ <label id="torPreferences-torLogs"/>
+ <spacer flex="1"/>
+ <button id="torPreferences-buttonTorLogs" class="torMarginFix" oncommand="gTorPane.onViewTorLogs();"/>
+ </hbox>
+</groupbox>
diff --git a/browser/components/torpreferences/content/torPreferences.css b/browser/components/torpreferences/content/torPreferences.css
new file mode 100644
index 000000000000..19c7421cd647
--- /dev/null
+++ b/browser/components/torpreferences/content/torPreferences.css
@@ -0,0 +1,63 @@
+#category-tor > .category-icon {
+ list-style-image: url("chrome://browser/content/torpreferences/torPreferencesIcon.svg");
+}
+
+hbox#torPreferences-torDaemon-hbox {
+ margin-top: 20px;
+}
+
+description#torPreferences-requestBridge-description {
+ /*margin-bottom: 1em;*/
+ min-height: 2em;
+}
+
+image#torPreferences-requestBridge-captchaImage {
+ margin: 1em;
+ min-height: 125px;
+}
+
+button#torPreferences-requestBridge-refreshCaptchaButton {
+ min-width: initial;
+}
+
+dialog#torPreferences-requestBridge-dialog > hbox
+{
+ margin-bottom: 1em;
+}
+
+/*
+ Various elements that really should be lining up don't because they have inconsistent margins
+*/
+.torMarginFix
+{
+ margin-left : 4px;
+ margin-right : 4px;
+}
+
+/*
+ This hbox is hidden by css here by default so that the
+ xul dialog allocates enough screen space for the error message
+ element, otherwise it gets cut off since dialog's overflow is hidden
+*/
+hbox#torPreferences-requestBridge-incorrectCaptchaHbox {
+ visibility: hidden;
+}
+
+image#torPreferences-requestBridge-errorIcon {
+ list-style-image: url("chrome://browser/skin/warning.svg");
+}
+
+groupbox#torPreferences-bridges-group textarea {
+ white-space: pre;
+ overflow: auto;
+}
+
+textarea#torPreferences-torDialog-textarea {
+ -moz-box-flex: 1;
+ font-family: monospace;
+ font-size: 0.8em;
+ white-space: pre;
+ overflow: auto;
+ /* 10 lines */
+ min-height: 20em;
+}
\ No newline at end of file
diff --git a/browser/components/torpreferences/content/torPreferencesIcon.svg b/browser/components/torpreferences/content/torPreferencesIcon.svg
new file mode 100644
index 000000000000..d7895f1107c5
--- /dev/null
+++ b/browser/components/torpreferences/content/torPreferencesIcon.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <g fill="context-fill" fill-opacity="context-fill-opacity" fill-rule="nonzero">
+ <path d="M12.0246161,21.8174863 L12.0246161,20.3628098 C16.6324777,20.3495038 20.3634751,16.6108555 20.3634751,11.9996673 C20.3634751,7.38881189 16.6324777,3.65016355 12.0246161,3.63685757 L12.0246161,2.18218107 C17.4358264,2.1958197 21.8178189,6.58546322 21.8178189,11.9996673 C21.8178189,17.4142042 17.4358264,21.8041803 12.0246161,21.8174863 L12.0246161,21.8174863 Z M12.0246161,16.7259522 C14.623607,16.7123136 16.7272828,14.6023175 16.7272828,11.9996673 C16.7272828,9.39734991 14.623607,7.28735377 12.0246161,7.27371516 L12.0246161,5.81937131 C15.4272884,5.8326773 18.1819593,8.59400123 18.1819593,11.9996673 C18.1819593,15.4056661 15.4272884,18.1669901 12.0246161,18.1802961 L12.0246161,16.7259522 Z M12.0246161,9.45556355 C13.4187503,9.46886953 14.5454344,10.6022066 14.5454344,11.9996673 C14.5454344,13.3974608 13.4187503,14.5307978 12.0246161,14.5441038 L12.0246161,9.45556355 Z M0,11.9996673 C0,18.6273771 5.37229031,24 12,24 C18.6273771,24 24,18.6273771 24,11.9996673 C24,5.37229031
18.6273771,0 12,0 C5.37229031,0 0,5.37229031 0,11.9996673 Z"/>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/browser/components/torpreferences/content/torProxySettings.jsm b/browser/components/torpreferences/content/torProxySettings.jsm
new file mode 100644
index 000000000000..98bb5e8d5cbf
--- /dev/null
+++ b/browser/components/torpreferences/content/torProxySettings.jsm
@@ -0,0 +1,245 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = [
+ "TorProxyType",
+ "TorProxySettings",
+ "makeTorProxySettingsNone",
+ "makeTorProxySettingsSocks4",
+ "makeTorProxySettingsSocks5",
+ "makeTorProxySettingsHTTPS",
+];
+
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+const { parseAddrPort, parseUsernamePassword } = ChromeUtils.import(
+ "chrome://browser/content/torpreferences/parseFunctions.jsm"
+);
+
+const TorProxyType = {
+ NONE: "NONE",
+ SOCKS4: "SOCKS4",
+ SOCKS5: "SOCKS5",
+ HTTPS: "HTTPS",
+};
+
+class TorProxySettings {
+ constructor() {
+ this._proxyType = TorProxyType.NONE;
+ this._proxyAddress = undefined;
+ this._proxyPort = undefined;
+ this._proxyUsername = undefined;
+ this._proxyPassword = undefined;
+ }
+
+ get type() {
+ return this._proxyType;
+ }
+ get address() {
+ return this._proxyAddress;
+ }
+ get port() {
+ return this._proxyPort;
+ }
+ get username() {
+ return this._proxyUsername;
+ }
+ get password() {
+ return this._proxyPassword;
+ }
+ get proxyURI() {
+ switch (this._proxyType) {
+ case TorProxyType.SOCKS4:
+ return `socks4a://${this._proxyAddress}:${this._proxyPort}`;
+ case TorProxyType.SOCKS5:
+ if (this._proxyUsername) {
+ return `socks5://${this._proxyUsername}:${this._proxyPassword}@${
+ this._proxyAddress
+ }:${this._proxyPort}`;
+ }
+ return `socks5://${this._proxyAddress}:${this._proxyPort}`;
+ case TorProxyType.HTTPS:
+ if (this._proxyUsername) {
+ return `http://${this._proxyUsername}:${this._proxyPassword}@${
+ this._proxyAddress
+ }:${this._proxyPort}`;
+ }
+ return `http://${this._proxyAddress}:${this._proxyPort}`;
+ }
+ return undefined;
+ }
+
+ // attempts to read proxy settings from Tor daemon
+ readSettings() {
+ // SOCKS4
+ {
+ let addressPort = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.socks4Proxy
+ );
+ if (addressPort) {
+ // address+port
+ let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
+
+ this._proxyType = TorProxyType.SOCKS4;
+ this._proxyAddress = proxyAddress;
+ this._proxyPort = proxyPort;
+ this._proxyUsername = "";
+ this._proxyPassword = "";
+
+ return;
+ }
+ }
+
+ // SOCKS5
+ {
+ let addressPort = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.socks5Proxy
+ );
+
+ if (addressPort) {
+ // address+port
+ let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
+ // username
+ let proxyUsername = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.socks5ProxyUsername
+ );
+ // password
+ let proxyPassword = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.socks5ProxyPassword
+ );
+
+ this._proxyType = TorProxyType.SOCKS5;
+ this._proxyAddress = proxyAddress;
+ this._proxyPort = proxyPort;
+ this._proxyUsername = proxyUsername;
+ this._proxyPassword = proxyPassword;
+
+ return;
+ }
+ }
+
+ // HTTP
+ {
+ let addressPort = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.httpsProxy
+ );
+
+ if (addressPort) {
+ // address+port
+ let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
+
+ // username:password
+ let proxyAuthenticator = TorProtocolService.readStringSetting(
+ TorStrings.configKeys.httpsProxyAuthenticator
+ );
+
+ let [proxyUsername, proxyPassword] = ["", ""];
+ if (proxyAuthenticator) {
+ [proxyUsername, proxyPassword] = parseUsernamePassword(
+ proxyAuthenticator
+ );
+ }
+
+ this._proxyType = TorProxyType.HTTPS;
+ this._proxyAddress = proxyAddress;
+ this._proxyPort = proxyPort;
+ this._proxyUsername = proxyUsername;
+ this._proxyPassword = proxyPassword;
+ }
+ }
+ // no proxy settings
+ } /* TorProxySettings::ReadFromTor() */
+
+ // attempts to write proxy settings to Tor daemon
+ // throws on error
+ writeSettings() {
+ let settingsObject = new Map();
+
+ // init proxy related settings to null so Tor daemon resets them
+ settingsObject.set(TorStrings.configKeys.socks4Proxy, null);
+ settingsObject.set(TorStrings.configKeys.socks5Proxy, null);
+ settingsObject.set(TorStrings.configKeys.socks5ProxyUsername, null);
+ settingsObject.set(TorStrings.configKeys.socks5ProxyPassword, null);
+ settingsObject.set(TorStrings.configKeys.httpsProxy, null);
+ settingsObject.set(TorStrings.configKeys.httpsProxyAuthenticator, null);
+
+ switch (this._proxyType) {
+ case TorProxyType.SOCKS4:
+ settingsObject.set(
+ TorStrings.configKeys.socks4Proxy,
+ `${this._proxyAddress}:${this._proxyPort}`
+ );
+ break;
+ case TorProxyType.SOCKS5:
+ settingsObject.set(
+ TorStrings.configKeys.socks5Proxy,
+ `${this._proxyAddress}:${this._proxyPort}`
+ );
+ settingsObject.set(
+ TorStrings.configKeys.socks5ProxyUsername,
+ this._proxyUsername
+ );
+ settingsObject.set(
+ TorStrings.configKeys.socks5ProxyPassword,
+ this._proxyPassword
+ );
+ break;
+ case TorProxyType.HTTPS:
+ settingsObject.set(
+ TorStrings.configKeys.httpsProxy,
+ `${this._proxyAddress}:${this._proxyPort}`
+ );
+ settingsObject.set(
+ TorStrings.configKeys.httpsProxyAuthenticator,
+ `${this._proxyUsername}:${this._proxyPassword}`
+ );
+ break;
+ }
+
+ TorProtocolService.writeSettings(settingsObject);
+ } /* TorProxySettings::WriteToTor() */
+}
+
+// factory methods for our various supported proxies
+function makeTorProxySettingsNone() {
+ return new TorProxySettings();
+}
+
+function makeTorProxySettingsSocks4(aProxyAddress, aProxyPort) {
+ let retval = new TorProxySettings();
+ retval._proxyType = TorProxyType.SOCKS4;
+ retval._proxyAddress = aProxyAddress;
+ retval._proxyPort = aProxyPort;
+ return retval;
+}
+
+function makeTorProxySettingsSocks5(
+ aProxyAddress,
+ aProxyPort,
+ aProxyUsername,
+ aProxyPassword
+) {
+ let retval = new TorProxySettings();
+ retval._proxyType = TorProxyType.SOCKS5;
+ retval._proxyAddress = aProxyAddress;
+ retval._proxyPort = aProxyPort;
+ retval._proxyUsername = aProxyUsername;
+ retval._proxyPassword = aProxyPassword;
+ return retval;
+}
+
+function makeTorProxySettingsHTTPS(
+ aProxyAddress,
+ aProxyPort,
+ aProxyUsername,
+ aProxyPassword
+) {
+ let retval = new TorProxySettings();
+ retval._proxyType = TorProxyType.HTTPS;
+ retval._proxyAddress = aProxyAddress;
+ retval._proxyPort = aProxyPort;
+ retval._proxyUsername = aProxyUsername;
+ retval._proxyPassword = aProxyPassword;
+ return retval;
+}
diff --git a/browser/components/torpreferences/jar.mn b/browser/components/torpreferences/jar.mn
new file mode 100644
index 000000000000..44920322fe4f
--- /dev/null
+++ b/browser/components/torpreferences/jar.mn
@@ -0,0 +1,14 @@
+browser.jar:
+ content/browser/torpreferences/parseFunctions.jsm (content/parseFunctions.jsm)
+ content/browser/torpreferences/requestBridgeDialog.xul (content/requestBridgeDialog.xul)
+ content/browser/torpreferences/requestBridgeDialog.jsm (content/requestBridgeDialog.jsm)
+ content/browser/torpreferences/torBridgeSettings.jsm (content/torBridgeSettings.jsm)
+ content/browser/torpreferences/torCategory.inc.xul (content/torCategory.inc.xul)
+ content/browser/torpreferences/torFirewallSettings.jsm (content/torFirewallSettings.jsm)
+ content/browser/torpreferences/torLogDialog.jsm (content/torLogDialog.jsm)
+ content/browser/torpreferences/torLogDialog.xul (content/torLogDialog.xul)
+ content/browser/torpreferences/torPane.js (content/torPane.js)
+ content/browser/torpreferences/torPane.xul (content/torPane.xul)
+ content/browser/torpreferences/torPreferences.css (content/torPreferences.css)
+ content/browser/torpreferences/torPreferencesIcon.svg (content/torPreferencesIcon.svg)
+ content/browser/torpreferences/torProxySettings.jsm (content/torProxySettings.jsm)
diff --git a/browser/components/torpreferences/moz.build b/browser/components/torpreferences/moz.build
new file mode 100644
index 000000000000..7e103239c8d6
--- /dev/null
+++ b/browser/components/torpreferences/moz.build
@@ -0,0 +1 @@
+JAR_MANIFESTS += ['jar.mn']
diff --git a/browser/modules/BridgeDB.jsm b/browser/modules/BridgeDB.jsm
new file mode 100644
index 000000000000..16bf02e6c688
--- /dev/null
+++ b/browser/modules/BridgeDB.jsm
@@ -0,0 +1,110 @@
+"use strict;";
+
+var EXPORTED_SYMBOLS = ["BridgeDB"];
+
+const { TorLauncherBridgeDB } = ChromeUtils.import(
+ "resource://torlauncher/modules/tl-bridgedb.jsm"
+);
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+
+var BridgeDB = {
+ _moatRequestor: null,
+ _currentCaptchaInfo: null,
+ _bridges: null,
+
+ get currentCaptchaImage() {
+ if (this._currentCaptchaInfo) {
+ return this._currentCaptchaInfo.captchaImage;
+ }
+ return null;
+ },
+
+ get currentBridges() {
+ return this._bridges;
+ },
+
+ submitCaptchaGuess(aCaptchaSolution) {
+ if (this._moatRequestor && this._currentCaptchaInfo) {
+ return this._moatRequestor
+ .finishFetch(
+ this._currentCaptchaInfo.transport,
+ this._currentCaptchaInfo.challenge,
+ aCaptchaSolution
+ )
+ .then(aBridgeInfo => {
+ this._moatRequestor.close();
+ this._moatRequestor = null;
+ this._currentCaptchaInfo = null;
+ this._bridges = aBridgeInfo.bridges;
+ // array of bridge strings
+ return this._bridges;
+ });
+ }
+
+ return new Promise((aResponse, aReject) => {
+ aReject(new Error("Invalid _moatRequestor or _currentCaptchaInfo"));
+ });
+ },
+
+ requestNewCaptchaImage(aProxyURI) {
+ // close and clear out existing state on captcha request
+ this.close();
+
+ let transportPlugins = TorProtocolService.readStringArraySetting(
+ TorStrings.configKeys.clientTransportPlugin
+ );
+
+ let meekClientPath;
+ let meekTransport; // We support both "meek" and "meek_lite".
+ let meekClientArgs;
+ // TODO: shouldn't this early out once meek settings are found?
+ for (const line of transportPlugins) {
+ // Parse each ClientTransportPlugin line and look for the meek or
+ // meek_lite transport. This code works a lot like the Tor daemon's
+ // parse_transport_line() function.
+ let tokens = line.split(" ");
+ if (tokens.length > 2 && tokens[1] == "exec") {
+ let transportArray = tokens[0].split(",").map(aStr => aStr.trim());
+ let transport = transportArray.find(
+ aTransport => aTransport === "meek"
+ );
+ if (!transport) {
+ transport = transportArray.find(
+ aTransport => aTransport === "meek_lite"
+ );
+ }
+ if (transport) {
+ meekTransport = transport;
+ meekClientPath = tokens[2];
+ meekClientArgs = tokens.slice(3);
+ }
+ }
+ }
+
+ this._moatRequestor = TorLauncherBridgeDB.createMoatRequestor();
+
+ return this._moatRequestor
+ .init(aProxyURI, meekTransport, meekClientPath, meekClientArgs)
+ .then(() => {
+ // TODO: get this from TorLauncherUtil
+ let bridgeType = "obfs4";
+ return this._moatRequestor.fetchBridges([bridgeType]);
+ })
+ .then(aCaptchaInfo => {
+ // cache off the current captcha info as the challenge is needed for response
+ this._currentCaptchaInfo = aCaptchaInfo;
+ return aCaptchaInfo.captchaImage;
+ });
+ },
+
+ close() {
+ if (this._moatRequestor) {
+ this._moatRequestor.close();
+ this._moatRequestor = null;
+ }
+ this._currentCaptchaInfo = null;
+ },
+};
diff --git a/browser/modules/TorProtocolService.jsm b/browser/modules/TorProtocolService.jsm
new file mode 100644
index 000000000000..682e7be9de1a
--- /dev/null
+++ b/browser/modules/TorProtocolService.jsm
@@ -0,0 +1,203 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorProtocolService"];
+
+var TorProtocolService = {
+ _tlps: Cc["@torproject.org/torlauncher-protocol-service;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject,
+ // maintain a map of tor settings set by Tor Browser so that we don't
+ // repeatedly set the same key/values over and over
+ // this map contains string keys to primitive or array values
+ _settingsCache: new Map(),
+
+ _typeof(aValue) {
+ switch (typeof aValue) {
+ case "boolean":
+ return "boolean";
+ case "string":
+ return "string";
+ case "object":
+ if (aValue == null) {
+ return "null";
+ } else if (Array.isArray(aValue)) {
+ return "array";
+ }
+ return "object";
+ }
+ return "unknown";
+ },
+
+ _assertValidSettingKey(aSetting) {
+ // ensure the 'key' is a string
+ if (typeof aSetting != "string") {
+ throw new Error(
+ `Expected setting of type string but received ${typeof aSetting}`
+ );
+ }
+ },
+
+ _assertValidSetting(aSetting, aValue) {
+ this._assertValidSettingKey(aSetting);
+
+ const valueType = this._typeof(aValue);
+ switch (valueType) {
+ case "boolean":
+ case "string":
+ case "null":
+ return;
+ case "array":
+ for (const element of aValue) {
+ if (typeof element != "string") {
+ throw new Error(
+ `Setting '${aSetting}' array contains value of invalid type '${typeof element}'`
+ );
+ }
+ }
+ return;
+ default:
+ throw new Error(
+ `Invalid object type received for setting '${aSetting}'`
+ );
+ }
+ },
+
+ // takes a Map containing tor settings
+ // throws on error
+ writeSettings(aSettingsObj) {
+ // only write settings that have changed
+ let newSettings = new Map();
+ for (const [setting, value] of aSettingsObj) {
+ let saveSetting = false;
+
+ // make sure we have valid data here
+ this._assertValidSetting(setting, value);
+
+ if (!this._settingsCache.has(setting)) {
+ // no cached setting, so write
+ saveSetting = true;
+ } else {
+ const cachedValue = this._settingsCache.get(setting);
+ if (value != cachedValue) {
+ // compare arrays member-wise
+ if (Array.isArray(value) && Array.isArray(cachedValue)) {
+ if (value.length != cachedValue.length) {
+ saveSetting = true;
+ } else {
+ const arrayLength = value.length;
+ for (let i = 0; i < arrayLength; ++i) {
+ if (value[i] != cachedValue[i]) {
+ saveSetting = true;
+ break;
+ }
+ }
+ }
+ } else {
+ // some other different values
+ saveSetting = true;
+ }
+ }
+ }
+
+ if (saveSetting) {
+ newSettings.set(setting, value);
+ }
+ }
+
+ // only write if new setting to save
+ if (newSettings.size > 0) {
+ // convert settingsObject map to js object for torlauncher-protocol-service
+ let settingsObject = {};
+ for (const [setting, value] of newSettings) {
+ // console.log(`${setting} : ${value}`);
+ settingsObject[setting] = value;
+ }
+
+ let errorObject = {};
+ if (!this._tlps.TorSetConfWithReply(settingsObject, errorObject)) {
+ throw new Error(errorObject.details);
+ }
+
+ // save settings to cache after successfully writing to Tor
+ for (const [setting, value] of newSettings) {
+ this._settingsCache.set(setting, value);
+ }
+ }
+ },
+
+ _readSetting(aSetting) {
+ this._assertValidSettingKey(aSetting);
+ let reply = this._tlps.TorGetConf(aSetting);
+ if (this._tlps.TorCommandSucceeded(reply)) {
+ return reply.lineArray;
+ }
+ throw new Error(reply.lineArray.join("\n"));
+ },
+
+ _readBoolSetting(aSetting) {
+ let lineArray = this._readSetting(aSetting);
+ if (lineArray.length != 1) {
+ throw new Error(
+ `Expected an array with length 1 but received array of length ${
+ lineArray.length
+ }`
+ );
+ }
+
+ let retval = lineArray[0];
+ switch (retval) {
+ case "0":
+ return false;
+ case "1":
+ return true;
+ default:
+ throw new Error(`Expected boolean (1 or 0) but received '${retval}'`);
+ }
+ },
+
+ _readStringSetting(aSetting) {
+ let lineArray = this._readSetting(aSetting);
+ if (lineArray.length != 1) {
+ throw new Error(
+ `Expected an array with length 1 but received array of length ${
+ lineArray.length
+ }`
+ );
+ }
+ return lineArray[0];
+ },
+
+ _readStringArraySetting(aSetting) {
+ let lineArray = this._readSetting(aSetting);
+ return lineArray;
+ },
+
+ readBoolSetting(aSetting) {
+ let value = this._readBoolSetting(aSetting);
+ this._settingsCache.set(aSetting, value);
+ return value;
+ },
+
+ readStringSetting(aSetting) {
+ let value = this._readStringSetting(aSetting);
+ this._settingsCache.set(aSetting, value);
+ return value;
+ },
+
+ readStringArraySetting(aSetting) {
+ let value = this._readStringArraySetting(aSetting);
+ this._settingsCache.set(aSetting, value);
+ return value;
+ },
+
+ // writes current tor settings to disk
+ flushSettings() {
+ this._tlps.TorSendCommand("SAVECONF");
+ },
+
+ getLog() {
+ let countObj = { value: 0 };
+ let torLog = this._tlps.TorGetLog(countObj);
+ return torLog;
+ },
+};
diff --git a/browser/modules/TorStrings.jsm b/browser/modules/TorStrings.jsm
new file mode 100644
index 000000000000..c7bd6f4236ae
--- /dev/null
+++ b/browser/modules/TorStrings.jsm
@@ -0,0 +1,326 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorStrings"];
+
+const { XPCOMUtils } = ChromeUtils.import(
+ "resource://gre/modules/XPCOMUtils.jsm"
+);
+const { getLocale } = ChromeUtils.import(
+ "resource://torbutton/modules/utils.js"
+);
+
+XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser"]);
+XPCOMUtils.defineLazyGetter(this, "domParser", () => {
+ const parser = new DOMParser();
+ parser.forceEnableDTD();
+ return parser;
+});
+
+/*
+ Tor String Bundle
+
+ Strings loaded from torbutton/tor-launcher, but provide a fallback in case they aren't available
+*/
+class TorStringBundle {
+ constructor(aBundleURLs, aPrefix) {
+ let locations = [];
+ for (const [index, url] of aBundleURLs.entries()) {
+ locations.push(`<!ENTITY % dtd_${index} SYSTEM "${url}">%dtd_${index};`);
+ }
+ this._locations = locations;
+ this._prefix = aPrefix;
+ }
+
+ // copied from testing/marionette/l10n.js
+ localizeEntity(urls, id) {
+ // Use the DOM parser to resolve the entity and extract its real value
+ let header = `<?xml version="1.0"?><!DOCTYPE elem [${this._locations.join(
+ ""
+ )}]>`;
+ let elem = `<elem id="elementID">&${id};</elem>`;
+ let doc = domParser.parseFromString(header + elem, "text/xml");
+ let element = doc.querySelector("elem[id='elementID']");
+
+ if (element === null) {
+ throw new Error(`Entity with id='${id}' hasn't been found`);
+ }
+
+ return element.textContent;
+ }
+
+ getString(key, fallback) {
+ if (key) {
+ try {
+ return this.localizeEntity(this._bundleURLs, `${this._prefix}${key}`);
+ } catch (e) {}
+ }
+
+ // on failure, assign the fallback if it exists
+ if (fallback) {
+ return fallback;
+ }
+ // otherwise return string key
+ return `$(${key})`;
+ }
+}
+
+/*
+ Security Level Strings
+*/
+var TorStrings = {
+ /*
+ Tor Browser Security Level Strings
+ */
+ securityLevel: (function() {
+ let tsb = new TorStringBundle(
+ ["chrome://torbutton/locale/torbutton.dtd"],
+ "torbutton.prefs.sec_"
+ );
+ let getString = function(key, fallback) {
+ return tsb.getString(key, fallback);
+ };
+
+ // read localized strings from torbutton; but use hard-coded en-US strings as fallbacks in case of error
+ let retval = {
+ securityLevel: getString("caption", "Security Level"),
+ customWarning: getString("custom_warning", "Custom"),
+ overview: getString(
+ "overview",
+ "Disable certain web features that can be used to attack your security and anonymity."
+ ),
+ standard: {
+ level: getString("standard_label", "Standard"),
+ tooltip: getString("standard_tooltip", "Security Level : Standard"),
+ summary: getString(
+ "standard_description",
+ "All Tor Browser and website features are enabled."
+ ),
+ },
+ safer: {
+ level: getString("safer_label", "Safer"),
+ tooltip: getString("safer_tooltip", "Security Level : Safer"),
+ summary: getString(
+ "safer_description",
+ "Disables website features that are often dangerous, causing some sites to lose functionality."
+ ),
+ description1: getString(
+ "js_on_https_sites_only",
+ "JavaScript is disabled on non-HTTPS sites."
+ ),
+ description2: getString(
+ "limit_typography",
+ "Some fonts and math symbols are disabled."
+ ),
+ description3: getString(
+ "click_to_play_media",
+ "Audio and video (HTML5 media), and WebGL are click-to-play."
+ ),
+ },
+ safest: {
+ level: getString("safest_label", "Safest"),
+ tooltip: getString("safest_tooltip", "Security Level : Safest"),
+ summary: getString(
+ "safest_description",
+ "Only allows website features required for static sites and basic services. These changes affect images, media, and scripts."
+ ),
+ description1: getString(
+ "js_disabled",
+ "JavaScript is disabled by default on all sites."
+ ),
+ description2: getString(
+ "limit_graphics_and_typography",
+ "Some fonts, icons, math symbols, and images are disabled."
+ ),
+ description3: getString(
+ "click_to_play_media",
+ "Audio and video (HTML5 media), and WebGL are click-to-play."
+ ),
+ },
+ custom: {
+ summary: getString(
+ "custom_summary",
+ "Your custom browser preferences have resulted in unusual security settings. For security and privacy reasons, we recommend you choose one of the default security levels."
+ ),
+ },
+ learnMore: getString("learn_more_label", "Learn more"),
+ learnMoreURL: `https://tb-manual.torproject.org/${getLocale()}/security-settings/`,
+ restoreDefaults: getString("restore_defaults", "Restore Defaults"),
+ advancedSecuritySettings: getString(
+ "advanced_security_settings",
+ "Advanced Security Settings\u2026"
+ ),
+ };
+ return retval;
+ })() /* Security Level Strings */,
+
+ /*
+ Tor about:preferences#tor Strings
+ */
+ settings: (function() {
+ let tsb = new TorStringBundle(
+ ["chrome://torlauncher/locale/network-settings.dtd"],
+ ""
+ );
+ let getString = function(key, fallback) {
+ return tsb.getString(key, fallback);
+ };
+
+ let retval = {
+ categoryTitle: getString("torPreferences.categoryTitle", "Tor"),
+ torPreferencesHeading: getString(
+ "torPreferences.torSettings",
+ "Tor Settings"
+ ),
+ torPreferencesDescription: getString(
+ "torPreferences.torSettingsDescription",
+ "Tor Browser routes your traffic over the Tor Network, run by thousands of volunteers around the world."
+ ),
+ learnMore: getString("torPreferences.learnMore", "Learn More"),
+ bridgesHeading: getString("torPreferences.bridges", "Bridges"),
+ bridgesDescription: getString(
+ "torPreferences.bridgesDescription",
+ "Bridges help you access the Tor Network in places where Tor is blocked. Depending on where you are, one bridge may work better than another."
+ ),
+ useBridge: getString("torPreferences.useBridge", "Use a bridge"),
+ selectBridge: getString(
+ "torsettings.useBridges.default",
+ "Select a bridge"
+ ),
+ requestBridgeFromTorProject: getString(
+ "torsettings.useBridges.bridgeDB",
+ "Request a bridge from torproject.org"
+ ),
+ requestNewBridge: getString(
+ "torPreferences.requestNewBridge",
+ "Request a New Bridge\u2026"
+ ),
+ provideBridge: getString(
+ "torPreferences.provideBridge",
+ "Provide a bridge"
+ ),
+ provideBridgeDirections: getString(
+ "torsettings.useBridges.label",
+ "Enter bridge information from a trusted source."
+ ),
+ provideBridgePlaceholder: getString(
+ "torsettings.useBridges.placeholder",
+ "type address:port (one per line)"
+ ),
+ advancedHeading: getString("torPreferences.advanced", "Advanced"),
+ advancedDescription: getString(
+ "torPreferences.advancedDescription",
+ "Configure how Tor Browser connects to the internet."
+ ),
+ useLocalProxy: getString("torPreferences.useProxy", "Use a local proxy"),
+ proxyType: getString("torsettings.useProxy.type", "Proxy Type"),
+ proxyTypeSOCKS4: getString("torsettings.useProxy.type.socks4", "SOCKS4"),
+ proxyTypeSOCKS5: getString("torsettings.useProxy.type.socks5", "SOCKS5"),
+ proxyTypeHTTP: getString("torsettings.useProxy.type.http", "HTTP/HTTPS"),
+ proxyAddress: getString("torsettings.useProxy.address", "Address"),
+ proxyAddressPlaceholder: getString(
+ "torsettings.useProxy.address.placeholder",
+ "IP address or hostname"
+ ),
+ proxyPort: getString("torsettings.useProxy.port", "Port"),
+ proxyUsername: getString("torsettings.useProxy.username", "Username"),
+ proxyPassword: getString("torsettings.useProxy.password", "Password"),
+ proxyUsernamePasswordPlaceholder: getString(
+ "torsettings.optional",
+ "Optional"
+ ),
+ useFirewall: getString(
+ "torsettings.firewall.checkbox",
+ "This computer goes through a firewall that only allows connections to certain ports"
+ ),
+ allowedPorts: getString(
+ "torsettings.firewall.allowedPorts",
+ "Allowed Ports"
+ ),
+ allowedPortsPlaceholder: getString(
+ "torPreferences.firewallPortsPlaceholder",
+ "Comma-seperated values"
+ ),
+ requestBridgeDialogTitle: getString(
+ "torPreferences.requestBridgeDialogTitle",
+ "Request Bridge"
+ ),
+ submitCaptcha: getString(
+ "torsettings.useBridges.captchaSubmit",
+ "Submit"
+ ),
+ contactingBridgeDB: getString(
+ "torPreferences.requestBridgeDialogWaitPrompt",
+ "Contacting BridgeDB. Please Wait."
+ ),
+ solveTheCaptcha: getString(
+ "torPreferences.requestBridgeDialogSolvePrompt",
+ "Solve the CAPTCHA to request a bridge."
+ ),
+ captchaTextboxPlaceholder: getString(
+ "torsettings.useBridges.captchaSolution.placeholder",
+ "Enter the characters from the image"
+ ),
+ incorrectCaptcha: getString(
+ "torPreferences.requestBridgeErrorBadSolution",
+ "The solution is not correct. Please try again."
+ ),
+ showTorDaemonLogs: getString(
+ "torPreferences.viewTorLogs",
+ "View the Tor logs."
+ ),
+ showLogs: getString("torPreferences.viewLogs", "View Logs\u2026"),
+ torLogDialogTitle: getString(
+ "torPreferences.torLogsDialogTitle",
+ "Tor Logs"
+ ),
+ copyLog: getString("torsettings.copyLog", "Copy Tor Log to Clipboard"),
+
+ learnMoreTorBrowserURL: `https://tb-manual.torproject.org/${getLocale()}/about/`,
+ learnMoreBridgesURL: `https://tb-manual.torproject.org/${getLocale()}/bridges/`,
+ learnMoreNetworkSettingsURL: `about:blank`,
+ };
+
+ return retval;
+ })() /* Tor Network Settings Strings */,
+
+ /*
+ Tor Deamon Configuration Key Strings
+ */
+
+ // TODO: proper camel case
+ configKeys: {
+ /* Bridge Conf Settings */
+ useBridges: "UseBridges",
+ bridgeList: "Bridge",
+ /* Proxy Conf Strings */
+ socks4Proxy: "Socks4Proxy",
+ socks5Proxy: "Socks5Proxy",
+ socks5ProxyUsername: "Socks5ProxyUsername",
+ socks5ProxyPassword: "Socks5ProxyPassword",
+ httpsProxy: "HTTPSProxy",
+ httpsProxyAuthenticator: "HTTPSProxyAuthenticator",
+ /* Firewall Conf Strings */
+ reachableAddresses: "ReachableAddresses",
+
+ /* BridgeDB Strings */
+ clientTransportPlugin: "ClientTransportPlugin",
+ },
+
+ /*
+ about:config preference keys
+ */
+
+ preferenceKeys: {
+ defaultBridgeType: "extensions.torlauncher.default_bridge_type",
+ recommendedBridgeType:
+ "extensions.torlauncher.default_bridge_recommended_type",
+ },
+
+ /*
+ about:config preference branches
+ */
+ preferenceBranches: {
+ defaultBridge: "extensions.torlauncher.default_bridge.",
+ bridgeDBBridges: "extensions.torlauncher.bridgedb_bridge.",
+ },
+};
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index 304bd34d2ff2..43f1524f4553 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -134,6 +134,7 @@ XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
EXTRA_JS_MODULES += [
'AboutNewTab.jsm',
'AsyncTabSwitcher.jsm',
+ 'BridgeDB.jsm',
'BrowserUsageTelemetry.jsm',
'BrowserWindowTracker.jsm',
'ContentClick.jsm',
@@ -165,6 +166,8 @@ EXTRA_JS_MODULES += [
'TabsList.jsm',
'TabUnloader.jsm',
'ThemeVariableMap.jsm',
+ 'TorProtocolService.jsm',
+ 'TorStrings.jsm',
'TransientPrefs.jsm',
'webrtcUI.jsm',
'ZoomUI.jsm',
1
0
[translation/donatepages-messagespot_completed] https://gitweb.torproject.org/translation.git/commit/?h=donatepages-messagespot_completed
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit eb36ba92a7d11ec21020ea0567439752d9bcecce
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 12:45:47 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=donatepages-message…
---
locale/es/LC_MESSAGES/messages.po | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/locale/es/LC_MESSAGES/messages.po b/locale/es/LC_MESSAGES/messages.po
index c643a4e17..ff3be0f41 100644
--- a/locale/es/LC_MESSAGES/messages.po
+++ b/locale/es/LC_MESSAGES/messages.po
@@ -199,20 +199,20 @@ msgstr ""
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:178
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:91
msgid "Currency Amount"
-msgstr ""
+msgstr "Monto"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:180
msgid "Estimated Donation Date"
-msgstr ""
+msgstr "Fecha estimada de la donación."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:184
msgid "I'd like to make my donation anonymous."
-msgstr ""
+msgstr "Me gustaría hacer una donación anónima."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:188
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:64
msgid "Email"
-msgstr ""
+msgstr "Correo electrónico"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:192
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:342
@@ -229,7 +229,7 @@ msgstr "Apellidos"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:200
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:98
msgid "Report Donation"
-msgstr ""
+msgstr "Reportar Donación"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:204
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:392
@@ -240,7 +240,7 @@ msgstr ""
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:208
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:105
msgid "Wallet Addresses"
-msgstr ""
+msgstr "Direcciones de Cartera"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:212
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:333
@@ -479,7 +479,7 @@ msgstr "mensualmente"
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:167
msgid "Want to donate cryptocurrency?"
-msgstr ""
+msgstr "¿Quieres donar criptomoneda?"
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:172
msgid "Want to donate stock or via postal mail?"
@@ -654,7 +654,7 @@ msgstr "Donar"
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:479
msgid "State/Province/Region"
-msgstr ""
+msgstr "Estado/Provincia/Región"
#: tmp/cache_locale/af/af919ed4d7946ee7ed7d71a5580f4c75c5fb2b9374dd8d99d3a0671f71654f60.php:483
msgid "Gift Selected"
@@ -757,6 +757,7 @@ msgstr ""
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:101
msgid "Together, we will stand up for the universal right to privacy."
msgstr ""
+"Juntos, nos alzaremos en favor del derecho universal a la privacidad. "
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:103
msgid ""
@@ -2037,11 +2038,11 @@ msgstr ""
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:53
msgid "Subscribed | Tor"
-msgstr ""
+msgstr "Suscrito | Tor"
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:64
msgid "Subscription Confirmed!"
-msgstr ""
+msgstr "Suscripción confirmada! "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:78
msgid "Thanks for joining our email list - you'll hear from us soon!"
@@ -2063,15 +2064,15 @@ msgstr ""
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:86
msgid "Every little bit helps"
-msgstr ""
+msgstr "Cada pequeña aportación ayuda. "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:88
msgid "please donate today"
-msgstr ""
+msgstr "por favor dona hoy."
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:92
msgid "Donate Now"
-msgstr ""
+msgstr "Dona Ahora"
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:53
#: tmp/cache_locale/12/12677df2d2a5991edb775c6909b7be7ca718fd00abd6950a809cda5ab878d2ce.php:53
1
0
[translation/donatepages-messagespot] https://gitweb.torproject.org/translation.git/commit/?h=donatepages-messagespot
by translation@torproject.org 12 Oct '19
by translation@torproject.org 12 Oct '19
12 Oct '19
commit e9411abe07b5a688daeaf98f8560fb01a5977dc8
Author: Translation commit bot <translation(a)torproject.org>
Date: Sat Oct 12 12:45:40 2019 +0000
https://gitweb.torproject.org/translation.git/commit/?h=donatepages-message…
---
locale/es/LC_MESSAGES/messages.po | 57 +++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 29 deletions(-)
diff --git a/locale/es/LC_MESSAGES/messages.po b/locale/es/LC_MESSAGES/messages.po
index b08b92972..043c7d139 100644
--- a/locale/es/LC_MESSAGES/messages.po
+++ b/locale/es/LC_MESSAGES/messages.po
@@ -157,8 +157,8 @@ msgid ""
"know your communication preferences."
msgstr ""
"Completar este formulario no es necesario, pero al hacerlo seremos "
-"notificados rápidamente acerca de su donación, permitiéndonos enviarle un "
-"reconocimiento, y haciéndonos conocer sus preferencias de comunicación."
+"notificados rápidamente acerca de tu donación, permitiéndonos enviarte un "
+"reconocimiento, y conocer tus preferencias de comunicación."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:141
msgid ""
@@ -179,8 +179,8 @@ msgid ""
"Please make sure to copy the wallet addresses exactly when making your "
"donation, as we cannot recover funds sent to the wrong wallet."
msgstr ""
-"Por favor asegúrese de copiar las direcciones de las carteras exactamente al"
-" hacer su donación, ya que no podemos recuperar fondos enviados a una "
+"Por favor asegúrate de copiar las direcciones de las carteras exactamente al"
+" hacer tu donación, ya que no podemos recuperar fondos enviados a una "
"cartera errónea."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:151
@@ -188,8 +188,9 @@ msgid ""
"If you have any questions, or would like to donate a cryptocurrency not "
"listed below, please email us at giving(a)torproject.org."
msgstr ""
-"Si tiene cualquier pregunta, o le gustaría donar una criptomoneda no listada"
-" abajo, por favor envíenos un correo electrónico a giving(a)torproject.org."
+"Si tienes cualquier pregunta, o te gustaría donar una criptomoneda no "
+"listada abajo, por favor envíanos un correo electrónico a "
+"giving(a)torproject.org."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:166
msgid "Copied"
@@ -202,7 +203,7 @@ msgstr "La cantidad monetaria debe ser una cifra."
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:174
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:69
msgid "Choose a Currency"
-msgstr "Elija una Moneda"
+msgstr "Elige una Moneda"
#: tmp/cache_locale/cc/cc2e1dd4edb96c59a6514d676ca3f562a2a9a2cd34e2c211c03fb08b3e664469.php:178
#: tmp/cache_locale/a1/a1384b9a21e3d43e946972b01389567dff845ee982dcf05228aa3e5096a74210.php:91
@@ -736,14 +737,14 @@ msgstr "Fecha Estimada de Donación:"
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:83
msgid "Become a Defender of Privacy!"
-msgstr "Conviértase en un defensor de la privacidad."
+msgstr "Conviértete en un defensor de la privacidad."
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:87
msgid ""
"Join the Tor Project - Defenders of Privacy program - a monthly giving "
"circle designed to honor donors that make privacy a priority."
msgstr ""
-"Únase al programa de defensores de la privacidad de Tor Project, un programa"
+"Únete al programa de defensores de la privacidad de Tor Project, un programa"
" mensual diseñado para honrar a los donantes que hacen de la privacidad una "
"prioridad. "
@@ -755,7 +756,7 @@ msgid ""
msgstr ""
"Los defensores de la privacidad comprometen una modesta cantidad de dinero "
"mensualmente, creando una fuente de ingresos estable y fiable para ayudar a "
-"agilizarnos. Cambie el panorama de la privacidad y le enviaremos regalos "
+"agilizarnos. Cambia el panorama de la privacidad y le enviaremos regalos "
"exclusivos para mostrarle nuestro agradecimiento. "
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:95
@@ -764,13 +765,13 @@ msgid ""
"continue our mission to provide tools that protect people's privacy and "
"identity online."
msgstr ""
-"Tor Project cuenta con el soporte de nuestros defensores de la privacidad "
+"Tor Project cuenta con el soporte de nuestros Defensores de la Privacidad "
"para continuar nuestra misión de proveer herramientas que protejan la "
"privacidad de las personas y la identidad en línea."
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:97
msgid "With your help, we will make the Tor network accessible to everyone!"
-msgstr "Con su ayuda, podemos hacer accesible la red Tor para todo el mundo. "
+msgstr "Con tu ayuda, podemos hacer accesible la red Tor para todo el mundo. "
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:101
msgid "Together, we will stand up for the universal right to privacy."
@@ -782,12 +783,12 @@ msgid ""
"Please make your monthly donation now and stand with the Tor Project at this"
" critical time."
msgstr ""
-"Por favor haga ahora su donación mensual y apoye a Tor Project en estos "
+"Por favor haz ahora su donación mensual y apoya a Tor Project en estos "
"críticos momentos. "
#: tmp/cache_locale/94/94c6c1969d2fadbd23c135ac864b97902daca8f5c816b03864ea5c4970a167cf.php:109
msgid "Want to make a one time donation instead?"
-msgstr "En su lugar, ¿quiere hacer una donación por única vez?"
+msgstr "En su lugar, ¿quieres hacer una donación una única vez?"
#: tmp/cache_locale/92/92eb639bc328f3dd569fa22b60c4360b6fe38f1a4cd80a14fce862d91bd765cb.php:43
msgid ""
@@ -2067,7 +2068,7 @@ msgstr "Suscripción confirmada! "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:78
msgid "Thanks for joining our email list - you'll hear from us soon!"
msgstr ""
-"Gracias por unirse a nuestra lista de email. Pronto contactaremos con usted."
+"Gracias por unirte a nuestra lista de email. Pronto contactaremos con usted."
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:80
msgid ""
@@ -2075,9 +2076,9 @@ msgid ""
"href=\"https://twitter.com/torproject\">@TorProject</a> on Twitter to keep "
"in touch."
msgstr ""
-"Mientras tanto, siga <a target=\"_blank\" "
+"Mientras tanto, sigue <a target=\"_blank\" "
"href=\"https://twitter.com/torproject\">@TorProject en Twitter</a> para "
-"mantenerse en contacto. "
+"mantenerte en contacto. "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:84
msgid ""
@@ -2086,9 +2087,9 @@ msgid ""
" browse, communicate, and express themselves online privately."
msgstr ""
"Como organización sin ánimo de lucro, confiamos en las contribuciones de "
-"personas como usted para ayudarnos a crear y mantener tecnología utilizada "
-"por millones de usuarios diariamente para navegar, comunicarse y expresarse "
-"de forma privada en línea. "
+"personas como tú para ayudarnos a crear y mantener tecnología utilizada por "
+"millones de usuarios diariamente para navegar, comunicarse y expresarse de "
+"forma privada en línea. "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:86
msgid "Every little bit helps"
@@ -2096,7 +2097,7 @@ msgstr "Cada pequeña aportación ayuda. "
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:88
msgid "please donate today"
-msgstr "Por favor dona hoy."
+msgstr "por favor dona hoy."
#: tmp/cache_locale/6c/6cd01cfbd4684dcca4eada963c78b5d694a2f40cd309be9366b080c410b3c5a0.php:92
msgid "Donate Now"
@@ -2138,14 +2139,14 @@ msgstr ""
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:81
msgid "Thank you for standing up for privacy and freedom online."
-msgstr "Gracias por su apoyo a la privacidad y libertad en línea."
+msgstr "Gracias por tu apoyo a la privacidad y libertad en línea."
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:83
msgid ""
"With your gift of cryptocurrency, you're helping the Tor Project give "
"millions of people private access to the open web."
msgstr ""
-"Con su regalo de criptomoneda, está ayudando al Proyecto Tor a dar acceso "
+"Con tu regalo de criptomoneda, estás ayudando al Proyecto Tor a dar acceso "
"privado a millones de personas a la web abierta."
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:85
@@ -2153,22 +2154,20 @@ msgid ""
"Your contribution helps make Tor an even stronger tool against authoritarian"
" governments and privacy-invading corporations."
msgstr ""
-"Su contribución ayuda a hacer de Tor una herramienta aún más potente en "
+"Tu contribución ayuda a hacer de Tor una herramienta aún más potente en "
"contra de gobiernos autoritarios y corporaciones invasoras de la privacidad."
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:91
msgid "For your convenience, our wallet addresses are listed below."
-msgstr ""
-"Por su conveniencia, nuestras direcciones de carteras están listadas abajo."
+msgstr "Por comodidad nuestras direcciones de cartera están listadas abajo."
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:93
msgid ""
"Please make sure to copy the wallet addresses exactly when making your "
"donation, as we are unable to recover funds sent to the wrong wallet."
msgstr ""
-"Por favor asegúrese de copiar las direcciones de las carteras exactamente al"
-" hacer su donación, ya que no somos capaces de recuperar fondos enviados a "
-"una cartera errónea."
+"Asegúrate de copiar las direcciones de las carteras exactamente al hacer tu "
+"donación, ya que no podemos recuperar fondos enviados a una cartera errónea."
#: tmp/cache_locale/60/60fb10a60dd92fe380a6d105fd68d9375e135c65251f204fa37158d9c2e655d9.php:97
#: tmp/cache_locale/12/12677df2d2a5991edb775c6909b7be7ca718fd00abd6950a809cda5ab878d2ce.php:97
1
0
commit a1fe61ca5e14e166617c516f2af449b043a3ef1c
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Oct 12 12:09:12 2019 +0000
Translations update
---
chrome/locale/ar/browserOnboarding.properties | 2 +-
chrome/locale/bn-BD/browserOnboarding.properties | 2 +-
chrome/locale/ca/browserOnboarding.properties | 2 +-
chrome/locale/cs/browserOnboarding.properties | 2 +-
chrome/locale/da/browserOnboarding.properties | 2 +-
chrome/locale/de/browserOnboarding.properties | 2 +-
chrome/locale/el/browserOnboarding.properties | 2 +-
chrome/locale/es-AR/browserOnboarding.properties | 2 +-
chrome/locale/eu/browserOnboarding.properties | 2 +-
chrome/locale/fa/browserOnboarding.properties | 2 +-
chrome/locale/fr/browserOnboarding.properties | 8 ++++----
chrome/locale/ga-IE/browserOnboarding.properties | 2 +-
chrome/locale/he/browserOnboarding.properties | 12 ++++++------
chrome/locale/hu/browserOnboarding.properties | 2 +-
chrome/locale/id/browserOnboarding.properties | 2 +-
chrome/locale/is/browserOnboarding.properties | 2 +-
chrome/locale/it/browserOnboarding.properties | 2 +-
chrome/locale/ja/browserOnboarding.properties | 4 ++--
chrome/locale/ja/torbutton.properties | 6 +++---
chrome/locale/ka/browserOnboarding.properties | 2 +-
chrome/locale/ko/browserOnboarding.properties | 2 +-
chrome/locale/mk/browserOnboarding.properties | 12 ++++++------
chrome/locale/nb-NO/browserOnboarding.properties | 8 ++++----
chrome/locale/nl/browserOnboarding.properties | 12 ++++++------
chrome/locale/pl/browserOnboarding.properties | 2 +-
chrome/locale/pt-BR/browserOnboarding.properties | 12 ++++++------
chrome/locale/ro/browserOnboarding.properties | 2 +-
chrome/locale/ru/browserOnboarding.properties | 2 +-
chrome/locale/sv-SE/browserOnboarding.properties | 2 +-
chrome/locale/tr/browserOnboarding.properties | 12 ++++++------
chrome/locale/tr/torbutton.properties | 2 +-
chrome/locale/vi/browserOnboarding.properties | 2 +-
chrome/locale/zh-CN/browserOnboarding.properties | 12 ++++++------
chrome/locale/zh-TW/browserOnboarding.properties | 2 +-
34 files changed, 73 insertions(+), 73 deletions(-)
diff --git a/chrome/locale/ar/browserOnboarding.properties b/chrome/locale/ar/browserOnboarding.properties
index 33aaf5d2..4366f4d4 100644
--- a/chrome/locale/ar/browserOnboarding.properties
+++ b/chrome/locale/ar/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=تحديث
onboarding.tour-tor-toolbar=شريط الأدوات
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=اذهب الى شبكة تور
diff --git a/chrome/locale/bn-BD/browserOnboarding.properties b/chrome/locale/bn-BD/browserOnboarding.properties
index 1b6aa316..9513be00 100644
--- a/chrome/locale/bn-BD/browserOnboarding.properties
+++ b/chrome/locale/bn-BD/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Updated
onboarding.tour-tor-toolbar=Toolbar
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=টর নেটওয়ার্কে যান
diff --git a/chrome/locale/ca/browserOnboarding.properties b/chrome/locale/ca/browserOnboarding.properties
index 247260b3..b3125ed0 100644
--- a/chrome/locale/ca/browserOnboarding.properties
+++ b/chrome/locale/ca/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Actualitzat
onboarding.tour-tor-toolbar=Barra d'eines
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Aneu a la Xarxa Tor
diff --git a/chrome/locale/cs/browserOnboarding.properties b/chrome/locale/cs/browserOnboarding.properties
index 8f6d6e86..de61ab4e 100644
--- a/chrome/locale/cs/browserOnboarding.properties
+++ b/chrome/locale/cs/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Aktualizováno
onboarding.tour-tor-toolbar=Panel nástrojů
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Přejít na síť Tor
diff --git a/chrome/locale/da/browserOnboarding.properties b/chrome/locale/da/browserOnboarding.properties
index 3993caf5..0b6f4ddc 100644
--- a/chrome/locale/da/browserOnboarding.properties
+++ b/chrome/locale/da/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Opdateret
onboarding.tour-tor-toolbar=Værktøjslinje
onboarding.tour-tor-toolbar-update-9.0.title=Farvel Onion-knap.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=Forespørg en ny identitet
onboarding.tour-tor-toolbar-update-9.0.next-button=Gå til Tor-netværk
diff --git a/chrome/locale/de/browserOnboarding.properties b/chrome/locale/de/browserOnboarding.properties
index b6750198..9eea6582 100644
--- a/chrome/locale/de/browserOnboarding.properties
+++ b/chrome/locale/de/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Aktualisiert
onboarding.tour-tor-toolbar=Symbolleiste
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Öffne Tor-Netzwerk
diff --git a/chrome/locale/el/browserOnboarding.properties b/chrome/locale/el/browserOnboarding.properties
index 1f061edc..d76aebc3 100644
--- a/chrome/locale/el/browserOnboarding.properties
+++ b/chrome/locale/el/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Αναβαθμίστηκε
onboarding.tour-tor-toolbar=Γραμμή εργαλείων
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Πηγαίντε στο Δίκτυο Tor
diff --git a/chrome/locale/es-AR/browserOnboarding.properties b/chrome/locale/es-AR/browserOnboarding.properties
index cc8931f8..b3d531b7 100644
--- a/chrome/locale/es-AR/browserOnboarding.properties
+++ b/chrome/locale/es-AR/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Actualizado
onboarding.tour-tor-toolbar=Barra de herramientas
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Ir a la red Tor
diff --git a/chrome/locale/eu/browserOnboarding.properties b/chrome/locale/eu/browserOnboarding.properties
index 35289c49..e9103eaf 100644
--- a/chrome/locale/eu/browserOnboarding.properties
+++ b/chrome/locale/eu/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Eguneratua
onboarding.tour-tor-toolbar=Tresna-barra
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Joan Tor sarera
diff --git a/chrome/locale/fa/browserOnboarding.properties b/chrome/locale/fa/browserOnboarding.properties
index 8926015e..4d25d226 100644
--- a/chrome/locale/fa/browserOnboarding.properties
+++ b/chrome/locale/fa/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=بهروزرسانی شد
onboarding.tour-tor-toolbar=نوار ابزار
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=برو به شبکه تور
diff --git a/chrome/locale/fr/browserOnboarding.properties b/chrome/locale/fr/browserOnboarding.properties
index 01065625..8e1019c3 100644
--- a/chrome/locale/fr/browserOnboarding.properties
+++ b/chrome/locale/fr/browserOnboarding.properties
@@ -15,7 +15,7 @@ onboarding.tour-tor-privacy.button=Poursuivre vers Réseau Tor
onboarding.tour-tor-network=Réseau Tor
onboarding.tour-tor-network.title=Naviguez sur un réseau décentralisé.
onboarding.tour-tor-network.description=Le Navigateur Tor vous connecte au réseau Tor exploité par des milliers de bénévoles dans le monde entier. Contrairement à un RPV, il n’y a pas de point de défaillance unique ou d’entité centralisée auxquels vous devez faire confiance pour profiter d’Internet en toute confidentialité.
-onboarding.tour-tor-network.description-para2=NOUVEAU : paramètres du réseau Tor, dont la possibilité de demander des ponts où Tor est bloqué, se trouvent maintenant dans Préférences.
+onboarding.tour-tor-network.description-para2=NOUVEAU : Paramètres du réseau Tor, dont la possibilité de demander des ponts où Tor est bloqué, se trouvent maintenant dans Préférences.
onboarding.tour-tor-network.action-button=Réglez vos paramètres du réseau Tor
onboarding.tour-tor-network.button=Poursuivre vers Affichage des circuits
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Nouveau
onboarding.tour-tor-update.prefix-updated=Mis à jour
onboarding.tour-tor-toolbar=Barre d’outils
-onboarding.tour-tor-toolbar-update-9.0.title=Au revoir le bouton oignon.
+onboarding.tour-tor-toolbar-update-9.0.title=Adieu au bouton oignon.
onboarding.tour-tor-toolbar-update-9.0.description=Nous voulons que votre expérience d’utilisation de Tor soit entièrement intégrée au Navigateur Tor.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.description-para2=C’est pourquoi désormais, au lieu d’utiliser le bouton oignon, vous pouvez voir votre circuit Tor par le [i] de la barre d’URL et demander une nouvelle identité en utilisant le bouton de la barre d’outils ou le menu [≡] .
+onboarding.tour-tor-toolbar-update-9.0.button=Comment demander une nouvelle identité
onboarding.tour-tor-toolbar-update-9.0.next-button=Poursuivre vers Réseau Tor
# Circuit Display onboarding.
diff --git a/chrome/locale/ga-IE/browserOnboarding.properties b/chrome/locale/ga-IE/browserOnboarding.properties
index 6ec36431..754e6467 100644
--- a/chrome/locale/ga-IE/browserOnboarding.properties
+++ b/chrome/locale/ga-IE/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Nuashonraithe
onboarding.tour-tor-toolbar=Barra Uirlisí
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Téigh go Líonra Tor
diff --git a/chrome/locale/he/browserOnboarding.properties b/chrome/locale/he/browserOnboarding.properties
index 3da89d1a..d9a89e69 100644
--- a/chrome/locale/he/browserOnboarding.properties
+++ b/chrome/locale/he/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=לך אל רשת Tor
onboarding.tour-tor-network=רשת Tor
onboarding.tour-tor-network.title=טייל ברשת מבוזרת.
onboarding.tour-tor-network.description=דפדפן Tor מחבר אותך אל רשת Tor המופעלת ע"י אלפי מתנדבים ברחבי העולם. בשונה מאשר VPN, אין נקודת כשל בודדת או כניסה ממורכזת שאתה צריך לסמוך עליה על מנת ליהנות מהאינטרנט באופן פרטי.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=חדש: הגדרות רשת Tor, כולל היכולת לבקש גשרים במקום שבו Tor חסום, יכולות להימצא בהעדפות.
+onboarding.tour-tor-network.action-button=התאם את הגדרות רשת Tor שלך
onboarding.tour-tor-network.button=לך אל תצוגת מעגל
onboarding.tour-tor-circuit-display=תצוגת מעגל
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=חדש
onboarding.tour-tor-update.prefix-updated=מעודכן
onboarding.tour-tor-toolbar=סרגל כלים
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=להתראות כפתור בצל.
+onboarding.tour-tor-toolbar-update-9.0.description=אנחנו רוצים את החוויה של שימוש ב־Tor שלך שתהיה משולבת במלואה בתוך דפדפן Tor.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=זאת הסיבה מדוע כעת, ללא שימוש בכפתור הבצל, אתה יכול לראות את מעגל Tor שלך דרך [i] בשורת הכתובת ולבקש זהות חדשה ע"י שימוש בכפתור סרגל הכלים או בתפריט [≡].
+onboarding.tour-tor-toolbar-update-9.0.button=איך לבקש זהות חדשה
onboarding.tour-tor-toolbar-update-9.0.next-button=לך אל רשת Tor
# Circuit Display onboarding.
diff --git a/chrome/locale/hu/browserOnboarding.properties b/chrome/locale/hu/browserOnboarding.properties
index 3eafe389..cbb31d72 100644
--- a/chrome/locale/hu/browserOnboarding.properties
+++ b/chrome/locale/hu/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Frissített
onboarding.tour-tor-toolbar=Toolbar
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Irány a Tor Hálózat
diff --git a/chrome/locale/id/browserOnboarding.properties b/chrome/locale/id/browserOnboarding.properties
index 217ad01c..958fba00 100644
--- a/chrome/locale/id/browserOnboarding.properties
+++ b/chrome/locale/id/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Telah terupdate
onboarding.tour-tor-toolbar=Toolbar
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Pergi ke Jaringan Tor
diff --git a/chrome/locale/is/browserOnboarding.properties b/chrome/locale/is/browserOnboarding.properties
index 81980cb1..656b8ae5 100644
--- a/chrome/locale/is/browserOnboarding.properties
+++ b/chrome/locale/is/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Uppfært
onboarding.tour-tor-toolbar=Verkfærastika
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Fara á Tor-netið
diff --git a/chrome/locale/it/browserOnboarding.properties b/chrome/locale/it/browserOnboarding.properties
index b24127ce..95633f21 100644
--- a/chrome/locale/it/browserOnboarding.properties
+++ b/chrome/locale/it/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Aggiornato
onboarding.tour-tor-toolbar=Barra degli strumenti
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Vai alla rete Tor
diff --git a/chrome/locale/ja/browserOnboarding.properties b/chrome/locale/ja/browserOnboarding.properties
index 64f1baea..e1241ee5 100644
--- a/chrome/locale/ja/browserOnboarding.properties
+++ b/chrome/locale/ja/browserOnboarding.properties
@@ -44,14 +44,14 @@ onboarding.tour-tor-onion-services.description=Onion サービスは、検閲に
onboarding.tour-tor-onion-services.button=Onion サイトを訪問
onboarding.tour-tor-onion-services.next-button=完了
-onboarding.overlay-icon-tooltip-updated2=最新情報\n%S に
+onboarding.overlay-icon-tooltip-updated2=%S の\n変更点をご紹介します
onboarding.tour-tor-update.prefix-new=新機能
onboarding.tour-tor-update.prefix-updated=更新
onboarding.tour-tor-toolbar=ツールバー
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Tor ネットワークへ
diff --git a/chrome/locale/ja/torbutton.properties b/chrome/locale/ja/torbutton.properties
index b30ecc3c..a03e2d7b 100644
--- a/chrome/locale/ja/torbutton.properties
+++ b/chrome/locale/ja/torbutton.properties
@@ -7,7 +7,7 @@ torbutton.circuit_display.tor_bridge = ブリッジ
torbutton.circuit_display.unknown_country = 不明な国
torbutton.circuit_display.guard = ガード
torbutton.circuit_display.guard_note = [ガード] ノードは変更されない場合があります。
-torbutton.circuit_display.learn_more = さらに知る
+torbutton.circuit_display.learn_more = 詳細情報
torbutton.content_sizer.margin_tooltip = Tor Browser はウィンドウのサイズを平凡にするためにこのマージンを追加します。これにより、あなたのことをオンラインで追跡しにくくします。
torbutton.panel.tooltip.disabled = クリックしてTorを有効にする
torbutton.panel.tooltip.enabled = クリックしてTorを無効にする
@@ -56,5 +56,5 @@ profileMigrationFailed=存在しているプロファイル %S へのマイグ
updateDownloadingPanelUILabel=%S 更新をダウンロードしています
# .Onion Page Info prompt. Strings are kept here for ease of translation.
-pageInfo_OnionEncryptionWithBitsAndProtocol=接続が暗号化されています (Onionサービス、%1$S、鍵長 %2$S bit、%3$S)
-pageInfo_OnionEncryption=接続が暗号化されています (Onionサービス)
+pageInfo_OnionEncryptionWithBitsAndProtocol=接続が暗号化されています (Onion サービス、%1$S、鍵長 %2$S bit、%3$S)
+pageInfo_OnionEncryption=接続が暗号化されています (Onion サービス)
diff --git a/chrome/locale/ka/browserOnboarding.properties b/chrome/locale/ka/browserOnboarding.properties
index 11c88645..11832796 100644
--- a/chrome/locale/ka/browserOnboarding.properties
+++ b/chrome/locale/ka/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=განახლებული
onboarding.tour-tor-toolbar=ხელსაწყოთა ზოლი
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=იხილეთ Tor-ქსელი
diff --git a/chrome/locale/ko/browserOnboarding.properties b/chrome/locale/ko/browserOnboarding.properties
index 732ea8ab..ed818936 100644
--- a/chrome/locale/ko/browserOnboarding.properties
+++ b/chrome/locale/ko/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=업데이트됨
onboarding.tour-tor-toolbar=툴바
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Tor 네트워크 항목으로 가봅니다.
diff --git a/chrome/locale/mk/browserOnboarding.properties b/chrome/locale/mk/browserOnboarding.properties
index c0247407..08935029 100644
--- a/chrome/locale/mk/browserOnboarding.properties
+++ b/chrome/locale/mk/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=Оди на Tor Мрежа
onboarding.tour-tor-network=Tor Мрежа
onboarding.tour-tor-network.title=Патувајте низ децентрализираната мрежа.
onboarding.tour-tor-network.description=Tor Browser ве поврзува на Tor мрежата одржувана од илјадници волонтери низ целиот свет. За разлика од VPN, овде нема место за неуспех или централизиран ентитет на кого треба да му верувате со цел да уживате приватност на Интернет.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=НОВО: Tor Мрежните поставувања, вклучуваат можност да побараат мостови таму каде Tor е блокиран, сега можат да бидат пронајдени во Својства.
+onboarding.tour-tor-network.action-button=Прилагоди ги твоите Мрежни поставки
onboarding.tour-tor-network.button=Оди на Круг екранот
onboarding.tour-tor-circuit-display=Круг екран
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Ново
onboarding.tour-tor-update.prefix-updated=Ажурирано
onboarding.tour-tor-toolbar=Лента со алатки
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=Збогум Онион копче.
+onboarding.tour-tor-toolbar-update-9.0.description=Сакаме вашето искуство користејќи го Tor да биде целосно вградено во Tor Browser.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=Затоа сега, наместо да го користите онион копчето, можете да го видите вашиот Tor Круг преку [i] во URL лентата и да побарате Нов Идентитет користејќи го копчето во алатникот или [≡] менито.
+onboarding.tour-tor-toolbar-update-9.0.button=Како да побарате Нов Идентитет
onboarding.tour-tor-toolbar-update-9.0.next-button=Оди на Tor Мрежа
# Circuit Display onboarding.
diff --git a/chrome/locale/nb-NO/browserOnboarding.properties b/chrome/locale/nb-NO/browserOnboarding.properties
index 89bfd8e9..a444b823 100644
--- a/chrome/locale/nb-NO/browserOnboarding.properties
+++ b/chrome/locale/nb-NO/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=Gå til Tor Nettverk
onboarding.tour-tor-network=Tor Nettverk
onboarding.tour-tor-network.title=Reis et decentralisert nettverk.
onboarding.tour-tor-network.description=Tor Nettleser forbinder deg med Tor-nettet som drives av tusenvis av frivillige rundt om i verden. I motsetning til en VPN er det ingen feilpunkt eller sentralisert enhet du må stole på for å kunne nyte Internettet privat.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=NYTT: Tor nettverksinnstillinger, inkluderer muligheten til å be om broer der Tor er blokkert, kan nå finnes i Innstillinger.
+onboarding.tour-tor-network.action-button=Juster din Tor-nettverksinnstillinger
onboarding.tour-tor-network.button=Gå til Kretsvisning
onboarding.tour-tor-circuit-display=Kretsvisning
@@ -51,8 +51,8 @@ onboarding.tour-tor-update.prefix-updated=Oppdatert
onboarding.tour-tor-toolbar=Verktøylinje
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
+onboarding.tour-tor-toolbar-update-9.0.button=Hvordan be om en Ny identitet
onboarding.tour-tor-toolbar-update-9.0.next-button=Gå til Tor Nettverk
# Circuit Display onboarding.
diff --git a/chrome/locale/nl/browserOnboarding.properties b/chrome/locale/nl/browserOnboarding.properties
index 84ab0176..f109d951 100644
--- a/chrome/locale/nl/browserOnboarding.properties
+++ b/chrome/locale/nl/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=Naar Tor-netwerk
onboarding.tour-tor-network=Tor-netwerk
onboarding.tour-tor-network.title=Reis over een gedecentraliseerd netwerk.
onboarding.tour-tor-network.description=Tor Browser verbindt u met het Tor-netwerk, mogelijk gemaakt door duizenden vrijwilligers over de hele wereld. Anders dan bij een VPN is er geen sprake van één zwakke plek of centrale autoriteit die u moet vertrouwen om privé van het internet gebruik te maken.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=NIEUW: de Tor-netwerkinstellingen, waaronder de mogelijkheid om bridges aan te vragen waar Tor is geblokkeerd, zijn nu te vinden in Voorkeuren.
+onboarding.tour-tor-network.action-button=Uw Tor-netwerkinstellingen aanpassen
onboarding.tour-tor-network.button=Naar Circuit-venster
onboarding.tour-tor-circuit-display=Circuit-venster
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Nieuw
onboarding.tour-tor-update.prefix-updated=Bijgewerkt
onboarding.tour-tor-toolbar=Werkbalk
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=Vaarwel Onion-knop.
+onboarding.tour-tor-toolbar-update-9.0.description=We willen dat uw ervaring met Tor volledig is geïntegreerd binnen Tor Browser.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=Dat is waarom u nu, in plaats van de onion-knop te gebruiken, uw Tor-circuit via de [i] in de URL-balk kunt zien en een nieuwe identiteit kunt aanvragen via de werkbalkknop of het menu [≡].
+onboarding.tour-tor-toolbar-update-9.0.button=Een nieuwe identiteit aanvragen
onboarding.tour-tor-toolbar-update-9.0.next-button=Naar Tor-netwerk
# Circuit Display onboarding.
diff --git a/chrome/locale/pl/browserOnboarding.properties b/chrome/locale/pl/browserOnboarding.properties
index e0591437..e9ae1d69 100644
--- a/chrome/locale/pl/browserOnboarding.properties
+++ b/chrome/locale/pl/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Zaktualizowano
onboarding.tour-tor-toolbar=Pasek narzędzi
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Przejdź do Sieci Tor
diff --git a/chrome/locale/pt-BR/browserOnboarding.properties b/chrome/locale/pt-BR/browserOnboarding.properties
index 11f2240e..dfe66c08 100644
--- a/chrome/locale/pt-BR/browserOnboarding.properties
+++ b/chrome/locale/pt-BR/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=Vá para a Rede Tor.
onboarding.tour-tor-network=Rede Tor
onboarding.tour-tor-network.title=Viaje por uma rede descentralizada.
onboarding.tour-tor-network.description=O Tor Browser conecta você à rede Tor, composta por milhares de voluntários ao redor do mundo. Diferente de uma VPN, não há uma entidade ou ponto de falha central em que você precisa confiar para desfrutar da internet com privacidade.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=NOVO: As configurações de rede do Tor, incluindo a capacidade de solicitar pontes onde o Tor está bloqueado, agora podem ser encontradas em Preferências.
+onboarding.tour-tor-network.action-button=Ajuste suas configurações de rede do Tor
onboarding.tour-tor-network.button=Vá para a Exibição de Circuitos
onboarding.tour-tor-circuit-display=Exibição de Circuitos
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Novo
onboarding.tour-tor-update.prefix-updated=Atualizado
onboarding.tour-tor-toolbar=Barra de ferramentas
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=Adeus Onion Botão.
+onboarding.tour-tor-toolbar-update-9.0.description=Queremos que sua experiência com o Tor seja totalmente integrada ao Tor Browser.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=É por isso que agora, em vez de usar o onion botão, você pode ver o seu Tor Circuit através do [i] na barra de URL e solicitar uma nova identidade usando o botão da barra de ferramentas ou o menu [≡].
+onboarding.tour-tor-toolbar-update-9.0.button=Como solicitar uma nova identidade
onboarding.tour-tor-toolbar-update-9.0.next-button=Vá para a Rede Tor.
# Circuit Display onboarding.
diff --git a/chrome/locale/ro/browserOnboarding.properties b/chrome/locale/ro/browserOnboarding.properties
index c76a29e0..27989597 100644
--- a/chrome/locale/ro/browserOnboarding.properties
+++ b/chrome/locale/ro/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Actualizat
onboarding.tour-tor-toolbar=Bara cu instrumente
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Sari la Rețeaua Tor
diff --git a/chrome/locale/ru/browserOnboarding.properties b/chrome/locale/ru/browserOnboarding.properties
index 45cb0a8d..baba509f 100644
--- a/chrome/locale/ru/browserOnboarding.properties
+++ b/chrome/locale/ru/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Обновленный
onboarding.tour-tor-toolbar=Панель инструментов
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Перейти в Сеть Tor
diff --git a/chrome/locale/sv-SE/browserOnboarding.properties b/chrome/locale/sv-SE/browserOnboarding.properties
index 06b41901..21001db9 100644
--- a/chrome/locale/sv-SE/browserOnboarding.properties
+++ b/chrome/locale/sv-SE/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Uppdaterad
onboarding.tour-tor-toolbar=Verktygsfält
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Gå till Tor-nätverket
diff --git a/chrome/locale/tr/browserOnboarding.properties b/chrome/locale/tr/browserOnboarding.properties
index 0b50cf36..b5e9b49f 100644
--- a/chrome/locale/tr/browserOnboarding.properties
+++ b/chrome/locale/tr/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=Tor Ağına Geç
onboarding.tour-tor-network=Tor Ağı
onboarding.tour-tor-network.title=Tek merkezden yönetilmeyen bir ağda gezinin.
onboarding.tour-tor-network.description=Tor Browser sizi tüm dünyada binlerce gönüllü tarafından işletilen Tor Ağına bağlar. VPN bağlantısının aksine güvenlik açığı oluşturacak bir nokta ya da İnternet üzerinde kişisel gizliliğinizi koruyarak gezinmeniz için güvenmeniz gereken merkezi bir kuruluş yoktur.
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=YENİ: Tor Ağı Ayarları, Tor ağına erişimin engellendiği yerlerde köprü isteğinde bulunma özelliği artı Ayarlar bölümü altında bulunabilir.
+onboarding.tour-tor-network.action-button=Tor Ağı Ayarlarınızı Yapın
onboarding.tour-tor-network.button=Devre Görünümüne Geç
onboarding.tour-tor-circuit-display=Devre Görünümü
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=Yeni
onboarding.tour-tor-update.prefix-updated=Güncellendi
onboarding.tour-tor-toolbar=Araç Çubuğu
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=Soğan Düğmesine Veda Edin.
+onboarding.tour-tor-toolbar-update-9.0.description=Tor işlemlerini tamamen Tor Browser ile yapabilmenizi istiyoruz.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=Bu nedenle, artık soğan düğmesini kullanmak yerine adres çubuğundaki [i] simgesine tıklayarak Tor Devresini görebilir, araç çubuğu düğmesini ya da [≡] menüsünü kullanarak Yeni Kimlik isteğinde bulunabilirsiniz.
+onboarding.tour-tor-toolbar-update-9.0.button=Nasıl Yeni Kimlik İsteğinde Bulunacaksınız
onboarding.tour-tor-toolbar-update-9.0.next-button=Tor Ağına Geç
# Circuit Display onboarding.
diff --git a/chrome/locale/tr/torbutton.properties b/chrome/locale/tr/torbutton.properties
index 6105c7b1..4523d729 100644
--- a/chrome/locale/tr/torbutton.properties
+++ b/chrome/locale/tr/torbutton.properties
@@ -1,6 +1,6 @@
torbutton.circuit_display.internet = İnternet
torbutton.circuit_display.ip_unknown = Bilinmeyen IP
-torbutton.circuit_display.onion_site = Soğan sitesi
+torbutton.circuit_display.onion_site = Onion sitesi
torbutton.circuit_display.this_browser = Bu tarayıcı
torbutton.circuit_display.relay = Aktarıcı
torbutton.circuit_display.tor_bridge = Köprü
diff --git a/chrome/locale/vi/browserOnboarding.properties b/chrome/locale/vi/browserOnboarding.properties
index e9508e20..0b14f935 100644
--- a/chrome/locale/vi/browserOnboarding.properties
+++ b/chrome/locale/vi/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=Updated
onboarding.tour-tor-toolbar=Toolbar
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=Đi đến mạng Tor
diff --git a/chrome/locale/zh-CN/browserOnboarding.properties b/chrome/locale/zh-CN/browserOnboarding.properties
index 83aa1571..f188ac01 100644
--- a/chrome/locale/zh-CN/browserOnboarding.properties
+++ b/chrome/locale/zh-CN/browserOnboarding.properties
@@ -15,8 +15,8 @@ onboarding.tour-tor-privacy.button=前往“Tor 网络”
onboarding.tour-tor-network=Tor 网络
onboarding.tour-tor-network.title=通过非中心化的网络进行浏览。
onboarding.tour-tor-network.description=Tor 浏览器将你和世界数千名志愿者支持的 Tor 网络相连。和 VPN 不同的是,这里不会有单点故障,也不需要你为了私密浏览信任某一个中心化的实体。
-onboarding.tour-tor-network.description-para2=NEW: Tor Network Settings, including the ability to request bridges where Tor is blocked, can now be found in Preferences.
-onboarding.tour-tor-network.action-button=Adjust Your Tor Network Settings
+onboarding.tour-tor-network.description-para2=新内容:设置中的 Tor 网络设置,包括在 Tor 被屏蔽时获取网桥。
+onboarding.tour-tor-network.action-button=调整 Tor 网络设置
onboarding.tour-tor-network.button=前往 ’显示链路'
onboarding.tour-tor-circuit-display=显示链路
@@ -49,10 +49,10 @@ onboarding.tour-tor-update.prefix-new=新建
onboarding.tour-tor-update.prefix-updated=已更新
onboarding.tour-tor-toolbar=工具栏
-onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
-onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.title=拜拜,洋葱按钮。
+onboarding.tour-tor-toolbar-update-9.0.description=我们希望将你使用 Tor 全部操作搬到 Tor 浏览器内。
+onboarding.tour-tor-toolbar-update-9.0.description-para2=所以现在,你可以在地址栏中的[i]按钮中看到 Tor 链路,在工具栏按钮[≡]菜单中请求新的身份,而不是使用洋葱按钮。
+onboarding.tour-tor-toolbar-update-9.0.button=如何请求新身份
onboarding.tour-tor-toolbar-update-9.0.next-button=前往“Tor 网络”
# Circuit Display onboarding.
diff --git a/chrome/locale/zh-TW/browserOnboarding.properties b/chrome/locale/zh-TW/browserOnboarding.properties
index 5cd92164..0c96e284 100644
--- a/chrome/locale/zh-TW/browserOnboarding.properties
+++ b/chrome/locale/zh-TW/browserOnboarding.properties
@@ -51,7 +51,7 @@ onboarding.tour-tor-update.prefix-updated=已更新
onboarding.tour-tor-toolbar=工具列
onboarding.tour-tor-toolbar-update-9.0.title=Goodbye Onion Button.
onboarding.tour-tor-toolbar-update-9.0.description=We want your experience using Tor to be fully integrated within Tor Browser.
-onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [=] menu.
+onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
onboarding.tour-tor-toolbar-update-9.0.next-button=前往 Tor 網路
1
0