mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1582409 - ensure that we handle SVGs with role=img correctly when running text-label checks. r=nchevobbe
Differential Revision: https://phabricator.services.mozilla.com/D55976 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
826897618a
commit
b0376a86df
@ -30,6 +30,13 @@ loader.lazyRequireGetter(
|
||||
true
|
||||
);
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"getAriaRoles",
|
||||
"devtools/server/actors/utils/accessibility",
|
||||
true
|
||||
);
|
||||
|
||||
const {
|
||||
accessibility: {
|
||||
AUDIT_TYPE: { KEYBOARD },
|
||||
@ -127,27 +134,6 @@ function isInvalidNode(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get role attribute for an accessible object if specified for its
|
||||
* corresponding DOMNode.
|
||||
*
|
||||
* @param {nsIAccessible} accessible
|
||||
* Accessible for which to determine its role attribute value.
|
||||
*
|
||||
* @returns {null|String}
|
||||
* Role attribute value if specified.
|
||||
*/
|
||||
function getAriaRoles(accessible) {
|
||||
try {
|
||||
return accessible.attributes.getStringProperty("xml-roles");
|
||||
} catch (e) {
|
||||
// No xml-roles. nsPersistentProperties throws if the attribute for a key
|
||||
// is not found.
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if accessible is focusable with the keyboard.
|
||||
*
|
||||
|
@ -5,6 +5,14 @@
|
||||
"use strict";
|
||||
|
||||
const { Ci } = require("chrome");
|
||||
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"getAriaRoles",
|
||||
"devtools/server/actors/utils/accessibility",
|
||||
true
|
||||
);
|
||||
|
||||
const {
|
||||
accessibility: {
|
||||
AUDIT_TYPE: { TEXT_LABEL },
|
||||
@ -137,6 +145,23 @@ const dialogRule = shouldHaveNonEmptyNameRule.bind(null, DIALOG_NO_NAME);
|
||||
*/
|
||||
const imageRule = function(accessible) {
|
||||
const name = getAccessibleName(accessible);
|
||||
const { DOMNode } = accessible;
|
||||
if (
|
||||
DOMNode instanceof DOMNode.ownerGlobal.SVGElement &&
|
||||
DOMNode.ownerSVGElement
|
||||
) {
|
||||
let ownerSVGAccessible = accessible.parent;
|
||||
while (ownerSVGAccessible.DOMNode.ownerSVGElement) {
|
||||
ownerSVGAccessible = ownerSVGAccessible.parent;
|
||||
}
|
||||
|
||||
const ariaRoles = getAriaRoles(ownerSVGAccessible);
|
||||
if (ariaRoles && ariaRoles.includes("img")) {
|
||||
// Do not require a defined name if a wrapping SVG has a role="img".
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return name != null ? null : { score: FAIL, issue: IMAGE_NO_NAME };
|
||||
};
|
||||
|
||||
|
@ -103,7 +103,29 @@ function isWebRenderEnabled(win) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get role attribute for an accessible object if specified for its
|
||||
* corresponding DOMNode.
|
||||
*
|
||||
* @param {nsIAccessible} accessible
|
||||
* Accessible for which to determine its role attribute value.
|
||||
*
|
||||
* @returns {null|String}
|
||||
* Role attribute value if specified.
|
||||
*/
|
||||
function getAriaRoles(accessible) {
|
||||
try {
|
||||
return accessible.attributes.getStringProperty("xml-roles");
|
||||
} catch (e) {
|
||||
// No xml-roles. nsPersistentProperties throws if the attribute for a key
|
||||
// is not found.
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
exports.getAriaRoles = getAriaRoles;
|
||||
exports.isDefunct = isDefunct;
|
||||
exports.isWebRenderEnabled = isWebRenderEnabled;
|
||||
exports.loadSheetForBackgroundCalculation = loadSheetForBackgroundCalculation;
|
||||
exports.removeSheetForBackgroundCalculation = removeSheetForBackgroundCalculation;
|
||||
exports.isWebRenderEnabled = isWebRenderEnabled;
|
||||
|
@ -1062,6 +1062,66 @@ add_task(async function() {
|
||||
{ score: FAIL, issue: TOOLBAR_NO_NAME },
|
||||
],
|
||||
["Non-unique aria toolbar with aria-labelledby", "#toolbar-4", null],
|
||||
["SVGElement with role=img that has a title", "#svg-1", null],
|
||||
[
|
||||
"SVGElement with no name and with ownerSVGElement with role=img that has a title",
|
||||
"#svg-2",
|
||||
null,
|
||||
],
|
||||
["SVGElement without role=img that has a title", "#svg-3", null],
|
||||
[
|
||||
"SVGElement with no name and with ownerSVGElement without role=img",
|
||||
"#svg-4",
|
||||
{ score: FAIL, issue: IMAGE_NO_NAME },
|
||||
],
|
||||
[
|
||||
"SVGElement with role=img and no name",
|
||||
"#svg-5",
|
||||
{ score: FAIL, issue: IMAGE_NO_NAME },
|
||||
],
|
||||
[
|
||||
"SVGElement with no name and with ownerSVGElement with role=img",
|
||||
"#svg-6",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"SVGElement with no name",
|
||||
"#svg-7",
|
||||
{ score: FAIL, issue: IMAGE_NO_NAME },
|
||||
],
|
||||
[
|
||||
"SVGElement with no name and with ownerSVGElement with no name",
|
||||
"#svg-8",
|
||||
{ score: FAIL, issue: IMAGE_NO_NAME },
|
||||
],
|
||||
["SVGElement with a name", "#svg-9", null],
|
||||
[
|
||||
"SVGElement with a name and with ownerSVGElement with a name",
|
||||
"#svg-10",
|
||||
null,
|
||||
],
|
||||
["SVGElement with a title", "#svg-11", null],
|
||||
[
|
||||
"SVGElement with a name and with ownerSVGElement with a title",
|
||||
"#svg-12",
|
||||
null,
|
||||
],
|
||||
["SVGElement with role=img that has a title", "#svg-13", null],
|
||||
[
|
||||
"SVGElement with a name and with ownerSVGElement with role=img that has a title",
|
||||
"#svg-14",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"SVGElement with role=img and no title",
|
||||
"#svg-15",
|
||||
{ score: FAIL, issue: IMAGE_NO_NAME },
|
||||
],
|
||||
[
|
||||
"SVGElement with a name and with ownerSVGElement with role=img and no title",
|
||||
"#svg-16",
|
||||
null,
|
||||
],
|
||||
];
|
||||
|
||||
for (const [description, selector, expected] of tests) {
|
||||
|
@ -433,5 +433,33 @@
|
||||
<span id="toolbar-3" role="toolbar" aria-labelledby="toolbar-3-label"></span>
|
||||
<p id="toolbar-4-label">Toolbar</p>
|
||||
<span id="toolbar-4" role="toolbar" aria-labelledby="toolbar-4-label"></span>
|
||||
<svg id="svg-1" role="img" viewbox="0 0 100 10" height="10px">
|
||||
<title id="siteLogoTitle">Site Logo</title>
|
||||
<rect id="svg-2" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-3" viewbox="0 0 100 10" height="10px">
|
||||
<title id="siteLogoTitle">Site Logo</title>
|
||||
<rect id="svg-4" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-5" role="img" viewbox="0 0 100 10" height="10px">
|
||||
<rect id="svg-6" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-7" viewbox="0 0 100 10" height="10px">
|
||||
<rect id="svg-8" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-9" aria-label="foo" viewbox="0 0 100 10" height="10px">
|
||||
<rect id="svg-10" aria-label="bar" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-11" viewbox="0 0 100 10" height="10px">
|
||||
<title id="siteLogoTitle">Site Logo</title>
|
||||
<rect id="svg-12" aria-label="foo" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-13" role="img" viewbox="0 0 100 10" height="10px">
|
||||
<title id="siteLogoTitle">Site Logo</title>
|
||||
<rect aria-label="foo" id="svg-14" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
<svg id="svg-15" role="img" viewbox="0 0 100 10" height="10px">
|
||||
<rect aria-label="foo" id="svg-16" x="0" y="00" width="100" height="10" fill="red"></rect>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user