tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit b2cf2bcbdf8d6a10df62902a5247e30fc020f925
parent 3bb4ee67577f68107b11272216a9fd9c6cbb28a5
Author: Anna Yeddi ayeddi@mozilla.com <ayeddi@mozilla.com>
Date:   Wed, 19 Nov 2025 16:04:26 +0000

Bug 1983040 - Adding aria-pressed attribute support to moz-button. r=akulyk,sclements

Ensuring `aria-pressed` attribute is passed from the `<moz-button>` to its actual `<button>` descendant.

Since with this change the `<moz-button>` would be passing the `aria-pressed` attribute to its button element, a sidebar test needs to be adjusted to test the `<button>` itself instead of its component container.

Differential Revision: https://phabricator.services.mozilla.com/D262201

Diffstat:
Mbrowser/components/sidebar/tests/browser/browser_a11y_sidebar.js | 7++++---
Mtoolkit/content/tests/widgets/test_moz_button.html | 1+
Mtoolkit/content/widgets/moz-button/README.stories.md | 17+++++++++++++++++
Mtoolkit/content/widgets/moz-button/moz-button.mjs | 4++++
4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/browser/components/sidebar/tests/browser/browser_a11y_sidebar.js b/browser/components/sidebar/tests/browser/browser_a11y_sidebar.js @@ -98,13 +98,14 @@ add_task(async function test_keyboard_navigation() { toolButtons[0].getAttribute("view"), "Sidebar is showing the first tool." ); + // Moz-button is passing an "aria-pressed" attribute to the actual buttonEl: is( - toolButtons[0].getAttribute("aria-pressed"), + toolButtons[0].buttonEl.getAttribute("aria-pressed"), "true", "aria-pressed is true for the active tool button." ); is( - toolButtons[1].getAttribute("aria-pressed"), + toolButtons[1].buttonEl.getAttribute("aria-pressed"), "false", "aria-pressed is false for the inactive tool button." ); @@ -114,7 +115,7 @@ add_task(async function test_keyboard_navigation() { await sidebar.updateComplete; ok(!sidebar.open, "Sidebar is closed."); is( - toolButtons[0].getAttribute("aria-pressed"), + toolButtons[0].buttonEl.getAttribute("aria-pressed"), "false", "Tool is no longer active, aria-pressed becomes false." ); diff --git a/toolkit/content/tests/widgets/test_moz_button.html b/toolkit/content/tests/widgets/test_moz_button.html @@ -219,6 +219,7 @@ await testProperty("aria-label", "ariaLabel"); await testProperty("aria-haspopup", "ariaHasPopup"); await testProperty("aria-expanded", "ariaExpanded"); + await testProperty("aria-pressed", "ariaPressed"); }); add_task(async function testIconButtons() { diff --git a/toolkit/content/widgets/moz-button/README.stories.md b/toolkit/content/widgets/moz-button/README.stories.md @@ -241,6 +241,23 @@ Split Button is an action button combined with an adjacent menu button offering </div> ``` +#### Toggle button + +Adding `aria-pressed` to the `moz-button` turns it into a toggle button. The `aria-pressed` attribute represents the button's current "pressed" state. + +Refer to [the W3C ARIA documentation](https://w3c.github.io/aria/#aria-pressed) for more information on using `aria-pressed` attribute. + +```html +<moz-button label="Could be pressed" aria-pressed="false"></moz-button> +<moz-button label="Is already pressed" aria-pressed="true"></moz-button> +``` +```html story +<div style={{ display: 'flex', gap: '1rem' }}> + <moz-button label="Could be pressed" aria-pressed="false"></moz-button> + <moz-button label="Is already pressed" aria-pressed="true"></moz-button> +</div> +``` + ### Setting the `size` There are 2 options for the `moz-button` size: `default` and `small`. Small buttons are only used for smaller UI surfaces. (e.g., Infobar). diff --git a/toolkit/content/widgets/moz-button/moz-button.mjs b/toolkit/content/widgets/moz-button/moz-button.mjs @@ -184,10 +184,12 @@ class MenuController { * @property {string} ariaLabel - The button's aria-label attribute, used in shadow DOM and therefore not as an attribute on moz-button. * @property {string} ariaHasPopup - The button's aria-haspopup attribute, that indicates that a popup element can be triggered by the button. * @property {string} ariaExpanded - The button's aria-expanded attribute, that indicates whether or not the controlled elements are displayed or hidden. + * @property {string} ariaPressed - The button's aria-pressed attribute, used in shadow DOM and therefore not as an attribute on moz-button. * @property {string} iconSrc - Path to the icon that should be displayed in the button. * @property {string} ariaLabelAttribute - Internal, map aria-label attribute to the ariaLabel JS property. * @property {string} ariaHasPopupAttribute - Internal, map aria-haspopup attribute to the ariaHasPopup JS property. * @property {string} ariaExpandedAttribute - Internal, map aria-expanded attribute to the ariaExpanded JS property. + * @property {string} ariaPressedAttribute - Internal, map aria-pressed attribute to the ariaPressed JS property. * @property {string} hasVisibleLabel - Internal, tracks whether or not the button has a visible label. * @property {boolean} attention - Show a dot notification on the button if true. * @property {boolean} parentDisabled - When the parent of this component is disabled. @@ -221,6 +223,7 @@ export default class MozButton extends MozLitElement { ariaLabel: { type: String, mapped: true }, ariaHasPopup: { type: String, mapped: true }, ariaExpanded: { type: String, mapped: true }, + ariaPressed: { type: String, mapped: true }, iconSrc: { type: String }, hasVisibleLabel: { type: Boolean, state: true }, accessKey: { type: String, mapped: true }, @@ -332,6 +335,7 @@ export default class MozButton extends MozLitElement { aria-haspopup=${ifDefined( this.isSplitButton ? undefined : this.ariaHasPopup )} + aria-pressed=${ifDefined(this.ariaPressed)} accesskey=${ifDefined(this.accessKey)} > <span