diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/netmonitor/src/utils/sort-predicates.js | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/netmonitor/src/utils/sort-predicates.js')
-rw-r--r-- | devtools/client/netmonitor/src/utils/sort-predicates.js | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/src/utils/sort-predicates.js b/devtools/client/netmonitor/src/utils/sort-predicates.js new file mode 100644 index 0000000000..839a37d00e --- /dev/null +++ b/devtools/client/netmonitor/src/utils/sort-predicates.js @@ -0,0 +1,319 @@ +/* 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 { + getAbbreviatedMimeType, + getEndTime, + getResponseTime, + getResponseHeader, + getStartTime, + ipToLong, +} = require("resource://devtools/client/netmonitor/src/utils/request-utils.js"); +const { + RESPONSE_HEADERS, +} = require("resource://devtools/client/netmonitor/src/constants.js"); +const { + getUrlBaseName, +} = require("resource://devtools/client/netmonitor/src/utils/request-utils.js"); + +/** + * Predicates used when sorting items. + * + * @param object first + * The first item used in the comparison. + * @param object second + * The second item used in the comparison. + * @return number + * <0 to sort first to a lower index than second + * =0 to leave first and second unchanged with respect to each other + * >0 to sort second to a lower index than first + */ + +function compareValues(first, second) { + if (first === second) { + return 0; + } + return first > second ? 1 : -1; +} + +function waterfall(first, second) { + const result = compareValues(first.startedMs, second.startedMs); + return result || compareValues(first.id, second.id); +} + +function priority(first, second) { + const result = compareValues(first.priority, second.priority); + return result || waterfall(first, second); +} + +function status(first, second) { + const result = compareValues(getStatusValue(first), getStatusValue(second)); + return result || waterfall(first, second); +} + +function method(first, second) { + const result = compareValues(first.method, second.method); + return result || waterfall(first, second); +} + +function file(first, second) { + const firstUrl = first.urlDetails.baseNameWithQuery.toLowerCase(); + const secondUrl = second.urlDetails.baseNameWithQuery.toLowerCase(); + const result = compareValues(firstUrl, secondUrl); + return result || waterfall(first, second); +} + +function url(first, second) { + const firstUrl = first.url.toLowerCase(); + const secondUrl = second.url.toLowerCase(); + const result = compareValues(firstUrl, secondUrl); + return result || waterfall(first, second); +} + +function protocol(first, second) { + const result = compareValues(first.httpVersion, second.httpVersion); + return result || waterfall(first, second); +} + +function scheme(first, second) { + const result = compareValues( + first.urlDetails.scheme, + second.urlDetails.scheme + ); + return result || waterfall(first, second); +} + +function startTime(first, second) { + const result = compareValues(getStartTime(first), getStartTime(second)); + return result || waterfall(first, second); +} + +function endTime(first, second) { + const result = compareValues(getEndTime(first), getEndTime(second)); + return result || waterfall(first, second); +} + +function responseTime(first, second) { + const result = compareValues(getResponseTime(first), getResponseTime(second)); + return result || waterfall(first, second); +} + +function duration(first, second) { + const result = compareValues(first.totalTime, second.totalTime); + return result || waterfall(first, second); +} + +function latency(first, second) { + const { eventTimings: firstEventTimings = { timings: {} } } = first; + const { eventTimings: secondEventTimings = { timings: {} } } = second; + const result = compareValues( + firstEventTimings.timings.wait, + secondEventTimings.timings.wait + ); + return result || waterfall(first, second); +} + +function compareHeader(header, first, second) { + const firstValue = getResponseHeader(first, header) || ""; + const secondValue = getResponseHeader(second, header) || ""; + + let result; + + switch (header) { + case "Content-Length": { + result = compareValues( + parseInt(firstValue, 10) || 0, + parseInt(secondValue, 10) || 0 + ); + break; + } + case "Last-Modified": { + result = compareValues( + new Date(firstValue).valueOf() || -1, + new Date(secondValue).valueOf() || -1 + ); + break; + } + default: { + result = compareValues(firstValue, secondValue); + break; + } + } + + return result || waterfall(first, second); +} + +const responseHeaders = RESPONSE_HEADERS.reduce( + (acc, header) => + Object.assign(acc, { + [header]: (first, second) => compareHeader(header, first, second), + }), + {} +); + +function domain(first, second) { + const firstDomain = first.urlDetails.host.toLowerCase(); + const secondDomain = second.urlDetails.host.toLowerCase(); + const result = compareValues(firstDomain, secondDomain); + return result || waterfall(first, second); +} + +function remoteip(first, second) { + const firstIP = ipToLong(first.remoteAddress); + const secondIP = ipToLong(second.remoteAddress); + const result = compareValues(firstIP, secondIP); + return result || waterfall(first, second); +} + +function cause(first, second) { + const firstCause = first.cause.type; + const secondCause = second.cause.type; + const result = compareValues(firstCause, secondCause); + return result || waterfall(first, second); +} + +function initiator(first, second) { + const firstCause = first.cause.type; + const secondCause = second.cause.type; + + let firstInitiator = ""; + let firstInitiatorLineNumber = 0; + + if (first.cause.lastFrame) { + firstInitiator = getUrlBaseName(first.cause.lastFrame.filename); + firstInitiatorLineNumber = first.cause.lastFrame.lineNumber; + } + + let secondInitiator = ""; + let secondInitiatorLineNumber = 0; + + if (second.cause.lastFrame) { + secondInitiator = getUrlBaseName(second.cause.lastFrame.filename); + secondInitiatorLineNumber = second.cause.lastFrame.lineNumber; + } + + let result; + // if both initiators don't have a stack trace, compare their causes + if (!firstInitiator && !secondInitiator) { + result = compareValues(firstCause, secondCause); + } else if (!firstInitiator || !secondInitiator) { + // if one initiator doesn't have a stack trace but the other does, former should precede the latter + result = compareValues(firstInitiatorLineNumber, secondInitiatorLineNumber); + } else { + result = compareValues(firstInitiator, secondInitiator); + if (result === 0) { + result = compareValues( + firstInitiatorLineNumber, + secondInitiatorLineNumber + ); + } + } + + return result || waterfall(first, second); +} + +function setCookies(first, second) { + let { responseCookies: firstResponseCookies = { cookies: [] } } = first; + let { responseCookies: secondResponseCookies = { cookies: [] } } = second; + firstResponseCookies = firstResponseCookies.cookies || firstResponseCookies; + secondResponseCookies = + secondResponseCookies.cookies || secondResponseCookies; + const result = compareValues( + firstResponseCookies.length, + secondResponseCookies.length + ); + return result || waterfall(first, second); +} + +function cookies(first, second) { + let { requestCookies: firstRequestCookies = { cookies: [] } } = first; + let { requestCookies: secondRequestCookies = { cookies: [] } } = second; + firstRequestCookies = firstRequestCookies.cookies || firstRequestCookies; + secondRequestCookies = secondRequestCookies.cookies || secondRequestCookies; + const result = compareValues( + firstRequestCookies.length, + secondRequestCookies.length + ); + return result || waterfall(first, second); +} + +function type(first, second) { + const firstType = getAbbreviatedMimeType(first.mimeType).toLowerCase(); + const secondType = getAbbreviatedMimeType(second.mimeType).toLowerCase(); + const result = compareValues(firstType, secondType); + return result || waterfall(first, second); +} + +function getStatusValue(item) { + let value; + if (item.blockedReason) { + value = typeof item.blockedReason == "number" ? -item.blockedReason : -1000; + } else if (item.status == null) { + value = -2; + } else { + value = item.status; + } + return value; +} + +function getTransferedSizeValue(item) { + let value; + if (item.blockedReason) { + // Also properly group/sort various blocked reasons. + value = typeof item.blockedReason == "number" ? -item.blockedReason : -1000; + } else if (item.fromCache || item.status === "304") { + value = -2; + } else if (item.fromServiceWorker) { + value = -3; + } else if (typeof item.transferredSize == "number") { + value = item.transferredSize; + if (item.isRacing && typeof item.isRacing == "boolean") { + value = -4; + } + } else if (item.transferredSize === null) { + value = -5; + } + return value; +} + +function transferred(first, second) { + const result = compareValues( + getTransferedSizeValue(first), + getTransferedSizeValue(second) + ); + return result || waterfall(first, second); +} + +function contentSize(first, second) { + const result = compareValues(first.contentSize, second.contentSize); + return result || waterfall(first, second); +} + +const sorters = { + status, + method, + domain, + file, + protocol, + scheme, + cookies, + setCookies, + remoteip, + cause, + initiator, + type, + transferred, + contentSize, + startTime, + endTime, + responseTime, + duration, + latency, + waterfall, + url, + priority, +}; +exports.Sorters = Object.assign(sorters, responseHeaders); |