diff options
Diffstat (limited to 'devtools/client/debugger/content/reducers/sources.js')
-rw-r--r-- | devtools/client/debugger/content/reducers/sources.js | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/devtools/client/debugger/content/reducers/sources.js b/devtools/client/debugger/content/reducers/sources.js new file mode 100644 index 000000000..963a52fb5 --- /dev/null +++ b/devtools/client/debugger/content/reducers/sources.js @@ -0,0 +1,128 @@ +/* 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 constants = require("../constants"); +const Immutable = require("devtools/client/shared/vendor/seamless-immutable"); +const { mergeIn, setIn } = require("../utils"); + +const initialState = Immutable({ + sources: {}, + selectedSource: null, + selectedSourceOpts: null, + sourcesText: {} +}); + +function update(state = initialState, action, emitChange) { + switch (action.type) { + case constants.ADD_SOURCE: + emitChange("source", action.source); + return mergeIn(state, ["sources", action.source.actor], action.source); + + case constants.LOAD_SOURCES: + if (action.status === "done") { + const sources = action.value; + if (!sources) { + return state; + } + const sourcesByActor = {}; + sources.forEach(source => { + if (!state.sources[source.actor]) { + emitChange("source", source); + } + sourcesByActor[source.actor] = source; + }); + return mergeIn(state, ["sources"], state.sources.merge(sourcesByActor)); + } + break; + + case constants.SELECT_SOURCE: + emitChange("source-selected", action.source); + return state.merge({ + selectedSource: action.source.actor, + selectedSourceOpts: action.opts + }); + + case constants.LOAD_SOURCE_TEXT: { + const s = _updateText(state, action); + emitChange("source-text-loaded", s.sources[action.source.actor]); + return s; + } + + case constants.BLACKBOX: + if (action.status === "done") { + const s = mergeIn(state, + ["sources", action.source.actor, "isBlackBoxed"], + action.value.isBlackBoxed); + emitChange("blackboxed", s.sources[action.source.actor]); + return s; + } + break; + + case constants.TOGGLE_PRETTY_PRINT: + let s = state; + if (action.status === "error") { + s = mergeIn(state, ["sourcesText", action.source.actor], { + loading: false + }); + + // If it errored, just display the source as it was before, but + // only if there is existing text already. If auto-prettifying + // is on, the original text may still be coming in and we don't + // have it yet. If we try to set empty text we confuse the + // editor because it thinks it's already displaying the source's + // text and won't load the text when it actually comes in. + if (s.sourcesText[action.source.actor].text != null) { + emitChange("prettyprinted", s.sources[action.source.actor]); + } + } + else { + s = _updateText(state, action); + // Don't do this yet, the progress bar is still imperatively shown + // from the source view. We will fix in the next iteration. + // emitChange('source-text-loaded', s.sources[action.source.actor]); + + if (action.status === "done") { + s = mergeIn(s, + ["sources", action.source.actor, "isPrettyPrinted"], + action.value.isPrettyPrinted); + emitChange("prettyprinted", s.sources[action.source.actor]); + } + } + return s; + + case constants.UNLOAD: + // Reset the entire state to just the initial state, a blank state + // if you will. + return initialState; + } + + return state; +} + +function _updateText(state, action) { + const { source } = action; + + if (action.status === "start") { + // Merge this in, don't set it. That way the previous value is + // still stored here, and we can retrieve it if whatever we're + // doing fails. + return mergeIn(state, ["sourcesText", source.actor], { + loading: true + }); + } + else if (action.status === "error") { + return setIn(state, ["sourcesText", source.actor], { + error: action.error + }); + } + else { + return setIn(state, ["sourcesText", source.actor], { + text: action.value.text, + contentType: action.value.contentType + }); + } +} + +module.exports = update; |