☠☠ backed out by 22eb2228358f ☠ ☠ | |
author | J. Ryan Stinnett <jryans@gmail.com> |
Tue, 09 Dec 2014 14:35:13 -0600 | |
changeset 218963 | 09bd629ead0ff6be46c29d12d8a10945ba0a2f92 |
parent 218962 | 28be6b157ca4ba7eed9cb96bdbe7020bead04244 |
child 218964 | 9bbaa27f0975b196ed9f42a7c226917e137682fe |
push id | 27950 |
push user | cbook@mozilla.com |
push date | Wed, 10 Dec 2014 10:58:50 +0000 |
treeherder | autoland@5b01216f97f8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | vporof |
bugs | 731318 |
milestone | 37.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/devtools/netmonitor/netmonitor-controller.js +++ b/browser/devtools/netmonitor/netmonitor-controller.js @@ -387,16 +387,26 @@ let NetMonitorController = { */ get supportsCustomRequest() { return this.webConsoleClient && (this.webConsoleClient.traits.customNetworkRequest || !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 */ get supportsPerfStats() { return this.tabClient && (this.tabClient.traits.reconfigure || !this._target.isApp); }, @@ -585,16 +595,17 @@ NetworkEventsHandler.prototype = { statusText: aPacket.response.statusText, headersSize: aPacket.response.headersSize }); window.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor); break; case "responseContent": NetMonitorView.RequestsMenu.updateRequest(aPacket.from, { contentSize: aPacket.contentSize, + transferredSize: aPacket.transferredSize, mimeType: aPacket.mimeType }); this.webConsoleClient.getResponseContent(actor, this._onResponseContent); window.emit(EVENTS.UPDATING_RESPONSE_CONTENT, actor); break; case "eventTimings": NetMonitorView.RequestsMenu.updateRequest(aPacket.from, { totalTime: aPacket.totalTime
--- a/browser/devtools/netmonitor/netmonitor-view.js +++ b/browser/devtools/netmonitor/netmonitor-view.js @@ -411,16 +411,21 @@ RequestsMenuView.prototype = Heritage.ex $("#requests-menu-network-summary-label").addEventListener("click", this._onContextPerfCommand, false); $("#network-statistics-back-button").addEventListener("command", this._onContextPerfCommand, false); } else { $("#notice-perf-message").hidden = true; $("#request-menu-context-perf").hidden = true; $("#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; + } }, /** * Destruction function, called when the network monitor is closed. */ destroy: function() { dumpn("Destroying the SourcesView"); @@ -794,18 +799,18 @@ RequestsMenuView.prototype = Heritage.ex flash: this.isFlash, other: this.isOther }), /** * 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"); let headers = document.querySelectorAll(".requests-menu-header-button"); for (let header of headers) { if (header != target) { header.removeAttribute("sorted"); @@ -856,16 +861,23 @@ RequestsMenuView.prototype = Heritage.ex break; case "type": if (direction == "ascending") { this.sortContents(this._byType); } else { 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); } else { this.sortContents((a, b) => !this._bySize(a, b)); } break; case "waterfall": @@ -988,18 +1000,23 @@ RequestsMenuView.prototype = Heritage.ex _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; }, - _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 * concise information about all requests. */ refreshSummary: function() { let visibleItems = this.visibleItems; let visibleRequestsCount = visibleItems.length; @@ -1154,16 +1171,20 @@ RequestsMenuView.prototype = Heritage.ex break; case "headersSize": requestItem.attachment.headersSize = value; break; case "contentSize": 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); break; case "responseContent": // If there's no mime type available when the response content // is received, assume text/plain as a fallback. if (!requestItem.attachment.mimeType) { @@ -1302,16 +1323,30 @@ RequestsMenuView.prototype = Heritage.ex let kb = aValue / 1024; let size = L10N.numberWithDecimals(kb, CONTENT_SIZE_DECIMALS); let node = $(".requests-menu-size", target); let text = L10N.getFormatStr("networkMenu.sizeKB", size); node.setAttribute("value", text); 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); let text = CONTENT_MIME_TYPE_ABBREVIATIONS[type] || type; node.setAttribute("value", text); node.setAttribute("tooltiptext", aValue); break; }
--- a/browser/devtools/netmonitor/netmonitor.xul +++ b/browser/devtools/netmonitor/netmonitor.xul @@ -96,16 +96,26 @@ align="center"> <button id="requests-menu-type-button" class="requests-menu-header-button requests-menu-type" data-key="type" label="&netmonitorUI.toolbar.type;" 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"> <button id="requests-menu-size-button" class="requests-menu-header-button requests-menu-size" data-key="size" label="&netmonitorUI.toolbar.size;" flex="1"> @@ -169,16 +179,18 @@ <label class="plain requests-menu-file" crop="end" flex="1"/> </hbox> <label class="plain requests-menu-subitem requests-menu-domain" 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" align="center" flex="1"> <hbox class="requests-menu-timings" align="center"> <label class="plain requests-menu-timings-total"/>
--- a/browser/devtools/netmonitor/test/browser_net_simple-request-data.js +++ b/browser/devtools/netmonitor/test/browser_net_simple-request-data.js @@ -60,16 +60,18 @@ function test() { "The httpVersion should not yet be set."); is(requestItem.attachment.status, undefined, "The status should not yet be set."); is(requestItem.attachment.statusText, undefined, "The statusText should not yet be set."); 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."); is(requestItem.attachment.mimeType, undefined, "The mimeType should not yet be set."); is(requestItem.attachment.responseContent, undefined, "The responseContent should not yet be set."); @@ -151,24 +153,27 @@ function test() { status: "200", statusText: "Och Aye" }); }); 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", "The mimeType attachment has an incorrect value."); 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), }); }); aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_RESPONSE_CONTENT, () => { let requestItem = RequestsMenu.getItemAtIndex(0); ok(requestItem.attachment.responseContent, @@ -178,16 +183,17 @@ function test() { is(requestItem.attachment.responseContent.content.text, "Hello world!", "The responseContent attachment has an incorrect |content.text| property."); is(requestItem.attachment.responseContent.content.size, 12, "The responseContent attachment has an incorrect |content.size| property."); 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), }); }); aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_EVENT_TIMINGS, () => { let requestItem = RequestsMenu.getItemAtIndex(0); is(typeof requestItem.attachment.totalTime, "number",
--- a/browser/devtools/netmonitor/test/browser_net_sort-01.js +++ b/browser/devtools/netmonitor/test/browser_net_sort-01.js @@ -197,52 +197,57 @@ function test() { "The requests menu items aren't ordered correctly. Fifth item is misplaced."); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a), "GET", STATUS_CODES_SJS + "?sts=100", { status: 101, statusText: "Switching Protocols", type: "plain", fullMimeType: "text/plain; charset=utf-8", + transferred: L10N.getStr("networkMenu.sizeUnavailable"), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0), time: true }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b), "GET", STATUS_CODES_SJS + "?sts=200", { status: 202, 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 }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c), "GET", STATUS_CODES_SJS + "?sts=300", { status: 303, 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 }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d), "GET", STATUS_CODES_SJS + "?sts=400", { status: 404, 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 }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e), "GET", STATUS_CODES_SJS + "?sts=500", { status: 501, 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 }); return promise.resolve(null); } aDebuggee.performRequests();
--- a/browser/devtools/netmonitor/test/browser_net_sort-02.js +++ b/browser/devtools/netmonitor/test/browser_net_sort-02.js @@ -98,16 +98,34 @@ function test() { }) .then(() => { info("Testing type sort, ascending. Checking sort loops correctly."); EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-type-button")); 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")); testHeaders("size", "ascending"); return testContents([0, 1, 2, 3, 4]); }) .then(() => { info("Testing size sort, descending."); EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button")); @@ -194,56 +212,61 @@ function test() { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(a), "GET1", SORTING_SJS + "?index=1", { fuzzyUrl: true, status: 101, statusText: "Meh", type: "1", fullMimeType: "text/1", + transferred: L10N.getStr("networkMenu.sizeUnavailable"), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0), time: true }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(b), "GET2", SORTING_SJS + "?index=2", { fuzzyUrl: true, status: 200, statusText: "Meh", type: "2", fullMimeType: "text/2", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01), time: true }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(c), "GET3", SORTING_SJS + "?index=3", { fuzzyUrl: true, status: 300, statusText: "Meh", type: "3", fullMimeType: "text/3", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02), time: true }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(d), "GET4", SORTING_SJS + "?index=4", { fuzzyUrl: true, status: 400, statusText: "Meh", type: "4", fullMimeType: "text/4", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03), time: true }); verifyRequestItemTarget(RequestsMenu.getItemAtIndex(e), "GET5", SORTING_SJS + "?index=5", { fuzzyUrl: true, status: 500, statusText: "Meh", type: "5", fullMimeType: "text/5", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04), time: true }); return promise.resolve(null); } aDebuggee.performRequests();
--- a/browser/devtools/netmonitor/test/browser_net_sort-03.js +++ b/browser/devtools/netmonitor/test/browser_net_sort-03.js @@ -125,64 +125,69 @@ function test() { for (let i = 0, len = aOrder.length / 5; i < len; i++) { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]), "GET1", SORTING_SJS + "?index=1", { fuzzyUrl: true, status: 101, statusText: "Meh", type: "1", fullMimeType: "text/1", + transferred: L10N.getStr("networkMenu.sizeUnavailable"), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0), time: true }); } for (let i = 0, len = aOrder.length / 5; i < len; i++) { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]), "GET2", SORTING_SJS + "?index=2", { fuzzyUrl: true, status: 200, statusText: "Meh", type: "2", fullMimeType: "text/2", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.01), time: true }); } for (let i = 0, len = aOrder.length / 5; i < len; i++) { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]), "GET3", SORTING_SJS + "?index=3", { fuzzyUrl: true, status: 300, statusText: "Meh", type: "3", fullMimeType: "text/3", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.02), time: true }); } for (let i = 0, len = aOrder.length / 5; i < len; i++) { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]), "GET4", SORTING_SJS + "?index=4", { fuzzyUrl: true, status: 400, statusText: "Meh", type: "4", fullMimeType: "text/4", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.03), time: true }); } for (let i = 0, len = aOrder.length / 5; i < len; i++) { verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]), "GET5", SORTING_SJS + "?index=5", { fuzzyUrl: true, status: 500, statusText: "Meh", type: "5", fullMimeType: "text/5", + transferred: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04), size: L10N.getFormatStrWithNumbers("networkMenu.sizeKB", 0.04), time: true }); } return promise.resolve(null); }
--- a/browser/devtools/netmonitor/test/browser_net_timeline_ticks.js +++ b/browser/devtools/netmonitor/test/browser_net_timeline_ticks.js @@ -7,16 +7,22 @@ function test() { initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => { info("Starting 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"), "An timeline label should be displayed when the frontend is opened."); ok(document.querySelectorAll(".requests-menu-timings-division").length == 0, "No tick labels should be displayed when the frontend is opened."); ok(!RequestsMenu._canvas,
--- a/browser/devtools/netmonitor/test/head.js +++ b/browser/devtools/netmonitor/test/head.js @@ -259,17 +259,17 @@ function verifyRequestItemTarget(aReques let requestsMenu = aRequestItem.ownerView; let widgetIndex = requestsMenu.indexOfItem(aRequestItem); let visibleIndex = requestsMenu.visibleItems.indexOf(aRequestItem); 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); let name = uri.fileName || "/"; let query = uri.query; let hostPort = uri.hostPort; if (fuzzyUrl) { @@ -314,16 +314,24 @@ function verifyRequestItemTarget(aReques if (type !== undefined) { let value = target.querySelector(".requests-menu-type").getAttribute("value"); let tooltip = target.querySelector(".requests-menu-type").getAttribute("tooltiptext"); info("Displayed type: " + value); info("Tooltip type: " + tooltip); 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"); info("Displayed size: " + value); info("Tooltip size: " + tooltip); is(value, size, "The displayed size is incorrect."); is(tooltip, size, "The tooltip size is incorrect."); }
--- a/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd @@ -37,18 +37,24 @@ <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.domain): This is the label displayed - in the network table toolbar, above the "domain" column. --> <!ENTITY netmonitorUI.toolbar.domain "Domain"> <!-- LOCALIZATION NOTE (netmonitorUI.toolbar.type): This is the label displayed - 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 - in the network table toolbar, above the "waterfall" column. --> <!ENTITY netmonitorUI.toolbar.waterfall "Timeline"> <!-- LOCALIZATION NOTE (debuggerUI.tab.headers): This is the label displayed - in the network details pane identifying the headers tab. -->
--- a/browser/locales/en-US/chrome/browser/devtools/netmonitor.properties +++ b/browser/locales/en-US/chrome/browser/devtools/netmonitor.properties @@ -124,16 +124,21 @@ networkMenu.empty=No requests # information about all requests. Parameters: #1 is the number of requests, # #2 is the size, #3 is the number of seconds. networkMenu.summary=One request, #2 KB, #3 s;#1 requests, #2 KB, #3 s # LOCALIZATION NOTE (networkMenu.sizeKB): This is the label displayed # 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 # LOCALIZATION NOTE (networkMenu.millisecond): This is the label displayed # in the network menu specifying timing interval divisions (in milliseconds). networkMenu.millisecond=%S ms
--- a/browser/themes/shared/devtools/netmonitor.inc.css +++ b/browser/themes/shared/devtools/netmonitor.inc.css @@ -161,16 +161,21 @@ width: 4em; } .requests-menu-size { text-align: center; width: 8em; } +.requests-menu-transferred { + text-align: center; + width: 8em; +} + /* Network requests table: status codes */ box.requests-menu-status { background: #fff; width: 10px; -moz-margin-start: 5px; -moz-margin-end: 5px; border-radius: 10px;
--- a/toolkit/devtools/server/actors/webconsole.js +++ b/toolkit/devtools/server/actors/webconsole.js @@ -78,16 +78,17 @@ function WebConsoleActor(aConnection, aP this._onObserverNotification = this._onObserverNotification.bind(this); if (this.parentActor.isRootActor) { Services.obs.addObserver(this._onObserverNotification, "last-pb-context-exited", false); } this.traits = { customNetworkRequest: !this._parentIsContentActor, + transferredResponseSize: true }; } WebConsoleActor.l10n = new WebConsoleUtils.l10n("chrome://global/locale/console.properties"); WebConsoleActor.prototype = { /** @@ -1935,16 +1936,17 @@ NetworkEventActor.prototype = } let packet = { from: this.actorID, type: "networkEventUpdate", updateType: "responseContent", mimeType: aContent.mimeType, contentSize: aContent.text.length, + transferredSize: aContent.transferredSize, discardResponseBody: aDiscardedResponseBody, }; this.conn.send(packet); }, /** * Add network event timing information.
--- a/toolkit/devtools/webconsole/network-monitor.js +++ b/toolkit/devtools/webconsole/network-monitor.js @@ -58,17 +58,19 @@ function NetworkResponseListener(aOwner, this.httpActivity = aHttpActivity; this.bodySize = 0; } 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 * to find the associated uncached headers. * @private */ _foundOpenResponse: false, @@ -89,21 +91,26 @@ NetworkResponseListener.prototype = { httpActivity: null, /** * Stores the received data as a string. */ 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. */ request: null, /** * Set the async listener for the given nsIAsyncInputStream. This allows us to * wait asynchronously for any data coming from the stream. * @@ -172,16 +179,28 @@ NetworkResponseListener.prototype = { * https://developer.mozilla.org/En/NsIRequestObserver */ onStopRequest: function NRL_onStopRequest() { this._findOpenResponse(); 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 * NetworkMonitor.openResponses. This method takes the data from the open * response object and puts it into the HTTP activity object, then sends it to * the remote Web Console instance. * * @private @@ -254,16 +273,17 @@ NetworkResponseListener.prototype = { _onComplete: function NRL__onComplete(aData) { let response = { mimeType: "", text: aData || "", }; response.size = response.text.length; + response.transferredSize = this.transferredSize; try { response.mimeType = this.request.contentType; } catch (ex) { } if (!response.mimeType || !NetworkHelper.isTextMimeType(response.mimeType)) { response.encoding = "base64"; @@ -274,16 +294,17 @@ NetworkResponseListener.prototype = { response.mimeType += "; charset=" + this.request.contentCharset; } this.receivedData = ""; this.httpActivity.owner. addResponseContent(response, this.httpActivity.discardResponseBody); + this.httpActivity.channel.notificationCallbacks = null; this.httpActivity.channel = null; this.httpActivity.owner = null; this.httpActivity = null; this.sink = null; this.inputStream = null; this.request = null; this.owner = null; }, @@ -775,16 +796,18 @@ NetworkMonitor.prototype = { newListener.sink = sink; let tee = Cc["@mozilla.org/network/stream-listener-tee;1"]. createInstance(Ci.nsIStreamListenerTee); let originalListener = channel.setNewListener(tee); tee.init(originalListener, sink.outputStream, newListener); + + channel.notificationCallbacks = newListener; }, /** * Handler for ACTIVITY_SUBTYPE_REQUEST_BODY_SENT. The request body is logged * here. * * @private * @param object aHttpActivity