Bug 1379098 - ARIA combobox should map to AXComboBox. r=marcoz

Create a new internal role EDITCOMBOBOX so that we can distinguish
comboboxes with a text input (which is the case for the ARIA role)
from those which consist of only a popup button and associated list
(which is the case for the select element with a size of 1). Also
change the type of ARIA combobox from kGenericAccType to eCombobox
so that IsCombobox() will return true for both EDITCOMBOBOX and
COMBOBOX. Lastly, call IsCombobox() rather than role() when assigning
internal roles to descendants of comboboxes and emitting accessibility
events.

--HG--
extra : rebase_source : 3e31f2e2423d6cc7697b03c9afb3b1f8c136675a
This commit is contained in:
Joanmarie Diggs 2017-07-11 11:16:00 +02:00
Родитель 5fa0fd0ab5
Коммит 99540643ac
11 изменённых файлов: 44 добавлений и 24 удалений

Просмотреть файл

@ -133,14 +133,14 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
eARIASelectableIfDefined,
eARIAReadonlyOrEditableIfDefined
},
{ // combobox
{ // combobox, which consists of text input and popup
&nsGkAtoms::combobox,
roles::COMBOBOX,
roles::EDITCOMBOBOX,
kUseMapRole,
eNoValue,
eOpenCloseAction,
eNoLiveAttr,
kGenericAccType,
eCombobox,
states::COLLAPSED | states::HASPOPUP,
eARIAAutoComplete,
eARIAReadonly,

Просмотреть файл

@ -306,9 +306,9 @@ enum Role {
RADIOBUTTON = 45,
/**
* Represents a combo box; an edit control with an associated list box that
* provides a set of predefined choices. It is used for html:select,
* xul:menulist, role="combobox".
* Represents a combo box; a popup button with an associated list box that
* provides a set of predefined choices. It is used for html:select with a
* size of 1 and xul:menulist. See also ROLE_EDITCOMBOBOX.
*/
COMBOBOX = 46,
@ -1015,7 +1015,13 @@ enum Role {
*/
REGION = 173,
LAST_ROLE = REGION
/**
* Represents a control with a text input and a popup with a set of predefined
* choices. It is used for ARIA's combobox role. See also COMBOBOX.
*/
EDITCOMBOBOX = 174,
LAST_ROLE = EDITCOMBOBOX
};
} // namespace role

Просмотреть файл

@ -384,6 +384,7 @@ ROLE(RADIOBUTTON,
ROLE_SYSTEM_RADIOBUTTON,
eNameFromSubtreeRule)
// Equivalent of HTML select element with size="1". See also EDITCOMBOBOX.
ROLE(COMBOBOX,
"combobox",
ATK_ROLE_COMBO_BOX,
@ -1407,3 +1408,13 @@ ROLE(REGION,
USE_ROLE_STRING,
IA2_ROLE_LANDMARK,
eNoNameRule)
// A composite widget with a text input and popup. Used for ARIA role combobox.
// See also COMBOBOX.
ROLE(EDITCOMBOBOX,
"editcombobox",
ATK_ROLE_COMBO_BOX,
NSAccessibilityComboBoxRole,
ROLE_SYSTEM_COMBOBOX,
ROLE_SYSTEM_COMBOBOX,
eNameFromValueRule)

Просмотреть файл

@ -1450,14 +1450,14 @@ Accessible::ARIATransformRole(role aRole)
} else if (aRole == roles::LISTBOX) {
// A listbox inside of a combobox needs a special role because of ATK
// mapping to menu.
if (mParent && mParent->Role() == roles::COMBOBOX) {
if (mParent && mParent->IsCombobox()) {
return roles::COMBOBOX_LIST;
} else {
// Listbox is owned by a combobox
Relation rel = RelationByType(RelationType::NODE_CHILD_OF);
Accessible* targetAcc = nullptr;
while ((targetAcc = rel.Next()))
if (targetAcc->Role() == roles::COMBOBOX)
if (targetAcc->IsCombobox())
return roles::COMBOBOX_LIST;
}

Просмотреть файл

@ -135,8 +135,7 @@ DocAccessible::NotifyOfLoad(uint32_t aLoadEventType)
inline void
DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
{
a11y::role role = aAccessible->Role();
if (role == roles::ENTRY || role == roles::COMBOBOX)
if (aAccessible->IsCombobox() || aAccessible->Role() == roles::ENTRY)
FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
}

Просмотреть файл

@ -530,9 +530,7 @@ RootAccessible::HandlePopupShownEvent(Accessible* aAccessible)
if (!combobox)
return;
roles::Role comboboxRole = combobox->Role();
if (comboboxRole == roles::COMBOBOX ||
comboboxRole == roles::AUTOCOMPLETE) {
if (combobox->IsCombobox() || combobox->IsAutoComplete()) {
RefPtr<AccEvent> event =
new AccStateChangeEvent(combobox, states::EXPANDED, true);
if (event)

Просмотреть файл

@ -299,9 +299,9 @@ interface nsIAccessibleRole : nsISupports
const unsigned long ROLE_RADIOBUTTON = 45;
/**
* Represents a combo box; an edit control with an associated list box that
* provides a set of predefined choices. It is used for html:select,
* xul:menulist, role="combobox".
* Represents a combo box; a popup button with an associated list box that
* provides a set of predefined choices. It is used for html:select with a
* size of 1 and xul:menulist. See also ROLE_EDITCOMBOBOX.
*/
const unsigned long ROLE_COMBOBOX = 46;
@ -1009,4 +1009,10 @@ interface nsIAccessibleRole : nsISupports
* a summary of the page.
*/
const unsigned long ROLE_REGION = 173;
/**
* Represents a control with a text input and a popup with a set of predefined
* choices. It is used for ARIA's combobox role. See also ROLE_COMBOBOX.
*/
const unsigned long ROLE_EDITCOMBOBOX = 174;
};

Просмотреть файл

@ -24,6 +24,7 @@ const ROLE_DETAILS = nsIAccessibleRole.ROLE_DETAILS;
const ROLE_DIAGRAM = nsIAccessibleRole.ROLE_DIAGRAM;
const ROLE_DIALOG = nsIAccessibleRole.ROLE_DIALOG;
const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
const ROLE_EDITCOMBOBOX = nsIAccessibleRole.ROLE_EDITCOMBOBOX;
const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
const ROLE_EQUATION = nsIAccessibleRole.ROLE_EQUATION;

Просмотреть файл

@ -25,7 +25,7 @@
testRole("aria_button", ROLE_PUSHBUTTON);
testRole("aria_checkbox", ROLE_CHECKBUTTON);
testRole("aria_columnheader", ROLE_COLUMNHEADER);
testRole("aria_combobox", ROLE_COMBOBOX);
testRole("aria_combobox", ROLE_EDITCOMBOBOX);
testRole("aria_dialog", ROLE_DIALOG);
testRole("aria_directory", ROLE_LIST);
testRole("aria_document", ROLE_DOCUMENT);

Просмотреть файл

@ -51,7 +51,7 @@
name: "have bike"
},
{
role: ROLE_COMBOBOX,
role: ROLE_EDITCOMBOBOX,
name: "bike model"
},
{

Просмотреть файл

@ -99,7 +99,7 @@ XULMenuitemAccessible::NativeState()
Accessible* grandParent = parent->Parent();
if (!grandParent)
return state;
NS_ASSERTION(grandParent->Role() == roles::COMBOBOX,
NS_ASSERTION(grandParent->IsCombobox(),
"grandparent of combobox listitem is not combobox");
uint64_t grandParentState = grandParent->State();
state &= ~(states::OFFSCREEN | states::INVISIBLE);
@ -459,14 +459,13 @@ XULMenupopupAccessible::NativeRole()
// If accessible is not bound to the tree (this happens while children are
// cached) return general role.
if (mParent) {
roles::Role role = mParent->Role();
if (role == roles::COMBOBOX || role == roles::AUTOCOMPLETE)
if (mParent->IsCombobox() || mParent->IsAutoComplete())
return roles::COMBOBOX_LIST;
if (role == roles::PUSHBUTTON) {
if (mParent->Role() == roles::PUSHBUTTON) {
// Some widgets like the search bar have several popups, owned by buttons.
Accessible* grandParent = mParent->Parent();
if (grandParent && grandParent->Role() == roles::AUTOCOMPLETE)
if (grandParent && grandParent->IsAutoComplete())
return roles::COMBOBOX_LIST;
}
}