Bug 1307884 - Limit for messages in the store; r=bgrins
MozReview-Commit-ID: 3NLMvJFPbls
--- a/devtools/client/webconsole/new-console-output/reducers/messages.js
+++ b/devtools/client/webconsole/new-console-output/reducers/messages.js
@@ -3,16 +3,19 @@
/* 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 Services = require("Services");
+
+const logLimit = Math.max(Services.prefs.getIntPref("devtools.hud.loglimit"), 1);
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.
@@ -77,16 +80,26 @@ function messages(state = new MessageSta
)
);
if (newMessage.type === constants.MESSAGE_TYPE.START_GROUP) {
// We want the group to be open by default.
record.set("messagesUiById", messagesUiById.push(newMessage.id));
}
}
+
+ // Remove top level message if the total count of top level messages
+ // exceeds the current limit.
+ let topLevelCount = getToplevelMessageCount(record);
+ while (topLevelCount > logLimit) {
+ let removedMessage = removeFirstMessage(record);
+ if (!removedMessage.groupId) {
+ topLevelCount--;
+ }
+ }
});
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);
});
@@ -132,9 +145,53 @@ function getParentGroups(currentGroup, g
if (Array.isArray(parentGroups) && parentGroups.length > 0) {
groups = groups.concat(parentGroups);
}
}
return groups;
}
+/**
+ * Returns total count of top level messages (those which are not
+ * within a group).
+ */
+function getToplevelMessageCount(record) {
+ return [...record.messagesById].filter(message => !message.groupId).length;
+}
+
+/**
+ * Remove first (the oldest) message from the store. The methods removes
+ * also all its references and children from the store.
+ */
+function removeFirstMessage(record) {
+ let firstMessage = record.messagesById.first();
+ record.set("messagesById", record.messagesById.shift());
+
+ // Remove from list of opened groups.
+ let uiIndex = record.messagesUiById.indexOf(firstMessage);
+ if (uiIndex >= 0) {
+ record.set("messagesUiById", record.messagesUiById.delete(uiIndex));
+ }
+
+ // Remove from list of tables.
+ if (record.messagesTableDataById.has(firstMessage.id)) {
+ record.set("messagesTableDataById", record.messagesTableDataById.delete(firstMessage.id));
+ }
+
+ // Remove from list of parent groups.
+ if (record.groupsById.has(firstMessage.id)) {
+ record.set("groupsById", record.groupsById.delete(firstMessage.id));
+ }
+
+ // Remove all children. This loop assumes that children of removed
+ // group immediately follows the group. We use recursion since
+ // there might be inner groups.
+ let message = record.messagesById.first();
+ while (message.groupId == firstMessage.id) {
+ removeFirstMessage(record);
+ message = record.messagesById.first();
+ }
+
+ return firstMessage;
+}
+
exports.messages = messages;