tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ui.js (5654B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  AUDIT,
      9  ENABLE,
     10  RESET,
     11  SELECT,
     12  HIGHLIGHT,
     13  UNHIGHLIGHT,
     14  UPDATE_CAN_BE_DISABLED,
     15  UPDATE_CAN_BE_ENABLED,
     16  UPDATE_PREF,
     17  UPDATE_DETAILS,
     18  PREF_KEYS,
     19  PREFS,
     20  UPDATE_DISPLAY_TABBING_ORDER,
     21 } = require("resource://devtools/client/accessibility/constants.js");
     22 
     23 const TreeView = ChromeUtils.importESModule(
     24  "resource://devtools/client/shared/components/tree/TreeView.mjs"
     25 ).default;
     26 
     27 /**
     28 * Initial state definition
     29 */
     30 function getInitialState() {
     31  return {
     32    enabled: false,
     33    canBeDisabled: true,
     34    canBeEnabled: true,
     35    selected: null,
     36    highlighted: null,
     37    expanded: new Set(),
     38    [PREFS.SCROLL_INTO_VIEW]: Services.prefs.getBoolPref(
     39      PREF_KEYS[PREFS.SCROLL_INTO_VIEW],
     40      false
     41    ),
     42    tabbingOrderDisplayed: false,
     43    supports: {},
     44  };
     45 }
     46 
     47 /**
     48 * Maintain ui components of the accessibility panel.
     49 */
     50 function ui(state = getInitialState(), action) {
     51  switch (action.type) {
     52    case ENABLE:
     53      return onToggle(state, action, true);
     54    case UPDATE_CAN_BE_DISABLED:
     55      return onCanBeDisabledChange(state, action);
     56    case UPDATE_CAN_BE_ENABLED:
     57      return onCanBeEnabledChange(state, action);
     58    case UPDATE_PREF:
     59      return onPrefChange(state, action);
     60    case UPDATE_DETAILS:
     61      return onUpdateDetails(state, action);
     62    case HIGHLIGHT:
     63      return onHighlight(state, action);
     64    case AUDIT:
     65      return onAudit(state, action);
     66    case UNHIGHLIGHT:
     67      return onUnhighlight(state, action);
     68    case SELECT:
     69      return onSelect(state, action);
     70    case RESET:
     71      return onReset(state, action);
     72    case UPDATE_DISPLAY_TABBING_ORDER:
     73      return onUpdateDisplayTabbingOrder(state, action);
     74    default:
     75      return state;
     76  }
     77 }
     78 
     79 function onUpdateDetails(state) {
     80  if (!state.selected) {
     81    return state;
     82  }
     83 
     84  // Clear selected state that should only be set when select action is
     85  // performed.
     86  return Object.assign({}, state, { selected: null });
     87 }
     88 
     89 function onUnhighlight(state) {
     90  return Object.assign({}, state, { highlighted: null });
     91 }
     92 
     93 function updateExpandedNodes(expanded, ancestry) {
     94  expanded = new Set(expanded);
     95  const path = ancestry.reduceRight((accPath, { accessible }) => {
     96    accPath = TreeView.subPath(accPath, accessible.actorID);
     97    expanded.add(accPath);
     98    return accPath;
     99  }, "");
    100 
    101  return { path, expanded };
    102 }
    103 
    104 function onAudit(state, { response: ancestries, error }) {
    105  if (error) {
    106    console.warn("Error running audit", error);
    107    return state;
    108  }
    109 
    110  let expanded = new Set(state.expanded);
    111  for (const ancestry of ancestries) {
    112    ({ expanded } = updateExpandedNodes(expanded, ancestry));
    113  }
    114 
    115  return {
    116    ...state,
    117    expanded,
    118  };
    119 }
    120 
    121 function onHighlight(state, { accessible, response: ancestry, error }) {
    122  if (error) {
    123    console.warn("Error fetching ancestry", error);
    124    return state;
    125  }
    126 
    127  const { expanded } = updateExpandedNodes(state.expanded, ancestry);
    128  return Object.assign({}, state, { expanded, highlighted: accessible });
    129 }
    130 
    131 function onSelect(state, { accessible, response: ancestry, error }) {
    132  if (error) {
    133    console.warn("Error fetching ancestry", error);
    134    return state;
    135  }
    136 
    137  const { path, expanded } = updateExpandedNodes(state.expanded, ancestry);
    138  const selected = TreeView.subPath(path, accessible.actorID);
    139 
    140  return Object.assign({}, state, { expanded, selected });
    141 }
    142 
    143 /**
    144 * Handle "canBeDisabled" flag update for accessibility service
    145 *
    146 * @param  {object}  state   Current ui state
    147 * @param  {object}  action  Redux action object
    148 * @return {object}  updated state
    149 */
    150 function onCanBeDisabledChange(state, { canBeDisabled }) {
    151  return Object.assign({}, state, { canBeDisabled });
    152 }
    153 
    154 /**
    155 * Handle "canBeEnabled" flag update for accessibility service
    156 *
    157 * @param  {object}  state   Current ui state.
    158 * @param  {object}  action  Redux action object
    159 * @return {object}  updated state
    160 */
    161 function onCanBeEnabledChange(state, { canBeEnabled }) {
    162  return Object.assign({}, state, { canBeEnabled });
    163 }
    164 
    165 /**
    166 * Handle pref update for accessibility panel.
    167 *
    168 * @param  {object}  state   Current ui state.
    169 * @param  {object}  action  Redux action object
    170 * @return {object}  updated state
    171 */
    172 function onPrefChange(state, { name, value }) {
    173  return {
    174    ...state,
    175    [name]: value,
    176  };
    177 }
    178 
    179 /**
    180 * Handle reset action for the accessibility panel UI.
    181 *
    182 * @param  {object}  state   Current ui state.
    183 * @param  {object}  action  Redux action object
    184 * @return {object}  updated state
    185 */
    186 function onReset(state, { enabled, canBeDisabled, canBeEnabled, supports }) {
    187  const newState = {
    188    ...getInitialState(),
    189    enabled,
    190    canBeDisabled,
    191    canBeEnabled,
    192    supports,
    193  };
    194 
    195  return newState;
    196 }
    197 
    198 /**
    199 * Handle accessibilty service enabling/disabling.
    200 *
    201 * @param {object}  state   Current accessibility services enabled state.
    202 * @param {object}  action  Redux action object
    203 * @param {boolean} enabled New enabled state.
    204 * @return {object}  updated state
    205 */
    206 function onToggle(state, { error }, enabled) {
    207  if (error) {
    208    console.warn("Error enabling accessibility service: ", error);
    209    return state;
    210  }
    211 
    212  return Object.assign({}, state, { enabled });
    213 }
    214 
    215 function onUpdateDisplayTabbingOrder(state, { error, tabbingOrderDisplayed }) {
    216  if (error) {
    217    console.warn("Error updating displaying tabbing order: ", error);
    218    return state;
    219  }
    220 
    221  return Object.assign({}, state, { tabbingOrderDisplayed });
    222 }
    223 
    224 exports.ui = ui;