Bug 592193 - add dexpcom version of nsIAccessible::role, part2: dexpcomed GetRole, r=marcoz, a=davidb

This commit is contained in:
Alexander Surkov 2010-09-06 12:33:29 +09:00
parent d633f30def
commit 44dc338657
7 changed files with 65 additions and 76 deletions

View File

@ -752,11 +752,8 @@ getRoleCB(AtkObject *aAtkObj)
#endif
if (aAtkObj->role == ATK_ROLE_INVALID) {
PRUint32 accRole, atkRole;
nsresult rv = accWrap->GetRole(&accRole);
NS_ENSURE_SUCCESS(rv, ATK_ROLE_INVALID);
atkRole = atkRoleMap[accRole]; // map to the actual value
// map to the actual value
PRUint32 atkRole = atkRoleMap[accWrap->Role()];
NS_ASSERTION(atkRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY] ==
kROLE_ATK_LAST_ENTRY, "ATK role map skewed");
aAtkObj->role = static_cast<AtkRole>(atkRole);

View File

@ -1263,52 +1263,7 @@ nsAccessible::GetRole(PRUint32 *aRole)
if (IsDefunct())
return NS_ERROR_FAILURE;
if (mRoleMapEntry) {
*aRole = mRoleMapEntry->role;
// These unfortunate exceptions don't fit into the ARIA table
// This is where the nsIAccessible role depends on both the role and ARIA state
if (*aRole == nsIAccessibleRole::ROLE_PUSHBUTTON) {
if (nsAccUtils::HasDefinedARIAToken(mContent,
nsAccessibilityAtoms::aria_pressed)) {
// For simplicity, any existing pressed attribute except "", or "undefined"
// indicates a toggle.
*aRole = nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
} else if (mContent->AttrValueIs(kNameSpaceID_None,
nsAccessibilityAtoms::aria_haspopup,
nsAccessibilityAtoms::_true,
eCaseMatters)) {
// For button with aria-haspopup="true".
*aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
}
}
else if (*aRole == nsIAccessibleRole::ROLE_LISTBOX) {
// A listbox inside of a combo box needs a special role because of ATK mapping to menu
nsCOMPtr<nsIAccessible> possibleCombo;
GetParent(getter_AddRefs(possibleCombo));
if (nsAccUtils::Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX) {
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
}
else { // Check to see if combo owns the listbox instead
possibleCombo = nsRelUtils::
GetRelatedAccessible(this, nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
if (nsAccUtils::Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX)
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
}
}
else if (*aRole == nsIAccessibleRole::ROLE_OPTION) {
if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_COMBOBOX_LIST)
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
}
// We are done if the mapped role trumps native semantics
if (mRoleMapEntry->roleRule == kUseMapRole)
return NS_OK;
}
*aRole = NativeRole();
*aRole = Role();
return NS_OK;
}
@ -1628,10 +1583,6 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
}
}
PRUint32 role;
rv = GetRole(&role);
NS_ENSURE_SUCCESS(rv, rv);
// For some reasons DOM node may have not a frame. We tract such accessibles
// as invisible.
nsIFrame *frame = GetFrame();
@ -1853,6 +1804,52 @@ nsAccessible::GetKeyBindings(PRUint8 aActionIndex,
return NS_OK;
}
PRUint32
nsAccessible::Role()
{
// No ARIA role or it doesn't suppress role from native markup.
if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
return NativeRole();
// XXX: these unfortunate exceptions don't fit into the ARIA table. This is
// where the accessible role depends on both the role and ARIA state.
if (mRoleMapEntry->role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
if (nsAccUtils::HasDefinedARIAToken(mContent,
nsAccessibilityAtoms::aria_pressed)) {
// For simplicity, any existing pressed attribute except "" or "undefined"
// indicates a toggle.
return nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
}
if (mContent->AttrValueIs(kNameSpaceID_None,
nsAccessibilityAtoms::aria_haspopup,
nsAccessibilityAtoms::_true,
eCaseMatters)) {
// For button with aria-haspopup="true".
return nsIAccessibleRole::ROLE_BUTTONMENU;
}
} else if (mRoleMapEntry->role == nsIAccessibleRole::ROLE_LISTBOX) {
// A listbox inside of a combobox needs a special role because of ATK
// mapping to menu.
if (nsAccUtils::Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX) {
return nsIAccessibleRole::ROLE_COMBOBOX_LIST;
nsCOMPtr<nsIAccessible> possibleCombo =
nsRelUtils::GetRelatedAccessible(this,
nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
if (nsAccUtils::Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX)
return nsIAccessibleRole::ROLE_COMBOBOX_LIST;
}
} else if (mRoleMapEntry->role == nsIAccessibleRole::ROLE_OPTION) {
if (nsAccUtils::Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST)
return nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
}
return mRoleMapEntry->role;
}
PRUint32
nsAccessible::NativeRole()
{

View File

@ -143,6 +143,11 @@ public:
*/
virtual nsresult GetNameInternal(nsAString& aName);
/**
* Return enumerated accessible role (see constants in nsIAccessibleRole).
*/
virtual PRUint32 Role();
/**
* Returns enumerated accessible role from native markup (see constants in
* nsIAccessibleRole). Doesn't take into account ARIA roles.

View File

@ -139,15 +139,6 @@ nsApplicationAccessible::GetKeyboardShortcut(nsAString &aKeyboardShortcut)
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetRole(PRUint32 *aRole)
{
NS_ENSURE_ARG_POINTER(aRole);
*aRole = NativeRole();
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
@ -381,6 +372,12 @@ nsApplicationAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK;
}
PRUint32
nsApplicationAccessible::Role()
{
return NativeRole();
}
PRUint32
nsApplicationAccessible::NativeRole()
{

View File

@ -81,7 +81,6 @@ public:
NS_IMETHOD GetValue(nsAString &aValue);
NS_IMETHOD GetDescription(nsAString &aDescription);
NS_IMETHOD GetKeyboardShortcut(nsAString &aKeyboardShortcut);
NS_IMETHOD GetRole(PRUint32 *aRole);
NS_IMETHOD GetState(PRUint32 *aState , PRUint32 *aExtraState );
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
@ -113,6 +112,7 @@ public:
// nsAccessible
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual PRUint32 Role();
virtual PRUint32 NativeRole();
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);

View File

@ -135,7 +135,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
if ((self = [super init])) {
mGeckoAccessible = geckoAccessible;
mIsExpired = NO;
geckoAccessible->GetRole(&mRole);
mRole = geckoAccessible->Role();
// Check for OS X "role skew"; the role constants in nsIAccessible.idl need to match the ones
// in nsRoleMap.h.

View File

@ -399,11 +399,8 @@ __try {
"Does not support nsIAccessibleText when it should");
#endif
PRUint32 xpRole = 0, msaaRole = 0;
if (NS_FAILED(xpAccessible->GetRole(&xpRole)))
return E_FAIL;
msaaRole = gWindowsRoleMap[xpRole].msaaRole;
PRUint32 xpRole = xpAccessible->Role();
PRUint32 msaaRole = gWindowsRoleMap[xpRole].msaaRole;
NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].msaaRole == ROLE_WINDOWS_LAST_ENTRY,
"MSAA role map skewed");
@ -1192,14 +1189,10 @@ nsAccessibleWrap::role(long *aRole)
__try {
*aRole = 0;
PRUint32 xpRole = 0;
nsresult rv = GetRole(&xpRole);
if (NS_FAILED(rv))
return GetHRESULT(rv);
NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].ia2Role == ROLE_WINDOWS_LAST_ENTRY,
"MSAA role map skewed");
PRUint32 xpRole = Role();
*aRole = gWindowsRoleMap[xpRole].ia2Role;
// Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call