ComboBoxInput- & CapsuleMultiSelectWidget's (as of v0.17.9) are featuring role=combobox. This ARIA role requires listbox children,
Description
Details
Related Objects
- Mentioned Here
- P5234 Diff of combobox markup
Event Timeline
@Volker_E, is this an good first task task that one could mentor for Google-Code-In-2016?
@Prtksxna Not fully sure about good first task as it needs understanding of screen readers as well and that seems more like an intermediate task at least.
The output should change from:
<div class="oo-ui-comboBoxInputWidget-field"> <input type="text" tabindex="0" aria-disabled="false" class="oo-ui-inputWidget-input" autocomplete="off" role="combobox" aria-autocomplete="list" id="oojsui-31"> <span class="oo-ui-comboBoxInputWidget-dropdownButton oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-indicatorElement oo-ui-buttonWidget" aria-disabled="false"> <a class="oo-ui-buttonElement-button" role="button" tabindex="0" aria-disabled="false" rel="nofollow"> <span class="oo-ui-iconElement-icon"></span><span class="oo-ui-labelElement-label"></span><span class="oo-ui-indicatorElement-indicator oo-ui-indicator-down"></span> </a> </span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget oo-ui-selectWidget-depressed oo-ui-clippableElement-clippable oo-ui-menuSelectWidget oo-ui-floatableElement-floatable oo-ui-floatingMenuSelectWidget oo-ui-textInputMenuSelectWidget" aria-disabled="false" role="menu"> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="menuitem" aria-selected="false"> <span class="oo-ui-labelElement-label">Option 1</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="menuitem" aria-selected="false"> <span class="oo-ui-labelElement-label">Option 2</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="menuitem" aria-selected="false"> <span class="oo-ui-labelElement-label">Option 3</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="menuitem" aria-selected="false"> <span class="oo-ui-labelElement-label">Option 4</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="menuitem" aria-selected="false"> <span class="oo-ui-labelElement-label">Option 5</span> </div> </div>
become:
<div class="oo-ui-comboBoxInputWidget-field"> <input type="text" tabindex="0" aria-disabled="false" class="oo-ui-inputWidget-input" autocomplete="off" role="combobox" aria-autocomplete="list" id="oojsui-31" **aria-owns="oojsui-32" aria-activedescendant="oojsui-33"**> <span class="oo-ui-comboBoxInputWidget-dropdownButton oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-indicatorElement oo-ui-buttonWidget" aria-disabled="false"> <a class="oo-ui-buttonElement-button" role="button" tabindex="0" aria-disabled="false" rel="nofollow"> <span class="oo-ui-iconElement-icon"></span><span class="oo-ui-labelElement-label"></span><span class="oo-ui-indicatorElement-indicator oo-ui-indicator-down"></span> </a> </span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-selectWidget oo-ui-selectWidget-depressed oo-ui-clippableElement-clippable oo-ui-menuSelectWidget oo-ui-floatableElement-floatable oo-ui-floatingMenuSelectWidget oo-ui-textInputMenuSelectWidget" aria-disabled="false" **role="listbox" id="oojsui-32"**> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-iconElement oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget oo-ui-optionWidget-selected" aria-disabled="false" tabindex="-1" **role="option"** aria-selected="true" **id="oojsui-33"**> <span class="oo-ui-labelElement-label">Option 1</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="option" aria-selected="false" **id="oojsui-34"**> <span class="oo-ui-labelElement-label">Option 2</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="option" aria-selected="false" **id="oojsui-35"**> <span class="oo-ui-labelElement-label">Option 3</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="option" aria-selected="false" **id="oojsui-36"**> <span class="oo-ui-labelElement-label">Option 4</span> </div> <div class="oo-ui-widget oo-ui-widget-enabled oo-ui-labelElement oo-ui-optionWidget oo-ui-decoratedOptionWidget oo-ui-menuOptionWidget" aria-disabled="false" tabindex="-1" role="option" aria-selected="false" **id="oojsui-37"**> <span class="oo-ui-labelElement-label">Option 5</span> </div> </div>
So, to recap, we want the following:
- The dropdown list must be using role="listbox"/role="option" rather than role="menu"/role="menuitem".
- The combobox must be connected to the listbox using aria-owns.
- The combobox must be connected to the selected option using aria-activedescendant.
The first looks clear. The second seems only necessary if the listbox is in an overlay (otherwise, the relationship is inferred from the DOM nesting). The third, I'm not convinced about – I'm having trouble making sense of the spec for aria-activedescendant, but it doesn't seem to mean the selected option? Are you sure about this?
Change 348993 had a related patch set uploaded (by Bartosz Dziewoński):
[oojs/ui@master] Do not use role=menu/menuitem for MenuSelectWidget/MenuOptionWidget
Change 348993 merged by jenkins-bot:
[oojs/ui@master] Do not use role=menu/menuitem for MenuSelectWidget/MenuOptionWidget
Regarding aria-activedescendant the following example seems pretty clear: https://www.w3.org/WAI/GL/wiki/Using_aria-activedescendant_to_allow_changes_in_focus_within_widgets_to_be_communicated_to_Assistive_Technology#Example_1:_Combobox
Change 349134 had a related patch set uploaded (by Bartosz Dziewoński):
[oojs/ui@master] Set 'aria-owns' for everything with a dropdown list (ARIA combobox)
Change 349135 had a related patch set uploaded (by Bartosz Dziewoński):
[oojs/ui@master] SelectWidget/MenuSelectWidget: Maintain 'aria-activedescendant' attribute on focus owner
I see now what confused me – aria-activedescendant is not specific to combobox, but in general it's something that should be set on the currently focussed widget (in ARIA terminology) if the active widget (which roughly means the widget that keyboard actions apply to) is something else. It is also used, for example, on a radiogroup that doesn't allow focussing individual radio buttons: http://oaa-accessibility.org/example/29/ (incidentally, this is also how our RadioSelectWidget works). I ended up implementing this more generally for all kinds of SelectWidgets.
This article was also helpful for me: http://www.ssbbartgroup.com/blog/differences-aria-1-0-1-1-changes-rolecombobox/
Change 349134 merged by jenkins-bot:
[oojs/ui@master] Set aria-owns for everything with a dropdown list (ARIA role=combobox)
Change 349135 merged by VolkerE:
[oojs/ui@master] SelectWidget/MenuSelectWidget: Maintain aria-activedescendant attribute on focus owner
Change 741851 had a related patch set uploaded (by Thiemo Kreuz (WMDE); author: Thiemo Kreuz (WMDE)):
[oojs/ui@master] Fix dead "aria-activedescendant" code path in SelectWidget
Change 741851 merged by jenkins-bot:
[oojs/ui@master] Fix dead "aria-activedescendant" code path in SelectWidget
Change 935793 had a related patch set uploaded (by Catrope; author: Catrope):
[mediawiki/core@master] Update OOUI to v0.47.2