morgan pushed to branch tor-browser-128.5.0esr-14.5-2 at The Tor Project / Applications / Tor Browser
Commits:
-
46eb7528
by Henry Wilkes at 2024-12-19T11:13:03+00:00
-
018492cc
by Henry Wilkes at 2024-12-19T11:13:15+00:00
3 changed files:
- browser/components/torpreferences/content/connectionPane.js
- browser/components/torpreferences/content/connectionPane.xhtml
- browser/components/torpreferences/content/torPreferences.css
Changes:
| ... | ... | @@ -346,7 +346,7 @@ const gBridgeGrid = { |
| 346 | 346 | |
| 347 | 347 | Services.obs.addObserver(this, TorProviderTopics.BridgeChanged);
|
| 348 | 348 | |
| 349 | - this._grid.classList.add("grid-active");
|
|
| 349 | + this._grid.hidden = false;
|
|
| 350 | 350 | |
| 351 | 351 | this._updateConnectedBridge();
|
| 352 | 352 | },
|
| ... | ... | @@ -363,7 +363,7 @@ const gBridgeGrid = { |
| 363 | 363 | |
| 364 | 364 | this._forceCloseRowMenus();
|
| 365 | 365 | |
| 366 | - this._grid.classList.remove("grid-active");
|
|
| 366 | + this._grid.hidden = true;
|
|
| 367 | 367 | |
| 368 | 368 | Services.obs.removeObserver(this, TorProviderTopics.BridgeChanged);
|
| 369 | 369 | },
|
| ... | ... | @@ -1023,7 +1023,7 @@ const gBuiltinBridgesArea = { |
| 1023 | 1023 | |
| 1024 | 1024 | Services.obs.addObserver(this, TorProviderTopics.BridgeChanged);
|
| 1025 | 1025 | |
| 1026 | - this._area.classList.add("built-in-active");
|
|
| 1026 | + this._area.hidden = false;
|
|
| 1027 | 1027 | |
| 1028 | 1028 | this._updateBridgeIds();
|
| 1029 | 1029 | this._updateConnectedBridge();
|
| ... | ... | @@ -1038,7 +1038,7 @@ const gBuiltinBridgesArea = { |
| 1038 | 1038 | }
|
| 1039 | 1039 | this._active = false;
|
| 1040 | 1040 | |
| 1041 | - this._area.classList.remove("built-in-active");
|
|
| 1041 | + this._area.hidden = true;
|
|
| 1042 | 1042 | |
| 1043 | 1043 | Services.obs.removeObserver(this, TorProviderTopics.BridgeChanged);
|
| 1044 | 1044 | },
|
| ... | ... | @@ -1243,11 +1243,19 @@ const gLoxStatus = { |
| 1243 | 1243 | */
|
| 1244 | 1244 | _detailsArea: null,
|
| 1245 | 1245 | /**
|
| 1246 | - * The day counter for the next unlock.
|
|
| 1246 | + * The list items showing the next unlocks.
|
|
| 1247 | 1247 | *
|
| 1248 | - * @type {Element?}
|
|
| 1248 | + * @type {?Object<string, Element>}
|
|
| 1249 | + */
|
|
| 1250 | + _nextUnlockItems: null,
|
|
| 1251 | + /**
|
|
| 1252 | + * The day counter headings for the next unlock.
|
|
| 1253 | + *
|
|
| 1254 | + * One heading is shown during a search, the other is shown otherwise.
|
|
| 1255 | + *
|
|
| 1256 | + * @type {?Element[]}
|
|
| 1249 | 1257 | */
|
| 1250 | - _nextUnlockCounterEl: null,
|
|
| 1258 | + _nextUnlockCounterEls: null,
|
|
| 1251 | 1259 | /**
|
| 1252 | 1260 | * Shows the number of remaining invites.
|
| 1253 | 1261 | *
|
| ... | ... | @@ -1266,6 +1274,12 @@ const gLoxStatus = { |
| 1266 | 1274 | * @type {Element?}
|
| 1267 | 1275 | */
|
| 1268 | 1276 | _unlockAlert: null,
|
| 1277 | + /**
|
|
| 1278 | + * The list items showing the unlocks.
|
|
| 1279 | + *
|
|
| 1280 | + * @type {?Object<string, Element>}
|
|
| 1281 | + */
|
|
| 1282 | + _unlockItems: null,
|
|
| 1269 | 1283 | /**
|
| 1270 | 1284 | * The alert title.
|
| 1271 | 1285 | *
|
| ... | ... | @@ -1296,8 +1310,19 @@ const gLoxStatus = { |
| 1296 | 1310 | |
| 1297 | 1311 | this._area = document.getElementById("tor-bridges-lox-status");
|
| 1298 | 1312 | this._detailsArea = document.getElementById("tor-bridges-lox-details");
|
| 1299 | - this._nextUnlockCounterEl = document.getElementById(
|
|
| 1300 | - "tor-bridges-lox-next-unlock-counter"
|
|
| 1313 | + this._nextUnlockItems = {
|
|
| 1314 | + gainBridges: document.getElementById(
|
|
| 1315 | + "tor-bridges-lox-next-unlock-gain-bridges"
|
|
| 1316 | + ),
|
|
| 1317 | + firstInvites: document.getElementById(
|
|
| 1318 | + "tor-bridges-lox-next-unlock-first-invites"
|
|
| 1319 | + ),
|
|
| 1320 | + moreInvites: document.getElementById(
|
|
| 1321 | + "tor-bridges-lox-next-unlock-more-invites"
|
|
| 1322 | + ),
|
|
| 1323 | + };
|
|
| 1324 | + this._nextUnlockCounterEls = Array.from(
|
|
| 1325 | + document.querySelectorAll(".tor-bridges-lox-next-unlock-counter")
|
|
| 1301 | 1326 | );
|
| 1302 | 1327 | this._remainingInvitesEl = document.getElementById(
|
| 1303 | 1328 | "tor-bridges-lox-remaining-invites"
|
| ... | ... | @@ -1306,6 +1331,15 @@ const gLoxStatus = { |
| 1306 | 1331 | "tor-bridges-lox-show-invites-button"
|
| 1307 | 1332 | );
|
| 1308 | 1333 | this._unlockAlert = document.getElementById("tor-bridges-lox-unlock-alert");
|
| 1334 | + this._unlockItems = {
|
|
| 1335 | + gainBridges: document.getElementById(
|
|
| 1336 | + "tor-bridges-lox-unlock-alert-gain-bridges"
|
|
| 1337 | + ),
|
|
| 1338 | + newBridges: document.getElementById(
|
|
| 1339 | + "tor-bridges-lox-unlock-alert-new-bridges"
|
|
| 1340 | + ),
|
|
| 1341 | + invites: document.getElementById("tor-bridges-lox-unlock-alert-invites"),
|
|
| 1342 | + };
|
|
| 1309 | 1343 | this._unlockAlertTitle = document.getElementById(
|
| 1310 | 1344 | "tor-bridge-unlock-alert-title"
|
| 1311 | 1345 | );
|
| ... | ... | @@ -1404,6 +1438,7 @@ const gLoxStatus = { |
| 1404 | 1438 | return;
|
| 1405 | 1439 | }
|
| 1406 | 1440 | this._loxId = loxId;
|
| 1441 | + this._area.hidden = !loxId;
|
|
| 1407 | 1442 | // We unset _nextUnlock to ensure the areas no longer use the old value for
|
| 1408 | 1443 | // the new loxId.
|
| 1409 | 1444 | this._updateNextUnlock(true);
|
| ... | ... | @@ -1518,8 +1553,8 @@ const gLoxStatus = { |
| 1518 | 1553 | // Uninitialized or no Lox source.
|
| 1519 | 1554 | // NOTE: This area may already be hidden by the change in Lox source,
|
| 1520 | 1555 | // but we clean up for the next non-empty id.
|
| 1521 | - this._area.classList.remove("show-unlock-alert");
|
|
| 1522 | - this._area.classList.remove("show-next-unlock");
|
|
| 1556 | + this._unlockAlert.hidden = true;
|
|
| 1557 | + this._detailsArea.hidden = true;
|
|
| 1523 | 1558 | return;
|
| 1524 | 1559 | }
|
| 1525 | 1560 | |
| ... | ... | @@ -1529,8 +1564,8 @@ const gLoxStatus = { |
| 1529 | 1564 | |
| 1530 | 1565 | const pendingEvents = this._pendingEvents;
|
| 1531 | 1566 | const showAlert = !!pendingEvents.length;
|
| 1532 | - this._area.classList.toggle("show-unlock-alert", showAlert);
|
|
| 1533 | - this._area.classList.toggle("show-next-unlock", !showAlert);
|
|
| 1567 | + this._unlockAlert.hidden = !showAlert;
|
|
| 1568 | + this._detailsArea.hidden = showAlert;
|
|
| 1534 | 1569 | |
| 1535 | 1570 | if (showAlert) {
|
| 1536 | 1571 | // At level 0 and level 1, we do not have any invites.
|
| ... | ... | @@ -1567,6 +1602,7 @@ const gLoxStatus = { |
| 1567 | 1602 | blockage = true;
|
| 1568 | 1603 | }
|
| 1569 | 1604 | }
|
| 1605 | + |
|
| 1570 | 1606 | let alertTitleId;
|
| 1571 | 1607 | if (levelUp && !blockage) {
|
| 1572 | 1608 | alertTitleId = "tor-bridges-lox-upgrade";
|
| ... | ... | @@ -1585,9 +1621,9 @@ const gLoxStatus = { |
| 1585 | 1621 | "lox-unlock-upgrade",
|
| 1586 | 1622 | levelUp && !blockage
|
| 1587 | 1623 | );
|
| 1588 | - this._unlockAlert.classList.toggle("lox-unlock-new-bridges", blockage);
|
|
| 1589 | - this._unlockAlert.classList.toggle("lox-unlock-gain-bridges", bridgeGain);
|
|
| 1590 | - this._unlockAlert.classList.toggle("lox-unlock-invites", showInvites);
|
|
| 1624 | + this._unlockItems.gainBridges.hidden = !bridgeGain;
|
|
| 1625 | + this._unlockItems.newBridges.hidden = !blockage;
|
|
| 1626 | + this._unlockItems.invites.hidden = !showInvites;
|
|
| 1591 | 1627 | } else {
|
| 1592 | 1628 | // Show next unlock.
|
| 1593 | 1629 | // Number of days until the next unlock, rounded up.
|
| ... | ... | @@ -1598,29 +1634,42 @@ const gLoxStatus = { |
| 1598 | 1634 | (24 * 60 * 60 * 1000)
|
| 1599 | 1635 | )
|
| 1600 | 1636 | );
|
| 1601 | - document.l10n.setAttributes(
|
|
| 1602 | - this._nextUnlockCounterEl,
|
|
| 1603 | - "tor-bridges-lox-days-until-unlock",
|
|
| 1604 | - { numDays }
|
|
| 1605 | - );
|
|
| 1637 | + for (const counterEl of this._nextUnlockCounterEls) {
|
|
| 1638 | + document.l10n.setAttributes(
|
|
| 1639 | + counterEl,
|
|
| 1640 | + "tor-bridges-lox-days-until-unlock",
|
|
| 1641 | + { numDays }
|
|
| 1642 | + );
|
|
| 1643 | + }
|
|
| 1606 | 1644 | |
| 1607 | 1645 | // Gain 2 bridges from level 0 to 1. After that gain invites.
|
| 1608 | - const bridgeGain = this._nextUnlock.nextLevel === 1;
|
|
| 1609 | - const firstInvites = this._nextUnlock.nextLevel === 2;
|
|
| 1610 | - const moreInvites = this._nextUnlock.nextLevel > 2;
|
|
| 1611 | - |
|
| 1612 | - this._detailsArea.classList.toggle("lox-next-gain-bridges", bridgeGain);
|
|
| 1613 | - this._detailsArea.classList.toggle(
|
|
| 1614 | - "lox-next-first-invites",
|
|
| 1615 | - firstInvites
|
|
| 1616 | - );
|
|
| 1617 | - this._detailsArea.classList.toggle("lox-next-more-invites", moreInvites);
|
|
| 1646 | + this._nextUnlockItems.gainBridges.hidden =
|
|
| 1647 | + this._nextUnlock.nextLevel !== 1;
|
|
| 1648 | + this._nextUnlockItems.firstInvites.hidden =
|
|
| 1649 | + this._nextUnlock.nextLevel !== 2;
|
|
| 1650 | + this._nextUnlockItems.moreInvites.hidden =
|
|
| 1651 | + this._nextUnlock.nextLevel <= 2;
|
|
| 1618 | 1652 | }
|
| 1619 | 1653 | |
| 1620 | 1654 | if (alertHadFocus && !showAlert) {
|
| 1621 | 1655 | // Alert has become hidden, move focus back up to the now revealed details
|
| 1622 | 1656 | // area.
|
| 1623 | - this._nextUnlockCounterEl.focus();
|
|
| 1657 | + // NOTE: We have two headings: one shown during a search and one shown
|
|
| 1658 | + // otherwise. We focus the heading that is currently visible.
|
|
| 1659 | + // See tor-browser#43320.
|
|
| 1660 | + // TODO: It might be better if we could use the # named anchor to
|
|
| 1661 | + // re-orient the screen reader position instead of using tabIndex=-1, but
|
|
| 1662 | + // about:preferences currently uses the anchor for showing categories
|
|
| 1663 | + // only. See bugzilla bug 1799153.
|
|
| 1664 | + if (
|
|
| 1665 | + this._nextUnlockCounterEls[0].checkVisibility({
|
|
| 1666 | + visibilityProperty: true,
|
|
| 1667 | + })
|
|
| 1668 | + ) {
|
|
| 1669 | + this._nextUnlockCounterEls[0].focus();
|
|
| 1670 | + } else {
|
|
| 1671 | + this._nextUnlockCounterEls[1].focus();
|
|
| 1672 | + }
|
|
| 1624 | 1673 | } else if (detailsHadFocus && showAlert) {
|
| 1625 | 1674 | this._unlockAlertButton.focus();
|
| 1626 | 1675 | }
|
| ... | ... | @@ -1642,21 +1691,21 @@ const gLoxStatus = { |
| 1642 | 1691 | hasInvites = this._haveExistingInvites || !!this._remainingInvites;
|
| 1643 | 1692 | }
|
| 1644 | 1693 | |
| 1645 | - if (!hasInvites) {
|
|
| 1646 | - if (
|
|
| 1647 | - this._remainingInvitesEl.contains(document.activeElement) ||
|
|
| 1648 | - this._invitesButton.contains(document.activeElement)
|
|
| 1649 | - ) {
|
|
| 1650 | - // About to loose focus.
|
|
| 1651 | - // Unexpected for the lox level to loose all invites.
|
|
| 1652 | - // Move to the top of the details area, which should be visible if we
|
|
| 1653 | - // just had focus.
|
|
| 1654 | - this._nextUnlockCounterEl.focus();
|
|
| 1655 | - }
|
|
| 1694 | + if (
|
|
| 1695 | + !hasInvites &&
|
|
| 1696 | + (this._remainingInvitesEl.contains(document.activeElement) ||
|
|
| 1697 | + this._invitesButton.contains(document.activeElement))
|
|
| 1698 | + ) {
|
|
| 1699 | + // About to loose focus.
|
|
| 1700 | + // Unexpected for the lox level to loose all invites.
|
|
| 1701 | + // Move to the top of the details area, which should be visible if we
|
|
| 1702 | + // just had focus.
|
|
| 1703 | + this._nextUnlockCounterEl.focus();
|
|
| 1656 | 1704 | }
|
| 1657 | 1705 | // Hide the invite elements if we have no historic invites or a way of
|
| 1658 | 1706 | // creating new ones.
|
| 1659 | - this._detailsArea.classList.toggle("lox-has-invites", hasInvites);
|
|
| 1707 | + this._remainingInvitesEl.hidden = !hasInvites;
|
|
| 1708 | + this._invitesButton.hidden = !hasInvites;
|
|
| 1660 | 1709 | |
| 1661 | 1710 | if (hasInvites) {
|
| 1662 | 1711 | document.l10n.setAttributes(
|
| ... | ... | @@ -1691,17 +1740,27 @@ const gBridgeSettings = { |
| 1691 | 1740 | */
|
| 1692 | 1741 | _bridgesEl: null,
|
| 1693 | 1742 | /**
|
| 1694 | - * The heading for the bridge settings.
|
|
| 1743 | + * The area for sharing bridge addresses.
|
|
| 1695 | 1744 | *
|
| 1696 | 1745 | * @type {Element?}
|
| 1697 | 1746 | */
|
| 1698 | - _bridgesSettingsHeading: null,
|
|
| 1747 | + _shareEl: null,
|
|
| 1748 | + /**
|
|
| 1749 | + * The two headings for the bridge settings.
|
|
| 1750 | + *
|
|
| 1751 | + * One heading is shown during a search, the other is shown otherwise.
|
|
| 1752 | + *
|
|
| 1753 | + * @type {?Element[]}
|
|
| 1754 | + */
|
|
| 1755 | + _bridgesSettingsHeadings: null,
|
|
| 1699 | 1756 | /**
|
| 1700 | - * The current bridges heading, at the start of the area.
|
|
| 1757 | + * The two headings for the current bridges, at the start of the area.
|
|
| 1758 | + *
|
|
| 1759 | + * One heading is shown during a search, the other is shown otherwise.
|
|
| 1701 | 1760 | *
|
| 1702 | 1761 | * @type {Element?}
|
| 1703 | 1762 | */
|
| 1704 | - _currentBridgesHeading: null,
|
|
| 1763 | + _currentBridgesHeadings: null,
|
|
| 1705 | 1764 | /**
|
| 1706 | 1765 | * The area for showing no bridges.
|
| 1707 | 1766 | *
|
| ... | ... | @@ -1709,17 +1768,25 @@ const gBridgeSettings = { |
| 1709 | 1768 | */
|
| 1710 | 1769 | _noBridgesEl: null,
|
| 1711 | 1770 | /**
|
| 1712 | - * The heading element for changing bridges.
|
|
| 1771 | + * The heading elements for changing bridges.
|
|
| 1713 | 1772 | *
|
| 1714 | - * @type {Element?}
|
|
| 1773 | + * One heading is shown during a search, the other is shown otherwise.
|
|
| 1774 | + *
|
|
| 1775 | + * @type {?Element[]}
|
|
| 1715 | 1776 | */
|
| 1716 | - _changeHeadingEl: null,
|
|
| 1777 | + _changeHeadingEls: null,
|
|
| 1717 | 1778 | /**
|
| 1718 | 1779 | * The button for user to provide a bridge address or share code.
|
| 1719 | 1780 | *
|
| 1720 | 1781 | * @type {Element?}
|
| 1721 | 1782 | */
|
| 1722 | 1783 | _userProvideButton: null,
|
| 1784 | + /**
|
|
| 1785 | + * A map from the bridge source to its corresponding label.
|
|
| 1786 | + *
|
|
| 1787 | + * @type {?Map<number, Element>}
|
|
| 1788 | + */
|
|
| 1789 | + _sourceLabels: null,
|
|
| 1723 | 1790 | |
| 1724 | 1791 | /**
|
| 1725 | 1792 | * Initialize the bridge settings.
|
| ... | ... | @@ -1727,15 +1794,33 @@ const gBridgeSettings = { |
| 1727 | 1794 | init() {
|
| 1728 | 1795 | gBridgesNotification.init();
|
| 1729 | 1796 | |
| 1730 | - this._bridgesSettingsHeading = document.getElementById(
|
|
| 1731 | - "torPreferences-bridges-header"
|
|
| 1797 | + this._bridgesSettingsHeadings = Array.from(
|
|
| 1798 | + document.querySelectorAll(".tor-bridges-subcategory-heading")
|
|
| 1732 | 1799 | );
|
| 1733 | - this._currentBridgesHeading = document.getElementById(
|
|
| 1734 | - "tor-bridges-current-heading"
|
|
| 1800 | + this._currentBridgesHeadings = Array.from(
|
|
| 1801 | + document.querySelectorAll(".tor-bridges-current-heading")
|
|
| 1735 | 1802 | );
|
| 1736 | 1803 | this._bridgesEl = document.getElementById("tor-bridges-current");
|
| 1737 | 1804 | this._noBridgesEl = document.getElementById("tor-bridges-none");
|
| 1738 | 1805 | this._groupEl = document.getElementById("torPreferences-bridges-group");
|
| 1806 | + |
|
| 1807 | + this._sourceLabels = new Map([
|
|
| 1808 | + [
|
|
| 1809 | + TorBridgeSource.BuiltIn,
|
|
| 1810 | + document.getElementById("tor-bridges-built-in-label"),
|
|
| 1811 | + ],
|
|
| 1812 | + [
|
|
| 1813 | + TorBridgeSource.UserProvided,
|
|
| 1814 | + document.getElementById("tor-bridges-user-label"),
|
|
| 1815 | + ],
|
|
| 1816 | + [
|
|
| 1817 | + TorBridgeSource.BridgeDB,
|
|
| 1818 | + document.getElementById("tor-bridges-requested-label"),
|
|
| 1819 | + ],
|
|
| 1820 | + [TorBridgeSource.Lox, document.getElementById("tor-bridges-lox-label")],
|
|
| 1821 | + ]);
|
|
| 1822 | + this._shareEl = document.getElementById("tor-bridges-share");
|
|
| 1823 | + |
|
| 1739 | 1824 | this._toggleButton = document.getElementById("tor-bridges-enabled-toggle");
|
| 1740 | 1825 | // Initially disabled whilst TorSettings may not be initialized.
|
| 1741 | 1826 | this._toggleButton.disabled = true;
|
| ... | ... | @@ -1749,8 +1834,8 @@ const gBridgeSettings = { |
| 1749 | 1834 | });
|
| 1750 | 1835 | });
|
| 1751 | 1836 | |
| 1752 | - this._changeHeadingEl = document.getElementById(
|
|
| 1753 | - "tor-bridges-change-heading"
|
|
| 1837 | + this._changeHeadingEls = Array.from(
|
|
| 1838 | + document.querySelectorAll(".tor-bridges-change-heading")
|
|
| 1754 | 1839 | );
|
| 1755 | 1840 | this._userProvideButton = document.getElementById(
|
| 1756 | 1841 | "tor-bridges-open-user-provide-dialog-button"
|
| ... | ... | @@ -1855,6 +1940,12 @@ const gBridgeSettings = { |
| 1855 | 1940 | * @type {integer?}
|
| 1856 | 1941 | */
|
| 1857 | 1942 | _bridgeSource: null,
|
| 1943 | + /**
|
|
| 1944 | + * Whether the user is encouraged to share their bridge addresses.
|
|
| 1945 | + *
|
|
| 1946 | + * @type {boolean}
|
|
| 1947 | + */
|
|
| 1948 | + _canShare: false,
|
|
| 1858 | 1949 | |
| 1859 | 1950 | /**
|
| 1860 | 1951 | * Update _bridgeSource.
|
| ... | ... | @@ -1876,22 +1967,15 @@ const gBridgeSettings = { |
| 1876 | 1967 | this._bridgesEl.contains(document.activeElement) ||
|
| 1877 | 1968 | this._noBridgesEl.contains(document.activeElement);
|
| 1878 | 1969 | |
| 1879 | - this._bridgesEl.classList.toggle(
|
|
| 1880 | - "source-built-in",
|
|
| 1881 | - bridgeSource === TorBridgeSource.BuiltIn
|
|
| 1882 | - );
|
|
| 1883 | - this._bridgesEl.classList.toggle(
|
|
| 1884 | - "source-user",
|
|
| 1885 | - bridgeSource === TorBridgeSource.UserProvided
|
|
| 1886 | - );
|
|
| 1887 | - this._bridgesEl.classList.toggle(
|
|
| 1888 | - "source-requested",
|
|
| 1889 | - bridgeSource === TorBridgeSource.BridgeDB
|
|
| 1890 | - );
|
|
| 1891 | - this._bridgesEl.classList.toggle(
|
|
| 1892 | - "source-lox",
|
|
| 1893 | - bridgeSource === TorBridgeSource.Lox
|
|
| 1894 | - );
|
|
| 1970 | + for (const [source, labelEl] of this._sourceLabels.entries()) {
|
|
| 1971 | + labelEl.hidden = source !== bridgeSource;
|
|
| 1972 | + }
|
|
| 1973 | + |
|
| 1974 | + this._canShare =
|
|
| 1975 | + bridgeSource === TorBridgeSource.UserProvided ||
|
|
| 1976 | + bridgeSource === TorBridgeSource.BridgeDB;
|
|
| 1977 | + |
|
| 1978 | + this._shareEl.hidden = !this._canShare;
|
|
| 1895 | 1979 | |
| 1896 | 1980 | // Force the menu to close whenever the source changes.
|
| 1897 | 1981 | // NOTE: If the menu had focus then hadFocus will be true, and focus will be
|
| ... | ... | @@ -1937,15 +2021,18 @@ const gBridgeSettings = { |
| 1937 | 2021 | // Add classes to show or hide the "no bridges" and "Your bridges" sections.
|
| 1938 | 2022 | // NOTE: Before haveBridges is set, neither class is added, so both sections
|
| 1939 | 2023 | // and hidden.
|
| 1940 | - this._groupEl.classList.toggle("no-bridges", !haveBridges);
|
|
| 1941 | - this._groupEl.classList.toggle("have-bridges", haveBridges);
|
|
| 2024 | + this._groupEl.classList.add("bridges-initialized");
|
|
| 2025 | + this._bridgesEl.hidden = !haveBridges;
|
|
| 2026 | + this._noBridgesEl.hidden = haveBridges;
|
|
| 1942 | 2027 | |
| 1943 | - document.l10n.setAttributes(
|
|
| 1944 | - this._changeHeadingEl,
|
|
| 1945 | - haveBridges
|
|
| 1946 | - ? "tor-bridges-replace-bridges-heading"
|
|
| 1947 | - : "tor-bridges-add-bridges-heading"
|
|
| 1948 | - );
|
|
| 2028 | + for (const headingEl of this._changeHeadingEls) {
|
|
| 2029 | + document.l10n.setAttributes(
|
|
| 2030 | + headingEl,
|
|
| 2031 | + haveBridges
|
|
| 2032 | + ? "tor-bridges-replace-bridges-heading"
|
|
| 2033 | + : "tor-bridges-add-bridges-heading"
|
|
| 2034 | + );
|
|
| 2035 | + }
|
|
| 1949 | 2036 | document.l10n.setAttributes(
|
| 1950 | 2037 | this._userProvideButton,
|
| 1951 | 2038 | haveBridges ? "tor-bridges-replace-button" : "tor-bridges-add-new-button"
|
| ... | ... | @@ -1964,17 +2051,27 @@ const gBridgeSettings = { |
| 1964 | 2051 | }
|
| 1965 | 2052 | |
| 1966 | 2053 | // Make sure we have the latest value for _haveBridges.
|
| 1967 | - // We also ensure that the _currentBridgesHeading element is visible before
|
|
| 2054 | + // We also ensure that the _currentBridgesHeadings element is visible before
|
|
| 1968 | 2055 | // we focus it.
|
| 1969 | 2056 | this._updateHaveBridges();
|
| 1970 | - if (this._haveBridges) {
|
|
| 1971 | - // Move focus to the start of the area, which is the heading.
|
|
| 1972 | - // It has tabindex="-1" so should be focusable, even though it is not part
|
|
| 1973 | - // of the usual tab navigation.
|
|
| 1974 | - this._currentBridgesHeading.focus();
|
|
| 2057 | + |
|
| 2058 | + // Move focus to the start of the relevant section, which is a heading.
|
|
| 2059 | + // They have tabindex="-1" so should be focusable, even though they are not
|
|
| 2060 | + // part of the usual tab navigation.
|
|
| 2061 | + // NOTE: We have two headings: one shown during a search and one shown
|
|
| 2062 | + // otherwise. We focus the heading that is currently visible.
|
|
| 2063 | + // See tor-browser#43320.
|
|
| 2064 | + // TODO: It might be better if we could use the # named anchor to
|
|
| 2065 | + // re-orient the screen reader position instead of using tabIndex=-1, but
|
|
| 2066 | + // about:preferences currently uses the anchor for showing categories
|
|
| 2067 | + // only. See bugzilla bug 1799153.
|
|
| 2068 | + const focusHeadings = this._haveBridges
|
|
| 2069 | + ? this._currentBridgesHeadings // The heading above the new bridges.
|
|
| 2070 | + : this._bridgesSettingsHeadings; // The top of the bridge settings.
|
|
| 2071 | + if (focusHeadings[0].checkVisibility({ visibilityProperty: true })) {
|
|
| 2072 | + focusHeadings[0].focus();
|
|
| 1975 | 2073 | } else {
|
| 1976 | - // Move focus to the top of the bridge settings.
|
|
| 1977 | - this._bridgesSettingsHeading.focus();
|
|
| 2074 | + focusHeadings[1].focus();
|
|
| 1978 | 2075 | }
|
| 1979 | 2076 | },
|
| 1980 | 2077 | |
| ... | ... | @@ -2126,10 +2223,7 @@ const gBridgeSettings = { |
| 2126 | 2223 | });
|
| 2127 | 2224 | |
| 2128 | 2225 | this._bridgesMenu.addEventListener("showing", () => {
|
| 2129 | - const canShare =
|
|
| 2130 | - this._bridgeSource === TorBridgeSource.UserProvided ||
|
|
| 2131 | - this._bridgeSource === TorBridgeSource.BridgeDB;
|
|
| 2132 | - qrItem.hidden = !canShare || !this._canQRBridges;
|
|
| 2226 | + qrItem.hidden = !this._canShare || !this._canQRBridges;
|
|
| 2133 | 2227 | editItem.hidden = this._bridgeSource !== TorBridgeSource.UserProvided;
|
| 2134 | 2228 | });
|
| 2135 | 2229 |
| ... | ... | @@ -97,8 +97,8 @@ |
| 97 | 97 | <!-- Bridges -->
|
| 98 | 98 | <hbox class="subcategory" data-category="paneConnection" hidden="true">
|
| 99 | 99 | <html:h1
|
| 100 | - id="torPreferences-bridges-header"
|
|
| 101 | - class="tor-focusable-heading"
|
|
| 100 | + id="tor-bridges-subcategory-heading-non-search"
|
|
| 101 | + class="tor-bridges-subcategory-heading tor-focusable-heading"
|
|
| 102 | 102 | tabindex="-1"
|
| 103 | 103 | data-l10n-id="tor-bridges-heading"
|
| 104 | 104 | ></html:h1>
|
| ... | ... | @@ -107,7 +107,22 @@ |
| 107 | 107 | id="torPreferences-bridges-group"
|
| 108 | 108 | data-category="paneConnection"
|
| 109 | 109 | hidden="true"
|
| 110 | + aria-labelledby="tor-bridges-subcategory-heading-non-search"
|
|
| 110 | 111 | >
|
| 112 | + <!-- Add a search-header that only appears in search results as a substitute
|
|
| 113 | + - for the hidden h1 element. See tor-browser#43320.
|
|
| 114 | + - NOTE: Usually the first xul:label will act as the accessible name for
|
|
| 115 | + - a xul:groubbox element *if* it is not hidden. Since the search-header
|
|
| 116 | + - is sometimes hidden we need an explicit aria-labelledby anyway.
|
|
| 117 | + - However, we keep the wrapper xul:label for styling consistency with the
|
|
| 118 | + - other settings. -->
|
|
| 119 | + <label class="search-header" hidden="true">
|
|
| 120 | + <html:h2
|
|
| 121 | + class="tor-bridges-subcategory-heading tor-focusable-heading"
|
|
| 122 | + tabindex="-1"
|
|
| 123 | + data-l10n-id="tor-bridges-heading"
|
|
| 124 | + ></html:h2>
|
|
| 125 | + </label>
|
|
| 111 | 126 | <description class="description-deemphasized" flex="1">
|
| 112 | 127 | <html:span data-l10n-id="tor-bridges-overview"></html:span>
|
| 113 | 128 | <label
|
| ... | ... | @@ -164,8 +179,13 @@ |
| 164 | 179 | - See https://github.com/WICG/proposals/issues/112
|
| 165 | 180 | -->
|
| 166 | 181 | <!-- NOTE: This area is hidden by default, and is only shown temporarily
|
| 167 | - - when a notification is added. -->
|
|
| 168 | - <html:div id="tor-bridges-update-area" hidden="hidden">
|
|
| 182 | + - when a notification is added. It should never match with search
|
|
| 183 | + - queries. -->
|
|
| 184 | + <html:div
|
|
| 185 | + id="tor-bridges-update-area"
|
|
| 186 | + hidden="hidden"
|
|
| 187 | + data-hidden-from-search="true"
|
|
| 188 | + >
|
|
| 169 | 189 | <!-- NOTE: This first span's text content will *not* be read out as part
|
| 170 | 190 | - of the notification because it does not have an aria-live
|
| 171 | 191 | - attribute. Instead it is just here to give context to the following
|
| ... | ... | @@ -182,18 +202,33 @@ |
| 182 | 202 | aria-live="polite"
|
| 183 | 203 | ></html:span>
|
| 184 | 204 | </html:div>
|
| 185 | - <html:div id="tor-bridges-none">
|
|
| 205 | + <html:div id="tor-bridges-none" hidden="hidden">
|
|
| 186 | 206 | <html:img id="tor-bridges-none-icon" alt="" />
|
| 187 | 207 | <html:div data-l10n-id="tor-bridges-none-added"></html:div>
|
| 188 | 208 | </html:div>
|
| 189 | - <html:div id="tor-bridges-current">
|
|
| 209 | + <html:div id="tor-bridges-current" hidden="hidden">
|
|
| 190 | 210 | <html:div id="tor-bridges-current-header-bar">
|
| 191 | 211 | <html:h2
|
| 192 | - id="tor-bridges-current-heading"
|
|
| 193 | - class="tor-focusable-heading"
|
|
| 212 | + id="tor-bridges-current-heading-non-search"
|
|
| 213 | + class="tor-bridges-current-heading tor-focusable-heading tor-small-heading tor-non-search-heading"
|
|
| 194 | 214 | tabindex="-1"
|
| 195 | 215 | data-l10n-id="tor-bridges-your-bridges"
|
| 196 | 216 | ></html:h2>
|
| 217 | + <!-- Add a duplicate search heading.
|
|
| 218 | + - In a search result the heading h1.tor-bridges-subcategory-heading
|
|
| 219 | + - will be hidden, and the h2.tor-bridges-subcategory-heading
|
|
| 220 | + - will be visible.
|
|
| 221 | + - As such, all headings below h2.tor-bridges-subcategory-heading also
|
|
| 222 | + - need to shift one lower in heading level to preseve the correct
|
|
| 223 | + - hierarchy of - heading levels.
|
|
| 224 | + - In this case we hide the <h2> heading and show the duplicate <h3>
|
|
| 225 | + - heading instead.
|
|
| 226 | + - See tor-browser#43320. -->
|
|
| 227 | + <html:h3
|
|
| 228 | + class="tor-bridges-current-heading tor-focusable-heading tor-small-heading tor-search-heading"
|
|
| 229 | + tabindex="-1"
|
|
| 230 | + data-l10n-id="tor-bridges-your-bridges"
|
|
| 231 | + ></html:h3>
|
|
| 197 | 232 | <html:span
|
| 198 | 233 | id="tor-bridges-user-label"
|
| 199 | 234 | class="tor-bridges-source-label"
|
| ... | ... | @@ -221,7 +256,10 @@ |
| 221 | 256 | aria-controls="tor-bridges-all-options-menu"
|
| 222 | 257 | data-l10n-id="tor-bridges-options-button"
|
| 223 | 258 | ></html:button>
|
| 224 | - <html:panel-list id="tor-bridges-all-options-menu">
|
|
| 259 | + <html:panel-list
|
|
| 260 | + id="tor-bridges-all-options-menu"
|
|
| 261 | + data-hidden-from-search="true"
|
|
| 262 | + >
|
|
| 225 | 263 | <html:panel-item
|
| 226 | 264 | id="tor-bridges-options-qr-all-menu-item"
|
| 227 | 265 | data-l10n-attrs="accesskey"
|
| ... | ... | @@ -244,7 +282,7 @@ |
| 244 | 282 | ></html:panel-item>
|
| 245 | 283 | </html:panel-list>
|
| 246 | 284 | </html:div>
|
| 247 | - <html:div id="tor-bridges-built-in-display">
|
|
| 285 | + <html:div id="tor-bridges-built-in-display" hidden="hidden">
|
|
| 248 | 286 | <html:div id="tor-bridges-built-in-type-name"></html:div>
|
| 249 | 287 | <html:div
|
| 250 | 288 | id="tor-bridges-built-in-connected"
|
| ... | ... | @@ -261,7 +299,8 @@ |
| 261 | 299 | id="tor-bridges-grid-display"
|
| 262 | 300 | class="tor-bridges-grid"
|
| 263 | 301 | role="grid"
|
| 264 | - aria-labelledby="tor-bridges-current-heading"
|
|
| 302 | + aria-labelledby="tor-bridges-current-heading-non-search"
|
|
| 303 | + hidden="hidden"
|
|
| 265 | 304 | ></html:div>
|
| 266 | 305 | <html:template id="tor-bridges-grid-row-template">
|
| 267 | 306 | <html:div class="tor-bridges-grid-row" role="row">
|
| ... | ... | @@ -297,7 +336,10 @@ |
| 297 | 336 | aria-expanded="false"
|
| 298 | 337 | data-l10n-id="tor-bridges-individual-bridge-options-button"
|
| 299 | 338 | ></html:button>
|
| 300 | - <html:panel-list class="tor-bridges-individual-options-menu">
|
|
| 339 | + <html:panel-list
|
|
| 340 | + class="tor-bridges-individual-options-menu"
|
|
| 341 | + data-hidden-from-search="true"
|
|
| 342 | + >
|
|
| 301 | 343 | <html:panel-item
|
| 302 | 344 | class="tor-bridges-options-qr-one-menu-item"
|
| 303 | 345 | data-l10n-attrs="accesskey"
|
| ... | ... | @@ -318,11 +360,20 @@ |
| 318 | 360 | </html:span>
|
| 319 | 361 | </html:div>
|
| 320 | 362 | </html:template>
|
| 321 | - <html:div id="tor-bridges-share" class="tor-bridges-details-box">
|
|
| 363 | + <html:div
|
|
| 364 | + id="tor-bridges-share"
|
|
| 365 | + class="tor-bridges-details-box"
|
|
| 366 | + hidden="hidden"
|
|
| 367 | + >
|
|
| 322 | 368 | <html:h3
|
| 323 | - id="tor-bridges-share-heading"
|
|
| 369 | + class="tor-bridges-share-heading tor-small-heading tor-non-search-heading"
|
|
| 324 | 370 | data-l10n-id="tor-bridges-share-heading"
|
| 325 | 371 | ></html:h3>
|
| 372 | + <!-- Add a duplicate search heading. See tor-browser#43320. -->
|
|
| 373 | + <html:h4
|
|
| 374 | + class="tor-bridges-share-heading tor-small-heading tor-search-heading"
|
|
| 375 | + data-l10n-id="tor-bridges-share-heading"
|
|
| 376 | + ></html:h4>
|
|
| 326 | 377 | <html:span
|
| 327 | 378 | id="tor-bridges-share-description"
|
| 328 | 379 | data-l10n-id="tor-bridges-share-description"
|
| ... | ... | @@ -336,68 +387,84 @@ |
| 336 | 387 | data-l10n-id="tor-bridges-qr-addresses-button"
|
| 337 | 388 | ></html:button>
|
| 338 | 389 | </html:div>
|
| 339 | - <html:div id="tor-bridges-lox-status">
|
|
| 390 | + <html:div id="tor-bridges-lox-status" hidden="hidden">
|
|
| 340 | 391 | <html:div data-l10n-id="tor-bridges-lox-description"></html:div>
|
| 341 | 392 | <html:div
|
| 342 | 393 | id="tor-bridges-lox-details"
|
| 343 | 394 | class="tor-bridges-details-box tor-bridges-lox-box"
|
| 395 | + hidden="hidden"
|
|
| 344 | 396 | >
|
| 345 | 397 | <html:img alt="" class="tor-bridges-lox-image-inner" />
|
| 346 | 398 | <html:img alt="" class="tor-bridges-lox-image-outer" />
|
| 347 | 399 | <html:h3
|
| 348 | - id="tor-bridges-lox-next-unlock-counter"
|
|
| 349 | - class="tor-bridges-lox-intro tor-focusable-heading"
|
|
| 400 | + class="tor-bridges-lox-next-unlock-counter tor-small-heading tor-bridges-lox-intro tor-focusable-heading tor-non-search-heading"
|
|
| 350 | 401 | tabindex="-1"
|
| 351 | 402 | ></html:h3>
|
| 403 | + <!-- Add a duplicate search heading. See tor-browser#43320. -->
|
|
| 404 | + <html:h4
|
|
| 405 | + class="tor-bridges-lox-next-unlock-counter tor-small-heading tor-bridges-lox-intro tor-focusable-heading tor-search-heading"
|
|
| 406 | + tabindex="-1"
|
|
| 407 | + ></html:h4>
|
|
| 352 | 408 | <html:ul class="tor-bridges-lox-list">
|
| 353 | 409 | <html:li
|
| 354 | 410 | id="tor-bridges-lox-next-unlock-gain-bridges"
|
| 355 | 411 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-bridge"
|
| 356 | 412 | data-l10n-id="tor-bridges-lox-unlock-two-bridges"
|
| 413 | + hidden="hidden"
|
|
| 357 | 414 | ></html:li>
|
| 358 | 415 | <html:li
|
| 359 | 416 | id="tor-bridges-lox-next-unlock-first-invites"
|
| 360 | 417 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-invite"
|
| 361 | 418 | data-l10n-id="tor-bridges-lox-unlock-first-invites"
|
| 419 | + hidden="hidden"
|
|
| 362 | 420 | ></html:li>
|
| 363 | 421 | <html:li
|
| 364 | 422 | id="tor-bridges-lox-next-unlock-more-invites"
|
| 365 | 423 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-invite"
|
| 366 | 424 | data-l10n-id="tor-bridges-lox-unlock-more-invites"
|
| 425 | + hidden="hidden"
|
|
| 367 | 426 | ></html:li>
|
| 368 | 427 | </html:ul>
|
| 369 | - <html:div id="tor-bridges-lox-remaining-invites"></html:div>
|
|
| 428 | + <html:div
|
|
| 429 | + id="tor-bridges-lox-remaining-invites"
|
|
| 430 | + hidden="hidden"
|
|
| 431 | + ></html:div>
|
|
| 370 | 432 | <html:button
|
| 371 | 433 | id="tor-bridges-lox-show-invites-button"
|
| 372 | 434 | class="tor-bridges-lox-button"
|
| 373 | 435 | data-l10n-id="tor-bridges-lox-show-invites-button"
|
| 436 | + hidden="hidden"
|
|
| 374 | 437 | ></html:button>
|
| 375 | 438 | </html:div>
|
| 376 | 439 | <html:div
|
| 377 | 440 | id="tor-bridges-lox-unlock-alert"
|
| 378 | 441 | role="alert"
|
| 379 | 442 | class="tor-bridges-details-box tor-bridges-lox-box"
|
| 443 | + hidden="hidden"
|
|
| 380 | 444 | >
|
| 381 | 445 | <html:img alt="" class="tor-bridges-lox-image-inner" />
|
| 382 | 446 | <html:img alt="" class="tor-bridges-lox-image-outer" />
|
| 383 | 447 | <html:div
|
| 384 | 448 | id="tor-bridge-unlock-alert-title"
|
| 385 | - class="tor-bridges-lox-intro"
|
|
| 449 | + class="tor-small-heading tor-bridges-lox-intro"
|
|
| 386 | 450 | ></html:div>
|
| 387 | 451 | <html:ul class="tor-bridges-lox-list">
|
| 388 | 452 | <html:li
|
| 389 | 453 | id="tor-bridges-lox-unlock-alert-gain-bridges"
|
| 390 | 454 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-bridge"
|
| 391 | 455 | data-l10n-id="tor-bridges-lox-gained-two-bridges"
|
| 456 | + hidden="hidden"
|
|
| 392 | 457 | ></html:li>
|
| 393 | 458 | <html:li
|
| 394 | 459 | id="tor-bridges-lox-unlock-alert-new-bridges"
|
| 395 | 460 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-bridge"
|
| 396 | 461 | data-l10n-id="tor-bridges-lox-new-bridges"
|
| 462 | + hidden="hidden"
|
|
| 397 | 463 | ></html:li>
|
| 398 | 464 | <html:li
|
| 399 | 465 | id="tor-bridges-lox-unlock-alert-invites"
|
| 400 | 466 | class="tor-bridges-lox-list-item tor-bridges-lox-list-item-invite"
|
| 467 | + hidden="hidden"
|
|
| 401 | 468 | ></html:li>
|
| 402 | 469 | </html:ul>
|
| 403 | 470 | <html:button
|
| ... | ... | @@ -408,7 +475,14 @@ |
| 408 | 475 | </html:div>
|
| 409 | 476 | </html:div>
|
| 410 | 477 | </html:div>
|
| 411 | - <html:h2 id="tor-bridges-change-heading"></html:h2>
|
|
| 478 | + <html:h2
|
|
| 479 | + class="tor-bridges-change-heading tor-medium-heading tor-non-search-heading"
|
|
| 480 | + ></html:h2>
|
|
| 481 | + <!-- Add a duplicate search heading. See tor-browser#43320.
|
|
| 482 | + - This has the same content, but a smaller font. -->
|
|
| 483 | + <html:h3
|
|
| 484 | + class="tor-bridges-change-heading tor-small-heading tor-search-heading"
|
|
| 485 | + ></html:h3>
|
|
| 412 | 486 | <hbox align="center">
|
| 413 | 487 | <description
|
| 414 | 488 | flex="1"
|
| ... | ... | @@ -428,9 +502,15 @@ |
| 428 | 502 | ></html:button>
|
| 429 | 503 | </hbox>
|
| 430 | 504 | <html:h3
|
| 431 | - id="tor-bridges-provider-heading"
|
|
| 505 | + class="tor-bridges-provider-heading tor-medium-heading tor-non-search-heading"
|
|
| 432 | 506 | data-l10n-id="tor-bridges-find-more-heading"
|
| 433 | 507 | ></html:h3>
|
| 508 | + <!-- Add a duplicate search heading. See tor-browser#43320.
|
|
| 509 | + - This has the same content, but a smaller font. -->
|
|
| 510 | + <html:h4
|
|
| 511 | + class="tor-bridges-provider-heading tor-small-heading tor-search-heading"
|
|
| 512 | + data-l10n-id="tor-bridges-find-more-heading"
|
|
| 513 | + ></html:h4>
|
|
| 434 | 514 | <description
|
| 435 | 515 | data-l10n-id="tor-bridges-find-more-description"
|
| 436 | 516 | class="description-deemphasized"
|
| ... | ... | @@ -511,15 +591,29 @@ |
| 511 | 591 | |
| 512 | 592 | <!-- Advanced -->
|
| 513 | 593 | <hbox class="subcategory" data-category="paneConnection" hidden="true">
|
| 514 | - <html:h1 data-l10n-id="tor-advanced-settings-heading"></html:h1>
|
|
| 594 | + <html:h1
|
|
| 595 | + id="tor-advanced-subcategory-heading-non-search"
|
|
| 596 | + data-l10n-id="tor-advanced-settings-heading"
|
|
| 597 | + ></html:h1>
|
|
| 515 | 598 | </hbox>
|
| 516 | 599 | <groupbox
|
| 517 | 600 | id="torPreferences-advanced-group"
|
| 518 | 601 | data-category="paneConnection"
|
| 519 | 602 | hidden="true"
|
| 603 | + aria-labelledby="tor-advanced-subcategory-heading-non-search"
|
|
| 520 | 604 | >
|
| 605 | + <!-- Add a search-header that only appears in search results as a substitute
|
|
| 606 | + - for the hidden h1 element. See tor-browser#43320.
|
|
| 607 | + - NOTE: Usually the first xul:label will act as the accessible name for
|
|
| 608 | + - a xul:groubbox element *if* it is not hidden. Since the search-header
|
|
| 609 | + - is sometimes hidden we need an explicit aria-labelledby anyway.
|
|
| 610 | + - However, we keep the wrapper xul:label for styling consistency with the
|
|
| 611 | + - other settings. -->
|
|
| 612 | + <label class="search-header" hidden="true">
|
|
| 613 | + <html:h2 data-l10n-id="tor-advanced-settings-heading"></html:h2>
|
|
| 614 | + </label>
|
|
| 521 | 615 | <hbox align="center">
|
| 522 | - <label data-l10n-id="tor-advanced-settings-description" flex="1" />
|
|
| 616 | + <description data-l10n-id="tor-advanced-settings-description" flex="1" />
|
|
| 523 | 617 | <html:button
|
| 524 | 618 | id="torPreferences-advanced-button"
|
| 525 | 619 | class="accessory-button"
|
| ... | ... | @@ -527,7 +621,7 @@ |
| 527 | 621 | ></html:button>
|
| 528 | 622 | </hbox>
|
| 529 | 623 | <hbox align="center" data-subcategory="viewlogs">
|
| 530 | - <label data-l10n-id="tor-view-log-description" flex="1" />
|
|
| 624 | + <description data-l10n-id="tor-view-log-description" flex="1" />
|
|
| 531 | 625 | <html:button
|
| 532 | 626 | id="torPreferences-buttonTorLogs"
|
| 533 | 627 | class="accessory-button"
|
| ... | ... | @@ -118,6 +118,48 @@ button.spoof-button-disabled { |
| 118 | 118 | |
| 119 | 119 | /* Bridge settings */
|
| 120 | 120 | |
| 121 | +.tor-medium-heading {
|
|
| 122 | + /* Same font size as mozilla preferences h2. */
|
|
| 123 | + font-size: var(--font-size-large);
|
|
| 124 | + font-weight: var(--font-weight-bold);
|
|
| 125 | + margin: 0;
|
|
| 126 | +}
|
|
| 127 | + |
|
| 128 | +.tor-small-heading {
|
|
| 129 | + font-size: inherit;
|
|
| 130 | + font-weight: var(--font-weight-bold);
|
|
| 131 | + margin: 0;
|
|
| 132 | +}
|
|
| 133 | + |
|
| 134 | +/* Hide the tor-search-heading elements when the group's search header is
|
|
| 135 | + * hidden. These only appear in search results.
|
|
| 136 | + * See tor-browser#43320.
|
|
| 137 | + * NOTE: `.search-header[hidden] ~ :is(* .tor-search-heading)` will not match
|
|
| 138 | + * (possibly because the `~` selector is unsure how to integrate with the
|
|
| 139 | + * non-compound `* .tor-search-heading` selector). So we need to duplicate the
|
|
| 140 | + * `.search-header[hidden]` rule. */
|
|
| 141 | +#torPreferences-bridges-group :is(
|
|
| 142 | + .search-header[hidden] ~ * .tor-search-heading,
|
|
| 143 | + .search-header[hidden] ~ .tor-search-heading
|
|
| 144 | +) {
|
|
| 145 | + display: none;
|
|
| 146 | +}
|
|
| 147 | + |
|
| 148 | +/* Hide the tor-non-search-heading elements when the group's search header is
|
|
| 149 | + * not hidden. These only appear outside of search results.
|
|
| 150 | + * See tor-browser#43320. */
|
|
| 151 | +#torPreferences-bridges-group :is(
|
|
| 152 | + .search-header:not([hidden]) ~ * .tor-non-search-heading,
|
|
| 153 | + .search-header:not([hidden]) ~ .tor-non-search-heading
|
|
| 154 | +) {
|
|
| 155 | + display: none;
|
|
| 156 | +}
|
|
| 157 | + |
|
| 158 | +.tor-focusable-heading {
|
|
| 159 | + /* Do not occupy more horizontal space than necessary. */
|
|
| 160 | + width: fit-content;
|
|
| 161 | +}
|
|
| 162 | + |
|
| 121 | 163 | .tor-focusable-heading:focus-visible {
|
| 122 | 164 | outline-offset: var(--in-content-focus-outline-offset);
|
| 123 | 165 | }
|
| ... | ... | @@ -182,53 +224,18 @@ button.spoof-button-disabled { |
| 182 | 224 | clip-path: inset(50%);
|
| 183 | 225 | }
|
| 184 | 226 | |
| 185 | -#torPreferences-bridges-group:not(.have-bridges, .no-bridges) {
|
|
| 227 | +#torPreferences-bridges-group:not(.bridges-initialized) {
|
|
| 186 | 228 | /* Hide bridge settings whilst not initialized. */
|
| 187 | 229 | display: none;
|
| 188 | 230 | }
|
| 189 | 231 | |
| 190 | -#torPreferences-bridges-group:not(.have-bridges) #tor-bridges-current {
|
|
| 191 | - display: none;
|
|
| 192 | -}
|
|
| 193 | - |
|
| 194 | -#torPreferences-bridges-group:not(.no-bridges) #tor-bridges-none {
|
|
| 195 | - display: none;
|
|
| 196 | -}
|
|
| 197 | - |
|
| 198 | -#tor-bridges-current:not(.source-built-in) #tor-bridges-built-in-label {
|
|
| 199 | - display: none;
|
|
| 200 | -}
|
|
| 201 | - |
|
| 202 | -#tor-bridges-current:not(.source-user) #tor-bridges-user-label {
|
|
| 203 | - display: none;
|
|
| 204 | -}
|
|
| 205 | - |
|
| 206 | -#tor-bridges-current:not(.source-requested) #tor-bridges-requested-label {
|
|
| 207 | - display: none;
|
|
| 208 | -}
|
|
| 209 | - |
|
| 210 | -#tor-bridges-current:not(.source-lox) #tor-bridges-lox-label {
|
|
| 211 | - display: none;
|
|
| 212 | -}
|
|
| 213 | - |
|
| 214 | -#tor-bridges-current:not(
|
|
| 215 | - .source-user,
|
|
| 216 | - .source-requested
|
|
| 217 | -) #tor-bridges-share {
|
|
| 218 | - display: none;
|
|
| 219 | -}
|
|
| 220 | - |
|
| 221 | -#tor-bridges-current:not(.source-lox) #tor-bridges-lox-status {
|
|
| 222 | - display: none;
|
|
| 223 | -}
|
|
| 224 | - |
|
| 225 | 232 | #tor-bridges-none,
|
| 226 | 233 | #tor-bridges-current {
|
| 227 | 234 | margin-inline: 0;
|
| 228 | 235 | margin-block: 32px;
|
| 229 | 236 | }
|
| 230 | 237 | |
| 231 | -#tor-bridges-none {
|
|
| 238 | +#tor-bridges-none:not([hidden]) {
|
|
| 232 | 239 | display: grid;
|
| 233 | 240 | justify-items: center;
|
| 234 | 241 | text-align: center;
|
| ... | ... | @@ -265,9 +272,7 @@ button.spoof-button-disabled { |
| 265 | 272 | white-space: nowrap;
|
| 266 | 273 | }
|
| 267 | 274 | |
| 268 | -#tor-bridges-current-heading {
|
|
| 269 | - margin: 0;
|
|
| 270 | - font-size: inherit;
|
|
| 275 | +.tor-bridges-current-heading {
|
|
| 271 | 276 | grid-area: heading;
|
| 272 | 277 | }
|
| 273 | 278 | |
| ... | ... | @@ -282,7 +287,7 @@ button.spoof-button-disabled { |
| 282 | 287 | grid-area: button;
|
| 283 | 288 | }
|
| 284 | 289 | |
| 285 | -#tor-bridges-lox-label {
|
|
| 290 | +#tor-bridges-lox-label:not([hidden]) {
|
|
| 286 | 291 | display: flex;
|
| 287 | 292 | align-items: center;
|
| 288 | 293 | gap: 6px;
|
| ... | ... | @@ -317,7 +322,7 @@ button.spoof-button-disabled { |
| 317 | 322 | fill: currentColor;
|
| 318 | 323 | }
|
| 319 | 324 | |
| 320 | -#tor-bridges-built-in-display {
|
|
| 325 | +#tor-bridges-built-in-display:not([hidden]) {
|
|
| 321 | 326 | display: grid;
|
| 322 | 327 | grid-template:
|
| 323 | 328 | "type status" min-content
|
| ... | ... | @@ -327,10 +332,6 @@ button.spoof-button-disabled { |
| 327 | 332 | margin-block-end: 16px;
|
| 328 | 333 | }
|
| 329 | 334 | |
| 330 | -#tor-bridges-built-in-display:not(.built-in-active) {
|
|
| 331 | - display: none;
|
|
| 332 | -}
|
|
| 333 | - |
|
| 334 | 335 | #tor-bridges-built-in-type-name {
|
| 335 | 336 | font-weight: 700;
|
| 336 | 337 | grid-area: type;
|
| ... | ... | @@ -345,7 +346,7 @@ button.spoof-button-disabled { |
| 345 | 346 | grid-area: description;
|
| 346 | 347 | }
|
| 347 | 348 | |
| 348 | -.tor-bridges-grid {
|
|
| 349 | +.tor-bridges-grid:not([hidden]) {
|
|
| 349 | 350 | display: grid;
|
| 350 | 351 | grid-template-columns: max-content repeat(4, max-content) 1fr;
|
| 351 | 352 | --tor-bridges-grid-column-gap: 8px;
|
| ... | ... | @@ -355,10 +356,6 @@ button.spoof-button-disabled { |
| 355 | 356 | align-items: stretch;
|
| 356 | 357 | }
|
| 357 | 358 | |
| 358 | -#tor-bridges-grid-display:not(.grid-active) {
|
|
| 359 | - display: none;
|
|
| 360 | -}
|
|
| 361 | - |
|
| 362 | 359 | .tor-bridges-grid-row {
|
| 363 | 360 | /* We want each row to act as a row of three items in the
|
| 364 | 361 | * .tor-bridges-grid grid layout.
|
| ... | ... | @@ -483,7 +480,7 @@ button.spoof-button-disabled { |
| 483 | 480 | padding: 16px;
|
| 484 | 481 | }
|
| 485 | 482 | |
| 486 | -#tor-bridges-share {
|
|
| 483 | +#tor-bridges-share:not([hidden]) {
|
|
| 487 | 484 | display: grid;
|
| 488 | 485 | grid-template:
|
| 489 | 486 | "heading heading heading" min-content
|
| ... | ... | @@ -496,12 +493,9 @@ button.spoof-button-disabled { |
| 496 | 493 | align-items: center;
|
| 497 | 494 | }
|
| 498 | 495 | |
| 499 | -#tor-bridges-share-heading {
|
|
| 496 | +.tor-bridges-share-heading {
|
|
| 500 | 497 | grid-area: heading;
|
| 501 | - font-size: inherit;
|
|
| 502 | - margin: 0;
|
|
| 503 | 498 | margin-block-end: 4px;
|
| 504 | - font-weight: 700;
|
|
| 505 | 499 | }
|
| 506 | 500 | |
| 507 | 501 | #tor-bridges-share-description {
|
| ... | ... | @@ -538,15 +532,7 @@ button.spoof-button-disabled { |
| 538 | 532 | margin-block-start: 8px;
|
| 539 | 533 | }
|
| 540 | 534 | |
| 541 | -#tor-bridges-lox-status:not(.show-next-unlock) #tor-bridges-lox-details {
|
|
| 542 | - display: none;
|
|
| 543 | -}
|
|
| 544 | - |
|
| 545 | -#tor-bridges-lox-status:not(.show-unlock-alert) #tor-bridges-lox-unlock-alert {
|
|
| 546 | - display: none;
|
|
| 547 | -}
|
|
| 548 | - |
|
| 549 | -.tor-bridges-lox-box {
|
|
| 535 | +.tor-bridges-lox-box:not([hidden]) {
|
|
| 550 | 536 | display: grid;
|
| 551 | 537 | grid-template:
|
| 552 | 538 | "image intro intro" min-content
|
| ... | ... | @@ -601,11 +587,8 @@ button.spoof-button-disabled { |
| 601 | 587 | |
| 602 | 588 | .tor-bridges-lox-intro {
|
| 603 | 589 | grid-area: intro;
|
| 604 | - font-weight: 700;
|
|
| 605 | - font-size: inherit;
|
|
| 606 | 590 | align-self: center;
|
| 607 | 591 | justify-self: start;
|
| 608 | - margin: 0;
|
|
| 609 | 592 | }
|
| 610 | 593 | |
| 611 | 594 | .tor-bridges-lox-list {
|
| ... | ... | @@ -619,11 +602,11 @@ button.spoof-button-disabled { |
| 619 | 602 | gap: 8px 0;
|
| 620 | 603 | }
|
| 621 | 604 | |
| 622 | -.tor-bridges-lox-list-item {
|
|
| 605 | +.tor-bridges-lox-list-item:not([hidden]) {
|
|
| 623 | 606 | display: contents;
|
| 624 | 607 | }
|
| 625 | 608 | |
| 626 | -.tor-bridges-lox-list-item::before {
|
|
| 609 | +.tor-bridges-lox-list-item:not([hidden])::before {
|
|
| 627 | 610 | /* We use ::before rather than list-style-image to have more control. */
|
| 628 | 611 | box-sizing: content-box;
|
| 629 | 612 | width: 18px;
|
| ... | ... | @@ -655,52 +638,19 @@ button.spoof-button-disabled { |
| 655 | 638 | stroke: var(--in-content-success-icon-color);
|
| 656 | 639 | }
|
| 657 | 640 | |
| 658 | -#tor-bridges-lox-details:not(.lox-next-gain-bridges) #tor-bridges-lox-next-unlock-gain-bridges {
|
|
| 659 | - display: none;
|
|
| 660 | -}
|
|
| 661 | - |
|
| 662 | -#tor-bridges-lox-details:not(.lox-next-first-invites) #tor-bridges-lox-next-unlock-first-invites {
|
|
| 663 | - display: none;
|
|
| 664 | -}
|
|
| 665 | - |
|
| 666 | -#tor-bridges-lox-details:not(.lox-next-more-invites) #tor-bridges-lox-next-unlock-more-invites {
|
|
| 667 | - display: none;
|
|
| 668 | -}
|
|
| 669 | - |
|
| 670 | - |
|
| 671 | -#tor-bridges-lox-unlock-alert:not(.lox-unlock-gain-bridges) #tor-bridges-lox-unlock-alert-gain-bridges {
|
|
| 672 | - display: none;
|
|
| 673 | -}
|
|
| 674 | - |
|
| 675 | -#tor-bridges-lox-unlock-alert:not(.lox-unlock-new-bridges) #tor-bridges-lox-unlock-alert-new-bridges {
|
|
| 676 | - display: none;
|
|
| 677 | -}
|
|
| 678 | - |
|
| 679 | -#tor-bridges-lox-unlock-alert:not(.lox-unlock-invites) #tor-bridges-lox-unlock-alert-invites {
|
|
| 680 | - display: none;
|
|
| 681 | -}
|
|
| 682 | - |
|
| 683 | 641 | #tor-bridges-lox-remaining-invites {
|
| 684 | 642 | grid-area: invites;
|
| 685 | 643 | justify-self: end;
|
| 686 | 644 | align-self: center;
|
| 687 | 645 | }
|
| 688 | 646 | |
| 689 | -#tor-bridges-lox-details:not(.lox-has-invites) :is(
|
|
| 690 | - #tor-bridges-lox-remaining-invites,
|
|
| 691 | - #tor-bridges-lox-show-invites-button
|
|
| 692 | -) {
|
|
| 693 | - display: none;
|
|
| 694 | -}
|
|
| 695 | - |
|
| 696 | 647 | .tor-bridges-lox-button {
|
| 697 | 648 | grid-area: button;
|
| 698 | 649 | margin: 0;
|
| 699 | 650 | align-self: center;
|
| 700 | 651 | }
|
| 701 | 652 | |
| 702 | -#tor-bridges-provider-heading {
|
|
| 703 | - font-size: 1.14em;
|
|
| 653 | +.tor-bridges-provider-heading {
|
|
| 704 | 654 | margin-block: 48px 8px;
|
| 705 | 655 | }
|
| 706 | 656 |