Bug 1020548 - update aria-orientation impl to ARIA 1.1, r=tbsaunde, sr=neil

This commit is contained in:
Alexander Surkov 2014-08-11 08:13:44 -04:00
parent 95991ba24f
commit 4b3527527d
5 changed files with 122 additions and 79 deletions

View File

@ -122,9 +122,10 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eOpenCloseAction,
eNoLiveAttr,
kGenericAccType,
states::COLLAPSED | states::HASPOPUP,
states::COLLAPSED | states::HASPOPUP | states::VERTICAL,
eARIAAutoComplete,
eARIAReadonly
eARIAReadonly,
eARIAOrientation
},
{ // dialog
&nsGkAtoms::dialog,
@ -261,10 +262,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eListControl | eSelect,
kNoReqStates,
states::VERTICAL,
eARIAMultiSelectable,
eARIAReadonly,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // listitem
&nsGkAtoms::listitem,
@ -315,7 +317,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
// any action, but menu can be open or close.
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::VERTICAL,
eARIAOrientation
},
{ // menubar
&nsGkAtoms::menubar,
@ -325,7 +328,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // menuitem
&nsGkAtoms::menuitem,
@ -422,7 +426,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
kNoReqStates,
eARIAOrientation
},
{ // region
&nsGkAtoms::region,
@ -475,7 +480,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::VERTICAL,
eARIAOrientation,
eARIAReadonly
},
@ -487,7 +492,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::HORIZONTAL,
eARIAOrientation
},
{ // slider
@ -498,7 +503,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::HORIZONTAL,
eARIAOrientation,
eARIAReadonly
},
@ -542,7 +547,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // tabpanel
&nsGkAtoms::tabpanel,
@ -584,7 +590,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // tooltip
&nsGkAtoms::tooltip,
@ -604,10 +611,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect,
kNoReqStates,
states::VERTICAL,
eARIAReadonly,
eARIAMultiSelectable,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // treegrid
&nsGkAtoms::treegrid,
@ -617,10 +625,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect | eTable,
kNoReqStates,
states::VERTICAL,
eARIAReadonlyOrEditable,
eARIAMultiSelectable,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // treeitem
&nsGkAtoms::treeitem,

View File

@ -180,6 +180,7 @@ struct nsRoleMapEntry
mozilla::a11y::aria::EStateRule attributeMap1;
mozilla::a11y::aria::EStateRule attributeMap2;
mozilla::a11y::aria::EStateRule attributeMap3;
mozilla::a11y::aria::EStateRule attributeMap4;
};

View File

@ -19,39 +19,18 @@ using namespace mozilla::a11y::aria;
*/
struct EnumTypeData
{
EnumTypeData(nsIAtom* aAttrName,
nsIAtom** aValue1, uint64_t aState1,
nsIAtom** aValue2, uint64_t aState2,
nsIAtom** aValue3 = 0, uint64_t aState3 = 0) :
mState1(aState1), mState2(aState2), mState3(aState3), mDefaultState(0),
mAttrName(aAttrName), mValue1(aValue1), mValue2(aValue2), mValue3(aValue3),
mNullValue(nullptr)
{ }
EnumTypeData(nsIAtom* aAttrName, uint64_t aDefaultState,
nsIAtom** aValue1, uint64_t aState1) :
mState1(aState1), mState2(0), mState3(0), mDefaultState(aDefaultState),
mAttrName(aAttrName), mValue1(aValue1), mValue2(nullptr), mValue3(nullptr),
mNullValue(nullptr)
{ }
// States applied if corresponding enum values are matched.
const uint64_t mState1;
const uint64_t mState2;
const uint64_t mState3;
// Default state if no one enum value is matched.
const uint64_t mDefaultState;
// ARIA attribute name.
nsIAtom* const mAttrName;
// States if the attribute value is matched to the enum value. Used as
// nsIContent::AttrValuesArray.
nsIAtom* const* const mValue1;
nsIAtom* const* const mValue2;
nsIAtom* const* const mValue3;
nsIAtom* const* const mNullValue;
// nsIContent::AttrValuesArray, last item must be nullptr.
nsIAtom* const* const mValues[4];
// States applied if corresponding enum values are matched.
const uint64_t mStates[3];
// States to clear in case of match.
const uint64_t mClearState;
};
enum ETokenType
@ -108,11 +87,15 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
switch (aRule) {
case eARIAAutoComplete:
{
static const EnumTypeData data(
static const EnumTypeData data = {
nsGkAtoms::aria_autocomplete,
&nsGkAtoms::inlinevalue, states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::list, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::both, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION);
{ &nsGkAtoms::inlinevalue,
&nsGkAtoms::list,
&nsGkAtoms::both, nullptr },
{ states::SUPPORTS_AUTOCOMPLETION,
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION }, 0
};
MapEnumType(aElement, aState, data);
return true;
@ -120,10 +103,13 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
case eARIABusy:
{
static const EnumTypeData data(
static const EnumTypeData data = {
nsGkAtoms::aria_busy,
&nsGkAtoms::_true, states::BUSY,
&nsGkAtoms::error, states::INVALID);
{ &nsGkAtoms::_true,
&nsGkAtoms::error, nullptr },
{ states::BUSY,
states::INVALID }, 0
};
MapEnumType(aElement, aState, data);
return true;
@ -221,23 +207,16 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
case eARIAOrientation:
{
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("horizontal"), eCaseMatters)) {
*aState &= ~states::VERTICAL;
*aState |= states::HORIZONTAL;
} else if (aElement->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("vertical"),
eCaseMatters)) {
*aState &= ~states::HORIZONTAL;
*aState |= states::VERTICAL;
} else {
NS_ASSERTION(!(*aState & (states::HORIZONTAL | states::VERTICAL)),
"orientation state on role with default aria-orientation!");
*aState |= GetRoleMap(aElement)->Is(nsGkAtoms::scrollbar) ?
states::VERTICAL : states::HORIZONTAL;
}
static const EnumTypeData data = {
nsGkAtoms::aria_orientation,
{ &nsGkAtoms::horizontal,
&nsGkAtoms::vertical, nullptr },
{ states::HORIZONTAL,
states::VERTICAL },
states::HORIZONTAL | states::VERTICAL
};
MapEnumType(aElement, aState, data);
return true;
}
@ -347,19 +326,17 @@ static void
MapEnumType(dom::Element* aElement, uint64_t* aState, const EnumTypeData& aData)
{
switch (aElement->FindAttrValueIn(kNameSpaceID_None, aData.mAttrName,
&aData.mValue1, eCaseMatters)) {
aData.mValues, eCaseMatters)) {
case 0:
*aState |= aData.mState1;
*aState = (*aState & ~aData.mClearState) | aData.mStates[0];
return;
case 1:
*aState |= aData.mState2;
*aState = (*aState & ~aData.mClearState) | aData.mStates[1];
return;
case 2:
*aState |= aData.mState3;
*aState = (*aState & ~aData.mClearState) | aData.mStates[2];
return;
}
*aState |= aData.mDefaultState;
}
static void

View File

@ -1592,8 +1592,9 @@ Accessible::ApplyARIAState(uint64_t* aState) const
*aState |= mRoleMapEntry->state;
if (aria::MapToState(mRoleMapEntry->attributeMap1, element, aState) &&
aria::MapToState(mRoleMapEntry->attributeMap2, element, aState))
aria::MapToState(mRoleMapEntry->attributeMap3, element, aState);
aria::MapToState(mRoleMapEntry->attributeMap2, element, aState) &&
aria::MapToState(mRoleMapEntry->attributeMap3, element, aState))
aria::MapToState(mRoleMapEntry->attributeMap4, element, aState);
// ARIA gridcell inherits editable/readonly states from the grid until it's
// overridden.

View File

@ -48,7 +48,7 @@
children = acc.children;
} catch(e) {}
ok(children, "Could not get children for " + aAccOrElmOrID +"!");
if (children) {
for (var i = 0; i < children.length; i++) {
var childAcc = children.queryElementAt(i, nsIAccessible);
@ -213,7 +213,22 @@
testStates("aria_main_anchor", STATE_SELECTABLE);
testStates("aria_navigation_anchor", STATE_SELECTABLE);
// aria-orientation (applied to scrollbar, separator, slider)
// aria-orientation
testStates("aria_combobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hcombobox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vcombobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_listbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hlistbox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vlistbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_menu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hmenu", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vmenu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_menubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_hmenubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vmenubar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_radiogroup", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL);
testStates("aria_hradiogroup", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vradiogroup", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
@ -223,6 +238,18 @@
testStates("aria_slider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vslider", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_tablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_htablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtablist", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_toolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_htoolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtoolbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_tree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_htree", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_treegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_htreegrid", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtreegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
// indeterminate ARIA progressbars (no aria-valuenow or aria-valuetext attribute)
// should expose mixed state
@ -498,6 +525,21 @@
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
<!-- aria-orientation -->
<div id="aria_combobox" role="combobox">combobox</div>
<div id="aria_hcombobox" role="combobox" aria-orientation="horizontal">horizontal combobox</div>
<div id="aria_vcombobox" role="combobox" aria-orientation="vertical">vertical combobox</div>
<div id="aria_listbox" role="listbox">listbox</div>
<div id="aria_hlistbox" role="listbox" aria-orientation="horizontal">horizontal listbox</div>
<div id="aria_vlistbox" role="listbox" aria-orientation="vertical">vertical listbox</div>
<div id="aria_menu" role="menu">menu</div>
<div id="aria_hmenu" role="menu" aria-orientation="horizontal">horizontal menu</div>
<div id="aria_vmenu" role="menu" aria-orientation="vertical">vertical menu</div>
<div id="aria_menubar" role="menubar">menubar</div>
<div id="aria_hmenubar" role="menubar" aria-orientation="horizontal">horizontal menubar</div>
<div id="aria_vmenubar" role="menubar" aria-orientation="vertical">vertical menubar</div>
<div id="aria_radiogroup" role="radiogroup">radiogroup</div>
<div id="aria_hradiogroup" role="radiogroup" aria-orientation="horizontal">horizontal radiogroup</div>
<div id="aria_vradiogroup" role="radiogroup" aria-orientation="vertical">vertical radiogroup</div>
<div id="aria_scrollbar" role="scrollbar">scrollbar</div>
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div>
@ -507,7 +549,20 @@
<div id="aria_slider" role="slider">slider</div>
<div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
<div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
<div id="aria_tablist" role="tablist">tablist</div>
<div id="aria_htablist" role="tablist" aria-orientation="horizontal">horizontal tablist</div>
<div id="aria_vtablist" role="tablist" aria-orientation="vertical">vertical tablist</div>
<div id="aria_toolbar" role="toolbar">toolbar</div>
<div id="aria_htoolbar" role="toolbar" aria-orientation="horizontal">horizontal toolbar</div>
<div id="aria_vtoolbar" role="toolbar" aria-orientation="vertical">vertical toolbar</div>
<div id="aria_tree" role="tree">tree</div>
<div id="aria_htree" role="tree" aria-orientation="horizontal">horizontal tree</div>
<div id="aria_vtree" role="tree" aria-orientation="vertical">vertical tree</div>
<div id="aria_treegrid" role="treegrid">treegrid</div>
<div id="aria_htreegrid" role="treegrid" aria-orientation="horizontal">horizontal treegrid</div>
<div id="aria_vtreegrid" role="treegrid" aria-orientation="vertical">vertical treegrid</div>
<!-- indeterminate ARIA progressbars should expose mixed state -->
<div id="aria_progressbar" role="progressbar"></div>
<div id="aria_progressbar_valuenow" role="progressbar" aria-valuenow="1"></div>