Merge mozilla-central to mozilla-inbound. a=merge CLOSED TREE

This commit is contained in:
Ciure Andrei 2018-11-02 11:45:44 +02:00
commit 5bf715b6ea
6 changed files with 104 additions and 0 deletions

View File

@ -1302,6 +1302,7 @@ static const AttrCharacteristics gWAIUnivAttrMap[] = {
{nsGkAtoms::aria_busy, ATTR_VALTOKEN | ATTR_GLOBAL },
{nsGkAtoms::aria_checked, ATTR_BYPASSOBJ | ATTR_VALTOKEN }, /* exposes checkable obj attr */
{nsGkAtoms::aria_controls, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{nsGkAtoms::aria_current, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
{nsGkAtoms::aria_describedby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{nsGkAtoms::aria_details, ATTR_BYPASSOBJ | ATTR_GLOBAL },
{nsGkAtoms::aria_disabled, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
@ -1474,6 +1475,15 @@ AttrIterator::Next(nsAString& aAttrName, nsAString& aAttrValue)
nsAutoString value;
if (mElement->GetAttr(kNameSpaceID_None, attrAtom, value)) {
aAttrName.Assign(Substring(attrStr, 5));
if (attrFlags & ATTR_VALTOKEN) {
nsAtom* normalizedValue =
nsAccUtils::NormalizeARIAToken(mElement, attrAtom);
if (normalizedValue) {
nsDependentAtomString normalizedValueStr(normalizedValue);
aAttrValue.Assign(normalizedValueStr);
return true;
}
}
aAttrValue.Assign(value);
return true;
}

View File

@ -225,6 +225,26 @@ nsAccUtils::GetARIAToken(dom::Element* aElement, nsAtom* aAttr)
return nullptr;
}
nsStaticAtom*
nsAccUtils::NormalizeARIAToken(dom::Element* aElement, nsAtom* aAttr)
{
if (!HasDefinedARIAToken(aElement, aAttr)) {
return nsGkAtoms::_empty;
}
if (aAttr== nsGkAtoms::aria_current) {
static Element::AttrValuesArray tokens[] =
{ nsGkAtoms::page, nsGkAtoms::step, nsGkAtoms::location_,
nsGkAtoms::date, nsGkAtoms::time, nsGkAtoms::_true, nullptr};
int32_t idx = aElement->FindAttrValueIn(kNameSpaceID_None,
aAttr, tokens, eCaseMatters);
// If the token is present, return it, otherwise TRUE as per spec.
return (idx >= 0) ? tokens[idx] : nsGkAtoms::_true;
}
return nullptr;
}
Accessible*
nsAccUtils::GetSelectableContainer(Accessible* aAccessible, uint64_t aState)
{

View File

@ -104,6 +104,14 @@ public:
static nsStaticAtom* GetARIAToken(mozilla::dom::Element* aElement,
nsAtom* aAttr);
/**
* If the given ARIA attribute has a specific known token value, return it.
* If the specification demands for a fallback value for unknown attribute
* values, return that. For all others, return a nullptr.
*/
static nsStaticAtom* NormalizeARIAToken(mozilla::dom::Element* aElement,
nsAtom* aAttr);
/**
* Return document accessible for the given DOM node.
*/

View File

@ -51,6 +51,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAttrs("sortOther", {"sort": "other"}, true);
testAttrs("roledescr", {"roledescription": "spreadshit"}, true);
testAttrs("currentPage", {"current": "page"}, true);
testAttrs("currentStep", {"current": "step"}, true);
testAttrs("currentLocation", {"current": "location"}, true);
testAttrs("currentDate", {"current": "date"}, true);
testAttrs("currentTime", {"current": "time"}, true);
testAttrs("currentTrue", {"current": "true"}, true);
testAttrs("currentOther", {"current": "true"}, true);
testAbsentAttrs("currentFalse", {"current": "true"});
testAttrs("currentSpan", {"current": "page"}, true);
// inherited attributes by subdocuments
var subdoc = getAccessible("iframe").firstChild;
@ -187,6 +195,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
<div id="sortOther" role="columnheader" aria-sort="other"></div>
<div id="roledescr" aria-roledescription="spreadshit"></div>
<div id="currentPage" aria-current="page"></div>
<div id="currentStep" aria-current="step"></div>
<div id="currentLocation" aria-current="location"></div>
<div id="currentDate" aria-current="date"></div>
<div id="currentTime" aria-current="time"></div>
<div id="currentTrue" aria-current="true"></div>
<div id="currentOther" aria-current="other"></div>
<div id="currentFalse" aria-current="false"></div>
<!-- aria-current on a span which must create an accessible -->
<ol>
<li><a href="...">Page 1</a></li>
<li><a href="...">Page 2</a></li>
<li><span id="currentSpan" aria-current="page">This page</span></li>
</ol>
<!-- inherited from iframe -->
<iframe id="iframe" src="data:text/html,<html><body></body></html>"

View File

@ -343,6 +343,39 @@ add_task(async function checkDefaultPermissionState() {
Services.prefs.setIntPref("permissions.default.desktop-notification", SitePermissions.UNKNOWN);
});
add_task(async function testTabBehaviour() {
// Test tab behaviour inside the permissions setting dialog when site permissions are selected.
// Only selected items in the richlistbox should be tabable for accessibility reasons.
// Force tabfocus for all elements on OSX.
SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]});
SitePermissions.set(URI, "desktop-notification", SitePermissions.ALLOW);
let u = Services.io.newURI("http://www.test.com");
SitePermissions.set(u, "desktop-notification", SitePermissions.ALLOW);
await openPermissionsDialog();
let doc = sitePermissionsDialog.document;
EventUtils.synthesizeKey("KEY_Tab", {}, sitePermissionsDialog);
let richlistbox = doc.getElementById("permissionsBox");
is(richlistbox, doc.activeElement.closest("#permissionsBox"), "The richlistbox is focused after pressing tab once.");
EventUtils.synthesizeKey("KEY_ArrowDown", {}, sitePermissionsDialog);
EventUtils.synthesizeKey("KEY_Tab", {}, sitePermissionsDialog);
let menulist = doc.getElementById("permissionsBox").children[1].getElementsByTagName("menulist")[0];
is(menulist, doc.activeElement, "The menulist inside the selected richlistitem is focused now");
EventUtils.synthesizeKey("KEY_Tab", {}, sitePermissionsDialog);
let removeButton = doc.getElementById("removePermission");
is(removeButton, doc.activeElement, "The focus moves outside the richlistbox and onto the remove button");
SitePermissions.remove(URI, "desktop-notification");
SitePermissions.remove(u, "desktop-notification");
doc.getElementById("cancel").click();
});
add_task(async function removeTab() {
gBrowser.removeCurrentTab();
});

View File

@ -346,6 +346,17 @@ var gSitePermissionsManager = {
onPermissionSelect() {
this._setRemoveButtonState();
// If any item is selected, it should be the only item tabable
// in the richlistbox for accessibility reasons.
this._list.children.forEach((item) => {
let menulist = item.getElementsByTagName("menulist")[0];
if (!item.selected) {
menulist.setAttribute("tabindex", -1);
} else {
menulist.removeAttribute("tabindex");
}
});
},
onPermissionChange(perm, capability) {