Skip to content
Snippets Groups Projects
Commit 0b412130 authored by henry's avatar henry
Browse files

fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in...

fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection

Bug 42036: Implement new bridge settings UI, ready for Lox.
parent dc354cb3
Branches
No related tags found
1 merge request!890Replace bridge cards with new design, ready for Lox
<svg width="24" height="24" viewBox="0 0 24 24" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 3C4.83696 3 4.20107 3.26339 3.73223 3.73223C3.26339 4.20107 3 4.83696 3 5.5V9H4.75V5.5C4.75 5.30109 4.82902 5.11032 4.96967 4.96967C5.11032 4.82902 5.30109 4.75 5.5 4.75H9V3H5.5ZM11 10.25C11 10.4489 10.921 10.6397 10.7803 10.7803C10.6397 10.921 10.4489 11 10.25 11H7.75C7.55109 11 7.36032 10.921 7.21967 10.7803C7.07902 10.6397 7 10.4489 7 10.25V7.75C7 7.55109 7.07902 7.36032 7.21967 7.21967C7.36032 7.07902 7.55109 7 7.75 7H10.25C10.4489 7 10.6397 7.07902 10.7803 7.21967C10.921 7.36032 11 7.55109 11 7.75V10.25ZM17 15H15V13H17V11H15V9H17V7H15V9H13V11H15V13H13V15H11V13H9V15H7V17H9V15H11V17H13V15H15V17H17V15ZM3 18.5V15H4.75V18.5C4.75 18.914 5.086 19.25 5.5 19.25H9V21H5.5C4.83696 21 4.20107 20.7366 3.73223 20.2678C3.26339 19.7989 3 19.163 3 18.5ZM15 3H18.5C19.163 3 19.7989 3.26339 20.2678 3.73223C20.7366 4.20107 21 4.83696 21 5.5V9H19.25V5.5C19.25 5.30109 19.171 5.11032 19.0303 4.96967C18.8897 4.82902 18.6989 4.75 18.5 4.75H15V3ZM21 18.5V15H19.25V18.5C19.25 18.6989 19.171 18.8897 19.0303 19.0303C18.8897 19.171 18.6989 19.25 18.5 19.25H15V21H18.5C19.163 21 19.7989 20.7366 20.2678 20.2678C20.7366 19.7989 21 19.163 21 18.5Z"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<path d="M15.5 11.5C15.5 7.35786 12.1421 4 8 4C3.85786 4 0.5 7.35786 0.5 11.5V12.7461H1.67188V11.5C1.67188 8.00507 4.50507 5.17188 8 5.17188C11.4949 5.17188 14.3281 8.00507 14.3281 11.5V12.7461H15.5V11.5Z"/>
<path d="M13.25 11.5C13.25 8.6005 10.8995 6.24999 7.99999 6.24999C5.1005 6.24999 2.74999 8.6005 2.74999 11.5L2.74989 12.7461H3.92177L3.92187 11.5C3.92187 9.24771 5.74771 7.42187 7.99999 7.42187C10.2523 7.42187 12.0781 9.24771 12.0781 11.5L12.0782 12.7461H13.2501L13.25 11.5Z"/>
<path d="M8 8.5C9.65686 8.5 11 9.84315 11 11.5L11.0002 12.7461H9.82836L9.82813 11.5C9.82813 10.4904 9.00965 9.67188 8 9.67188C6.99036 9.67188 6.17188 10.4904 6.17188 11.5L6.17164 12.7461H4.99977V11.5C4.99977 9.84315 6.34315 8.5 8 8.5Z"/>
</svg>
......@@ -69,8 +69,10 @@ export class BuiltinBridgeDialog {
optionEl.querySelector(
".torPreferences-current-bridge-label"
).textContent = TorStrings.settings.currentBridge;
optionEl.classList.toggle(
"current-builtin-bridge-type",
optionEl
.querySelector(".bridge-status-badge")
.classList.toggle(
"bridge-status-current-built-in",
type === currentBuiltinType
);
}
......
......@@ -20,8 +20,8 @@
aria-describedby="obfs-bridges-current obfs-bridges-description"
value="obfs4"
/>
<html:span class="torPreferences-current-bridge-badge">
<image class="torPreferences-current-bridge-icon" />
<html:span class="bridge-status-badge">
<html:div class="bridge-status-icon"></html:div>
<html:span
id="obfs-bridges-current"
class="torPreferences-current-bridge-label"
......@@ -41,8 +41,8 @@
aria-describedby="snowflake-bridges-current snowflake-bridges-description"
value="snowflake"
/>
<html:span class="torPreferences-current-bridge-badge">
<image class="torPreferences-current-bridge-icon" />
<html:span class="bridge-status-badge">
<html:div class="bridge-status-icon"></html:div>
<html:span
id="snowflake-bridges-current"
class="torPreferences-current-bridge-label"
......@@ -62,8 +62,8 @@
aria-describedby="meek-bridges-current meek-bridges-description"
value="meek-azure"
/>
<html:span class="torPreferences-current-bridge-badge">
<image class="torPreferences-current-bridge-icon" />
<html:span class="bridge-status-badge">
<html:div class="bridge-status-icon"></html:div>
<html:span
id="meek-bridges-current"
class="torPreferences-current-bridge-label"
......
This diff is collapsed.
......@@ -67,7 +67,7 @@
<!-- Bridges -->
<hbox class="subcategory" data-category="paneConnection" hidden="true">
<html:h1 id="torPreferences-bridges-header" />
<html:h1 id="torPreferences-bridges-header" tabindex="-1" />
</hbox>
<groupbox
id="torPreferences-bridges-group"
......@@ -103,6 +103,196 @@
class="primary"
/>
</hbox>
<html:moz-toggle
id="tor-bridges-enabled-toggle"
label-align-after=""
data-l10n-id="tor-bridges-use-bridges"
data-l10n-attrs="label"
/>
<!-- Add an aria-live area where we can post notifications to screen
- reader users about changes to their list of bridges. This is to give
- these users some feedback for when the remove a bridge or change
- their bridges in other ways. I.e. whenever tor-bridges-grid-display
- changes its rows.
-
- If we change the text in #tor-bridges-update-area-text, a screen
- reader should speak out the text to the user, even when this area
- does not have focus.
-
- In fact, we don't really want the user to navigate to this element
- directly. But currently using an aria-live region in the DOM is the
- only way to effectively pass a notification to a screen reader user.
- Since it must be somewhere in the DOM, we logically place it just
- before the grid, where it is hopefully least confusing to stumble
- across.
-
- TODO: Instead of aria-live in the DOM, use the proposed ariaNotify
- API if it gets accepted into firefox and works with screen readers.
- See https://github.com/WICG/proposals/issues/112
-->
<!-- NOTE: This area is hidden by default, and is only shown temporarily
- when a notification is added. -->
<html:div id="tor-bridges-update-area" hidden="hidden">
<!-- NOTE: This first span's text content will *not* be read out as part
- of the notification because it does not have an aria-live
- attribute. Instead it is just here to give context to the following
- text in #tor-bridges-update-area-text if the user navigates to
- #tor-bridges-update-area manually whilst it is not hidden.
- I.e. it is just here to make it less confusing if a screen reader
- user stumbles across this.
-->
<html:span data-l10n-id="tor-bridges-update-area-intro"></html:span>
<!-- Whitespace between spans. -->
<!-- This second span is the area to place notification text in. -->
<html:span
id="tor-bridges-update-area-text"
aria-live="polite"
></html:span>
</html:div>
<html:div id="tor-bridges-none">
<html:img id="tor-bridges-none-icon" alt="" />
<html:div data-l10n-id="tor-bridges-none-added"></html:div>
</html:div>
<html:div id="tor-bridges-current">
<html:div id="tor-bridges-current-header-bar">
<html:h2
id="tor-bridges-current-heading"
tabindex="-1"
data-l10n-id="tor-bridges-your-bridges"
></html:h2>
<html:span
id="tor-bridges-user-label"
data-l10n-id="tor-bridges-source-user"
></html:span>
<html:span
id="tor-bridges-built-in-label"
data-l10n-id="tor-bridges-source-built-in"
></html:span>
<html:span
id="tor-bridges-requested-label"
data-l10n-id="tor-bridges-source-requested"
></html:span>
<html:button
id="tor-bridges-all-options-button"
class="tor-bridges-options-button"
aria-haspopup="menu"
aria-expanded="false"
aria-controls="tor-bridges-all-options-menu"
data-l10n-id="tor-bridges-options-button"
></html:button>
<html:panel-list id="tor-bridges-all-options-menu">
<html:panel-item
id="tor-bridges-options-qr-all-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-qr-all-bridge-addresses"
></html:panel-item>
<html:panel-item
id="tor-bridges-options-copy-all-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-copy-all-bridge-addresses"
></html:panel-item>
<html:panel-item
id="tor-bridges-options-edit-all-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-edit-all-bridges"
></html:panel-item>
<html:panel-item
id="tor-bridges-options-remove-all-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-remove-all-bridges"
></html:panel-item>
</html:panel-list>
</html:div>
<html:div id="tor-bridges-built-in-display">
<html:div id="tor-bridges-built-in-type-name"></html:div>
<html:div
id="tor-bridges-built-in-connected"
class="bridge-status-badge"
>
<html:div class="bridge-status-icon"></html:div>
<html:span
data-l10n-id="tor-bridges-built-in-status-connected"
></html:span>
</html:div>
<html:div id="tor-bridges-built-in-description"></html:div>
</html:div>
<html:div
id="tor-bridges-grid-display"
role="grid"
aria-labelledby="tor-bridges-current-heading"
></html:div>
<html:template id="tor-bridges-grid-row-template">
<html:div class="tor-bridges-grid-row" role="row">
<!-- TODO: lox status cell for new bridges? -->
<html:span
class="tor-bridges-type-cell tor-bridges-grid-cell"
role="gridcell"
></html:span>
<html:span class="tor-bridges-emojis-block" role="none"></html:span>
<html:span class="tor-bridges-grid-end-block" role="none">
<html:span
class="tor-bridges-address-cell tor-bridges-grid-cell"
role="gridcell"
></html:span>
<html:span
class="tor-bridges-status-cell tor-bridges-grid-cell"
role="gridcell"
>
<html:div class="bridge-status-badge">
<html:div class="bridge-status-icon"></html:div>
<html:span class="tor-bridges-status-cell-text"></html:span>
</html:div>
</html:span>
<html:span
class="tor-bridges-options-cell tor-bridges-grid-cell"
role="gridcell"
>
<html:button
class="tor-bridges-options-cell-button tor-bridges-options-button tor-bridges-grid-focus"
aria-haspopup="menu"
aria-expanded="false"
data-l10n-id="tor-bridges-individual-bridge-options-button"
></html:button>
<html:panel-list class="tor-bridges-individual-options-menu">
<html:panel-item
class="tor-bridges-options-qr-one-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-qr-address"
></html:panel-item>
<html:panel-item
class="tor-bridges-options-copy-one-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-copy-address"
></html:panel-item>
<html:panel-item
class="tor-bridges-options-remove-one-menu-item"
data-l10n-attrs="accesskey"
data-l10n-id="tor-bridges-menu-item-remove-bridge"
></html:panel-item>
</html:panel-list>
</html:span>
</html:span>
</html:div>
</html:template>
<html:div id="tor-bridges-share">
<html:h3
id="tor-bridges-share-heading"
data-l10n-id="tor-bridges-share-heading"
></html:h3>
<html:span
id="tor-bridges-share-description"
data-l10n-id="tor-bridges-share-description"
></html:span>
<html:button
id="tor-bridges-copy-addresses-button"
data-l10n-id="tor-bridges-copy-addresses-button"
></html:button>
<html:button
id="tor-bridges-qr-addresses-button"
data-l10n-id="tor-bridges-qr-addresses-button"
></html:button>
</html:div>
</html:div>
<html:h2 id="torPreferences-addBridge-header"></html:h2>
<hbox align="center">
<label id="torPreferences-addBridge-labelBuiltinBridge" flex="1" />
......
......@@ -69,6 +69,384 @@
}
/* Bridge settings */
.bridge-status-badge {
display: flex;
min-width: max-content;
align-items: center;
gap: 0.5em;
font-size: 0.85em;
}
.bridge-status-badge:not(
.bridge-status-connected,
.bridge-status-none,
.bridge-status-current-built-in
) {
display: none;
}
.bridge-status-badge.bridge-status-connected {
color: var(--purple-60);
}
@media (prefers-color-scheme: dark) {
.bridge-status-badge.bridge-status-connected {
color: var(--purple-30);
}
}
.bridge-status-badge.bridge-status-current-built-in {
color: var(--in-content-accent-color);
}
.bridge-status-badge > * {
flex: 0 0 auto;
}
.bridge-status-icon {
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-position: center center;
-moz-context-properties: fill;
fill: currentColor;
}
.bridge-status-badge:is(
.bridge-status-connected,
.bridge-status-current-built-in
) .bridge-status-icon {
background-image: url("chrome://global/skin/icons/check.svg");
}
.bridge-status-badge.bridge-status-none .bridge-status-icon {
/* Hide the icon. */
display: none;
}
#tor-bridges-enabled-toggle {
margin-block: 16px;
width: max-content;
}
#tor-bridges-update-area {
/* Still accessible to screen reader, but not visual. */
position: absolute;
clip-path: inset(50%);
}
#torPreferences-bridges-group:not(.have-bridges, .no-bridges) {
/* Hide bridge settings whilst not initialized. */
display: none;
}
#torPreferences-bridges-group:not(.have-bridges) #tor-bridges-current {
display: none;
}
#torPreferences-bridges-group:not(.no-bridges) #tor-bridges-none {
display: none;
}
#tor-bridges-current:not(.source-built-in) #tor-bridges-built-in-label {
display: none;
}
#tor-bridges-current:not(.source-user) #tor-bridges-user-label {
display: none;
}
#tor-bridges-current:not(.source-requested) #tor-bridges-requested-label {
display: none;
}
#tor-bridges-current:not(
.source-user,
.source-requested
) #tor-bridges-share {
display: none;
}
#tor-bridges-none,
#tor-bridges-current {
margin-inline: 0;
margin-block: 32px;
line-height: 1.8;
}
#tor-bridges-none {
display: grid;
justify-items: center;
text-align: center;
padding-block: 64px;
padding-inline: 32px;
gap: 16px;
border-radius: 4px;
color: var(--text-color-deemphasized);
border: 2px dashed color-mix(in srgb, currentColor 20%, transparent);
}
#tor-bridges-none-icon {
width: 20px;
height: 20px;
content: url("chrome://browser/content/torpreferences/bridge.svg");
-moz-context-properties: fill;
fill: currentColor;
}
#tor-bridges-current {
padding: 16px;
border-radius: 4px;
background: var(--in-content-box-info-background);
}
#tor-bridges-current-header-bar {
display: flex;
min-width: max-content;
align-items: center;
border-block-end: 1px solid var(--in-content-border-color);
padding-block-end: 16px;
margin-block-end: 16px;
}
#tor-bridges-current-header-bar > * {
flex: 0 0 auto;
}
#tor-bridges-current-heading {
margin: 0;
margin-inline-end: 2em;
font-size: inherit;
flex: 1 0 auto;
}
.tor-bridges-options-button {
padding: 3px;
margin: 0;
min-height: auto;
min-width: auto;
box-sizing: content-box;
width: 16px;
height: 16px;
background-image: url("chrome://global/skin/icons/more.svg");
background-repeat: no-repeat;
background-position: center center;
background-origin: content-box;
background-size: contain;
-moz-context-properties: fill;
fill: currentColor;
}
#tor-bridges-all-options-button {
margin-inline-start: 8px;
}
#tor-bridges-built-in-display {
display: grid;
grid-template:
"type status" min-content
"description description" auto
/ max-content 1fr;
gap: 4px 1.5em;
margin-block-end: 16px;
}
#tor-bridges-built-in-display:not(.built-in-active) {
display: none;
}
#tor-bridges-built-in-type-name {
font-weight: 700;
grid-area: type;
}
#tor-bridges-built-in-connected {
grid-area: status;
justify-self: end;
}
#tor-bridges-built-in-description {
grid-area: description;
}
#tor-bridges-grid-display {
display: grid;
grid-template-columns: max-content repeat(4, max-content) 1fr;
--tor-bridges-grid-column-gap: 8px;
--tor-bridges-grid-column-short-gap: 4px;
}
#tor-bridges-grid-display:not(.grid-active) {
display: none;
}
.tor-bridges-grid-row {
/* We want each row to act as a row of three items in the
* #tor-bridges-grid-display grid layout.
* We also want a 16px spacing between rows, and 8px spacing between columns,
* which are outside the .tor-bridges-grid-cell's border area. So that
* clicking these gaps will not focus any item, and their focus outlines do
* not overlap.
* Moreover, we also want each row to show its .tor-bridges-options-cell when
* the .tor-bridges-grid-row has :hover.
*
* We could use "display: contents" on the row and set a "gap: 16px 8px" on
* the parent so that its items fall into the parent layout. However, the gap
* between the items would mean there are places where no row has :hover. So
* if the user glided across the grid, the options button would visibly
* disappear any time the pointer entered a gap, causing the display to feel
* "jumpy".
*
* Instead, we use a "subgrid" layout for each .tor-bridges-grid-row, and
* using padding, rather than a gap, for the vertical spacing. Therefore,
* every part of the grid is covered by a row, so moving the pointer over the
* grid will always have one row with :hover, so one of the options cell will
* always be visible.
*/
display: grid;
grid-column: 1 / -1;
grid-template-columns: subgrid;
/* Add 16px gap between rows, plus 8px at the start and end of the grid. */
padding-block: 8px;
}
.tor-bridges-grid-cell:focus-visible {
outline: var(--in-content-focus-outline);
outline-offset: var(--in-content-focus-outline-offset);
}
.tor-bridges-grid-cell {
/* The cell is stretched to the height of the row, so that each focus outline
* shares the same height, but we want to center-align the content within,
* which is either a single Element or a TextNode. */
display: grid;
align-content: center;
}
.tor-bridges-type-cell {
margin-inline-end: var(--tor-bridges-grid-column-gap);
}
.tor-bridges-emojis-block {
/* Emoji block occupies four columns, but with a smaller gap. */
display: contents;
}
.tor-bridges-emoji-cell:not(:last-child) {
margin-inline-end: var(--tor-bridges-grid-column-short-gap);
}
.tor-bridges-emoji-icon {
display: block;
box-sizing: content-box;
width: 16px;
height: 16px;
background: var(--in-content-button-background);
border-radius: 4px;
padding: 8px;
}
.tor-bridges-grid-end-block {
/* The last three cells all share a single grid item slot in the
* #tor-bridges-grid-display layout.
* This is because we do not want to align its cells between rows. */
min-width: max-content;
display: flex;
/* Choose "stretch" instead of "center" so that focus outline is a consistent
* height between cells. */
align-items: stretch;
margin-inline-start: var(--tor-bridges-grid-column-gap);
gap: var(--tor-bridges-grid-column-gap);
}
.tor-bridges-address-cell {
/* base size */
width: 10em;
flex: 1 0 auto;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--text-color-deemphasized);
}
.tor-bridges-status-cell,
.tor-bridges-options-cell {
flex: 0 0 auto;
}
/* Hide the options button if the row does not have hover or focus. */
.tor-bridges-grid-row:not(
:hover,
:focus-within
) .tor-bridges-options-cell,
/* Hide the status cell when it shows "No status" if the cell does not have
* focus. */
.tor-bridges-grid-row.hide-status .tor-bridges-status-cell:not(:focus) {
/* Still accessible to screen reader, but not visual and does not contribute
* to the parent flex layout. */
/* NOTE: We assume that the height of these cell's content is equal to or less
* than the other cells, so there won't be a jump in row height when they
* become visual again and contribute to the layout. */
position: absolute;
clip-path: inset(50%);
}
#tor-bridges-share {
margin-block-start: 24px;
border-radius: 4px;
border: 1px solid var(--in-content-border-color);
padding: 16px;
display: grid;
grid-template:
"heading heading heading" min-content
/* If the description spans one line, it will be center-aligned with the
* buttons, otherwise it will start to expand upwards. */
"description . ." 1fr
"description copy qr" min-content
/ 1fr max-content max-content;
gap: 0 8px;
align-items: center;
}
#tor-bridges-share-heading {
grid-area: heading;
font-size: inherit;
margin: 0;
font-weight: 700;
}
#tor-bridges-share-description {
grid-area: description;
}
#tor-bridges-copy-addresses-button {
grid-area: copy;
margin: 0;
/* Match the QR height if it is higher than ours. */
min-height: auto;
line-height: 1;
align-self: stretch;
}
#tor-bridges-qr-addresses-button {
grid-area: qr;
padding: 5px;
margin: 0;
min-height: auto;
min-width: auto;
box-sizing: content-box;
width: 24px;
height: 24px;
background-image: url("chrome://browser/content/torpreferences/bridge-qr.svg");
background-repeat: no-repeat;
background-position: center center;
background-origin: content-box;
background-size: contain;
-moz-context-properties: fill;
fill: currentColor;
}
#torPreferences-bridges-location {
width: 280px;
}
......@@ -177,28 +555,6 @@ dialog#torPreferences-requestBridge-dialog > hbox {
font-weight: 700;
}
.torPreferences-current-bridge-badge {
display: flex;
align-items: center;
font-size: 0.85em;
color: var(--in-content-accent-color);
}
.builtin-bridges-option:not(
.current-builtin-bridge-type
) .torPreferences-current-bridge-badge {
display: none;
}
.torPreferences-current-bridge-icon {
margin-inline-start: 1px;
margin-inline-end: 7px;
list-style-image: url("chrome://global/skin/icons/check.svg");
-moz-context-properties: fill;
fill: currentColor;
flex: 0 0 auto;
}
/* Request bridge dialog */
/*
This hbox is hidden by css here by default so that the
......
browser.jar:
content/browser/torpreferences/bridge.svg (content/bridge.svg)
content/browser/torpreferences/bridge-qr.svg (content/bridge-qr.svg)
content/browser/torpreferences/bridgeQrDialog.xhtml (content/bridgeQrDialog.xhtml)
content/browser/torpreferences/bridgeQrDialog.mjs (content/bridgeQrDialog.mjs)
content/browser/torpreferences/builtinBridgeDialog.xhtml (content/builtinBridgeDialog.xhtml)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment