зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
9b603aad32
|
@ -16,6 +16,9 @@ Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
|
|||
Cu.import("resource:///modules/devtools/VariablesView.jsm");
|
||||
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||
"resource://gre/modules/PluralForm.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "NetworkHelper",
|
||||
"resource://gre/modules/devtools/NetworkHelper.jsm");
|
||||
|
||||
|
|
|
@ -278,6 +278,8 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
dumpn("Initializing the RequestsMenuView");
|
||||
|
||||
this.node = new SideMenuWidget($("#requests-menu-contents"), false);
|
||||
this._summary = $("#request-menu-network-summary");
|
||||
|
||||
this.node.maintainSelectionVisible = false;
|
||||
this.node.autoscrollWithAppendedItems = true;
|
||||
|
||||
|
@ -351,6 +353,7 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
$("#details-pane-toggle").disabled = false;
|
||||
$("#requests-menu-empty-notice").hidden = true;
|
||||
|
||||
this.refreshSummary();
|
||||
this._cache.set(aId, requestItem);
|
||||
},
|
||||
|
||||
|
@ -404,6 +407,8 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
this.filterContents(this._onFlash);
|
||||
break;
|
||||
}
|
||||
|
||||
this.refreshSummary();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -572,6 +577,32 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
_bySize: function({ attachment: first }, { attachment: second })
|
||||
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("value", L10N.getStr("networkMenu.empty"));
|
||||
return;
|
||||
}
|
||||
|
||||
let totalBytes = this._getTotalBytesOfRequests(visibleItems);
|
||||
let totalMillis =
|
||||
this._getNewestRequest(visibleItems).attachment.endedMillis -
|
||||
this._getOldestRequest(visibleItems).attachment.startedMillis;
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Localization_and_Plurals
|
||||
let str = PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary"));
|
||||
this._summary.setAttribute("value", str
|
||||
.replace("#1", visibleRequestsCount)
|
||||
.replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, 2))
|
||||
.replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, 2))
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Schedules adding additional information to a network request.
|
||||
*
|
||||
|
@ -691,6 +722,7 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
// so this doesn't happen once per network event update).
|
||||
this.sortContents();
|
||||
this.filterContents();
|
||||
this.refreshSummary();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1116,6 +1148,50 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
return (aMimeType.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 aItemsArray
|
||||
* @return number
|
||||
*/
|
||||
_getTotalBytesOfRequests: function(aItemsArray) {
|
||||
if (!aItemsArray.length) {
|
||||
return 0;
|
||||
}
|
||||
return aItemsArray.reduce((prev, curr) => prev + curr.attachment.contentSize || 0, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the oldest (first performed) request in a set. Returns null for an
|
||||
* empty set.
|
||||
*
|
||||
* @param array aItemsArray
|
||||
* @return MenuItem
|
||||
*/
|
||||
_getOldestRequest: function(aItemsArray) {
|
||||
if (!aItemsArray.length) {
|
||||
return null;
|
||||
}
|
||||
return aItemsArray.reduce((prev, curr) =>
|
||||
prev.attachment.startedMillis < curr.attachment.startedMillis ? prev : curr);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the newest (latest performed) request in a set. Returns null for an
|
||||
* empty set.
|
||||
*
|
||||
* @param array aItemsArray
|
||||
* @return MenuItem
|
||||
*/
|
||||
_getNewestRequest: function(aItemsArray) {
|
||||
if (!aItemsArray.length) {
|
||||
return null;
|
||||
}
|
||||
return aItemsArray.reduce((prev, curr) =>
|
||||
prev.attachment.startedMillis > curr.attachment.startedMillis ? prev : curr);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the available waterfall width in this container.
|
||||
* @return number
|
||||
|
@ -1132,6 +1208,7 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
|||
},
|
||||
|
||||
_cache: null,
|
||||
_summary: null,
|
||||
_canvas: null,
|
||||
_ctx: null,
|
||||
_cachedWaterfallWidth: 0,
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
}
|
||||
|
||||
@media (min-width: 701px) and (max-width: 1024px) {
|
||||
#body:not([pane-collapsed]) #requests-menu-footer {
|
||||
#body:not([pane-collapsed]) .requests-menu-footer-button,
|
||||
#body:not([pane-collapsed]) .requests-menu-footer-spacer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,6 +178,10 @@
|
|||
<spacer id="requests-menu-spacer-end"
|
||||
class="requests-menu-footer-spacer"
|
||||
flex="100"/>
|
||||
<label id="request-menu-network-summary"
|
||||
class="plain requests-menu-footer-label"
|
||||
flex="1"
|
||||
crop="end"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_net_filter-03.js \
|
||||
browser_net_accessibility-01.js \
|
||||
browser_net_accessibility-02.js \
|
||||
browser_net_footer-summary.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the summary text displayed in the network requests menu footer
|
||||
* is correct.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
let { PluralForm } = Cu.import("resource://gre/modules/PluralForm.jsm", {});
|
||||
|
||||
initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { $, L10N, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
testStatus();
|
||||
|
||||
waitForNetworkEvents(aMonitor, 8).then(() => {
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
|
||||
testStatus();
|
||||
|
||||
info("Performing more requests.");
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
return waitForNetworkEvents(aMonitor, 8);
|
||||
})
|
||||
.then(() => {
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
|
||||
testStatus();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
|
||||
testStatus();
|
||||
|
||||
teardown(aMonitor).then(finish);
|
||||
})
|
||||
|
||||
function testStatus() {
|
||||
let summary = $("#request-menu-network-summary");
|
||||
let value = summary.getAttribute("value");
|
||||
info("Current summary: " + value);
|
||||
|
||||
let visibleItems = RequestsMenu.visibleItems;
|
||||
let visibleRequestsCount = visibleItems.length;
|
||||
let totalRequestsCount = RequestsMenu.itemCount;
|
||||
info("Current requests: " + visibleRequestsCount + " of " + totalRequestsCount + ".");
|
||||
|
||||
if (!totalRequestsCount) {
|
||||
is(value, "",
|
||||
"The current summary text is incorrect, expected an empty string.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!visibleRequestsCount) {
|
||||
is(value, L10N.getStr("networkMenu.empty"),
|
||||
"The current summary text is incorrect, expected an 'empty' label.");
|
||||
return;
|
||||
}
|
||||
|
||||
let totalBytes = RequestsMenu._getTotalBytesOfRequests(visibleItems);
|
||||
let totalMillis =
|
||||
RequestsMenu._getNewestRequest(visibleItems).attachment.endedMillis -
|
||||
RequestsMenu._getOldestRequest(visibleItems).attachment.startedMillis;
|
||||
|
||||
info("Computed total bytes: " + totalBytes);
|
||||
info("Computed total millis: " + totalMillis);
|
||||
|
||||
is(value, PluralForm.get(visibleRequestsCount, L10N.getStr("networkMenu.summary"))
|
||||
.replace("#1", visibleRequestsCount)
|
||||
.replace("#2", L10N.numberWithDecimals((totalBytes || 0) / 1024, 2))
|
||||
.replace("#3", L10N.numberWithDecimals((totalMillis || 0) / 1000, 2))
|
||||
, "The current summary text is incorrect.")
|
||||
}
|
||||
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
});
|
||||
}
|
|
@ -1215,6 +1215,12 @@ MenuContainer.prototype = {
|
|||
*/
|
||||
get itemCount() this._itemsByElement.size,
|
||||
|
||||
/**
|
||||
* Gets the total number of visible (non-hidden) items in this container.
|
||||
* @return number
|
||||
*/
|
||||
get visibleItemsCount() this.visibleItems.length,
|
||||
|
||||
/**
|
||||
* Returns a list of all items in this container, in the displayed order.
|
||||
* @return array
|
||||
|
|
|
@ -540,23 +540,21 @@ ViewHelpers.create({ constructor: BrowserConsole, proto: WebConsole.prototype },
|
|||
}
|
||||
|
||||
let window = this.iframeWindow;
|
||||
|
||||
// Make sure that the closing of the Browser Console window destroys this
|
||||
// instance.
|
||||
let onClose = () => {
|
||||
window.removeEventListener("unload", onClose);
|
||||
this.destroy();
|
||||
};
|
||||
window.addEventListener("unload", onClose);
|
||||
|
||||
this._bc_init = this.$init().then((aReason) => {
|
||||
this._telemetry.toolOpened("browserconsole");
|
||||
let title = this.ui.rootElement.getAttribute("browserConsoleTitle");
|
||||
this.ui.rootElement.setAttribute("title", title);
|
||||
// Make sure Ctrl-W closes the Browser Console window.
|
||||
window.document.getElementById("cmd_close").removeAttribute("disabled");
|
||||
|
||||
let cmd_close = this.ui.document.getElementById("cmd_close");
|
||||
cmd_close.removeAttribute("disabled");
|
||||
|
||||
return aReason;
|
||||
});
|
||||
this._telemetry.toolOpened("browserconsole");
|
||||
|
||||
this._bc_init = this.$init();
|
||||
return this._bc_init;
|
||||
},
|
||||
|
||||
|
@ -700,8 +698,13 @@ var HeadsUpDisplayUICommands = {
|
|||
|
||||
let win = Services.ww.openWindow(null, devtools.Tools.webConsole.url, "_blank",
|
||||
BROWSER_CONSOLE_WINDOW_FEATURES, null);
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad);
|
||||
win.addEventListener("DOMContentLoaded", function onLoad() {
|
||||
win.removeEventListener("DOMContentLoaded", onLoad);
|
||||
|
||||
// Set the correct Browser Console title.
|
||||
let root = win.document.documentElement;
|
||||
root.setAttribute("title", root.getAttribute("browserConsoleTitle"));
|
||||
|
||||
deferred.resolve(win);
|
||||
});
|
||||
|
||||
|
|
|
@ -105,6 +105,14 @@ networkMenu.sortedAsc=Sorted ascending
|
|||
# in the network table toolbar, for any column that is sorted descending.
|
||||
networkMenu.sortedDesc=Sorted descending
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.empty): This is the label displayed
|
||||
# in the network table footer when there are no requests available.
|
||||
networkMenu.empty=No requests
|
||||
|
||||
# LOCALIZATION NOTE (networkMenu.summary): This is the label displayed
|
||||
# in the network table footer providing concise information about all requests.
|
||||
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
|
||||
|
|
|
@ -378,6 +378,10 @@ box.requests-menu-status[code^="5"] {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer {
|
||||
min-width: 2px;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
|
|
|
@ -378,6 +378,10 @@ box.requests-menu-status[code^="5"] {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer {
|
||||
min-width: 2px;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
|
|
|
@ -378,6 +378,10 @@ box.requests-menu-status[code^="5"] {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer {
|
||||
min-width: 2px;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
|
|
|
@ -600,7 +600,9 @@ class RunProgram(MachCommandBase):
|
|||
help='Command-line arguments to pass to the program.')
|
||||
@CommandArgument('+remote', '+r', action='store_true',
|
||||
help='Do not pass the -no-remote argument by default.')
|
||||
def run(self, params, remote):
|
||||
@CommandArgument('+background', '+b', action='store_true',
|
||||
help='Do not pass the -foreground argument by default on Mac')
|
||||
def run(self, params, remote, background):
|
||||
try:
|
||||
args = [self.get_binary_path('app')]
|
||||
except Exception as e:
|
||||
|
@ -610,6 +612,8 @@ class RunProgram(MachCommandBase):
|
|||
return 1
|
||||
if not remote:
|
||||
args.append('-no-remote')
|
||||
if not background and sys.platform == 'darwin':
|
||||
args.append('-foreground')
|
||||
if params:
|
||||
args.extend(params)
|
||||
return self.run_process(args=args, ensure_exit_code=False,
|
||||
|
@ -625,7 +629,9 @@ class DebugProgram(MachCommandBase):
|
|||
help='Command-line arguments to pass to the program.')
|
||||
@CommandArgument('+remote', '+r', action='store_true',
|
||||
help='Do not pass the -no-remote argument by default')
|
||||
def debug(self, params, remote):
|
||||
@CommandArgument('+background', '+b', action='store_true',
|
||||
help='Do not pass the -foreground argument by default on Mac')
|
||||
def debug(self, params, remote, background):
|
||||
import which
|
||||
try:
|
||||
debugger = which.which('gdb')
|
||||
|
@ -642,6 +648,8 @@ class DebugProgram(MachCommandBase):
|
|||
return 1
|
||||
if not remote:
|
||||
args.append('-no-remote')
|
||||
if not background and sys.platform == 'darwin':
|
||||
args.append('-foreground')
|
||||
if params:
|
||||
args.extend(params)
|
||||
return self.run_process(args=args, ensure_exit_code=False,
|
||||
|
|
Загрузка…
Ссылка в новой задаче