forked from mirrors/gecko-dev
Bug 1778795: role="form" with empty accessible name returns native role, r=Jamie
The ARIA spec requires that, for certain landmark roles with no author-specified names, user agents must treat such elements as if no role had been provided. This revision accomplishes that task by carving out an exception in ARIATransformRole and ComputeARIARole for roles::FORM, similar to the existing carveout for roles::REGION. This revision also implements a NameIsEmpty function which is helpful for checking name emptiness (since we do this in a few places) without leaving a "name" variable on the stack. Finally, this revision updates a expected WPT failure (by removing it). Differential Revision: https://phabricator.services.mozilla.com/D202778
This commit is contained in:
parent
d91da7450d
commit
dbe5ffd60b
7 changed files with 40 additions and 24 deletions
|
|
@ -539,17 +539,13 @@ nsStaticAtom* Accessible::LandmarkRole() const {
|
|||
}
|
||||
|
||||
if (tagName == nsGkAtoms::section) {
|
||||
nsAutoString name;
|
||||
Name(name);
|
||||
if (!name.IsEmpty()) {
|
||||
if (!NameIsEmpty()) {
|
||||
return nsGkAtoms::region;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagName == nsGkAtoms::form) {
|
||||
nsAutoString name;
|
||||
Name(name);
|
||||
if (!name.IsEmpty()) {
|
||||
if (!NameIsEmpty()) {
|
||||
return nsGkAtoms::form;
|
||||
}
|
||||
}
|
||||
|
|
@ -567,8 +563,10 @@ nsStaticAtom* Accessible::LandmarkRole() const {
|
|||
nsStaticAtom* Accessible::ComputedARIARole() const {
|
||||
const nsRoleMapEntry* roleMap = ARIARoleMap();
|
||||
if (roleMap && roleMap->roleAtom != nsGkAtoms::_empty &&
|
||||
// region has its own Gecko role and it needs to be handled specially.
|
||||
// region and form have their own Gecko roles and need to be handled
|
||||
// specially.
|
||||
roleMap->roleAtom != nsGkAtoms::region &&
|
||||
roleMap->roleAtom != nsGkAtoms::form &&
|
||||
(roleMap->roleRule == kUseNativeRole || roleMap->IsOfType(eLandmark) ||
|
||||
roleMap->roleAtom == nsGkAtoms::alertdialog ||
|
||||
roleMap->roleAtom == nsGkAtoms::feed ||
|
||||
|
|
@ -651,6 +649,12 @@ void Accessible::ApplyImplicitState(uint64_t& aState) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool Accessible::NameIsEmpty() const {
|
||||
nsAutoString name;
|
||||
Name(name);
|
||||
return name.IsEmpty();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// KeyBinding class
|
||||
|
||||
|
|
|
|||
|
|
@ -720,6 +720,11 @@ class Accessible {
|
|||
*/
|
||||
void ApplyImplicitState(uint64_t& aState) const;
|
||||
|
||||
/*
|
||||
* Return true if the accessible name is empty.
|
||||
*/
|
||||
bool NameIsEmpty() const;
|
||||
|
||||
private:
|
||||
static const uint8_t kTypeBits = 6;
|
||||
static const uint8_t kGenericTypesBits = 18;
|
||||
|
|
|
|||
|
|
@ -1842,8 +1842,10 @@ bool LocalAccessible::SetCurValue(double aValue) {
|
|||
|
||||
role LocalAccessible::ARIATransformRole(role aRole) const {
|
||||
// Beginning with ARIA 1.1, user agents are expected to use the native host
|
||||
// language role of the element when the region role is used without a name.
|
||||
// https://rawgit.com/w3c/aria/master/core-aam/core-aam.html#role-map-region
|
||||
// language role of the element when the form or region roles are used without
|
||||
// a name. Says the spec, "the user agent MUST treat such elements as if no
|
||||
// role had been provided."
|
||||
// https://w3c.github.io/aria/#document-handling_author-errors_roles
|
||||
//
|
||||
// XXX: While the name computation algorithm can be non-trivial in the general
|
||||
// case, it should not be especially bad here: If the author hasn't used the
|
||||
|
|
@ -1851,10 +1853,8 @@ role LocalAccessible::ARIATransformRole(role aRole) const {
|
|||
// calculation rule excludes name from content. That said, this use case is
|
||||
// another example of why we should consider caching the accessible name. See:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
|
||||
if (aRole == roles::REGION) {
|
||||
nsAutoString name;
|
||||
Name(name);
|
||||
return name.IsEmpty() ? NativeRole() : aRole;
|
||||
if (aRole == roles::REGION || aRole == roles::FORM) {
|
||||
return NameIsEmpty() ? NativeRole() : aRole;
|
||||
}
|
||||
|
||||
// XXX: these unfortunate exceptions don't fit into the ARIA table. This is
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ addAccessibleTask(
|
|||
<div id="complementary" role="complementary"></div>
|
||||
<div id="contentinfo" role="contentinfo"></div>
|
||||
<div id="form" role="form"></div>
|
||||
<div id="form_label" aria-label="form" role="form"></div>
|
||||
<div id="main" role="main"></div>
|
||||
<div id="navigation" role="navigation"></div>
|
||||
<div id="search" role="search"></div>
|
||||
|
|
@ -149,7 +150,8 @@ addAccessibleTask(
|
|||
"AXLandmarkComplementary"
|
||||
);
|
||||
testRoleAndSubRole(accDoc, "contentinfo", null, "AXLandmarkContentInfo");
|
||||
testRoleAndSubRole(accDoc, "form", null, "AXLandmarkForm");
|
||||
testRoleAndSubRole(accDoc, "form", null, "AXApplicationGroup");
|
||||
testRoleAndSubRole(accDoc, "form_label", null, "AXLandmarkForm");
|
||||
testRoleAndSubRole(accDoc, "main", null, "AXLandmarkMain");
|
||||
testRoleAndSubRole(accDoc, "navigation", null, "AXLandmarkNavigation");
|
||||
testRoleAndSubRole(accDoc, "search", null, "AXLandmarkSearch");
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@
|
|||
testRole("aria_directory_mixed", ROLE_LIST);
|
||||
testRole("aria_document", ROLE_NON_NATIVE_DOCUMENT);
|
||||
testRole("aria_document_mixed", ROLE_NON_NATIVE_DOCUMENT);
|
||||
testRole("aria_form", ROLE_FORM);
|
||||
testRole("aria_form_mixed", ROLE_FORM);
|
||||
testRole("aria_form", ROLE_TEXT);
|
||||
testRole("aria_form_mixed", ROLE_TEXT);
|
||||
testRole("aria_form_with_label", ROLE_FORM);
|
||||
testRole("aria_form_with_label_mixed", ROLE_FORM);
|
||||
testRole("aria_feed", ROLE_GROUPING);
|
||||
|
|
@ -184,8 +184,10 @@
|
|||
|
||||
testRole("articlemain", ROLE_LANDMARK);
|
||||
testRole("articlemain_mixed", ROLE_LANDMARK);
|
||||
testRole("articleform", ROLE_FORM);
|
||||
testRole("articleform_mixed", ROLE_FORM);
|
||||
testRole("articleform", ROLE_ARTICLE);
|
||||
testRole("articleform_mixed", ROLE_ARTICLE);
|
||||
testRole("articleform_label", ROLE_FORM);
|
||||
testRole("articleform_label_mixed", ROLE_FORM);
|
||||
|
||||
// Test article exposed as article
|
||||
testRole("testArticle", ROLE_ARTICLE);
|
||||
|
|
@ -204,8 +206,10 @@
|
|||
// strong landmark
|
||||
testRole("application", ROLE_APPLICATION);
|
||||
testRole("application_mixed", ROLE_APPLICATION);
|
||||
testRole("form", ROLE_FORM);
|
||||
testRole("form_mixed", ROLE_FORM);
|
||||
testRole("form", ROLE_SECTION);
|
||||
testRole("form_mixed", ROLE_SECTION);
|
||||
testRole("form_label", ROLE_FORM);
|
||||
testRole("form_label_mixed", ROLE_FORM);
|
||||
testRole("application_table", ROLE_APPLICATION);
|
||||
testRole("application_table_mixed", ROLE_APPLICATION);
|
||||
|
||||
|
|
@ -535,6 +539,8 @@
|
|||
<article id="articlemain_mixed" role="mAIn">a main area</article>
|
||||
<article id="articleform" role="form">a form area</article>
|
||||
<article id="articleform_mixed" role="fORm">a form area</article>
|
||||
<article id="articleform_label" aria-label="form" role="form">a form area</article>
|
||||
<article id="articleform_label_mixed" aria-label="form" role="fORm">a form area</article>
|
||||
|
||||
<div id="testArticle" role="article" title="Test article">
|
||||
<p>This is a paragraph inside the article.</p>
|
||||
|
|
@ -561,6 +567,8 @@
|
|||
<div role="aPPLICATIOn" id="application_mixed">application</div>
|
||||
<div role="form" id="form">form</div>
|
||||
<div role="fORm" id="form_mixed">form</div>
|
||||
<div role="form" id="form_label" aria-label="form">form</div>
|
||||
<div role="fORm" id="form_label_mixed" aria-label="form">form</div>
|
||||
|
||||
<!-- weak landmarks -->
|
||||
<div role="banner" id="banner">banner</div>
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@
|
|||
<!-- natural and aria-owns hierarchy -->
|
||||
<div id="t5_2" role="note"><div aria-owns="t5_3" role="heading"></div></div>
|
||||
<div id="t5_1"><div aria-owns="t5_2" role="group"></div></div>
|
||||
<div id="t5_3" role="form"><div aria-owns="t5_1" role="tooltip"></div></div>
|
||||
<div id="t5_3" aria-label="form" role="form"><div aria-owns="t5_1" role="tooltip"></div></div>
|
||||
|
||||
<!-- rearrange children -->
|
||||
<div id="t6_1" aria-owns="t6_3 t6_2">
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
[form-roles.html]
|
||||
[form without label]
|
||||
expected: FAIL
|
||||
Loading…
Reference in a new issue