summaryrefslogtreecommitdiffstats
path: root/devtools/client/accessibility/reducers/ui.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/client/accessibility/reducers/ui.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/devtools/client/accessibility/reducers/ui.js b/devtools/client/accessibility/reducers/ui.js
new file mode 100644
index 0000000000..828889680c
--- /dev/null
+++ b/devtools/client/accessibility/reducers/ui.js
@@ -0,0 +1,217 @@
+/* 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";
+
+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;