/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* 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 Immutable = require("devtools/client/shared/vendor/immutable"); const constants = require("devtools/client/webconsole/new-console-output/constants"); const {isGroupType} = require("devtools/client/webconsole/new-console-output/utils/messages"); const MessageState = Immutable.Record({ // List of all the messages added to the console. messagesById: Immutable.List(), // List of the message ids which are opened. messagesUiById: Immutable.List(), // Map of the form {messageId : tableData}, which represent the data passed // as an argument in console.table calls. messagesTableDataById: Immutable.Map(), // Map of the form {groupMessageId : groupArray}, // where groupArray is the list of of all the parent groups' ids of the groupMessageId. groupsById: Immutable.Map(), // Message id of the current group (no corresponding console.groupEnd yet). currentGroup: null, }); function messages(state = new MessageState(), action) { const { messagesById, messagesUiById, messagesTableDataById, groupsById, currentGroup } = state; switch (action.type) { case constants.MESSAGE_ADD: let newMessage = action.message; if (newMessage.type === constants.MESSAGE_TYPE.NULL_MESSAGE) { // When the message has a NULL type, we don't add it. return state; } if (newMessage.type === constants.MESSAGE_TYPE.END_GROUP) { // Compute the new current group. return state.set("currentGroup", getNewCurrentGroup(currentGroup, groupsById)); } if (newMessage.allowRepeating && messagesById.size > 0) { let lastMessage = messagesById.last(); if (lastMessage.repeatId === newMessage.repeatId) { return state.withMutations(function (record) { record.set("messagesById", messagesById.pop().push( newMessage.set("repeat", lastMessage.repeat + 1) )); }); } } return state.withMutations(function (record) { // Add the new message with a reference to the parent group. record.set( "messagesById", messagesById.push(newMessage.set("groupId", currentGroup)) ); if (newMessage.type === "trace") { // We want the stacktrace to be open by default. record.set("messagesUiById", messagesUiById.push(newMessage.id)); } else if (isGroupType(newMessage.type)) { record.set("currentGroup", newMessage.id); record.set("groupsById", groupsById.set( newMessage.id, getParentGroups(currentGroup, groupsById) ) ); if (newMessage.type === constants.MESSAGE_TYPE.START_GROUP) { // We want the group to be open by default. record.set("messagesUiById", messagesUiById.push(newMessage.id)); } } }); case constants.MESSAGES_CLEAR: return state.withMutations(function (record) { record.set("messagesById", Immutable.List()); record.set("messagesUiById", Immutable.List()); record.set("groupsById", Immutable.Map()); record.set("currentGroup", null); }); case constants.MESSAGE_OPEN: return state.set("messagesUiById", messagesUiById.push(action.id)); case constants.MESSAGE_CLOSE: let index = state.messagesUiById.indexOf(action.id); return state.deleteIn(["messagesUiById", index]); case constants.MESSAGE_TABLE_RECEIVE: const {id, data} = action; return state.set("messagesTableDataById", messagesTableDataById.set(id, data)); } return state; } function getNewCurrentGroup(currentGoup, groupsById) { let newCurrentGroup = null; if (currentGoup) { // Retrieve the parent groups of the current group. let parents = groupsById.get(currentGoup); if (Array.isArray(parents) && parents.length > 0) { // If there's at least one parent, make the first one the new currentGroup. newCurrentGroup = parents[0]; } } return newCurrentGroup; } function getParentGroups(currentGroup, groupsById) { let groups = []; if (currentGroup) { // If there is a current group, we add it as a parent groups = [currentGroup]; // As well as all its parents, if it has some. let parentGroups = groupsById.get(currentGroup); if (Array.isArray(parentGroups) && parentGroups.length > 0) { groups = groups.concat(parentGroups); } } return groups; } exports.messages = messages;