зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1540904 - added full page API for accessibility walker actor. r=pbro
Differential Revision: https://phabricator.services.mozilla.com/D26458 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
2c9b6e5406
Коммит
4c0b4af80b
|
@ -122,6 +122,27 @@ function isStale(accessible) {
|
|||
return !!(extraState.value & Ci.nsIAccessibleStates.EXT_STATE_STALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accessibility audit starting with the passed accessible object as a root.
|
||||
*
|
||||
* @param {Object} acc
|
||||
* AccessibileActor to be used as the root for the audit.
|
||||
* @param {Map} report
|
||||
* An accumulator map to be used to store audit information.
|
||||
*/
|
||||
function getAudit(acc, report) {
|
||||
if (acc.isDefunct) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Audit returns a promise, save the actual value in the report.
|
||||
report.set(acc, acc.audit().then(result => report.set(acc, result)));
|
||||
|
||||
for (const child of acc.children()) {
|
||||
getAudit(child, report);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The AccessibleWalkerActor stores a cache of AccessibleActors that represent
|
||||
* accessible objects in a given document.
|
||||
|
@ -367,6 +388,30 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
|
|||
{ accessible: parent, children: parent.children() }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Run accessibility audit and return relevant ancestries for AccessibleActors
|
||||
* that have non-empty audit checks.
|
||||
*
|
||||
* @return {Promise}
|
||||
* A promise that resolves when the audit is complete and all relevant
|
||||
* ancestries are calculated.
|
||||
*/
|
||||
async audit() {
|
||||
const doc = await this.getDocument();
|
||||
const report = new Map();
|
||||
getAudit(doc, report);
|
||||
await Promise.all(report.values());
|
||||
|
||||
const ancestries = [];
|
||||
for (const [acc, audit] of report.entries()) {
|
||||
if (audit && Object.values(audit).filter(check => check != null).length > 0) {
|
||||
ancestries.push(this.getAncestry(acc));
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(ancestries);
|
||||
},
|
||||
|
||||
onHighlighterEvent: function(data) {
|
||||
this.emit("highlighter-event", data);
|
||||
},
|
||||
|
|
|
@ -5,6 +5,7 @@ support-files =
|
|||
head.js
|
||||
animation.html
|
||||
animation-data.html
|
||||
doc_accessibility_audit.html
|
||||
doc_accessibility_infobar.html
|
||||
doc_accessibility.html
|
||||
doc_allocations.html
|
||||
|
@ -47,6 +48,7 @@ skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
|||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_simple.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
|
||||
[browser_accessibility_walker_audit.js]
|
||||
[browser_accessibility_walker.js]
|
||||
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533487
|
||||
[browser_actor_error.js]
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Checks for the AccessibleWalkerActor audit.
|
||||
add_task(async function() {
|
||||
const {target, accessibility} =
|
||||
await initAccessibilityFrontForUrl(MAIN_DOMAIN + "doc_accessibility_audit.html");
|
||||
|
||||
const accessibles = [{
|
||||
name: "",
|
||||
role: "document",
|
||||
value: "",
|
||||
description: "",
|
||||
keyboardShortcut: "",
|
||||
childCount: 2,
|
||||
domNodeType: 9,
|
||||
indexInParent: 0,
|
||||
states: [
|
||||
"focused", "readonly", "focusable", "active", "opaque", "enabled", "sensitive",
|
||||
],
|
||||
actions: [],
|
||||
attributes: {
|
||||
display: "block",
|
||||
"explicit-name": "true",
|
||||
"margin-bottom": "8px",
|
||||
"margin-left": "8px",
|
||||
"margin-right": "8px",
|
||||
"margin-top": "8px",
|
||||
tag: "body",
|
||||
"text-align": "start",
|
||||
"text-indent": "0px",
|
||||
},
|
||||
checks: {
|
||||
"CONTRAST": null,
|
||||
},
|
||||
}, {
|
||||
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " +
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
role: "heading",
|
||||
value: "",
|
||||
description: "",
|
||||
keyboardShortcut: "",
|
||||
childCount: 1,
|
||||
domNodeType: 1,
|
||||
indexInParent: 0,
|
||||
states: [ "selectable text", "opaque", "enabled", "sensitive" ],
|
||||
actions: [],
|
||||
attributes: {
|
||||
display: "block",
|
||||
formatting: "block",
|
||||
id: "h1",
|
||||
level: "1",
|
||||
"margin-bottom": "21.4333px",
|
||||
"margin-left": "0px",
|
||||
"margin-right": "0px",
|
||||
"margin-top": "21.4333px",
|
||||
tag: "h1",
|
||||
"text-align": "start",
|
||||
"text-indent": "0px",
|
||||
},
|
||||
checks: {
|
||||
"CONTRAST": null,
|
||||
},
|
||||
}, {
|
||||
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " +
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
role: "text leaf",
|
||||
value: "",
|
||||
description: "",
|
||||
keyboardShortcut: "",
|
||||
childCount: 0,
|
||||
domNodeType: 3,
|
||||
indexInParent: 0,
|
||||
states: [ "opaque", "enabled", "sensitive" ],
|
||||
actions: [],
|
||||
attributes: { "explicit-name": "true" },
|
||||
checks: {
|
||||
"CONTRAST": {
|
||||
"value": 21,
|
||||
"color": [0, 0, 0, 1],
|
||||
"backgroundColor": [255, 255, 255, 1],
|
||||
"isLargeText": true,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "",
|
||||
role: "paragraph",
|
||||
value: "",
|
||||
description: "",
|
||||
keyboardShortcut: "",
|
||||
childCount: 1,
|
||||
domNodeType: 1,
|
||||
indexInParent: 1,
|
||||
states: [ "selectable text", "opaque", "enabled", "sensitive" ],
|
||||
actions: [ "Press" ],
|
||||
attributes: {
|
||||
display: "block",
|
||||
formatting: "block",
|
||||
id: "p",
|
||||
"margin-bottom": "16px",
|
||||
"margin-left": "0px",
|
||||
"margin-right": "0px",
|
||||
"margin-top": "16px",
|
||||
tag: "p",
|
||||
"text-align": "start",
|
||||
"text-indent": "0px",
|
||||
},
|
||||
checks: {
|
||||
"CONTRAST": null,
|
||||
},
|
||||
}, {
|
||||
name: "Accessible Paragraph",
|
||||
role: "text leaf",
|
||||
value: "",
|
||||
description: "",
|
||||
keyboardShortcut: "",
|
||||
childCount: 0,
|
||||
domNodeType: 3,
|
||||
indexInParent: 0,
|
||||
states: [ "opaque", "enabled", "sensitive" ],
|
||||
actions: [],
|
||||
attributes: { "explicit-name": "true" },
|
||||
checks: {
|
||||
"CONTRAST": {
|
||||
"value": 21,
|
||||
"color": [0, 0, 0, 1],
|
||||
"backgroundColor": [255, 255, 255, 1],
|
||||
"isLargeText": false,
|
||||
},
|
||||
},
|
||||
}];
|
||||
|
||||
function findAccessible(name, role) {
|
||||
return accessibles.find(accessible =>
|
||||
accessible.name === name && accessible.role === role);
|
||||
}
|
||||
|
||||
const a11yWalker = await accessibility.getWalker();
|
||||
ok(a11yWalker, "The AccessibleWalkerFront was returned");
|
||||
await accessibility.enable();
|
||||
|
||||
info("Checking AccessibleWalker audit functionality");
|
||||
const ancestries = await a11yWalker.audit();
|
||||
|
||||
for (const ancestry of ancestries) {
|
||||
for (const { accessible, children } of ancestry) {
|
||||
checkA11yFront(accessible,
|
||||
findAccessible(accessibles.name, accessibles.role));
|
||||
for (const child of children) {
|
||||
checkA11yFront(child,
|
||||
findAccessible(child.name, child.role));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await accessibility.disable();
|
||||
await waitForA11yShutdown();
|
||||
await target.destroy();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="h1">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</h1>
|
||||
<p id="p">Accessible Paragraph</p>
|
||||
</body>
|
||||
</html>
|
|
@ -272,7 +272,7 @@ function checkA11yFront(front, expected, expectedFront) {
|
|||
}
|
||||
|
||||
for (const key in expected) {
|
||||
if (["actions", "states", "attributes"].includes(key)) {
|
||||
if (["actions", "states", "attributes", "checks"].includes(key)) {
|
||||
SimpleTest.isDeeply(front[key], expected[key],
|
||||
`Accessible Front has correct ${key}`);
|
||||
} else {
|
||||
|
|
|
@ -162,6 +162,12 @@ const accessibleWalkerSpec = generateActorSpec({
|
|||
ancestry: RetVal("array:accessibleWithChildren"),
|
||||
},
|
||||
},
|
||||
audit: {
|
||||
request: {},
|
||||
response: {
|
||||
audit: RetVal("array:array:accessibleWithChildren"),
|
||||
},
|
||||
},
|
||||
highlightAccessible: {
|
||||
request: {
|
||||
accessible: Arg(0, "accessible"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче