Bug 731318 - Show transferred size in Net Monitor. r=vporof

This commit is contained in:
J. Ryan Stinnett 2014-12-09 14:35:13 -06:00
Родитель 0670ed467e
Коммит 46c55add68
14 изменённых файлов: 160 добавлений и 8 удалений

Просмотреть файл

@ -391,6 +391,16 @@ let NetMonitorController = {
!this._target.isApp);
},
/**
* Getter that tells if the server includes the transferred (compressed /
* encoded) response size.
* @type boolean
*/
get supportsTransferredResponseSize() {
return this.webConsoleClient &&
this.webConsoleClient.traits.transferredResponseSize;
},
/**
* Getter that tells if the server can do network performance statistics.
* @type boolean
@ -590,6 +600,7 @@ NetworkEventsHandler.prototype = {
case "responseContent":
NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
contentSize: aPacket.contentSize,
transferredSize: aPacket.transferredSize,
mimeType: aPacket.mimeType
});
this.webConsoleClient.getResponseContent(actor, this._onResponseContent);

Просмотреть файл

@ -416,6 +416,11 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
$("#requests-menu-network-summary-button").hidden = true;
$("#requests-menu-network-summary-label").hidden = true;
}
if (!NetMonitorController.supportsTransferredResponseSize) {
$("#requests-menu-transferred-header-box").hidden = true;
$("#requests-menu-item-template .requests-menu-transferred").hidden = true;
}
},
/**
@ -799,8 +804,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
* Sorts all network requests in this container by a specified detail.
*
* @param string aType
* Either "status", "method", "file", "domain", "type", "size" or
* "waterfall".
* Either "status", "method", "file", "domain", "type", "transferred",
* "size" or "waterfall".
*/
sortBy: function(aType = "waterfall") {
let target = $("#requests-menu-" + aType + "-button");
@ -861,6 +866,13 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.sortContents((a, b) => !this._byType(a, b));
}
break;
case "transferred":
if (direction == "ascending") {
this.sortContents(this._byTransferred);
} else {
this.sortContents((a, b) => !this._byTransferred(a, b));
}
break;
case "size":
if (direction == "ascending") {
this.sortContents(this._bySize);
@ -993,8 +1005,13 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
: firstType > secondType;
},
_bySize: function({ attachment: first }, { attachment: second })
first.contentSize > second.contentSize,
_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
@ -1159,6 +1176,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
requestItem.attachment.contentSize = value;
this.updateMenuView(requestItem, key, value);
break;
case "transferredSize":
requestItem.attachment.transferredSize = value;
this.updateMenuView(requestItem, key, value);
break;
case "mimeType":
requestItem.attachment.mimeType = value;
this.updateMenuView(requestItem, key, value);
@ -1307,6 +1328,20 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
node.setAttribute("tooltiptext", text);
break;
}
case "transferredSize": {
let text;
if (aValue === null) {
text = L10N.getStr("networkMenu.sizeUnavailable");
} else {
let kb = aValue / 1024;
let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS);
text = L10N.getFormatStr("networkMenu.sizeKB", size);
}
let node = $(".requests-menu-transferred", target);
node.setAttribute("value", text);
node.setAttribute("tooltiptext", text);
break;
}
case "mimeType": {
let type = this._getAbbreviatedMimeType(aValue);
let node = $(".requests-menu-type", target);

Просмотреть файл

@ -101,6 +101,16 @@
flex="1">
</button>
</hbox>
<hbox id="requests-menu-transferred-header-box"
class="requests-menu-header requests-menu-transferred"
align="center">
<button id="requests-menu-transferred-button"
class="requests-menu-header-button requests-menu-transferred"
data-key="transferred"
label="&netmonitorUI.toolbar.transferred;"
flex="1">
</button>
</hbox>
<hbox id="requests-menu-size-header-box"
class="requests-menu-header requests-menu-size"
align="center">
@ -174,6 +184,8 @@
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-type"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-transferred"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-size"
crop="end"/>
<hbox class="requests-menu-subitem requests-menu-waterfall"

Просмотреть файл

@ -65,6 +65,8 @@ function test() {
is(requestItem.attachment.headersSize, undefined,
"The headersSize should not yet be set.");
is(requestItem.attachment.transferredSize, undefined,
"The transferredSize should not yet be set.");
is(requestItem.attachment.contentSize, undefined,
"The contentSize should not yet be set.");
@ -156,6 +158,8 @@ function test() {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_RESPONSE_CONTENT, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
is(requestItem.attachment.transferredSize, "12",
"The transferredSize attachment has an incorrect value.");
is(requestItem.attachment.contentSize, "12",
"The contentSize attachment has an incorrect value.");
is(requestItem.attachment.mimeType, "text/plain; charset=utf-8",
@ -164,6 +168,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
});
});
@ -183,6 +188,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, {
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
});
});

Просмотреть файл

@ -202,6 +202,7 @@ function test() {
statusText: "Switching Protocols",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -211,6 +212,7 @@ function test() {
statusText: "Created",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -220,6 +222,7 @@ function test() {
statusText: "See Other",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -229,6 +232,7 @@ function test() {
statusText: "Not Found",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -238,6 +242,7 @@ function test() {
statusText: "Not Implemented",
type: "plain",
fullMimeType: "text/plain; charset=utf-8",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});

Просмотреть файл

@ -102,6 +102,24 @@ function test() {
testHeaders("type", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing transferred sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing transferred sort, descending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "descending");
return testContents([4, 3, 2, 1, 0]);
})
.then(() => {
info("Testing transferred sort, ascending. Checking sort loops correctly.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-transferred-button"));
testHeaders("transferred", "ascending");
return testContents([0, 1, 2, 3, 4]);
})
.then(() => {
info("Testing size sort, ascending.");
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
@ -199,6 +217,7 @@ function test() {
statusText: "Meh",
type: "1",
fullMimeType: "text/1",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -209,6 +228,7 @@ function test() {
statusText: "Meh",
type: "2",
fullMimeType: "text/2",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
time: true
});
@ -219,6 +239,7 @@ function test() {
statusText: "Meh",
type: "3",
fullMimeType: "text/3",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -229,6 +250,7 @@ function test() {
statusText: "Meh",
type: "4",
fullMimeType: "text/4",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
time: true
});
@ -239,6 +261,7 @@ function test() {
statusText: "Meh",
type: "5",
fullMimeType: "text/5",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});

Просмотреть файл

@ -130,6 +130,7 @@ function test() {
statusText: "Meh",
type: "1",
fullMimeType: "text/1",
transferred: L10N.getStr("networkMenu.sizeUnavailable"),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0),
time: true
});
@ -142,6 +143,7 @@ function test() {
statusText: "Meh",
type: "2",
fullMimeType: "text/2",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01),
time: true
});
@ -154,6 +156,7 @@ function test() {
statusText: "Meh",
type: "3",
fullMimeType: "text/3",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02),
time: true
});
@ -166,6 +169,7 @@ function test() {
statusText: "Meh",
type: "4",
fullMimeType: "text/4",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03),
time: true
});
@ -178,6 +182,7 @@ function test() {
statusText: "Meh",
type: "5",
fullMimeType: "text/5",
transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04),
time: true
});

Просмотреть файл

@ -12,6 +12,12 @@ function test() {
let { document, L10N, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
// Disable transferred size column support for this test.
// Without this, the waterfall only has enough room for one division, which
// would remove most of the value of this test.
document.querySelector("#requests-menu-transferred-header-box").hidden = true;
document.querySelector("#requests-menu-item-template .requests-menu-transferred").hidden = true;
RequestsMenu.lazyUpdate = false;
ok(document.querySelector("#requests-menu-waterfall-label"),

Просмотреть файл

@ -264,7 +264,7 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
info("Widget index of item: " + widgetIndex);
info("Visible index of item: " + visibleIndex);
let { fuzzyUrl, status, statusText, type, fullMimeType, size, time } = aData;
let { fuzzyUrl, status, statusText, type, fullMimeType, transferred, size, time } = aData;
let { attachment, target } = aRequestItem
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
@ -319,6 +319,14 @@ function verifyRequestItemTarget(aRequestItem, aMethod, aUrl, aData = {}) {
is(value, type, "The displayed type is incorrect.");
is(tooltip, fullMimeType, "The tooltip type is incorrect.");
}
if (transferred !== undefined) {
let value = target.querySelector(".requests-menu-transferred").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-transferred").getAttribute("tooltiptext");
info("Displayed transferred size: " + value);
info("Tooltip transferred size: " + tooltip);
is(value, transferred, "The displayed transferred size is incorrect.");
is(tooltip, transferred, "The tooltip transferred size is incorrect.");
}
if (size !== undefined) {
let value = target.querySelector(".requests-menu-size").getAttribute("value");
let tooltip = target.querySelector(".requests-menu-size").getAttribute("tooltiptext");

Просмотреть файл

@ -42,8 +42,14 @@
- in the network table toolbar, above the "type" column. -->
<!ENTITY netmonitorUI.toolbar.type "Type">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.transferred): This is the label displayed
- in the network table toolbar, above the "transferred" column, which is the
- compressed / encoded size. -->
<!ENTITY netmonitorUI.toolbar.transferred "Transferred">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.size): This is the label displayed
- in the network table toolbar, above the "size" column. -->
- in the network table toolbar, above the "size" column, which is the
- uncompressed / decoded size. -->
<!ENTITY netmonitorUI.toolbar.size "Size">
<!-- LOCALIZATION NOTE (netmonitorUI.toolbar.waterfall): This is the label displayed

Просмотреть файл

@ -129,6 +129,11 @@ networkMenu.summary=One request, #2 KB, #3 s;#1 requests, #2 KB, #3 s
# in the network menu specifying the size of a request (in kilobytes).
networkMenu.sizeKB=%S KB
# LOCALIZATION NOTE (networkMenu.sizeUnavailable): This is the label displayed
# in the network menu specifying the transferred size of a request is
# unavailable.
networkMenu.sizeUnavailable=
# LOCALIZATION NOTE (networkMenu.totalMS): This is the label displayed
# in the network menu specifying the time for a request to finish (in milliseconds).
networkMenu.totalMS=→ %S ms

Просмотреть файл

@ -166,6 +166,11 @@
width: 8em;
}
.requests-menu-transferred {
text-align: center;
width: 8em;
}
/* Network requests table: status codes */
box.requests-menu-status {

Просмотреть файл

@ -83,6 +83,7 @@ function WebConsoleActor(aConnection, aParentActor)
this.traits = {
customNetworkRequest: !this._parentIsContentActor,
transferredResponseSize: true
};
}
@ -1940,6 +1941,7 @@ NetworkEventActor.prototype =
updateType: "responseContent",
mimeType: aContent.mimeType,
contentSize: aContent.text.length,
transferredSize: aContent.transferredSize,
discardResponseBody: aDiscardedResponseBody,
};

Просмотреть файл

@ -63,7 +63,9 @@ exports.NetworkResponseListener = NetworkResponseListener;
NetworkResponseListener.prototype = {
QueryInterface:
XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIInputStreamCallback,
Ci.nsIRequestObserver, Ci.nsISupports]),
Ci.nsIRequestObserver, Ci.nsIInterfaceRequestor,
Ci.nsISupports]),
getInterface: XPCOMUtils.generateQI([Ci.nsIProgressEventSink]),
/**
* This NetworkResponseListener tracks the NetworkMonitor.openResponses object
@ -94,10 +96,15 @@ NetworkResponseListener.prototype = {
receivedData: null,
/**
* The network response body size.
* The uncompressed, decoded response body size.
*/
bodySize: null,
/**
* Response body size on the wire, potentially compressed / encoded.
*/
transferredSize: null,
/**
* The nsIRequest we are started for.
*/
@ -177,6 +184,18 @@ NetworkResponseListener.prototype = {
this.sink.outputStream.close();
},
// nsIProgressEventSink implementation
/**
* Handle progress event as data is transferred. This is used to record the
* size on the wire, which may be compressed / encoded.
*/
onProgress: function(request, context, progress, progressMax) {
this.transferredSize = progress;
},
onStatus: function () {},
/**
* Find the open response object associated to the current request. The
* NetworkMonitor._httpResponseExaminer() method saves the response headers in
@ -259,6 +278,7 @@ NetworkResponseListener.prototype = {
};
response.size = response.text.length;
response.transferredSize = this.transferredSize;
try {
response.mimeType = this.request.contentType;
@ -279,6 +299,7 @@ NetworkResponseListener.prototype = {
this.httpActivity.owner.
addResponseContent(response, this.httpActivity.discardResponseBody);
this.httpActivity.channel.notificationCallbacks = null;
this.httpActivity.channel = null;
this.httpActivity.owner = null;
this.httpActivity = null;
@ -780,6 +801,8 @@ NetworkMonitor.prototype = {
let originalListener = channel.setNewListener(tee);
tee.init(originalListener, sink.outputStream, newListener);
channel.notificationCallbacks = newListener;
},
/**