--- a/devtools/client/netmonitor/requests-menu-view.js
+++ b/devtools/client/netmonitor/requests-menu-view.js
@@ -11,19 +11,27 @@ const {HTMLTooltip} = require("devtools/
const {setImageTooltip, getImageDimensions} =
require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper");
const {Heritage, WidgetMethods, setNamedTimeout} =
require("devtools/client/shared/widgets/view-helpers");
const {gDevTools} = require("devtools/client/framework/devtools");
const {Curl, CurlUtils} = require("devtools/client/shared/curl");
const {PluralForm} = require("devtools/shared/plural-form");
const {Filters, isFreetextMatch} = require("./filter-predicates");
-const {getFormDataSections, formDataURI, writeHeaderText, getKeyWithEvent,
+const {Sorters} = require("./sort-predicates");
+const {L10N, WEBCONSOLE_L10N} = require("./l10n");
+const {getFormDataSections,
+ formDataURI,
+ writeHeaderText,
+ getKeyWithEvent,
+ getAbbreviatedMimeType,
+ getUriNameWithQuery,
+ getUriHostPort,
+ getUriHost,
loadCauseString} = require("./request-utils");
-const {L10N, WEBCONSOLE_L10N} = require("./l10n");
loader.lazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
loader.lazyRequireGetter(this, "HarExporter",
"devtools/client/netmonitor/har/har-exporter", true);
loader.lazyRequireGetter(this, "NetworkHelper",
@@ -87,19 +95,16 @@ function RequestsMenuView() {
dumpn("RequestsMenuView was instantiated");
this._flushRequests = this._flushRequests.bind(this);
this._onHover = this._onHover.bind(this);
this._onSelect = this._onSelect.bind(this);
this._onSwap = this._onSwap.bind(this);
this._onResize = this._onResize.bind(this);
this._onScroll = this._onScroll.bind(this);
- this._byFile = this._byFile.bind(this);
- this._byDomain = this._byDomain.bind(this);
- this._byType = this._byType.bind(this);
this._onSecurityIconClick = this._onSecurityIconClick.bind(this);
}
RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
/**
* Initialization function, called when the network monitor is started.
*/
initialize: function () {
@@ -117,17 +122,17 @@ RequestsMenuView.prototype = Heritage.ex
this.tooltip = new HTMLTooltip(NetMonitorController._toolbox.doc, { type: "arrow" });
this.tooltip.startTogglingOnHover(widgetParentEl, this._onHover, {
toggleDelay: REQUESTS_TOOLTIP_TOGGLE_DELAY,
interactive: true
});
$("#requests-menu-contents").addEventListener("scroll", this._onScroll, true);
Prefs.filters.forEach(type => this.filterOn(type));
- this.sortContents(this._byTiming);
+ this.sortContents((a, b) => Sorters.waterfall(a.attachment, b.attachment));
this.allowFocusOnRightClick = true;
this.maintainSelectionVisible = true;
this.widget.addEventListener("select", this._onSelect, false);
this.widget.addEventListener("swap", this._onSwap, false);
this._splitter.addEventListener("mousemove", this._onResize, false);
window.addEventListener("resize", this._onResize, false);
@@ -784,75 +789,75 @@ RequestsMenuView.prototype = Heritage.ex
// Used to style the next column.
target.parentNode.setAttribute("active", "true");
}
// Sort by whatever was requested.
switch (type) {
case "status":
if (direction == "ascending") {
- this.sortContents(this._byStatus);
+ this.sortContents((a, b) => Sorters.status(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byStatus(a, b));
+ this.sortContents((a, b) => -Sorters.status(a.attachment, b.attachment));
}
break;
case "method":
if (direction == "ascending") {
- this.sortContents(this._byMethod);
+ this.sortContents((a, b) => Sorters.method(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byMethod(a, b));
+ this.sortContents((a, b) => -Sorters.method(a.attachment, b.attachment));
}
break;
case "file":
if (direction == "ascending") {
- this.sortContents(this._byFile);
+ this.sortContents((a, b) => Sorters.file(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byFile(a, b));
+ this.sortContents((a, b) => -Sorters.file(a.attachment, b.attachment));
}
break;
case "domain":
if (direction == "ascending") {
- this.sortContents(this._byDomain);
+ this.sortContents((a, b) => Sorters.domain(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byDomain(a, b));
+ this.sortContents((a, b) => -Sorters.domain(a.attachment, b.attachment));
}
break;
case "cause":
if (direction == "ascending") {
- this.sortContents(this._byCause);
+ this.sortContents((a, b) => Sorters.cause(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byCause(a, b));
+ this.sortContents((a, b) => -Sorters.cause(a.attachment, b.attachment));
}
break;
case "type":
if (direction == "ascending") {
- this.sortContents(this._byType);
+ this.sortContents((a, b) => Sorters.type(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byType(a, b));
+ this.sortContents((a, b) => -Sorters.type(a.attachment, b.attachment));
}
break;
case "transferred":
if (direction == "ascending") {
- this.sortContents(this._byTransferred);
+ this.sortContents((a, b) => Sorters.transferred(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byTransferred(a, b));
+ this.sortContents((a, b) => -Sorters.transferred(a.attachment, b.attachment));
}
break;
case "size":
if (direction == "ascending") {
- this.sortContents(this._bySize);
+ this.sortContents((a, b) => Sorters.size(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._bySize(a, b));
+ this.sortContents((a, b) => -Sorters.size(a.attachment, b.attachment));
}
break;
case "waterfall":
if (direction == "ascending") {
- this.sortContents(this._byTiming);
+ this.sortContents((a, b) => Sorters.waterfall(a.attachment, b.attachment));
} else {
- this.sortContents((a, b) => !this._byTiming(a, b));
+ this.sortContents((a, b) => -Sorters.waterfall(a.attachment, b.attachment));
}
break;
}
this.refreshSummary();
this.refreshZebra();
},
@@ -866,86 +871,16 @@ RequestsMenuView.prototype = Heritage.ex
$("#details-pane-toggle").disabled = true;
$("#requests-menu-empty-notice").hidden = false;
this.empty();
this.refreshSummary();
},
/**
- * Predicates used when sorting items.
- *
- * @param object aFirst
- * The first item used in the comparison.
- * @param object aSecond
- * The second item used in the comparison.
- * @return number
- * -1 to sort aFirst to a lower index than aSecond
- * 0 to leave aFirst and aSecond unchanged with respect to each other
- * 1 to sort aSecond to a lower index than aFirst
- */
- _byTiming: function ({ attachment: first }, { attachment: second }) {
- return first.startedMillis > second.startedMillis;
- },
-
- _byStatus: function ({ attachment: first }, { attachment: second }) {
- return first.status == second.status
- ? first.startedMillis > second.startedMillis
- : first.status > second.status;
- },
-
- _byMethod: function ({ attachment: first }, { attachment: second }) {
- return first.method == second.method
- ? first.startedMillis > second.startedMillis
- : first.method > second.method;
- },
-
- _byFile: function ({ attachment: first }, { attachment: second }) {
- let firstUrl = this._getUriNameWithQuery(first.url).toLowerCase();
- let secondUrl = this._getUriNameWithQuery(second.url).toLowerCase();
- return firstUrl == secondUrl
- ? first.startedMillis > second.startedMillis
- : firstUrl > secondUrl;
- },
-
- _byDomain: function ({ attachment: first }, { attachment: second }) {
- let firstDomain = this._getUriHostPort(first.url).toLowerCase();
- let secondDomain = this._getUriHostPort(second.url).toLowerCase();
- return firstDomain == secondDomain
- ? first.startedMillis > second.startedMillis
- : firstDomain > secondDomain;
- },
-
- _byCause: function ({ attachment: first }, { attachment: second }) {
- let firstCause = loadCauseString(first.cause.type);
- let secondCause = loadCauseString(second.cause.type);
-
- return firstCause == secondCause
- ? first.startedMillis > second.startedMillis
- : firstCause > secondCause;
- },
-
- _byType: function ({ attachment: first }, { attachment: second }) {
- let firstType = this._getAbbreviatedMimeType(first.mimeType).toLowerCase();
- let secondType = this._getAbbreviatedMimeType(second.mimeType).toLowerCase();
-
- return firstType == secondType
- ? first.startedMillis > second.startedMillis
- : firstType > secondType;
- },
-
- _byTransferred: function ({ attachment: first }, { attachment: second }) {
- return first.transferredSize > second.transferredSize;
- },
-
- _bySize: function ({ attachment: first }, { attachment: second }) {
- return first.contentSize > second.contentSize;
- },
-
- /**
* Refreshes the status displayed in this container's footer, providing
* concise information about all requests.
*/
refreshSummary: function () {
let visibleItems = this.visibleItems;
let visibleRequestsCount = visibleItems.length;
if (!visibleRequestsCount) {
this._summary.setAttribute("label", L10N.getStr("networkMenu.empty"));
@@ -1340,19 +1275,19 @@ RequestsMenuView.prototype = Heritage.ex
case "url": {
let uri;
try {
uri = NetworkHelper.nsIURL(value);
} catch (e) {
// User input may not make a well-formed url yet.
break;
}
- let nameWithQuery = this._getUriNameWithQuery(uri);
- let hostPort = this._getUriHostPort(uri);
- let host = this._getUriHost(uri);
+ let nameWithQuery = getUriNameWithQuery(uri);
+ let hostPort = getUriHostPort(uri);
+ let host = getUriHost(uri);
let unicodeUrl = NetworkHelper.convertToUnicode(unescape(uri.spec));
let file = $(".requests-menu-file", target);
file.setAttribute("value", nameWithQuery);
file.setAttribute("tooltiptext", unicodeUrl);
let domain = $(".requests-menu-domain", target);
domain.setAttribute("value", hostPort);
@@ -1459,17 +1394,17 @@ RequestsMenuView.prototype = Heritage.ex
text = this.getFormattedSize(value);
}
node.setAttribute("value", text);
node.setAttribute("tooltiptext", text);
break;
}
case "mimeType": {
- let type = this._getAbbreviatedMimeType(value);
+ let type = getAbbreviatedMimeType(value);
let node = $(".requests-menu-type", target);
let text = CONTENT_MIME_TYPE_ABBREVIATIONS[type] || type;
node.setAttribute("value", text);
node.setAttribute("tooltiptext", value);
break;
}
case "responseContent": {
let { mimeType } = item.attachment;
@@ -1989,58 +1924,16 @@ RequestsMenuView.prototype = Heritage.ex
*/
_registerLastRequestEnd: function (unixTime) {
if (this._lastRequestEndedMillis < unixTime) {
this._lastRequestEndedMillis = unixTime;
}
},
/**
- * Helpers for getting details about an nsIURL.
- *
- * @param nsIURL | string url
- * @return string
- */
- _getUriNameWithQuery: function (url) {
- if (!(url instanceof Ci.nsIURL)) {
- url = NetworkHelper.nsIURL(url);
- }
-
- let name = NetworkHelper.convertToUnicode(
- unescape(url.fileName || url.filePath || "/"));
- let query = NetworkHelper.convertToUnicode(unescape(url.query));
-
- return name + (query ? "?" + query : "");
- },
-
- _getUriHostPort: function (url) {
- if (!(url instanceof Ci.nsIURL)) {
- url = NetworkHelper.nsIURL(url);
- }
- return NetworkHelper.convertToUnicode(unescape(url.hostPort));
- },
-
- _getUriHost: function (url) {
- return this._getUriHostPort(url).replace(/:\d+$/, "");
- },
-
- /**
- * Helper for getting an abbreviated string for a mime type.
- *
- * @param string mimeType
- * @return string
- */
- _getAbbreviatedMimeType: function (mimeType) {
- if (!mimeType) {
- return "";
- }
- return (mimeType.split(";")[0].split("/")[1] || "").split("+")[0];
- },
-
- /**
* Gets the total number of bytes representing the cumulated content size of
* a set of requests. Returns 0 for an empty set.
*
* @param array itemsArray
* @return number
*/
_getTotalBytesOfRequests: function (itemsArray) {
if (!itemsArray.length) {
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/sort-predicates.js
@@ -0,0 +1,92 @@
+"use strict";
+
+const { getAbbreviatedMimeType,
+ getUriNameWithQuery,
+ getUriHostPort,
+ loadCauseString } = require("./request-utils");
+
+/**
+ * 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 waterfall(first, second) {
+ return first.startedMillis - second.startedMillis;
+}
+
+function status(first, second) {
+ return first.status == second.status
+ ? first.startedMillis - second.startedMillis
+ : first.status - second.status;
+}
+
+function method(first, second) {
+ if (first.method == second.method) {
+ return first.startedMillis - second.startedMillis;
+ }
+ return first.method > second.method ? 1 : -1;
+}
+
+function file(first, second) {
+ let firstUrl = getUriNameWithQuery(first.url).toLowerCase();
+ let secondUrl = getUriNameWithQuery(second.url).toLowerCase();
+ if (firstUrl == secondUrl) {
+ return first.startedMillis - second.startedMillis;
+ }
+ return firstUrl > secondUrl ? 1 : -1;
+}
+
+function domain(first, second) {
+ let firstDomain = getUriHostPort(first.url).toLowerCase();
+ let secondDomain = getUriHostPort(second.url).toLowerCase();
+ if (firstDomain == secondDomain) {
+ return first.startedMillis - second.startedMillis;
+ }
+ return firstDomain > secondDomain ? 1 : -1;
+}
+
+function cause(first, second) {
+ let firstCause = loadCauseString(first.cause.type);
+ let secondCause = loadCauseString(second.cause.type);
+ if (firstCause == secondCause) {
+ return first.startedMillis - second.startedMillis;
+ }
+ return firstCause > secondCause ? 1 : -1;
+}
+
+function type(first, second) {
+ let firstType = getAbbreviatedMimeType(first.mimeType).toLowerCase();
+ let secondType = getAbbreviatedMimeType(second.mimeType).toLowerCase();
+ if (firstType == secondType) {
+ return first.startedMillis - second.startedMillis;
+ }
+ return firstType > secondType ? 1 : -1;
+}
+
+function transferred(first, second) {
+ return first.transferredSize - second.transferredSize;
+}
+
+function size(first, second) {
+ return first.contentSize - second.contentSize;
+}
+
+exports.Sorters = {
+ status,
+ method,
+ file,
+ domain,
+ cause,
+ type,
+ transferred,
+ size,
+ waterfall,
+};