Commit 54812ad6 authored by John Emau's avatar John Emau Committed by Commit Bot

DevTools: Put audio context name in drop down label

Previously the accessible name for the audio context selector was 'BaseAudioContext'.

With this change the accessible name becomes `Audio context: ${content title}`
and if no context is selected: `Audio context: (no recording)`.

This is a much better experience for screen reader users and meets success
criteria for WCAG 2.5.3 Label in Name https://www.w3.org/WAI/WCAG21/quickref/#label-in-name

Test page: https://mdn.github.io/webaudio-examples/audiocontext-states/

Screenshot (NVDA Speech Viewer):  https://i.imgur.com/m5pKYnx.png (NOTE: This screenshot was taken with https://crrev.com/c/1626643 applied to better screen reader support)
Screenshot (Accessibility Tree): https://i.imgur.com/e04n8m9.png

Bug: 963183
Change-Id: I89e14599313766e7bd2be8a6a953df28c648dbe2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1711008Reviewed-by: default avatarLorne Mitchell <lomitch@microsoft.com>
Commit-Queue: John Emau <John.Emau@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#706226}
parent 5b17a406
...@@ -6,19 +6,22 @@ ...@@ -6,19 +6,22 @@
* @implements {UI.SoftDropDown.Delegate<!Protocol.WebAudio.BaseAudioContext>} * @implements {UI.SoftDropDown.Delegate<!Protocol.WebAudio.BaseAudioContext>}
*/ */
WebAudio.AudioContextSelector = class extends Common.Object { WebAudio.AudioContextSelector = class extends Common.Object {
constructor(title) { constructor() {
super(); super();
/** @type {string} */
this._placeholderText = ls`(no recordings)`;
/** @type {!UI.ListModel<!Protocol.WebAudio.BaseAudioContext>} */ /** @type {!UI.ListModel<!Protocol.WebAudio.BaseAudioContext>} */
this._items = new UI.ListModel(); this._items = new UI.ListModel();
/** @type {!UI.SoftDropDown<!Protocol.WebAudio.BaseAudioContext>} */ /** @type {!UI.SoftDropDown<!Protocol.WebAudio.BaseAudioContext>} */
this._dropDown = new UI.SoftDropDown(this._items, this); this._dropDown = new UI.SoftDropDown(this._items, this);
this._dropDown.setPlaceholderText(ls`(no recordings)`); this._dropDown.setPlaceholderText(this._placeholderText);
this._toolbarItem = new UI.ToolbarItem(this._dropDown.element); this._toolbarItem = new UI.ToolbarItem(this._dropDown.element);
this._toolbarItem.setEnabled(false); this._toolbarItem.setEnabled(false);
this._toolbarItem.setTitle(title); this._toolbarItem.setTitle(ls`Audio context: ${this._placeholderText}`);
this._items.addEventListener(UI.ListModel.Events.ItemsReplaced, this._onListItemReplaced, this); this._items.addEventListener(UI.ListModel.Events.ItemsReplaced, this._onListItemReplaced, this);
this._toolbarItem.element.classList.add('toolbar-has-dropdown'); this._toolbarItem.element.classList.add('toolbar-has-dropdown');
...@@ -27,7 +30,11 @@ WebAudio.AudioContextSelector = class extends Common.Object { ...@@ -27,7 +30,11 @@ WebAudio.AudioContextSelector = class extends Common.Object {
} }
_onListItemReplaced() { _onListItemReplaced() {
this._toolbarItem.setEnabled(!!this._items.length); const hasItems = !!this._items.length;
this._toolbarItem.setEnabled(hasItems);
if (!hasItems) {
this._toolbarItem.setTitle(ls`Audio context: ${this._placeholderText}`);
}
} }
/** /**
...@@ -132,6 +139,7 @@ WebAudio.AudioContextSelector = class extends Common.Object { ...@@ -132,6 +139,7 @@ WebAudio.AudioContextSelector = class extends Common.Object {
// It's possible that no context is selected yet. // It's possible that no context is selected yet.
if (!this._selectedContext || this._selectedContext.contextId !== item.contextId) { if (!this._selectedContext || this._selectedContext.contextId !== item.contextId) {
this._selectedContext = item; this._selectedContext = item;
this._toolbarItem.setTitle(ls`Audio context: ${this.titleFor(item)}`);
} }
this.dispatchEventToListeners(WebAudio.AudioContextSelector.Events.ContextSelected, item); this.dispatchEventToListeners(WebAudio.AudioContextSelector.Events.ContextSelected, item);
......
...@@ -14,7 +14,7 @@ WebAudio.WebAudioView = class extends UI.ThrottledWidget { ...@@ -14,7 +14,7 @@ WebAudio.WebAudioView = class extends UI.ThrottledWidget {
// Creates the toolbar. // Creates the toolbar.
const toolbarContainer = this.contentElement.createChild( const toolbarContainer = this.contentElement.createChild(
'div', 'web-audio-toolbar-container vbox'); 'div', 'web-audio-toolbar-container vbox');
this._contextSelector = new WebAudio.AudioContextSelector(ls`BaseAudioContexts`); this._contextSelector = new WebAudio.AudioContextSelector();
const toolbar = new UI.Toolbar('web-audio-toolbar', toolbarContainer); const toolbar = new UI.Toolbar('web-audio-toolbar', toolbarContainer);
toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage')); toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));
toolbar.appendSeparator(); toolbar.appendSeparator();
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
<message name="IDS_DEVTOOLS_ab7799fb0ebb5a4167781f756efb820a" desc="Text in Audio Context Content Builder"> <message name="IDS_DEVTOOLS_ab7799fb0ebb5a4167781f756efb820a" desc="Text in Audio Context Content Builder">
Callback Interval Callback Interval
</message> </message>
<message name="IDS_DEVTOOLS_b78dc7712ef83a078c1c68822d2a1a3f" desc="Text in Web Audio View"> <message name="IDS_DEVTOOLS_d1adc6d57af38b75e7b7c3bb0b9a44ee" desc="Label prefix for an audio context selection">
BaseAudioContexts Audio context: <ph name="THIS__PLACEHOLDERTEXT">$1s<ex>realtime (1e03ec)</ex></ph>
</message> </message>
<message name="IDS_DEVTOOLS_f047f03535a9154caf9a858b5aed17c0" desc="Text in Audio Context Content Builder"> <message name="IDS_DEVTOOLS_f047f03535a9154caf9a858b5aed17c0" desc="Text in Audio Context Content Builder">
Current Time Current Time
......
...@@ -3,12 +3,14 @@ Tests the AudioContextSelector. ...@@ -3,12 +3,14 @@ Tests the AudioContextSelector.
Running: testStartsEmpty Running: testStartsEmpty
Number of contexts (items): 0 Number of contexts (items): 0
Title: Audio context: (no recordings)}
Selected Context: null Selected Context: null
Running: testSelectsCreatedContext Running: testSelectsCreatedContext
Number of contexts (items): 1 Number of contexts (items): 1
Title: Audio context: realtime (dc39fd)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
...@@ -18,6 +20,7 @@ Selected Context: { ...@@ -18,6 +20,7 @@ Selected Context: {
Running: testResetClearsList Running: testResetClearsList
Number of contexts (items): 0 Number of contexts (items): 0
Title: Audio context: (no recordings)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
...@@ -27,6 +30,7 @@ Selected Context: { ...@@ -27,6 +30,7 @@ Selected Context: {
Running: testReSelectsCreatedContextAfterChange Running: testReSelectsCreatedContextAfterChange
Number of contexts (items): 1 Number of contexts (items): 1
Title: Audio context: realtime (dc39fd)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
...@@ -36,6 +40,7 @@ Selected Context: { ...@@ -36,6 +40,7 @@ Selected Context: {
Running: testFirstCreatedContextStaysSelected Running: testFirstCreatedContextStaysSelected
Number of contexts (items): 2 Number of contexts (items): 2
Title: Audio context: realtime (dc39fd)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
...@@ -45,6 +50,7 @@ Selected Context: { ...@@ -45,6 +50,7 @@ Selected Context: {
Running: testChangingContextDoesNotChangeSelection Running: testChangingContextDoesNotChangeSelection
Number of contexts (items): 2 Number of contexts (items): 2
Title: Audio context: realtime (dc39fd)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
...@@ -54,6 +60,7 @@ Selected Context: { ...@@ -54,6 +60,7 @@ Selected Context: {
Running: testSelectedContextBecomesSelected Running: testSelectedContextBecomesSelected
Number of contexts (items): 2 Number of contexts (items): 2
Title: Audio context: realtime (695c9e)}
Selected Context: { Selected Context: {
"contextId": "78a3e94e-4968-4bf6-8905-325109695c9e", "contextId": "78a3e94e-4968-4bf6-8905-325109695c9e",
"contextType": "realtime" "contextType": "realtime"
...@@ -65,6 +72,7 @@ _onListItemReplaced called with contexts (items) count: 1 ...@@ -65,6 +72,7 @@ _onListItemReplaced called with contexts (items) count: 1
_onListItemReplaced called with contexts (items) count: 1 _onListItemReplaced called with contexts (items) count: 1
Number of contexts (items): 1 Number of contexts (items): 1
Title: Audio context: realtime (dc39fd)}
Selected Context: { Selected Context: {
"contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd", "contextId": "924c4ee4-4cae-4e62-b4c6-71603edc39fd",
"contextType": "realtime" "contextType": "realtime"
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/** @type {!WebAudio.AudioContextSelector} */ selector) { /** @type {!WebAudio.AudioContextSelector} */ selector) {
TestRunner.addResult(` TestRunner.addResult(`
Number of contexts (items): ${selector._items.length} Number of contexts (items): ${selector._items.length}
Title: ${selector.toolbarItem()._title}}
Selected Context: ${JSON.stringify(selector.selectedContext(), null, 3)} Selected Context: ${JSON.stringify(selector.selectedContext(), null, 3)}
`); `);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment