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 |