richard pushed to branch tor-browser-102.11.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
f89920b2
by Henry Wilkes at 2023-05-25T19:57:03+00:00
-
77d2560d
by Henry Wilkes at 2023-05-25T19:57:03+00:00
-
efa05015
by Henry Wilkes at 2023-05-25T19:57:03+00:00
-
a71b5035
by Henry Wilkes at 2023-05-25T19:57:03+00:00
-
ba98c304
by Henry Wilkes at 2023-05-25T19:57:03+00:00
-
702051f1
by Henry Wilkes at 2023-05-25T19:57:03+00:00
21 changed files:
- browser/base/content/browser.js
- browser/base/content/browser.xhtml
- browser/base/content/navigator-toolbox.inc.xhtml
- browser/components/onionservices/content/onionlocation-urlbar.inc.xhtml
- browser/components/onionservices/content/onionlocation.css
- browser/components/torconnect/content/aboutTorConnect.js
- − browser/components/torconnect/content/onion-slash.svg
- − browser/components/torconnect/content/torBootstrapUrlbar.js
- + browser/components/torconnect/content/torConnectTitlebarStatus.css
- + browser/components/torconnect/content/torConnectTitlebarStatus.js
- + browser/components/torconnect/content/torConnectUrlbarButton.js
- − browser/components/torconnect/content/torconnect-urlbar.css
- − browser/components/torconnect/content/torconnect-urlbar.inc.xhtml
- browser/components/torconnect/jar.mn
- browser/components/torpreferences/content/torPreferences.css
- browser/modules/TorConnect.jsm
- browser/modules/TorStrings.jsm
- browser/themes/shared/browser-shared.css
- browser/themes/shared/jar.inc.mn
- + browser/themes/shared/tor-urlbar-button.css
- toolkit/torbutton/chrome/locale/en-US/torConnect.properties
Changes:
| ... | ... | @@ -80,6 +80,8 @@ XPCOMUtils.defineLazyModuleGetters(this, { |
| 80 | 80 | TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
|
| 81 | 81 | TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.jsm",
|
| 82 | 82 | TorConnect: "resource:///modules/TorConnect.jsm",
|
| 83 | + TorConnectState: "resource:///modules/TorConnect.jsm",
|
|
| 84 | + TorConnectTopics: "resource:///modules/TorConnect.jsm",
|
|
| 83 | 85 | Translation: "resource:///modules/translation/TranslationParent.jsm",
|
| 84 | 86 | UITour: "resource:///modules/UITour.jsm",
|
| 85 | 87 | UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
|
| ... | ... | @@ -269,6 +271,16 @@ XPCOMUtils.defineLazyScriptGetter( |
| 269 | 271 | "gSharedTabWarning",
|
| 270 | 272 | "chrome://browser/content/browser-webrtc.js"
|
| 271 | 273 | );
|
| 274 | +XPCOMUtils.defineLazyScriptGetter(
|
|
| 275 | + this,
|
|
| 276 | + ["gTorConnectUrlbarButton"],
|
|
| 277 | + "chrome://browser/content/torconnect/torConnectUrlbarButton.js"
|
|
| 278 | +);
|
|
| 279 | +XPCOMUtils.defineLazyScriptGetter(
|
|
| 280 | + this,
|
|
| 281 | + ["gTorConnectTitlebarStatus"],
|
|
| 282 | + "chrome://browser/content/torconnect/torConnectTitlebarStatus.js"
|
|
| 283 | +);
|
|
| 272 | 284 | XPCOMUtils.defineLazyScriptGetter(
|
| 273 | 285 | this,
|
| 274 | 286 | ["gTorCircuitPanel"],
|
| ... | ... | @@ -1808,6 +1820,9 @@ var gBrowserInit = { |
| 1808 | 1820 | // Init the OnionAuthPrompt
|
| 1809 | 1821 | OnionAuthPrompt.init();
|
| 1810 | 1822 | |
| 1823 | + gTorConnectUrlbarButton.init();
|
|
| 1824 | + gTorConnectTitlebarStatus.init();
|
|
| 1825 | + |
|
| 1811 | 1826 | gTorCircuitPanel.init();
|
| 1812 | 1827 | |
| 1813 | 1828 | // Certain kinds of automigration rely on this notification to complete
|
| ... | ... | @@ -1895,8 +1910,6 @@ var gBrowserInit = { |
| 1895 | 1910 | }
|
| 1896 | 1911 | |
| 1897 | 1912 | this._loadHandled = true;
|
| 1898 | - |
|
| 1899 | - TorBootstrapUrlbar.init();
|
|
| 1900 | 1913 | },
|
| 1901 | 1914 | |
| 1902 | 1915 | _cancelDelayedStartup() {
|
| ... | ... | @@ -2554,9 +2567,10 @@ var gBrowserInit = { |
| 2554 | 2567 | |
| 2555 | 2568 | OnionAuthPrompt.uninit();
|
| 2556 | 2569 | |
| 2557 | - gTorCircuitPanel.uninit();
|
|
| 2570 | + gTorConnectUrlbarButton.uninit();
|
|
| 2571 | + gTorConnectTitlebarStatus.uninit();
|
|
| 2558 | 2572 | |
| 2559 | - TorBootstrapUrlbar.uninit();
|
|
| 2573 | + gTorCircuitPanel.uninit();
|
|
| 2560 | 2574 | |
| 2561 | 2575 | gAccessibilityServiceIndicator.uninit();
|
| 2562 | 2576 |
| ... | ... | @@ -37,6 +37,7 @@ |
| 37 | 37 | <?xml-stylesheet href="chrome://browser/skin/places/editBookmark.css" type="text/css"?>
|
| 38 | 38 | <?xml-stylesheet href="chrome://browser/content/onionservices/onionservices.css" type="text/css"?>
|
| 39 | 39 | <?xml-stylesheet href="chrome://browser/content/torCircuitPanel.css" type="text/css"?>
|
| 40 | +<?xml-stylesheet href="chrome://browser/content/torconnect/torConnectTitlebarStatus.css" type="text/css"?>
|
|
| 40 | 41 | |
| 41 | 42 | <!DOCTYPE window [
|
| 42 | 43 | #include browser-doctype.inc
|
| ... | ... | @@ -123,7 +124,6 @@ |
| 123 | 124 | Services.scriptloader.loadSubScript("chrome://browser/content/search/searchbar.js", this);
|
| 124 | 125 | Services.scriptloader.loadSubScript("chrome://browser/content/languageNotification.js", this);
|
| 125 | 126 | Services.scriptloader.loadSubScript("chrome://torbutton/content/torbutton.js", this);
|
| 126 | - Services.scriptloader.loadSubScript("chrome://browser/content/torconnect/torBootstrapUrlbar.js", this);
|
|
| 127 | 127 | |
| 128 | 128 | window.onload = gBrowserInit.onLoad.bind(gBrowserInit);
|
| 129 | 129 | window.onunload = gBrowserInit.onUnload.bind(gBrowserInit);
|
| ... | ... | @@ -93,6 +93,11 @@ |
| 93 | 93 | aria-live="polite"/>
|
| 94 | 94 | <hbox class="private-browsing-indicator"/>
|
| 95 | 95 | |
| 96 | + <html:div id="tor-connect-titlebar-status" role="status">
|
|
| 97 | + <html:img alt="" id="tor-connect-titlebar-status-icon" />
|
|
| 98 | + <html:span id="tor-connect-titlebar-status-label"></html:span>
|
|
| 99 | + </html:div>
|
|
| 100 | + |
|
| 96 | 101 | #include titlebar-items.inc.xhtml
|
| 97 | 102 | |
| 98 | 103 | </toolbar>
|
| ... | ... | @@ -335,7 +340,6 @@ |
| 335 | 340 | data-l10n-id="urlbar-go-button"/>
|
| 336 | 341 | <hbox id="page-action-buttons" context="pageActionContextMenu">
|
| 337 | 342 | <toolbartabstop/>
|
| 338 | -#include ../../components/torconnect/content/torconnect-urlbar.inc.xhtml
|
|
| 339 | 343 | <hbox id="contextual-feature-recommendation" role="button" hidden="true">
|
| 340 | 344 | <hbox id="cfr-label-container">
|
| 341 | 345 | <label id="cfr-label"/>
|
| ... | ... | @@ -363,9 +367,6 @@ |
| 363 | 367 | onclick="FullZoom.reset(); FullZoom.resetScalingZoom();"
|
| 364 | 368 | tooltip="dynamic-shortcut-tooltip"
|
| 365 | 369 | hidden="true"/>
|
| 366 | - |
|
| 367 | -#include ../../components/onionservices/content/onionlocation-urlbar.inc.xhtml
|
|
| 368 | - |
|
| 369 | 370 | <hbox id="pageActionButton"
|
| 370 | 371 | class="urlbar-page-action"
|
| 371 | 372 | role="button"
|
| ... | ... | @@ -383,6 +384,15 @@ |
| 383 | 384 | class="urlbar-icon"/>
|
| 384 | 385 | </hbox>
|
| 385 | 386 | </hbox>
|
| 387 | + |
|
| 388 | + <hbox id="tor-connect-urlbar-button"
|
|
| 389 | + role="button"
|
|
| 390 | + class="tor-urlbar-button"
|
|
| 391 | + hidden="true">
|
|
| 392 | + <label id="tor-connect-urlbar-button-label"/>
|
|
| 393 | + </hbox>
|
|
| 394 | + |
|
| 395 | +#include ../../components/onionservices/content/onionlocation-urlbar.inc.xhtml
|
|
| 386 | 396 | </hbox>
|
| 387 | 397 | </hbox>
|
| 388 | 398 | <toolbartabstop/>
|
| 1 | 1 | # Copyright (c) 2020, The Tor Project, Inc.
|
| 2 | 2 | |
| 3 | 3 | <hbox id="onion-location-box"
|
| 4 | - class="urlbar-icon-wrapper urlbar-page-action"
|
|
| 4 | + class="tor-urlbar-button"
|
|
| 5 | 5 | role="button"
|
| 6 | 6 | hidden="true"
|
| 7 | 7 | onclick="OnionLocationParent.buttonClick(event);">
|
| 8 | 8 | <image id="onion-location-button" role="presentation"/>
|
| 9 | - <hbox id="onion-label-container"><label id="onion-label"/></hbox>
|
|
| 9 | + <label id="onion-label"/>
|
|
| 10 | 10 | </hbox> |
| 1 | 1 | /* Copyright (c) 2020, The Tor Project, Inc. */
|
| 2 | 2 | |
| 3 | -#onion-location-box {
|
|
| 4 | - background-color: var(--purple-60);
|
|
| 5 | - -moz-context-properties: fill;
|
|
| 6 | - fill: white;
|
|
| 7 | -}
|
|
| 8 | - |
|
| 9 | -#onion-location-box:hover {
|
|
| 10 | - background-color: var(--purple-70);
|
|
| 11 | -}
|
|
| 12 | - |
|
| 13 | -#onion-location-box:active {
|
|
| 14 | - background-color: var(--purple-80);
|
|
| 15 | -}
|
|
| 16 | - |
|
| 17 | -@media (prefers-color-scheme: dark) {
|
|
| 18 | - #onion-location-box {
|
|
| 19 | - background-color: var(--purple-50);
|
|
| 20 | - }
|
|
| 21 | - |
|
| 22 | - #onion-location-box:hover {
|
|
| 23 | - background-color: var(--purple-60);
|
|
| 24 | - }
|
|
| 25 | - |
|
| 26 | - #onion-location-box:active {
|
|
| 27 | - background-color: var(--purple-70);
|
|
| 28 | - }
|
|
| 29 | -}
|
|
| 30 | - |
|
| 31 | 3 | #onion-location-button {
|
| 32 | 4 | list-style-image: url(chrome://browser/content/onionservices/onionlocation.svg);
|
| 33 | - padding-inline-start: 0.5em;
|
|
| 34 | -}
|
|
| 35 | - |
|
| 36 | -label#onion-label {
|
|
| 37 | - margin: 0;
|
|
| 38 | - padding-block: 0;
|
|
| 39 | - padding-inline: 0.5em;
|
|
| 40 | - color: white;
|
|
| 41 | - font-weight: normal;
|
|
| 5 | + -moz-context-properties: fill;
|
|
| 6 | + fill: currentColor;
|
|
| 42 | 7 | }
|
| 43 | 8 | |
| 44 | 9 | .onionlocation-notification-icon {
|
| ... | ... | @@ -769,26 +769,29 @@ class AboutTorConnect { |
| 769 | 769 | }
|
| 770 | 770 | });
|
| 771 | 771 | |
| 772 | - // Delay the "Enter" activation of the given button from "keydown" to
|
|
| 773 | - // "keyup".
|
|
| 772 | + // Prevent repeat triggering on keydown when the Enter key is held down.
|
|
| 774 | 773 | //
|
| 775 | - // Without this, holding down Enter will continue to trigger the button
|
|
| 776 | - // until the user stops holding. This means that a user can accidentally
|
|
| 777 | - // re-trigger a button several times. This is particularly bad when the
|
|
| 778 | - // focus gets moved to a new button, and the new button can get triggered
|
|
| 779 | - // immediately. E.g. when the "Connect" button is triggered it disappears
|
|
| 780 | - // and focus moves to the "Cancel" button.
|
|
| 774 | + // Without this, holding down Enter will continue to trigger the button's
|
|
| 775 | + // click event until the user stops holding. This means that a user can
|
|
| 776 | + // accidentally re-trigger a button several times. And if focus moves to a
|
|
| 777 | + // new button it can also get triggered, despite not receiving the initial
|
|
| 778 | + // keydown event.
|
|
| 779 | + //
|
|
| 780 | + // E.g. If the user presses down Enter on the "Connect" button it will
|
|
| 781 | + // trigger and focus will move to the "Cancel" button. This should prevent
|
|
| 782 | + // the user accidentally triggering the "Cancel" button if they hold down
|
|
| 783 | + // Enter for a little bit too long.
|
|
| 781 | 784 | for (const button of document.body.querySelectorAll("button")) {
|
| 782 | 785 | button.addEventListener("keydown", event => {
|
| 783 | - if (event.key === "Enter") {
|
|
| 786 | + // If the keydown is a repeating Enter event, ignore it.
|
|
| 787 | + // NOTE: If firefox uses wayland display (rather than xwayland), the
|
|
| 788 | + // "repeat" event is always "false" so this will not work.
|
|
| 789 | + // See bugzilla bug 1784438. Also see bugzilla bug 1594003.
|
|
| 790 | + // Currently tor browser uses xwayland by default on linux.
|
|
| 791 | + if (event.key === "Enter" && event.repeat) {
|
|
| 784 | 792 | event.preventDefault();
|
| 785 | 793 | }
|
| 786 | 794 | });
|
| 787 | - button.addEventListener("keyup", event => {
|
|
| 788 | - if (event.key === "Enter") {
|
|
| 789 | - button.click();
|
|
| 790 | - }
|
|
| 791 | - });
|
|
| 792 | 795 | }
|
| 793 | 796 | }
|
| 794 | 797 |
| 1 | -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
| 2 | -<svg viewBox="0 0 16 16" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
|
| 3 | - <path d="m14.1161 15.6245c-.0821.0001-.1634-.016-.2393-.0474-.0758-.0314-.1447-.0775-.2027-.1356l-12.749984-12.749c-.109266-.11882-.168406-.27526-.165071-.43666.003335-.16139.068886-.31525.182967-.42946.114078-.11421.267868-.17994.429258-.18345.16139-.00352.3179.05544.43685.16457l12.74998 12.75c.1168.1176.1824.2767.1824.4425s-.0656.3249-.1824.4425c-.058.058-.1269.1039-.2028.1352-.0759.0312-.1571.0471-.2392.0468z" fill-opacity="context-fill-opacity" fill="#ff0039" />
|
|
| 4 | - <path d="m 8,0.5000002 c -1.61963,0 -3.1197431,0.5137987 -4.3457031,1.3867188 l 0.84375,0.8417968 0.7792969,0.78125 0.8613281,0.8613282 0.8164062,0.8164062 0.9863281,0.984375 h 0.058594 c 1.00965,0 1.828125,0.818485 1.828125,1.828125 0,0.01968 6.2e-4,0.039074 0,0.058594 L 10.8125,9.0449221 C 10.9334,8.7195921 11,8.3674002 11,8.0000002 c 0,-1.65685 -1.34314,-3 -3,-3 v -1.078125 c 2.25231,0 4.078125,1.825845 4.078125,4.078125 0,0.67051 -0.162519,1.3033281 -0.449219,1.8613281 l 0.861328,0.8613277 C 12.972434,9.9290067 13.25,8.9965102 13.25,8.0000002 c 0,-2.89949 -2.35049,-5.25 -5.25,-5.25 v -1.078125 c 3.4949,0 6.328125,2.833195 6.328125,6.328125 0,1.29533 -0.388841,2.4990528 -1.056641,3.5019528 l 0.841797,0.84375 C 14.986181,11.119703 15.5,9.6196302 15.5,8.0000002 c 0,-4.14214 -3.3579,-7.5 -7.5,-7.5 z m -6.1113281,3.15625 C 1.0154872,4.8821451 0.5,6.3803304 0.5,8.0000002 0.5,12.1421 3.85786,15.5 8,15.5 c 1.6198027,0 3.117896,-0.515441 4.34375,-1.388672 L 11.501953,13.269531 C 10.498787,13.937828 9.295838,14.328125 8,14.328125 V 13.25 c 0.9967306,0 1.9287093,-0.277621 2.722656,-0.759766 L 9.859375,11.626953 C 9.3016226,11.913918 8.6705338,12.078125 8,12.078125 V 11 C 8.3664751,11 8.716425,10.93088 9.0410156,10.810547 6.6639891,8.4300416 4.2743195,6.0418993 1.8886719,3.6562502 Z" fill-opacity="context-fill-opacity" fill="context-fill"/>
|
|
| 5 | -</svg> |
| 1 | -// Copyright (c) 2021, The Tor Project, Inc.
|
|
| 2 | - |
|
| 3 | -"use strict";
|
|
| 4 | - |
|
| 5 | -const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
|
|
| 6 | - "resource:///modules/TorConnect.jsm"
|
|
| 7 | -);
|
|
| 8 | -const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
|
|
| 9 | - |
|
| 10 | -/* globals browser, gURLBar, Services */
|
|
| 11 | - |
|
| 12 | -var TorBootstrapUrlbar = {
|
|
| 13 | - selectors: Object.freeze({
|
|
| 14 | - torConnect: {
|
|
| 15 | - box: "hbox#torconnect-box",
|
|
| 16 | - label: "label#torconnect-label",
|
|
| 17 | - },
|
|
| 18 | - }),
|
|
| 19 | - |
|
| 20 | - elements: null,
|
|
| 21 | - |
|
| 22 | - updateTorConnectBox(state) {
|
|
| 23 | - switch (state) {
|
|
| 24 | - case TorConnectState.Initial:
|
|
| 25 | - case TorConnectState.Configuring:
|
|
| 26 | - case TorConnectState.AutoConfiguring:
|
|
| 27 | - case TorConnectState.Error:
|
|
| 28 | - case TorConnectState.FatalError: {
|
|
| 29 | - this.elements.torConnectBox.removeAttribute("hidden");
|
|
| 30 | - this.elements.torConnectLabel.textContent =
|
|
| 31 | - TorStrings.torConnect.torNotConnectedConcise;
|
|
| 32 | - this.elements.inputContainer.setAttribute("torconnect", "offline");
|
|
| 33 | - break;
|
|
| 34 | - }
|
|
| 35 | - case TorConnectState.Bootstrapping: {
|
|
| 36 | - this.elements.torConnectBox.removeAttribute("hidden");
|
|
| 37 | - this.elements.torConnectLabel.textContent =
|
|
| 38 | - TorStrings.torConnect.torConnectingConcise;
|
|
| 39 | - this.elements.inputContainer.setAttribute("torconnect", "connecting");
|
|
| 40 | - break;
|
|
| 41 | - }
|
|
| 42 | - case TorConnectState.Bootstrapped: {
|
|
| 43 | - this.elements.torConnectBox.removeAttribute("hidden");
|
|
| 44 | - this.elements.torConnectLabel.textContent =
|
|
| 45 | - TorStrings.torConnect.torConnectedConcise;
|
|
| 46 | - this.elements.inputContainer.setAttribute("torconnect", "connected");
|
|
| 47 | - // hide torconnect box after 5 seconds
|
|
| 48 | - setTimeout(() => {
|
|
| 49 | - this.elements.torConnectBox.setAttribute("hidden", "true");
|
|
| 50 | - }, 5000);
|
|
| 51 | - break;
|
|
| 52 | - }
|
|
| 53 | - case TorConnectState.Disabled: {
|
|
| 54 | - this.elements.torConnectBox.setAttribute("hidden", "true");
|
|
| 55 | - break;
|
|
| 56 | - }
|
|
| 57 | - default:
|
|
| 58 | - break;
|
|
| 59 | - }
|
|
| 60 | - },
|
|
| 61 | - |
|
| 62 | - observe(aSubject, aTopic, aData) {
|
|
| 63 | - if (aTopic === TorConnectTopics.StateChange) {
|
|
| 64 | - const obj = aSubject?.wrappedJSObject;
|
|
| 65 | - this.updateTorConnectBox(obj?.state);
|
|
| 66 | - }
|
|
| 67 | - },
|
|
| 68 | - |
|
| 69 | - init() {
|
|
| 70 | - if (TorConnect.shouldShowTorConnect) {
|
|
| 71 | - // browser isn't populated until init
|
|
| 72 | - this.elements = Object.freeze({
|
|
| 73 | - torConnectBox: browser.ownerGlobal.document.querySelector(
|
|
| 74 | - this.selectors.torConnect.box
|
|
| 75 | - ),
|
|
| 76 | - torConnectLabel: browser.ownerGlobal.document.querySelector(
|
|
| 77 | - this.selectors.torConnect.label
|
|
| 78 | - ),
|
|
| 79 | - inputContainer: gURLBar._inputContainer,
|
|
| 80 | - });
|
|
| 81 | - this.elements.torConnectBox.addEventListener("click", () => {
|
|
| 82 | - TorConnect.openTorConnect();
|
|
| 83 | - });
|
|
| 84 | - Services.obs.addObserver(this, TorConnectTopics.StateChange);
|
|
| 85 | - this.observing = true;
|
|
| 86 | - this.updateTorConnectBox(TorConnect.state);
|
|
| 87 | - }
|
|
| 88 | - },
|
|
| 89 | - |
|
| 90 | - uninit() {
|
|
| 91 | - if (this.observing) {
|
|
| 92 | - Services.obs.removeObserver(this, TorConnectTopics.StateChange);
|
|
| 93 | - }
|
|
| 94 | - },
|
|
| 95 | -}; |
| 1 | +#tor-connect-titlebar-status:not([hidden]) {
|
|
| 2 | + display: flex;
|
|
| 3 | + align-items: center;
|
|
| 4 | + /* Want same as #private-browsing-indicator-with-label */
|
|
| 5 | + margin-inline: 7px;
|
|
| 6 | +}
|
|
| 7 | + |
|
| 8 | +#tor-connect-titlebar-status-label {
|
|
| 9 | + margin-inline: 6px;
|
|
| 10 | + white-space: nowrap;
|
|
| 11 | +}
|
|
| 12 | + |
|
| 13 | +#tor-connect-titlebar-status-icon {
|
|
| 14 | + -moz-context-properties: fill;
|
|
| 15 | + fill: currentColor;
|
|
| 16 | + width: 16px;
|
|
| 17 | + height: 16px;
|
|
| 18 | +}
|
|
| 19 | + |
|
| 20 | +#tor-connect-titlebar-status-icon.tor-connect-status-connected {
|
|
| 21 | + fill: var(--purple-60);
|
|
| 22 | +}
|
|
| 23 | + |
|
| 24 | +@media (prefers-color-scheme: dark) {
|
|
| 25 | + #tor-connect-titlebar-status-icon.tor-connect-status-connected {
|
|
| 26 | + fill: var(--purple-30);
|
|
| 27 | + }
|
|
| 28 | +}
|
|
| 29 | + |
|
| 30 | +#tor-connect-titlebar-status-icon.tor-connect-status-potentially-blocked {
|
|
| 31 | + fill: #c50042;
|
|
| 32 | +}
|
|
| 33 | + |
|
| 34 | +@media (prefers-color-scheme: dark) {
|
|
| 35 | + #tor-connect-titlebar-status-icon.tor-connect-status-potentially-blocked {
|
|
| 36 | + fill: #ff9aa2;
|
|
| 37 | + }
|
|
| 38 | +} |
| 1 | +/* eslint-env mozilla/browser-window */
|
|
| 2 | + |
|
| 3 | +/**
|
|
| 4 | + * A TorConnect status shown in the application title bar.
|
|
| 5 | + */
|
|
| 6 | +var gTorConnectTitlebarStatus = {
|
|
| 7 | + /**
|
|
| 8 | + * The status element in the title bar.
|
|
| 9 | + *
|
|
| 10 | + * @type {Element}
|
|
| 11 | + */
|
|
| 12 | + node: null,
|
|
| 13 | + /**
|
|
| 14 | + * The status label.
|
|
| 15 | + *
|
|
| 16 | + * @type {Element}
|
|
| 17 | + */
|
|
| 18 | + label: null,
|
|
| 19 | + /**
|
|
| 20 | + * The status icon.
|
|
| 21 | + *
|
|
| 22 | + * @type {Element}
|
|
| 23 | + */
|
|
| 24 | + icon: null,
|
|
| 25 | + |
|
| 26 | + /**
|
|
| 27 | + * Initialize the component.
|
|
| 28 | + */
|
|
| 29 | + init() {
|
|
| 30 | + const { TorStrings } = ChromeUtils.import(
|
|
| 31 | + "resource:///modules/TorStrings.jsm"
|
|
| 32 | + );
|
|
| 33 | + |
|
| 34 | + this._strings = TorStrings.torConnect;
|
|
| 35 | + |
|
| 36 | + this.node = document.getElementById("tor-connect-titlebar-status");
|
|
| 37 | + this.icon = document.getElementById("tor-connect-titlebar-status-icon");
|
|
| 38 | + this.label = document.getElementById("tor-connect-titlebar-status-label");
|
|
| 39 | + // The title also acts as an accessible name for the role="status".
|
|
| 40 | + this.node.setAttribute("title", this._strings.titlebarStatusName);
|
|
| 41 | + |
|
| 42 | + this._observeTopic = TorConnectTopics.StateChange;
|
|
| 43 | + this._stateListener = {
|
|
| 44 | + observe: (subject, topic, data) => {
|
|
| 45 | + if (topic !== this._observeTopic) {
|
|
| 46 | + return;
|
|
| 47 | + }
|
|
| 48 | + this._torConnectStateChanged();
|
|
| 49 | + },
|
|
| 50 | + };
|
|
| 51 | + Services.obs.addObserver(this._stateListener, this._observeTopic);
|
|
| 52 | + |
|
| 53 | + this._torConnectStateChanged();
|
|
| 54 | + },
|
|
| 55 | + |
|
| 56 | + /**
|
|
| 57 | + * De-initialize the component.
|
|
| 58 | + */
|
|
| 59 | + deinit() {
|
|
| 60 | + Services.obs.removeObserver(this._stateListener, this._observeTopic);
|
|
| 61 | + },
|
|
| 62 | + |
|
| 63 | + /**
|
|
| 64 | + * Callback for when the TorConnect state changes.
|
|
| 65 | + */
|
|
| 66 | + _torConnectStateChanged() {
|
|
| 67 | + let textId;
|
|
| 68 | + let connected = false;
|
|
| 69 | + let potentiallyBlocked = false;
|
|
| 70 | + switch (TorConnect.state) {
|
|
| 71 | + case TorConnectState.Disabled:
|
|
| 72 | + // Hide immediately.
|
|
| 73 | + this.node.hidden = true;
|
|
| 74 | + return;
|
|
| 75 | + case TorConnectState.Bootstrapped:
|
|
| 76 | + this._startHiding();
|
|
| 77 | + textId = "titlebarStatusConnected";
|
|
| 78 | + connected = true;
|
|
| 79 | + break;
|
|
| 80 | + case TorConnectState.Bootstrapping:
|
|
| 81 | + case TorConnectState.AutoBootstrapping:
|
|
| 82 | + textId = "titlebarStatusConnecting";
|
|
| 83 | + break;
|
|
| 84 | + default:
|
|
| 85 | + if (TorConnect.potentiallyBlocked) {
|
|
| 86 | + textId = "titlebarStatusPotentiallyBlocked";
|
|
| 87 | + potentiallyBlocked = true;
|
|
| 88 | + } else {
|
|
| 89 | + textId = "titlebarStatusNotConnected";
|
|
| 90 | + }
|
|
| 91 | + break;
|
|
| 92 | + }
|
|
| 93 | + this.label.textContent = this._strings[textId];
|
|
| 94 | + this.icon.setAttribute(
|
|
| 95 | + "src",
|
|
| 96 | + connected
|
|
| 97 | + ? "chrome://browser/content/torconnect/onion.svg"
|
|
| 98 | + : "chrome://browser/content/torconnect/onion-slash-fillable.svg"
|
|
| 99 | + );
|
|
| 100 | + this.icon.classList.toggle("tor-connect-status-connected", connected);
|
|
| 101 | + this.icon.classList.toggle(
|
|
| 102 | + "tor-connect-status-potentially-blocked",
|
|
| 103 | + potentiallyBlocked
|
|
| 104 | + );
|
|
| 105 | + },
|
|
| 106 | + |
|
| 107 | + /**
|
|
| 108 | + * Mark the component to be hidden after some delay.
|
|
| 109 | + */
|
|
| 110 | + _startHiding() {
|
|
| 111 | + setTimeout(() => {
|
|
| 112 | + this.node.hidden = true;
|
|
| 113 | + }, 5000);
|
|
| 114 | + },
|
|
| 115 | +}; |
| 1 | +/* eslint-env mozilla/browser-window */
|
|
| 2 | + |
|
| 3 | +/**
|
|
| 4 | + * A "Connect" button shown in the urlbar when not connected to tor and in tabs
|
|
| 5 | + * other than about:torconnect.
|
|
| 6 | + */
|
|
| 7 | +var gTorConnectUrlbarButton = {
|
|
| 8 | + /**
|
|
| 9 | + * The urlbar button node.
|
|
| 10 | + *
|
|
| 11 | + * @type {Element}
|
|
| 12 | + */
|
|
| 13 | + button: null,
|
|
| 14 | + /**
|
|
| 15 | + * Whether we are active.
|
|
| 16 | + *
|
|
| 17 | + * @type {boolean}
|
|
| 18 | + */
|
|
| 19 | + _isActive: false,
|
|
| 20 | + /**
|
|
| 21 | + * Whether we are in the "about:torconnect" tab.
|
|
| 22 | + *
|
|
| 23 | + * @type {boolean}
|
|
| 24 | + */
|
|
| 25 | + // We init to "true" so that the button can only appear after the first page
|
|
| 26 | + // load.
|
|
| 27 | + _inAboutTorConnectTab: true,
|
|
| 28 | + |
|
| 29 | + /**
|
|
| 30 | + * Initialize the button.
|
|
| 31 | + */
|
|
| 32 | + init() {
|
|
| 33 | + if (this._isActive) {
|
|
| 34 | + return;
|
|
| 35 | + }
|
|
| 36 | + this._isActive = true;
|
|
| 37 | + |
|
| 38 | + const { TorStrings } = ChromeUtils.import(
|
|
| 39 | + "resource:///modules/TorStrings.jsm"
|
|
| 40 | + );
|
|
| 41 | + |
|
| 42 | + this.button = document.getElementById("tor-connect-urlbar-button");
|
|
| 43 | + document.getElementById("tor-connect-urlbar-button-label").value =
|
|
| 44 | + TorStrings.torConnect.torConnectButton;
|
|
| 45 | + this.button.addEventListener("click", event => {
|
|
| 46 | + if (event.button !== 0) {
|
|
| 47 | + return;
|
|
| 48 | + }
|
|
| 49 | + this.connect();
|
|
| 50 | + });
|
|
| 51 | + this.button.addEventListener("keydown", event => {
|
|
| 52 | + if (event.key !== "Enter" && event.key !== " ") {
|
|
| 53 | + return;
|
|
| 54 | + }
|
|
| 55 | + this.connect();
|
|
| 56 | + });
|
|
| 57 | + |
|
| 58 | + this._observeTopic = TorConnectTopics.StateChange;
|
|
| 59 | + this._stateListener = {
|
|
| 60 | + observe: (subject, topic, data) => {
|
|
| 61 | + if (topic !== this._observeTopic) {
|
|
| 62 | + return;
|
|
| 63 | + }
|
|
| 64 | + this._torConnectStateChanged();
|
|
| 65 | + },
|
|
| 66 | + };
|
|
| 67 | + Services.obs.addObserver(this._stateListener, this._observeTopic);
|
|
| 68 | + |
|
| 69 | + this._locationListener = {
|
|
| 70 | + onLocationChange: (webProgress, request, locationURI, flags) => {
|
|
| 71 | + if (
|
|
| 72 | + webProgress.isTopLevel &&
|
|
| 73 | + !(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)
|
|
| 74 | + ) {
|
|
| 75 | + this._inAboutTorConnectTab = gBrowser.selectedBrowser.currentURI?.spec.startsWith(
|
|
| 76 | + "about:torconnect"
|
|
| 77 | + );
|
|
| 78 | + this._updateButtonVisibility();
|
|
| 79 | + }
|
|
| 80 | + },
|
|
| 81 | + };
|
|
| 82 | + // Notified of new locations for the currently selected browser (tab) *and*
|
|
| 83 | + // switching selected browser.
|
|
| 84 | + gBrowser.addProgressListener(this._locationListener);
|
|
| 85 | + |
|
| 86 | + this._torConnectStateChanged();
|
|
| 87 | + },
|
|
| 88 | + |
|
| 89 | + /**
|
|
| 90 | + * Deactivate and de-initialize the button.
|
|
| 91 | + */
|
|
| 92 | + deinit() {
|
|
| 93 | + if (!this._isActive) {
|
|
| 94 | + return;
|
|
| 95 | + }
|
|
| 96 | + this._isActive = false;
|
|
| 97 | + |
|
| 98 | + Services.obs.removeObserver(this._stateListener, this._observeTopic);
|
|
| 99 | + gBrowser.removeProgressListener(this._locationListener);
|
|
| 100 | + this._updateButtonVisibility();
|
|
| 101 | + },
|
|
| 102 | + |
|
| 103 | + /**
|
|
| 104 | + * Begin the tor connection bootstrapping process.
|
|
| 105 | + */
|
|
| 106 | + connect() {
|
|
| 107 | + TorConnect.openTorConnect({ beginBootstrap: true });
|
|
| 108 | + },
|
|
| 109 | + |
|
| 110 | + /**
|
|
| 111 | + * Callback for when the TorConnect state changes.
|
|
| 112 | + */
|
|
| 113 | + _torConnectStateChanged() {
|
|
| 114 | + if (
|
|
| 115 | + TorConnect.state === TorConnectState.Bootstrapped ||
|
|
| 116 | + TorConnect.state === TorConnectState.Disabled
|
|
| 117 | + ) {
|
|
| 118 | + this.deinit();
|
|
| 119 | + return;
|
|
| 120 | + }
|
|
| 121 | + this._updateButtonVisibility();
|
|
| 122 | + },
|
|
| 123 | + |
|
| 124 | + /**
|
|
| 125 | + * Callback when the TorConnect state, current browser location, or activation
|
|
| 126 | + * state changes.
|
|
| 127 | + */
|
|
| 128 | + _updateButtonVisibility() {
|
|
| 129 | + if (!this.button) {
|
|
| 130 | + return;
|
|
| 131 | + }
|
|
| 132 | + // NOTE: We do not manage focus when hiding the button. We only expect to
|
|
| 133 | + // move from "not hidden" to "hidden" when:
|
|
| 134 | + // + switching tabs to "about:torconnect", or
|
|
| 135 | + // + starting bootstrapping.
|
|
| 136 | + //
|
|
| 137 | + // When switching tabs, the normal tab switching logic will eventually move
|
|
| 138 | + // focus to the new tab or url bar, so whilst the focus may be lost
|
|
| 139 | + // temporarily when we hide the button, it will be re-established quickly on
|
|
| 140 | + // tab switch.
|
|
| 141 | + //
|
|
| 142 | + // And we don't expect bootstrapping to start whilst outside of the
|
|
| 143 | + // "about:torconnect", and the automatic bootstrapping should only trigger
|
|
| 144 | + // at the initial start.
|
|
| 145 | + this.button.hidden =
|
|
| 146 | + !this._isActive ||
|
|
| 147 | + this._inAboutTorConnectTab ||
|
|
| 148 | + !TorConnect.enabled ||
|
|
| 149 | + !TorConnect.canBeginBootstrap;
|
|
| 150 | + this.button.classList.toggle(
|
|
| 151 | + "tor-urlbar-button-plain",
|
|
| 152 | + TorConnect.potentiallyBlocked
|
|
| 153 | + );
|
|
| 154 | + },
|
|
| 155 | +}; |
| 1 | -/*
|
|
| 2 | - ensure our torconnect button is always visible (same rule as for the bookmark button)
|
|
| 3 | -*/
|
|
| 4 | -label#torconnect-label {
|
|
| 5 | - margin: 0;
|
|
| 6 | - opacity: 0.6;
|
|
| 7 | - padding: 0 0.5em;
|
|
| 8 | -}
|
|
| 9 | - |
|
| 10 | -hbox.urlbar-page-action#torconnect-box {
|
|
| 11 | - display: -moz-inline-box!important;
|
|
| 12 | -}
|
|
| 13 | - |
|
| 14 | -/* hide when hidden attribute is set */
|
|
| 15 | -hbox.urlbar-page-action#torconnect-box[hidden="true"],
|
|
| 16 | -/* hide when user is typing in URL bar */
|
|
| 17 | -#urlbar[usertyping] > #urlbar-input-container > #page-action-buttons > #torconnect-box {
|
|
| 18 | - display: none!important;
|
|
| 19 | -}
|
|
| 20 | - |
|
| 21 | -/* hide urlbar's placeholder text when not connectd to tor */
|
|
| 22 | -hbox#urlbar-input-container[torconnect="offline"] input#urlbar-input::placeholder,
|
|
| 23 | -hbox#urlbar-input-container[torconnect="connecting"] input#urlbar-input::placeholder {
|
|
| 24 | - opacity: 0;
|
|
| 25 | -}
|
|
| 26 | - |
|
| 27 | -/* hide search suggestions when not connected to tor */
|
|
| 28 | -hbox#urlbar-input-container[torconnect="offline"] + vbox.urlbarView,
|
|
| 29 | -hbox#urlbar-input-container[torconnect="connecting"] + vbox.urlbarView {
|
|
| 30 | - display: none!important;
|
|
| 31 | -}
|
|
| 32 | - |
|
| 33 | -/* hide search icon when we are not connected to tor */
|
|
| 34 | -hbox#urlbar-input-container[torconnect="offline"] > #identity-box[pageproxystate="invalid"] > #identity-icon,
|
|
| 35 | -hbox#urlbar-input-container[torconnect="connecting"] > #identity-box[pageproxystate="invalid"] > #identity-icon {
|
|
| 36 | - display: none!important;
|
|
| 37 | -} |
| 1 | -# Copyright (c) 2021, The Tor Project, Inc.
|
|
| 2 | - |
|
| 3 | -<hbox id="torconnect-box"
|
|
| 4 | - class="urlbar-icon-wrapper urlbar-page-action"
|
|
| 5 | - role="status"
|
|
| 6 | - align="center"
|
|
| 7 | - hidden="true">
|
|
| 8 | - <hbox id="torconnect-container">
|
|
| 9 | - <label id="torconnect-label"/>
|
|
| 10 | - </hbox>
|
|
| 11 | -</hbox> |
|
| \ No newline at end of file |
| 1 | 1 | browser.jar:
|
| 2 | - content/browser/torconnect/torBootstrapUrlbar.js (content/torBootstrapUrlbar.js)
|
|
| 2 | + content/browser/torconnect/torConnectUrlbarButton.js (content/torConnectUrlbarButton.js)
|
|
| 3 | + content/browser/torconnect/torConnectTitlebarStatus.js (content/torConnectTitlebarStatus.js)
|
|
| 4 | + content/browser/torconnect/torConnectTitlebarStatus.css (content/torConnectTitlebarStatus.css)
|
|
| 3 | 5 | content/browser/torconnect/aboutTorConnect.css (content/aboutTorConnect.css)
|
| 4 | 6 | * content/browser/torconnect/aboutTorConnect.xhtml (content/aboutTorConnect.xhtml)
|
| 5 | 7 | content/browser/torconnect/aboutTorConnect.js (content/aboutTorConnect.js)
|
| ... | ... | @@ -8,6 +10,4 @@ browser.jar: |
| 8 | 10 | content/browser/torconnect/connection-failure.svg (content/connection-failure.svg)
|
| 9 | 11 | content/browser/torconnect/connection-location.svg (content/connection-location.svg)
|
| 10 | 12 | content/browser/torconnect/onion.svg (content/onion.svg)
|
| 11 | - content/browser/torconnect/onion-slash.svg (content/onion-slash.svg)
|
|
| 12 | 13 | content/browser/torconnect/onion-slash-fillable.svg (content/onion-slash-fillable.svg) |
| 13 | - skin/classic/browser/torconnect-urlbar.css (content/torconnect-urlbar.css) |
| ... | ... | @@ -58,7 +58,7 @@ html:dir(rtl) input[type="checkbox"].toggle-button::before { |
| 58 | 58 | |
| 59 | 59 | #torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-icon
|
| 60 | 60 | {
|
| 61 | - mask: url("chrome://browser/skin/onion-slash.svg");
|
|
| 61 | + mask: url("chrome://browser/content/torconnect/onion-slash-fillable.svg");
|
|
| 62 | 62 | background-color: white;
|
| 63 | 63 | }
|
| 64 | 64 |
| ... | ... | @@ -99,7 +99,7 @@ const TorConnectState = Object.freeze({ |
| 99 | 99 | └─┼─────▶ │ │ │
|
| 100 | 100 | │ └──────────────────────────────────────────────────────────┘ │
|
| 101 | 101 | │ │ ▲ │
|
| 102 | - │ │ beginAutoBootstrap() │ cancelAutoBootstrap() │
|
|
| 102 | + │ │ beginAutoBootstrap() │ cancelBootstrap() │
|
|
| 103 | 103 | │ ▼ │ │
|
| 104 | 104 | │ ┌───────────────────────┐ │ │
|
| 105 | 105 | └────── │ AutoBootstrapping │ ─┘ │
|
| ... | ... | @@ -464,6 +464,7 @@ const TorConnect = (() => { |
| 464 | 464 | |
| 465 | 465 | const tbr = new TorBootstrapRequest();
|
| 466 | 466 | const internetTest = new InternetTest();
|
| 467 | + let cancelled = false;
|
|
| 467 | 468 | |
| 468 | 469 | let bootstrapError = "";
|
| 469 | 470 | let bootstrapErrorDetails = "";
|
| ... | ... | @@ -506,6 +507,7 @@ const TorConnect = (() => { |
| 506 | 507 | this.on_transition = async nextState => {
|
| 507 | 508 | if (nextState === TorConnectState.Configuring) {
|
| 508 | 509 | // stop bootstrap process if user cancelled
|
| 510 | + cancelled = true;
|
|
| 509 | 511 | internetTest.cancel();
|
| 510 | 512 | await tbr.cancel();
|
| 511 | 513 | }
|
| ... | ... | @@ -520,6 +522,19 @@ const TorConnect = (() => { |
| 520 | 522 | TorConnect._changeState(TorConnectState.Bootstrapped);
|
| 521 | 523 | };
|
| 522 | 524 | tbr.onbootstraperror = (message, details) => {
|
| 525 | + if (cancelled) {
|
|
| 526 | + // We ignore this error since it occurred after cancelling (by
|
|
| 527 | + // the user). We assume the error is just a side effect of the
|
|
| 528 | + // cancelling.
|
|
| 529 | + // E.g. If the cancelling is triggered late in the process, we
|
|
| 530 | + // get "Building circuits: Establishing a Tor circuit failed".
|
|
| 531 | + // TODO: Maybe move this logic deeper in the process to know
|
|
| 532 | + // when to filter out such errors triggered by cancelling.
|
|
| 533 | + console.log(
|
|
| 534 | + `TorConnect: Post-cancel error => ${message}; ${details}`
|
|
| 535 | + );
|
|
| 536 | + return;
|
|
| 537 | + }
|
|
| 523 | 538 | // We have to wait for the Internet test to finish before sending the bootstrap error
|
| 524 | 539 | bootstrapError = message;
|
| 525 | 540 | bootstrapErrorDetails = details;
|
| ... | ... | @@ -1023,11 +1038,6 @@ const TorConnect = (() => { |
| 1023 | 1038 | this._changeState(TorConnectState.AutoBootstrapping, countryCode);
|
| 1024 | 1039 | },
|
| 1025 | 1040 | |
| 1026 | - cancelAutoBootstrap() {
|
|
| 1027 | - console.log("TorConnect: cancelAutoBootstrap()");
|
|
| 1028 | - this._changeState(TorConnectState.Configuring);
|
|
| 1029 | - },
|
|
| 1030 | - |
|
| 1031 | 1041 | /*
|
| 1032 | 1042 | Further external commands and helper methods
|
| 1033 | 1043 | */
|
| ... | ... | @@ -207,10 +207,6 @@ const Loader = { |
| 207 | 207 | |
| 208 | 208 | torConnecting: "Establishing a Connection",
|
| 209 | 209 | |
| 210 | - torNotConnectedConcise: "Not Connected",
|
|
| 211 | - |
|
| 212 | - torConnectingConcise: "Connecting…",
|
|
| 213 | - |
|
| 214 | 210 | tryingAgain: "Trying again…",
|
| 215 | 211 | |
| 216 | 212 | noInternet: "Tor Browser couldn’t reach the Internet",
|
| ... | ... | @@ -250,8 +246,6 @@ const Loader = { |
| 250 | 246 | |
| 251 | 247 | torConnected: "Connected to the Tor network",
|
| 252 | 248 | |
| 253 | - torConnectedConcise: "Connected",
|
|
| 254 | - |
|
| 255 | 249 | tryAgain: "Try Again",
|
| 256 | 250 | |
| 257 | 251 | // tor connect strings for message box in about:preferences#connection
|
| ... | ... | @@ -275,6 +269,13 @@ const Loader = { |
| 275 | 269 | autoBootstrappingAllFailed: "None of the configurations we tried worked",
|
| 276 | 270 | cannotDetermineCountry: "Unable to determine user country",
|
| 277 | 271 | noSettingsForCountry: "No settings available for your location",
|
| 272 | + |
|
| 273 | + // Titlebar status.
|
|
| 274 | + titlebarStatusName: "Tor connection",
|
|
| 275 | + titlebarStatusNotConnected: "Not connected",
|
|
| 276 | + titlebarStatusConnecting: "Connecting…",
|
|
| 277 | + titlebarStatusPotentiallyBlocked: "Potentially blocked",
|
|
| 278 | + titlebarStatusConnected: "Connected",
|
|
| 278 | 279 | };
|
| 279 | 280 | |
| 280 | 281 | const tsb = new TorPropertyStringBundle(
|
| ... | ... | @@ -23,8 +23,8 @@ |
| 23 | 23 | @import url("chrome://browser/skin/UITour.css");
|
| 24 | 24 | @import url("chrome://browser/skin/browser-colors.css");
|
| 25 | 25 | @import url("chrome://branding/content/tor-styles.css");
|
| 26 | -@import url("chrome://browser/skin/torconnect-urlbar.css");
|
|
| 27 | 26 | @import url("chrome://browser/skin/onionlocation.css");
|
| 27 | +@import url("chrome://browser/skin/tor-urlbar-button.css");
|
|
| 28 | 28 | |
| 29 | 29 | @namespace html url("http://www.w3.org/1999/xhtml");
|
| 30 | 30 |
| ... | ... | @@ -32,6 +32,7 @@ |
| 32 | 32 | skin/classic/browser/tabs.css (../shared/tabs.css)
|
| 33 | 33 | skin/classic/browser/toolbarbuttons.css (../shared/toolbarbuttons.css)
|
| 34 | 34 | skin/classic/browser/toolbarbutton-icons.css (../shared/toolbarbutton-icons.css)
|
| 35 | + skin/classic/browser/tor-urlbar-button.css (../shared/tor-urlbar-button.css)
|
|
| 35 | 36 | skin/classic/browser/urlbar-dynamic-results.css (../shared/urlbar-dynamic-results.css)
|
| 36 | 37 | skin/classic/browser/urlbar-searchbar.css (../shared/urlbar-searchbar.css)
|
| 37 | 38 | skin/classic/browser/urlbarView.css (../shared/urlbarView.css)
|
| 1 | +.tor-urlbar-button:not([hidden]) {
|
|
| 2 | + --tor-urlbar-button-background-color: var(--purple-60);
|
|
| 3 | + background-color: var(--tor-urlbar-button-background-color);
|
|
| 4 | + /* FIXME: Use different colors for light and dark theme, rather than "white".
|
|
| 5 | + * See tor-browser#41787 */
|
|
| 6 | + color: white;
|
|
| 7 | + display: flex;
|
|
| 8 | + align-items: center;
|
|
| 9 | + gap: 0.5em;
|
|
| 10 | + border-radius: var(--urlbar-icon-border-radius);
|
|
| 11 | + --tor-urlbar-button-inline-padding: 8px;
|
|
| 12 | + padding-inline: var(--tor-urlbar-button-inline-padding);
|
|
| 13 | + margin: 0;
|
|
| 14 | +}
|
|
| 15 | + |
|
| 16 | +.tor-urlbar-button > * {
|
|
| 17 | + flex: 0 0 auto;
|
|
| 18 | + margin: 0;
|
|
| 19 | +}
|
|
| 20 | + |
|
| 21 | +.tor-urlbar-button:focus-visible {
|
|
| 22 | + /* This button lies within the urlbar, so if the outline extends beyond the
|
|
| 23 | + * button's boundary, it will be clipped by the urlbar.
|
|
| 24 | + * Most button's in the urlbar get around this by using --focus-outline-inset,
|
|
| 25 | + * but our button has a purple background, which does not contrast well with
|
|
| 26 | + * the focus outline.
|
|
| 27 | + * Therefore, we use an offset outline rather than an inset outline, and
|
|
| 28 | + * compensate by shrinking the button's width and height so that the outline
|
|
| 29 | + * fits within the non-focused button boundary. Essentially, this has a
|
|
| 30 | + * similar effect to using an inset outline that matches the color of the
|
|
| 31 | + * urlbar background, but we keep the rounded corners. */
|
|
| 32 | + outline: var(--focus-outline);
|
|
| 33 | + outline-offset: var(--focus-outline-offset);
|
|
| 34 | + /* Use the background color for the outline, same as in-content buttons. */
|
|
| 35 | + outline-color: var(--tor-urlbar-button-background-color);
|
|
| 36 | + /* Calculate the difference between the button's border area and the outline
|
|
| 37 | + * area. */
|
|
| 38 | + --tor-urlbar-focus-outline-difference: calc(
|
|
| 39 | + var(--focus-outline-offset)
|
|
| 40 | + + var(--focus-outline-width)
|
|
| 41 | + );
|
|
| 42 | + /* For the inline direction, we shrink the padding by the difference, and
|
|
| 43 | + * increase the margin by the same amount so that the button text remains in
|
|
| 44 | + * the same position.
|
|
| 45 | + * For the block direction, the height of the button is flexibly sized with
|
|
| 46 | + * the urlbar height, so we should only need to increase the margin. */
|
|
| 47 | + padding-inline: calc(
|
|
| 48 | + var(--tor-urlbar-button-inline-padding)
|
|
| 49 | + - var(--tor-urlbar-focus-outline-difference)
|
|
| 50 | + );
|
|
| 51 | + margin: var(--tor-urlbar-focus-outline-difference);
|
|
| 52 | +}
|
|
| 53 | + |
|
| 54 | +.tor-urlbar-button:focus-visible > * {
|
|
| 55 | + /* Negate the margin that would be added on focus to ensure the button does
|
|
| 56 | + * not grow in height.
|
|
| 57 | + * Ideally, this should not change anything noticeable, otherwise the text
|
|
| 58 | + * could be clipped when focused. */
|
|
| 59 | + margin-block: calc(-1 * var(--tor-urlbar-focus-outline-difference));
|
|
| 60 | +}
|
|
| 61 | + |
|
| 62 | +#urlbar[usertyping] .tor-urlbar-button {
|
|
| 63 | + /* Hide whilst the user is typing in the url bar. */
|
|
| 64 | + display: none;
|
|
| 65 | +}
|
|
| 66 | + |
|
| 67 | +.tor-urlbar-button:hover {
|
|
| 68 | + --tor-urlbar-button-background-color: var(--purple-70);
|
|
| 69 | +}
|
|
| 70 | + |
|
| 71 | +.tor-urlbar-button:hover:active {
|
|
| 72 | + --tor-urlbar-button-background-color: var(--purple-80);
|
|
| 73 | +}
|
|
| 74 | + |
|
| 75 | +@media (prefers-color-scheme: dark) {
|
|
| 76 | + .tor-urlbar-button {
|
|
| 77 | + --tor-urlbar-button-background-color: var(--purple-50);
|
|
| 78 | + }
|
|
| 79 | + |
|
| 80 | + .tor-urlbar-button:hover {
|
|
| 81 | + --tor-urlbar-button-background-color: var(--purple-60);
|
|
| 82 | + }
|
|
| 83 | + |
|
| 84 | + .tor-urlbar-button:hover:active {
|
|
| 85 | + --tor-urlbar-button-background-color: var(--purple-70);
|
|
| 86 | + }
|
|
| 87 | +}
|
|
| 88 | + |
|
| 89 | +/* Make the button look plain like the identity #urlbar-label-box. */
|
|
| 90 | +.tor-urlbar-button.tor-urlbar-button-plain {
|
|
| 91 | + --tor-urlbar-button-background-color: var(--urlbar-box-bgcolor);
|
|
| 92 | + color: var(--urlbar-box-text-color);
|
|
| 93 | +}
|
|
| 94 | + |
|
| 95 | +.tor-urlbar-button.tor-urlbar-button-plain:focus-visible {
|
|
| 96 | + outline-color: var(--focus-outline-color);
|
|
| 97 | +}
|
|
| 98 | + |
|
| 99 | +.tor-urlbar-button.tor-urlbar-button-plain:hover {
|
|
| 100 | + --tor-urlbar-button-background-color: var(--urlbar-box-hover-bgcolor);
|
|
| 101 | + color: var(--urlbar-box-hover-text-color);
|
|
| 102 | +}
|
|
| 103 | + |
|
| 104 | +.tor-urlbar-button.tor-urlbar-button-plain:hover:active {
|
|
| 105 | + --tor-urlbar-button-background-color: var(--urlbar-box-active-bgcolor);
|
|
| 106 | + color: var(--urlbar-box-hover-text-color);
|
|
| 107 | +} |
| ... | ... | @@ -3,10 +3,14 @@ |
| 3 | 3 | # License, v. 2.0. If a copy of the MPL was not distributed with this
|
| 4 | 4 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
| 5 | 5 | |
| 6 | +torConnect.titlebarStatusName=Tor connection
|
|
| 7 | +torConnect.titlebarStatusNotConnected=Not connected
|
|
| 8 | +torConnect.titlebarStatusConnecting=Connecting…
|
|
| 9 | +torConnect.titlebarStatusPotentiallyBlocked=Potentially blocked
|
|
| 10 | +torConnect.titlebarStatusConnected=Connected
|
|
| 11 | + |
|
| 6 | 12 | torConnect.torConnect=Connect to Tor
|
| 7 | 13 | torConnect.torConnecting=Establishing a Connection
|
| 8 | -torConnect.torNotConnectedConcise=Not Connected
|
|
| 9 | -torConnect.torConnectingConcise=Connecting…
|
|
| 10 | 14 | torConnect.tryingAgain=Trying again…
|
| 11 | 15 | torConnect.noInternet=Tor Browser couldn’t reach the Internet
|
| 12 | 16 | torConnect.noInternetDescription=This could be due to a connection issue rather than Tor being blocked. Check your Internet connection, proxy and firewall settings before trying again.
|
| ... | ... | @@ -35,7 +39,6 @@ torConnect.viewLog=View logs… |
| 35 | 39 | torConnect.torConnectButton=Connect
|
| 36 | 40 | torConnect.cancel=Cancel
|
| 37 | 41 | torConnect.torConnected=Connected to the Tor network!
|
| 38 | -torConnect.torConnectedConcise=Connected
|
|
| 39 | 42 | torConnect.tryAgain=Try Again
|
| 40 | 43 | torConnect.connectMessage=Changes to Tor Settings will not take effect until you connect
|
| 41 | 44 | torConnect.tryAgainMessage=Tor Browser has failed to establish a connection to the Tor Network
|
| ... | ... | @@ -51,3 +54,8 @@ torConnect.autoBootstrappingFailed=Automatic configuration failed |
| 51 | 54 | torConnect.autoBootstrappingAllFailed=None of the configurations we tried worked
|
| 52 | 55 | torConnect.cannotDetermineCountry=Unable to determine user country
|
| 53 | 56 | torConnect.noSettingsForCountry=No settings available for your location
|
| 57 | + |
|
| 58 | +# Urlbar strings used up to 12.0 - TODO: remove when 12.5 becomes stable:
|
|
| 59 | +torConnect.torNotConnectedConcise=Not Connected
|
|
| 60 | +torConnect.torConnectingConcise=Connecting…
|
|
| 61 | +torConnect.torConnectedConcise=Connected |