summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/reducers/expressions.js
blob: 9af13523e4078ca86bb6ea856ffaa585e7f7749a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* 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/>. */

/**
 * Expressions reducer
 * @module reducers/expressions
 */

import { prefs } from "../utils/prefs";

export const initialExpressionState = () => ({
  expressions: restoreExpressions(),
  autocompleteMatches: {},
  currentAutocompleteInput: null,
});

function update(state = initialExpressionState(), action) {
  switch (action.type) {
    case "ADD_EXPRESSION":
      return appendExpressionToList(state, {
        input: action.input,
        value: null,
        updating: true,
      });

    case "UPDATE_EXPRESSION":
      const key = action.expression.input;
      return updateExpressionInList(state, key, {
        input: action.input,
        value: null,
        updating: true,
      });

    case "EVALUATE_EXPRESSION":
      return updateExpressionInList(state, action.input, {
        input: action.input,
        value: action.value,
        updating: false,
      });

    case "EVALUATE_EXPRESSIONS":
      const { inputs, results } = action;

      return inputs.reduce(
        (_state, input, index) =>
          updateExpressionInList(_state, input, {
            input,
            value: results[index],
            updating: false,
          }),
        state
      );

    case "DELETE_EXPRESSION":
      return deleteExpression(state, action.input);

    case "AUTOCOMPLETE":
      const { matchProp, matches } = action.result;

      return {
        ...state,
        currentAutocompleteInput: matchProp,
        autocompleteMatches: {
          ...state.autocompleteMatches,
          [matchProp]: matches,
        },
      };

    case "CLEAR_AUTOCOMPLETE":
      return {
        ...state,
        autocompleteMatches: {},
        currentAutocompleteInput: "",
      };
  }

  return state;
}

function restoreExpressions() {
  const exprs = prefs.expressions;
  if (!exprs.length) {
    return [];
  }

  return exprs;
}

function storeExpressions({ expressions }) {
  // Return the expressions without the `value` property
  prefs.expressions = expressions.map(({ input, updating }) => ({
    input,
    updating,
  }));
}

function appendExpressionToList(state, value) {
  const newState = { ...state, expressions: [...state.expressions, value] };

  storeExpressions(newState);
  return newState;
}

function updateExpressionInList(state, key, value) {
  const list = [...state.expressions];
  const index = list.findIndex(e => e.input == key);
  list[index] = value;

  const newState = { ...state, expressions: list };
  storeExpressions(newState);
  return newState;
}

function deleteExpression(state, input) {
  const list = [...state.expressions];
  const index = list.findIndex(e => e.input == input);
  list.splice(index, 1);
  const newState = { ...state, expressions: list };
  storeExpressions(newState);
  return newState;
}

export default update;