/* 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/. */
get enabled() { returnthis.accessibilityFront && this.accessibilityFront.enabled;
}
/** * Indicates whether the accessibility service is enabled.
*/
get canBeEnabled() { returnthis.parentAccessibilityFront.canBeEnabled;
}
get currentTarget() { returnthis.commands.targetCommand.selectedTargetFront;
}
/** * Perform an audit for a given filter. * * @param {String} filter * Type of an audit to perform. * @param {Function} onProgress * Audit progress callback. * * @return {Promise} * Resolves when the audit for every document, that each of the frame * accessibility walkers traverse, completes.
*/
async audit(filter, onProgress) { const types = filter === FILTERS.ALL ? Object.values(AUDIT_TYPE) : [filter];
const progress = new CombinedProgress({
onProgress,
totalFrames: targets.length,
}); const audits = await this.withAllAccessibilityWalkerFronts(
async accessibleWalkerFront =>
accessibleWalkerFront.audit({
types,
onProgress: progress.onProgressForWalker.bind(
progress,
accessibleWalkerFront
), // If a frame was selected in the iframe picker, we don't want to retrieve the // ancestries at it would mess with the tree structure and would make it misbehave.
retrieveAncestries: this.commands.targetCommand.isTopLevelTargetSelected(),
})
);
// Accumulate all audits into a single structure. const combinedAudit = { ancestries: [] }; for (const audit of audits) { // If any of the audits resulted in an error, no need to continue. if (audit.error) { return audit;
}
async toggleDisplayTabbingOrder(displayTabbingOrder) { if (displayTabbingOrder) { const { walker: domWalkerFront } =
await this.currentTarget.getFront("inspector");
await this.accessibilityFront.accessibleWalkerFront.showTabbingOrder(
await domWalkerFront.getRootNode(),
0
);
} else { // we don't want to use withAllAccessibilityWalkerFronts as it only acts on selected // target tree, and we want to hide _all_ highlighters. const accessibilityFronts =
await this.commands.targetCommand.getAllFronts(
[this.commands.targetCommand.TYPES.FRAME], "accessibility"
);
await Promise.all(
accessibilityFronts.map(accessibilityFront =>
accessibilityFront.accessibleWalkerFront.hideTabbingOrder()
)
);
}
}
async enableAccessibility() { // Accessibility service is initialized using the parent accessibility // front. That, in turn, initializes accessibility service in all content // processes. We need to wait until that happens to be sure platform // accessibility is fully enabled. const enabled = this.accessibilityFront.once("init");
await this.parentAccessibilityFront.enable();
await enabled;
}
/** * Return the topmost level accessibility walker to be used as the root of * the accessibility tree view. * * @return {Object} * Topmost accessibility walker.
*/
getAccessibilityTreeRoot() { returnthis.accessibilityFront.accessibleWalkerFront;
}
/** * Look up accessibility fronts (get an existing one or create a new one) for * all existing target fronts and run a task with each one of them. * @param {Function} task * Function to execute with each accessiblity front.
*/
async withAllAccessibilityFronts(taskFn) { const accessibilityFronts = await this.commands.targetCommand.getAllFronts(
[this.commands.targetCommand.TYPES.FRAME], "accessibility",
{ // only get the fronts for the selected frame tree, in case a specific document // is selected in the iframe picker (if not, the top-level target is considered // as the selected target)
onlyInSelectedTargetTree: true,
}
); const tasks = []; for (const accessibilityFront of accessibilityFronts) {
tasks.push(taskFn(accessibilityFront));
}
return Promise.all(tasks);
}
/** * Look up accessibility walker fronts (get an existing one or create a new * one using accessibility front) for all existing target fronts and run a * task with each one of them. * @param {Function} task * Function to execute with each accessiblity walker front.
*/
withAllAccessibilityWalkerFronts(taskFn) { returnthis.withAllAccessibilityFronts(async accessibilityFront =>
taskFn(accessibilityFront.accessibleWalkerFront)
);
}
/** * Unhighlight previous accessible object if we switched between processes and * call the appropriate event handler.
*/
unhighlightBeforeCalling(listener) { return async accessible => { if (accessible) { const accessibleWalkerFront = accessible.getParent(); if (this._currentAccessibleWalkerFront !== accessibleWalkerFront) { if (this._currentAccessibleWalkerFront) {
await this._currentAccessibleWalkerFront.unhighlight();
}
/** * Start picking and add walker listeners. * @param {Boolean} doFocus * If true, move keyboard focus into content.
*/
pick(doFocus, onHovered, onPicked, onPreviewed, onCanceled) { returnthis.withAllAccessibilityWalkerFronts(
async accessibleWalkerFront => { this.startListening(accessibleWalkerFront, {
events: { "picker-accessible-hovered": this.unhighlightBeforeCalling(onHovered), "picker-accessible-picked": this.unhighlightBeforeCalling(onPicked), "picker-accessible-previewed": this.unhighlightBeforeCalling(onPreviewed), "picker-accessible-canceled": this.unhighlightBeforeCalling(onCanceled),
}, // Only register listeners once (for top level), no need to register // them for all walkers again and again.
register: accessibleWalkerFront.targetFront.isTopLevel,
});
await accessibleWalkerFront.pick( // Only pass doFocus to the top level accessibility walker front.
doFocus && accessibleWalkerFront.targetFront.isTopLevel
);
}
);
}
/** * Stop picking and remove all walker listeners.
*/
async cancelPick() { this._currentAccessibleWalkerFront = null; returnthis.withAllAccessibilityWalkerFronts(
async accessibleWalkerFront => {
await accessibleWalkerFront.cancelPick(); this.stopListening(accessibleWalkerFront, {
events: { "picker-accessible-hovered": null, "picker-accessible-picked": null, "picker-accessible-previewed": null, "picker-accessible-canceled": null,
}, // Only unregister listeners once (for top level), no need to // unregister them for all walkers again and again.
unregister: accessibleWalkerFront.targetFront.isTopLevel,
});
}
);
}
startListening(front, { events, register = false } = {}) { for (const [type, listener] of Object.entries(events)) {
front.on(type, listener); if (register) { this.registerEvent(front, type, listener);
}
}
}
stopListening(front, { events, unregister = false } = {}) { for (const [type, listener] of Object.entries(events)) {
front.off(type, listener); if (unregister) { this.unregisterEvent(front, type, listener);
}
}
}
startListeningForAccessibilityEvents(events) { for (const accessibleWalkerFront of this._accessibilityWalkerFronts.values()) { this.startListening(accessibleWalkerFront, {
events, // Only register listeners once (for top level), no need to register // them for all walkers again and again.
register: accessibleWalkerFront.targetFront.isTopLevel,
});
}
}
stopListeningForAccessibilityEvents(events) { for (const accessibleWalkerFront of this._accessibilityWalkerFronts.values()) { this.stopListening(accessibleWalkerFront, {
events, // Only unregister listeners once (for top level), no need to unregister // them for all walkers again and again.
unregister: accessibleWalkerFront.targetFront.isTopLevel,
});
}
}
highlightAccessible(accessibleFront, options) { if (!accessibleFront) { return;
}
const accessibleWalkerFront = accessibleFront.getParent(); if (!accessibleWalkerFront) { return;
}
accessibleWalkerFront
.highlightAccessible(accessibleFront, options)
.catch(error => { // Only report an error where there's still a commands instance. // Ignore cases where toolbox is already destroyed. if (this.commands) {
console.error(error);
}
});
}
unhighlightAccessible(accessibleFront) { if (!accessibleFront) { return;
}
const accessibleWalkerFront = accessibleFront.getParent(); if (!accessibleWalkerFront) { return;
}
accessibleWalkerFront.unhighlight().catch(error => { // Only report an error where there's still a commands instance. // Ignore cases where toolbox is already destroyed. if (this.commands) {
console.error(error);
}
});
}
async initialize() { // Initialize it first as it may be used on target selection when calling watchTargets this.parentAccessibilityFront =
await this.commands.targetCommand.rootFront.getFront( "parentaccessibility"
);
// Enable accessibility service if necessary. if (this.canBeEnabled && !this.enabled) {
await this.enableAccessibility();
} this.#initialized = true;
}
get supports() { // Retrieve backward compatibility traits. // New API's must be described in the "getTraits" method of the AccessibilityActor. returnthis.accessibilityFront.traits;
}
onAccessibleWalkerFrontAvailable(accessibleWalkerFront) { this._accessibilityWalkerFronts.add(accessibleWalkerFront); // Apply all existing accessible walker front event listeners to the new // front. for (const [type, listeners] of this.accessibilityEvents.entries()) { for (const listener of listeners) {
accessibleWalkerFront.on(type, listener);
}
}
}
onAccessibleWalkerFrontDestroyed(accessibleWalkerFront) { this._accessibilityWalkerFronts.delete(accessibleWalkerFront); // Remove all existing accessible walker front event listeners from the // destroyed front. for (const [type, listeners] of this.accessibilityEvents.entries()) { for (const listener of listeners) {
accessibleWalkerFront.off(type, listener);
}
}
}
// Move accessibility front lifecycle event listeners to a new top level // front. for (const [type, listeners] of this.lifecycleEvents.entries()) { for (const listener of listeners.values()) { this.accessibilityFront.on(type, listener);
}
}
// Hold on refreshing the view on initialization. // This will be done by the Panel class after everything is setup. // (we especially need to wait for the a11y service to be started) if (this.#initialized) {
await this.#panel.forceRefresh();
}
}
}
exports.AccessibilityProxy = AccessibilityProxy;
¤ Dauer der Verarbeitung: 0.25 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.