Source code
Revision control
Copy as Markdown
Other Tools
/* 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
"use strict";
const {
AUDIT,
ENABLE,
RESET,
SELECT,
HIGHLIGHT,
UNHIGHLIGHT,
UPDATE_CAN_BE_DISABLED,
UPDATE_CAN_BE_ENABLED,
UPDATE_PREF,
UPDATE_DETAILS,
PREF_KEYS,
PREFS,
UPDATE_DISPLAY_TABBING_ORDER,
} = require("resource://devtools/client/accessibility/constants.js");
const TreeView = require("resource://devtools/client/shared/components/tree/TreeView.js");
/**
* Initial state definition
*/
function getInitialState() {
return {
enabled: false,
canBeDisabled: true,
canBeEnabled: true,
selected: null,
highlighted: null,
expanded: new Set(),
[PREFS.SCROLL_INTO_VIEW]: Services.prefs.getBoolPref(
PREF_KEYS[PREFS.SCROLL_INTO_VIEW],
false
),
tabbingOrderDisplayed: false,
supports: {},
};
}
/**
* Maintain ui components of the accessibility panel.
*/
function ui(state = getInitialState(), action) {
switch (action.type) {
case ENABLE:
return onToggle(state, action, true);
case UPDATE_CAN_BE_DISABLED:
return onCanBeDisabledChange(state, action);
case UPDATE_CAN_BE_ENABLED:
return onCanBeEnabledChange(state, action);
case UPDATE_PREF:
return onPrefChange(state, action);
case UPDATE_DETAILS:
return onUpdateDetails(state, action);
case HIGHLIGHT:
return onHighlight(state, action);
case AUDIT:
return onAudit(state, action);
case UNHIGHLIGHT:
return onUnhighlight(state, action);
case SELECT:
return onSelect(state, action);
case RESET:
return onReset(state, action);
case UPDATE_DISPLAY_TABBING_ORDER:
return onUpdateDisplayTabbingOrder(state, action);
default:
return state;
}
}
function onUpdateDetails(state) {
if (!state.selected) {
return state;
}
// Clear selected state that should only be set when select action is
// performed.
return Object.assign({}, state, { selected: null });
}
function onUnhighlight(state) {
return Object.assign({}, state, { highlighted: null });
}
function updateExpandedNodes(expanded, ancestry) {
expanded = new Set(expanded);
const path = ancestry.reduceRight((accPath, { accessible }) => {
accPath = TreeView.subPath(accPath, accessible.actorID);
expanded.add(accPath);
return accPath;
}, "");
return { path, expanded };
}
function onAudit(state, { response: ancestries, error }) {
if (error) {
console.warn("Error running audit", error);
return state;
}
let expanded = new Set(state.expanded);
for (const ancestry of ancestries) {
({ expanded } = updateExpandedNodes(expanded, ancestry));
}
return {
...state,
expanded,
};
}
function onHighlight(state, { accessible, response: ancestry, error }) {
if (error) {
console.warn("Error fetching ancestry", error);
return state;
}
const { expanded } = updateExpandedNodes(state.expanded, ancestry);
return Object.assign({}, state, { expanded, highlighted: accessible });
}
function onSelect(state, { accessible, response: ancestry, error }) {
if (error) {
console.warn("Error fetching ancestry", error);
return state;
}
const { path, expanded } = updateExpandedNodes(state.expanded, ancestry);
const selected = TreeView.subPath(path, accessible.actorID);
return Object.assign({}, state, { expanded, selected });
}
/**
* Handle "canBeDisabled" flag update for accessibility service
* @param {Object} state Current ui state
* @param {Object} action Redux action object
* @return {Object} updated state
*/
function onCanBeDisabledChange(state, { canBeDisabled }) {
return Object.assign({}, state, { canBeDisabled });
}
/**
* Handle "canBeEnabled" flag update for accessibility service
* @param {Object} state Current ui state.
* @param {Object} action Redux action object
* @return {Object} updated state
*/
function onCanBeEnabledChange(state, { canBeEnabled }) {
return Object.assign({}, state, { canBeEnabled });
}
/**
* Handle pref update for accessibility panel.
* @param {Object} state Current ui state.
* @param {Object} action Redux action object
* @return {Object} updated state
*/
function onPrefChange(state, { name, value }) {
return {
...state,
[name]: value,
};
}
/**
* Handle reset action for the accessibility panel UI.
* @param {Object} state Current ui state.
* @param {Object} action Redux action object
* @return {Object} updated state
*/
function onReset(state, { enabled, canBeDisabled, canBeEnabled, supports }) {
const newState = {
...getInitialState(),
enabled,
canBeDisabled,
canBeEnabled,
supports,
};
return newState;
}
/**
* Handle accessibilty service enabling/disabling.
* @param {Object} state Current accessibility services enabled state.
* @param {Object} action Redux action object
* @param {Boolean} enabled New enabled state.
* @return {Object} updated state
*/
function onToggle(state, { error }, enabled) {
if (error) {
console.warn("Error enabling accessibility service: ", error);
return state;
}
return Object.assign({}, state, { enabled });
}
function onUpdateDisplayTabbingOrder(state, { error, tabbingOrderDisplayed }) {
if (error) {
console.warn("Error updating displaying tabbing order: ", error);
return state;
}
return Object.assign({}, state, { tabbingOrderDisplayed });
}
exports.ui = ui;