178 lines
5.4 KiB
JavaScript
178 lines
5.4 KiB
JavaScript
/* -*- 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 { l10n } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
|
const { getAllFilters } = require("devtools/client/webconsole/new-console-output/selectors/filters");
|
|
const { getLogLimit } = require("devtools/client/webconsole/new-console-output/selectors/prefs");
|
|
const {
|
|
MESSAGE_TYPE,
|
|
MESSAGE_SOURCE
|
|
} = require("devtools/client/webconsole/new-console-output/constants");
|
|
|
|
function getAllMessages(state) {
|
|
let messages = getAllMessagesById(state);
|
|
let logLimit = getLogLimit(state);
|
|
let filters = getAllFilters(state);
|
|
|
|
let groups = getAllGroupsById(state);
|
|
let messagesUI = getAllMessagesUiById(state);
|
|
|
|
return prune(
|
|
messages.filter(message => {
|
|
return (
|
|
isInOpenedGroup(message, groups, messagesUI)
|
|
&& (
|
|
isUnfilterable(message)
|
|
|| (
|
|
matchLevelFilters(message, filters)
|
|
&& matchNetworkFilters(message, filters)
|
|
&& matchSearchFilters(message, filters)
|
|
)
|
|
)
|
|
);
|
|
}),
|
|
logLimit
|
|
);
|
|
}
|
|
|
|
function getAllMessagesById(state) {
|
|
return state.messages.messagesById;
|
|
}
|
|
|
|
function getAllMessagesUiById(state) {
|
|
return state.messages.messagesUiById;
|
|
}
|
|
|
|
function getAllMessagesTableDataById(state) {
|
|
return state.messages.messagesTableDataById;
|
|
}
|
|
|
|
function getAllGroupsById(state) {
|
|
return state.messages.groupsById;
|
|
}
|
|
|
|
function getCurrentGroup(state) {
|
|
return state.messages.currentGroup;
|
|
}
|
|
|
|
function isUnfilterable(message) {
|
|
return [
|
|
MESSAGE_TYPE.COMMAND,
|
|
MESSAGE_TYPE.RESULT,
|
|
MESSAGE_TYPE.START_GROUP,
|
|
MESSAGE_TYPE.START_GROUP_COLLAPSED,
|
|
].includes(message.type);
|
|
}
|
|
|
|
function isInOpenedGroup(message, groups, messagesUI) {
|
|
return !message.groupId
|
|
|| (
|
|
!isGroupClosed(message.groupId, messagesUI)
|
|
&& !hasClosedParentGroup(groups.get(message.groupId), messagesUI)
|
|
);
|
|
}
|
|
|
|
function hasClosedParentGroup(group, messagesUI) {
|
|
return group.some(groupId => isGroupClosed(groupId, messagesUI));
|
|
}
|
|
|
|
function isGroupClosed(groupId, messagesUI) {
|
|
return messagesUI.includes(groupId) === false;
|
|
}
|
|
|
|
function matchLevelFilters(message, filters) {
|
|
return filters.get(message.level) === true;
|
|
}
|
|
|
|
function matchNetworkFilters(message, filters) {
|
|
return (
|
|
message.source !== MESSAGE_SOURCE.NETWORK
|
|
|| (filters.get("net") === true && message.isXHR === false)
|
|
|| (filters.get("netxhr") === true && message.isXHR === true)
|
|
);
|
|
}
|
|
|
|
function matchSearchFilters(message, filters) {
|
|
let text = filters.text || "";
|
|
return (
|
|
text === ""
|
|
// @TODO currently we return true for any object grip. We should find a way to
|
|
// search object grips.
|
|
|| (message.parameters !== null && !Array.isArray(message.parameters))
|
|
// Look for a match in location.
|
|
|| isTextInFrame(text, message.frame)
|
|
// Look for a match in stacktrace.
|
|
|| (
|
|
Array.isArray(message.stacktrace) &&
|
|
message.stacktrace.some(frame => isTextInFrame(text,
|
|
// isTextInFrame expect the properties of the frame object to be in the same
|
|
// order they are rendered in the Frame component.
|
|
{
|
|
functionName: frame.functionName ||
|
|
l10n.getStr("stacktrace.anonymousFunction"),
|
|
filename: frame.filename,
|
|
lineNumber: frame.lineNumber,
|
|
columnNumber: frame.columnNumber
|
|
}))
|
|
)
|
|
// Look for a match in messageText.
|
|
|| (message.messageText !== null
|
|
&& message.messageText.toLocaleLowerCase().includes(text.toLocaleLowerCase()))
|
|
// Look for a match in parameters. Currently only checks value grips.
|
|
|| (message.parameters !== null
|
|
&& message.parameters.join("").toLocaleLowerCase()
|
|
.includes(text.toLocaleLowerCase()))
|
|
// Look for a match in notes.
|
|
|| (Array.isArray(message.notes) && message.notes.some(note =>
|
|
// Look for a match in location.
|
|
isTextInFrame(text, note.frame)
|
|
// Look for a match in messageBody.
|
|
|| (note.messageBody !== null
|
|
&& note.messageBody.toLocaleLowerCase()
|
|
.includes(text.toLocaleLowerCase()))
|
|
))
|
|
);
|
|
}
|
|
|
|
function isTextInFrame(text, frame) {
|
|
if (!frame) {
|
|
return false;
|
|
}
|
|
// @TODO Change this to Object.values once it's supported in Node's version of V8
|
|
return Object.keys(frame)
|
|
.map(key => frame[key])
|
|
.join(":")
|
|
.toLocaleLowerCase()
|
|
.includes(text.toLocaleLowerCase());
|
|
}
|
|
|
|
function prune(messages, logLimit) {
|
|
let messageCount = messages.count();
|
|
if (messageCount > logLimit) {
|
|
// If the second non-pruned message is in a group,
|
|
// we want to return the group as the first non-pruned message.
|
|
let firstIndex = messages.size - logLimit;
|
|
let groupId = messages.get(firstIndex + 1).groupId;
|
|
|
|
if (groupId) {
|
|
return messages.splice(0, firstIndex + 1)
|
|
.unshift(
|
|
messages.findLast((message) => message.id === groupId)
|
|
);
|
|
}
|
|
return messages.splice(0, firstIndex);
|
|
}
|
|
|
|
return messages;
|
|
}
|
|
|
|
exports.getAllMessages = getAllMessages;
|
|
exports.getAllMessagesUiById = getAllMessagesUiById;
|
|
exports.getAllMessagesTableDataById = getAllMessagesTableDataById;
|
|
exports.getAllGroupsById = getAllGroupsById;
|
|
exports.getCurrentGroup = getCurrentGroup;
|