Bug 1604594 - decouple accessibility walker front from the audit redux action. r=rcaliman

Differential Revision: https://phabricator.services.mozilla.com/D58032

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Yura Zenevich 2020-02-10 18:12:33 +00:00
Родитель 0e49ad6183
Коммит 0ca3763ed8
6 изменённых файлов: 76 добавлений и 50 удалений

Просмотреть файл

@ -56,10 +56,6 @@ AccessibilityView.prototype = {
* accessibility walker and
* enable/disable accessibility
* services.
* - walker {Object}
* front for accessibility walker
* actor responsible for managing
* accessible objects actors/fronts.
* - supports {JSON}
* a collection of flags indicating
* which accessibility panel features
@ -84,10 +80,13 @@ AccessibilityView.prototype = {
* - stopListeningForAccessibilityEvents {Function}
* Remove listeners for specific
* accessibility events.
* - audit {Function}
* Audit function that will start
* accessibility audit for given types
* of accessibility issues.
*/
async initialize({
front,
walker,
supports,
fluentBundles,
simulator,
@ -95,19 +94,20 @@ AccessibilityView.prototype = {
getAccessibilityTreeRoot,
startListeningForAccessibilityEvents,
stopListeningForAccessibilityEvents,
audit,
}) {
// Make sure state is reset every time accessibility panel is initialized.
await this.store.dispatch(reset(front, supports));
const container = document.getElementById("content");
const mainFrame = MainFrame({
accessibility: front,
accessibilityWalker: walker,
fluentBundles,
simulator,
toolbox,
getAccessibilityTreeRoot,
startListeningForAccessibilityEvents,
stopListeningForAccessibilityEvents,
audit,
});
// Render top level component
const provider = createElement(Provider, { store: this.store }, mainFrame);

Просмотреть файл

@ -4,9 +4,6 @@
"use strict";
const {
accessibility: { AUDIT_TYPE },
} = require("devtools/shared/constants");
const {
AUDIT,
AUDIT_PROGRESS,
@ -23,29 +20,10 @@ exports.auditing = filter => dispatch => {
return dispatch({ auditing, type: AUDITING });
};
exports.audit = (accessibilityWalker, filter) => dispatch =>
new Promise(resolve => {
const types = filter === FILTERS.ALL ? Object.values(AUDIT_TYPE) : [filter];
const auditEventHandler = ({ type, ancestries, progress }) => {
switch (type) {
case "error":
accessibilityWalker.off("audit-event", auditEventHandler);
dispatch({ type: AUDIT, error: true });
resolve();
break;
case "completed":
accessibilityWalker.off("audit-event", auditEventHandler);
dispatch({ type: AUDIT, response: ancestries });
resolve();
break;
case "progress":
dispatch({ type: AUDIT_PROGRESS, progress });
break;
default:
break;
}
};
accessibilityWalker.on("audit-event", auditEventHandler);
accessibilityWalker.startAudit({ types });
});
exports.audit = (auditFunc, filter) => dispatch =>
auditFunc(
filter,
() => dispatch({ type: AUDIT, error: true }),
progress => dispatch({ type: AUDIT_PROGRESS, progress }),
ancestries => dispatch({ type: AUDIT, response: ancestries })
);

Просмотреть файл

@ -54,14 +54,14 @@ class AccessibilityTreeFilter extends Component {
auditing: PropTypes.array.isRequired,
filters: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accessibilityWalker: PropTypes.object.isRequired,
describedby: PropTypes.string,
toolboxDoc: PropTypes.object.isRequired,
audit: PropTypes.func.isRequired,
};
}
async toggleFilter(filterKey) {
const { dispatch, filters, accessibilityWalker } = this.props;
const { audit: auditFunc, dispatch, filters } = this.props;
if (filterKey !== FILTERS.NONE && !filters[filterKey]) {
if (gTelemetry) {
@ -69,7 +69,7 @@ class AccessibilityTreeFilter extends Component {
}
dispatch(actions.auditing(filterKey));
await dispatch(actions.audit(accessibilityWalker, filterKey));
await dispatch(actions.audit(auditFunc, filterKey));
}
// We wait to dispatch filter toggle until the tree is ready to be filtered

Просмотреть файл

@ -55,7 +55,6 @@ class MainFrame extends Component {
return {
accessibility: PropTypes.object.isRequired,
fluentBundles: PropTypes.array.isRequired,
accessibilityWalker: PropTypes.object.isRequired,
enabled: PropTypes.bool.isRequired,
dispatch: PropTypes.func.isRequired,
auditing: PropTypes.array.isRequired,
@ -65,6 +64,7 @@ class MainFrame extends Component {
getAccessibilityTreeRoot: PropTypes.func.isRequired,
startListeningForAccessibilityEvents: PropTypes.func.isRequired,
stopListeningForAccessibilityEvents: PropTypes.func.isRequired,
audit: PropTypes.func.isRequired,
};
}
@ -125,7 +125,6 @@ class MainFrame extends Component {
render() {
const {
accessibility,
accessibilityWalker,
fluentBundles,
enabled,
auditing,
@ -134,6 +133,7 @@ class MainFrame extends Component {
getAccessibilityTreeRoot,
startListeningForAccessibilityEvents,
stopListeningForAccessibilityEvents,
audit,
} = this.props;
if (!enabled) {
@ -149,7 +149,7 @@ class MainFrame extends Component {
{ className: "mainFrame", role: "presentation" },
Toolbar({
accessibility,
accessibilityWalker,
audit,
simulator,
toolboxDoc: toolbox.doc,
}),

Просмотреть файл

@ -38,12 +38,12 @@ const {
class Toolbar extends Component {
static get propTypes() {
return {
accessibilityWalker: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accessibility: PropTypes.object.isRequired,
canBeDisabled: PropTypes.bool.isRequired,
simulator: PropTypes.object,
toolboxDoc: PropTypes.object.isRequired,
audit: PropTypes.func.isRequired,
};
}
@ -86,12 +86,7 @@ class Toolbar extends Component {
}
render() {
const {
canBeDisabled,
accessibilityWalker,
simulator,
toolboxDoc,
} = this.props;
const { canBeDisabled, simulator, toolboxDoc, audit } = this.props;
const { disabling } = this.state;
const disableButtonStr = disabling
? "accessibility.disabling"
@ -147,7 +142,7 @@ class Toolbar extends Component {
L10N.getStr("accessibility.beta")
),
AccessibilityTreeFilter({
accessibilityWalker,
audit,
describedby: betaID,
toolboxDoc,
}),

Просмотреть файл

@ -29,6 +29,11 @@ const EVENTS = {
"Accessibility:AccessibilityInspectorUpdated",
};
const {
accessibility: { AUDIT_TYPE },
} = require("devtools/shared/constants");
const { FILTERS } = require("devtools/client/accessibility/constants");
/**
* This object represents Accessibility panel. It's responsibility is to
* render Accessibility Tree of the current debugger target and the sidebar that
@ -58,6 +63,7 @@ function AccessibilityPanel(iframeWindow, toolbox, startup) {
this.stopListeningForAccessibilityEvents = this.stopListeningForAccessibilityEvents.bind(
this
);
this.audit = this.audit.bind(this);
EventEmitter.decorate(this);
}
@ -175,7 +181,6 @@ AccessibilityPanel.prototype = {
this.shouldRefresh = false;
this.postContentMessage("initialize", {
front: this.front,
walker: this.walker,
supports: this.supports,
fluentBundles: this.fluentBundles,
simulator: this.simulator,
@ -185,6 +190,7 @@ AccessibilityPanel.prototype = {
.startListeningForAccessibilityEvents,
stopListeningForAccessibilityEvents: this
.stopListeningForAccessibilityEvents,
audit: this.audit,
});
},
@ -300,6 +306,53 @@ AccessibilityPanel.prototype = {
}
},
/**
* Perform an audit for a given filter.
*
* @param {Object} this.walker
* Accessibility walker to be used for accessibility audit.
* @param {String} filter
* Type of an audit to perform.
* @param {Function} onError
* Audit error callback.
* @param {Function} onProgress
* Audit progress callback.
* @param {Function} onCompleted
* Audit completion callback.
*
* @return {Promise}
* Resolves when the audit for a top document, that the walker
* traverses, completes.
*/
audit(filter, onError, onProgress, onCompleted) {
return new Promise(resolve => {
const types =
filter === FILTERS.ALL ? Object.values(AUDIT_TYPE) : [filter];
const auditEventHandler = ({ type, ancestries, progress }) => {
switch (type) {
case "error":
this.walker.off("audit-event", auditEventHandler);
onError();
resolve();
break;
case "completed":
this.walker.off("audit-event", auditEventHandler);
onCompleted(ancestries);
resolve();
break;
case "progress":
onProgress(progress);
break;
default:
break;
}
};
this.walker.on("audit-event", auditEventHandler);
this.walker.startAudit({ types });
});
},
get front() {
return this.startup.accessibility;
},