mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 859046 - Implement filtering out certain types of requests, r=rcampbell
* * * Bug 873761 - Several "XUL box for hbox element contained an inline #text child, forcing all its children to be wrapped in a block." warnings for netmonitor.xul, r=rcampbell
This commit is contained in:
parent
d025dfdef0
commit
1bcfae93c8
@ -243,13 +243,23 @@ TargetEventsHandler.prototype = {
|
||||
* Packet received from the server.
|
||||
*/
|
||||
_onTabNavigated: function(aType, aPacket) {
|
||||
if (aType == "will-navigate") {
|
||||
NetMonitorView.RequestsMenu.reset();
|
||||
NetMonitorView.NetworkDetails.reset();
|
||||
window.emit("NetMonitor:TargetWillNavigate");
|
||||
}
|
||||
if (aType == "navigate") {
|
||||
window.emit("NetMonitor:TargetNavigate");
|
||||
switch (aType) {
|
||||
case "will-navigate": {
|
||||
// Reset UI.
|
||||
NetMonitorView.RequestsMenu.reset();
|
||||
NetMonitorView.NetworkDetails.reset();
|
||||
|
||||
// Reset global helpers cache.
|
||||
nsIURL.store.clear();
|
||||
drain.store.clear();
|
||||
|
||||
window.emit("NetMonitor:TargetWillNavigate");
|
||||
break;
|
||||
}
|
||||
case "navigate": {
|
||||
window.emit("NetMonitor:TargetNavigate");
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -310,8 +320,8 @@ NetworkEventsHandler.prototype = {
|
||||
* The message received from the server.
|
||||
*/
|
||||
_onNetworkEvent: function(aType, aPacket) {
|
||||
let { actor, startedDateTime, method, url } = aPacket.eventActor;
|
||||
NetMonitorView.RequestsMenu.addRequest(actor, startedDateTime, method, url);
|
||||
let { actor, startedDateTime, method, url, isXHR } = aPacket.eventActor;
|
||||
NetMonitorView.RequestsMenu.addRequest(actor, startedDateTime, method, url, isXHR);
|
||||
|
||||
window.emit("NetMonitor:NetworkEvent");
|
||||
},
|
||||
|
@ -103,6 +103,7 @@ let NetMonitorView = {
|
||||
_initializePanes: function() {
|
||||
dumpn("Initializing the NetMonitorView panes");
|
||||
|
||||
this._body = $("#body");
|
||||
this._detailsPane = $("#details-pane");
|
||||
this._detailsPaneToggleButton = $("#details-pane-toggle");
|
||||
|
||||
@ -153,9 +154,11 @@ let NetMonitorView = {
|
||||
ViewHelpers.togglePane(aFlags, pane);
|
||||
|
||||
if (aFlags.visible) {
|
||||
this._body.removeAttribute("pane-collapsed");
|
||||
button.removeAttribute("pane-collapsed");
|
||||
button.setAttribute("tooltiptext", this._collapsePaneString);
|
||||
} else {
|
||||
this._body.setAttribute("pane-collapsed", "");
|
||||
button.setAttribute("pane-collapsed", "");
|
||||
button.setAttribute("tooltiptext", this._expandPaneString);
|
||||
}
|
||||
@ -190,9 +193,12 @@ let NetMonitorView = {
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_editorPromises: new Map(),
|
||||
_body: null,
|
||||
_detailsPane: null,
|
||||
_detailsPaneToggleButton: null,
|
||||
_collapsePaneString: "",
|
||||
_expandPaneString: "",
|
||||
_editorPromises: new Map(),
|
||||
_isInitialized: false,
|
||||
_isDestroyed: false
|
||||
};
|
||||
@ -259,6 +265,9 @@ function RequestsMenuView() {
|
||||
this._onMouseDown = this._onMouseDown.bind(this);
|
||||
this._onSelect = this._onSelect.bind(this);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this._byFile = this._byFile.bind(this);
|
||||
this._byDomain = this._byDomain.bind(this);
|
||||
this._byType = this._byType.bind(this);
|
||||
}
|
||||
|
||||
create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
@ -314,8 +323,10 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
* Specifies the request method (e.g. "GET", "POST", etc.)
|
||||
* @param string aUrl
|
||||
* Specifies the request's url.
|
||||
* @param boolean aIsXHR
|
||||
* True if this request was initiated via XHR.
|
||||
*/
|
||||
addRequest: function(aId, aStartedDateTime, aMethod, aUrl) {
|
||||
addRequest: function(aId, aStartedDateTime, aMethod, aUrl, aIsXHR) {
|
||||
// Convert the received date/time string to a unix timestamp.
|
||||
let unixTime = Date.parse(aStartedDateTime);
|
||||
|
||||
@ -333,22 +344,75 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
startedDeltaMillis: unixTime - this._firstRequestStartedMillis,
|
||||
startedMillis: unixTime,
|
||||
method: aMethod,
|
||||
url: aUrl
|
||||
url: aUrl,
|
||||
isXHR: aIsXHR
|
||||
},
|
||||
finalize: this._onRequestItemRemoved
|
||||
});
|
||||
|
||||
$("#details-pane-toggle").disabled = false;
|
||||
$(".requests-menu-empty-notice").hidden = true;
|
||||
$("#requests-menu-empty-notice").hidden = true;
|
||||
|
||||
this._cache.set(aId, requestItem);
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters all network requests in this container by a specified type.
|
||||
*
|
||||
* @param string aType
|
||||
* Either null, "html", "css", "js", "xhr", "fonts", "images", "media"
|
||||
* or "flash".
|
||||
*/
|
||||
filterOn: function(aType) {
|
||||
let target = $("#requests-menu-filter-" + aType + "-button");
|
||||
let buttons = document.querySelectorAll(".requests-menu-footer-button");
|
||||
|
||||
for (let button of buttons) {
|
||||
if (button != target) {
|
||||
button.removeAttribute("checked");
|
||||
} else {
|
||||
button.setAttribute("checked", "");
|
||||
}
|
||||
}
|
||||
|
||||
// Filter on nothing.
|
||||
if (!target) {
|
||||
this.filterContents(() => true);
|
||||
}
|
||||
// Filter on whatever was requested.
|
||||
else switch (aType) {
|
||||
case "html":
|
||||
this.filterContents(this._onHtml);
|
||||
break;
|
||||
case "css":
|
||||
this.filterContents(this._onCss);
|
||||
break;
|
||||
case "js":
|
||||
this.filterContents(this._onJs);
|
||||
break;
|
||||
case "xhr":
|
||||
this.filterContents(this._onXhr);
|
||||
break;
|
||||
case "fonts":
|
||||
this.filterContents(this._onFonts);
|
||||
break;
|
||||
case "images":
|
||||
this.filterContents(this._onImages);
|
||||
break;
|
||||
case "media":
|
||||
this.filterContents(this._onMedia);
|
||||
break;
|
||||
case "flash":
|
||||
this.filterContents(this._onFlash);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sorts all network requests in this container by a specified detail.
|
||||
*
|
||||
* @param string aType
|
||||
* Either "status", "method", "file", "domain", "type" or "size".
|
||||
* Either null, "status", "method", "file", "domain", "type" or "size".
|
||||
*/
|
||||
sortBy: function(aType) {
|
||||
let target = $("#requests-menu-" + aType + "-button");
|
||||
@ -426,6 +490,54 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Predicates used when filtering items.
|
||||
*
|
||||
* @param MenuItem aItem
|
||||
* The filtered menu item.
|
||||
* @return boolean
|
||||
* True if the menu item should be visible, false otherwise.
|
||||
*/
|
||||
_onHtml: function({ attachment: { mimeType } })
|
||||
mimeType && mimeType.contains("/html"),
|
||||
|
||||
_onCss: function({ attachment: { mimeType } })
|
||||
mimeType && mimeType.contains("/css"),
|
||||
|
||||
_onJs: function({ attachment: { mimeType } })
|
||||
mimeType && (
|
||||
mimeType.contains("/ecmascript") ||
|
||||
mimeType.contains("/javascript") ||
|
||||
mimeType.contains("/x-javascript")),
|
||||
|
||||
_onXhr: function({ attachment: { isXHR } })
|
||||
isXHR,
|
||||
|
||||
_onFonts: function({ attachment: { url, mimeType } }) // Fonts are a mess.
|
||||
(mimeType && (
|
||||
mimeType.contains("font/") ||
|
||||
mimeType.contains("/font"))) ||
|
||||
url.contains(".eot") ||
|
||||
url.contains(".ttf") ||
|
||||
url.contains(".otf") ||
|
||||
url.contains(".woff"),
|
||||
|
||||
_onImages: function({ attachment: { mimeType } })
|
||||
mimeType && mimeType.contains("image/"),
|
||||
|
||||
_onMedia: function({ attachment: { mimeType } }) // Not including images.
|
||||
mimeType && (
|
||||
mimeType.contains("audio/") ||
|
||||
mimeType.contains("video/") ||
|
||||
mimeType.contains("model/")),
|
||||
|
||||
_onFlash: function({ attachment: { url, mimeType } }) // Flash is a mess.
|
||||
(mimeType && (
|
||||
mimeType.contains("/x-flv") ||
|
||||
mimeType.contains("/x-shockwave-flash"))) ||
|
||||
url.contains(".swf") ||
|
||||
url.contains(".flv"),
|
||||
|
||||
/**
|
||||
* Predicates used when sorting items.
|
||||
*
|
||||
@ -438,32 +550,29 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
* 0 to leave aFirst and aSecond unchanged with respect to each other
|
||||
* 1 to sort aSecond to a lower index than aFirst
|
||||
*/
|
||||
_byTiming: (aFirst, aSecond) =>
|
||||
aFirst.attachment.startedMillis > aSecond.attachment.startedMillis,
|
||||
_byTiming: function({ attachment: first }, { attachment: second })
|
||||
first.startedMillis > second.startedMillis,
|
||||
|
||||
_byStatus: (aFirst, aSecond) =>
|
||||
aFirst.attachment.status > aSecond.attachment.status,
|
||||
_byStatus: function({ attachment: first }, { attachment: second })
|
||||
first.status > second.status,
|
||||
|
||||
_byMethod: (aFirst, aSecond) =>
|
||||
aFirst.attachment.method > aSecond.attachment.method,
|
||||
_byMethod: function({ attachment: first }, { attachment: second })
|
||||
first.method > second.method,
|
||||
|
||||
_byFile: (aFirst, aSecond) =>
|
||||
!aFirst.target || !aSecond.target ? -1 :
|
||||
$(".requests-menu-file", aFirst.target).getAttribute("value").toLowerCase() >
|
||||
$(".requests-menu-file", aSecond.target).getAttribute("value").toLowerCase(),
|
||||
_byFile: function({ attachment: first }, { attachment: second })
|
||||
this._getUriNameWithQuery(first.url).toLowerCase() >
|
||||
this._getUriNameWithQuery(second.url).toLowerCase(),
|
||||
|
||||
_byDomain: (aFirst, aSecond) =>
|
||||
!aFirst.target || !aSecond.target ? -1 :
|
||||
$(".requests-menu-domain", aFirst.target).getAttribute("value").toLowerCase() >
|
||||
$(".requests-menu-domain", aSecond.target).getAttribute("value").toLowerCase(),
|
||||
_byDomain: function({ attachment: first }, { attachment: second })
|
||||
this._getUriHostPort(first.url).toLowerCase() >
|
||||
this._getUriHostPort(second.url).toLowerCase(),
|
||||
|
||||
_byType: (aFirst, aSecond) =>
|
||||
!aFirst.target || !aSecond.target ? -1 :
|
||||
$(".requests-menu-type", aFirst.target).getAttribute("value").toLowerCase() >
|
||||
$(".requests-menu-type", aSecond.target).getAttribute("value").toLowerCase(),
|
||||
_byType: function({ attachment: first }, { attachment: second })
|
||||
this._getAbbreviatedMimeType(first.mimeType).toLowerCase() >
|
||||
this._getAbbreviatedMimeType(second.mimeType).toLowerCase(),
|
||||
|
||||
_bySize: (aFirst, aSecond) =>
|
||||
aFirst.attachment.contentSize > aSecond.attachment.contentSize,
|
||||
_bySize: function({ attachment: first }, { attachment: second })
|
||||
first.contentSize > second.contentSize,
|
||||
|
||||
/**
|
||||
* Schedules adding additional information to a network request.
|
||||
@ -577,8 +686,13 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
// We're done flushing all the requests, clear the update queue.
|
||||
this._updateQueue = [];
|
||||
|
||||
// Make sure all the requests are sorted.
|
||||
// Make sure all the requests are sorted and filtered.
|
||||
// Freshly added requests may not yet contain all the information required
|
||||
// for sorting and filtering predicates, so this is done each time the
|
||||
// network requests table is flushed (don't worry, events are drained first
|
||||
// so this doesn't happen once per network event update).
|
||||
this.sortContents();
|
||||
this.filterContents();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -592,19 +706,19 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
* The network request view.
|
||||
*/
|
||||
_createMenuView: function(aMethod, aUrl) {
|
||||
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
|
||||
let name = NetworkHelper.convertToUnicode(unescape(uri.fileName)) || "/";
|
||||
let query = NetworkHelper.convertToUnicode(unescape(uri.query));
|
||||
let hostPort = NetworkHelper.convertToUnicode(unescape(uri.hostPort));
|
||||
let uri = nsIURL(aUrl);
|
||||
let nameWithQuery = this._getUriNameWithQuery(uri);
|
||||
let hostPort = this._getUriHostPort(uri);
|
||||
|
||||
let template = $("#requests-menu-item-template");
|
||||
let fragment = document.createDocumentFragment();
|
||||
|
||||
$(".requests-menu-method", template).setAttribute("value", aMethod);
|
||||
let method = $(".requests-menu-method", template);
|
||||
method.setAttribute("value", aMethod);
|
||||
|
||||
let file = $(".requests-menu-file", template);
|
||||
file.setAttribute("value", name + (query ? "?" + query : ""));
|
||||
file.setAttribute("tooltiptext", name + (query ? "?" + query : ""));
|
||||
file.setAttribute("value", nameWithQuery);
|
||||
file.setAttribute("tooltiptext", nameWithQuery);
|
||||
|
||||
let domain = $(".requests-menu-domain", template);
|
||||
domain.setAttribute("value", hostPort);
|
||||
@ -653,7 +767,7 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
break;
|
||||
}
|
||||
case "mimeType": {
|
||||
let type = aValue.split(";")[0].split("/")[1] || "?";
|
||||
let type = this._getAbbreviatedMimeType(aValue);
|
||||
let node = $(".requests-menu-type", aItem.target);
|
||||
let text = CONTENT_MIME_TYPE_ABBREVIATIONS[type] || type;
|
||||
node.setAttribute("value", text);
|
||||
@ -981,6 +1095,40 @@ create({ constructor: RequestsMenuView, proto: MenuContainer.prototype }, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Helpers for getting details about an nsIURL.
|
||||
*
|
||||
* @param nsIURL | string aUrl
|
||||
* @return string
|
||||
*/
|
||||
_getUriNameWithQuery: function(aUrl) {
|
||||
if (!(aUrl instanceof Ci.nsIURL)) {
|
||||
aUrl = nsIURL(aUrl);
|
||||
}
|
||||
let name = NetworkHelper.convertToUnicode(unescape(aUrl.fileName)) || "/";
|
||||
let query = NetworkHelper.convertToUnicode(unescape(aUrl.query));
|
||||
return name + (query ? "?" + query : "");
|
||||
},
|
||||
_getUriHostPort: function(aUrl) {
|
||||
if (!(aUrl instanceof Ci.nsIURL)) {
|
||||
aUrl = nsIURL(aUrl);
|
||||
}
|
||||
return NetworkHelper.convertToUnicode(unescape(aUrl.hostPort));
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for getting an abbreviated string for a mime type.
|
||||
*
|
||||
* @param string aMimeType
|
||||
* @return string
|
||||
*/
|
||||
_getAbbreviatedMimeType: function(aMimeType) {
|
||||
if (!aMimeType) {
|
||||
return "";
|
||||
}
|
||||
return (aMimeType.split(";")[0].split("/")[1] || "").split("+")[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the available waterfall width in this container.
|
||||
* @return number
|
||||
@ -1296,8 +1444,7 @@ create({ constructor: NetworkDetailsView, proto: MenuContainer.prototype }, {
|
||||
* The request's url.
|
||||
*/
|
||||
_setRequestGetParams: function(aUrl) {
|
||||
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
|
||||
let query = uri.query;
|
||||
let query = nsIURL(aUrl).query;
|
||||
if (query) {
|
||||
this._addParams(this._paramsQueryString, query);
|
||||
}
|
||||
@ -1379,7 +1526,6 @@ create({ constructor: NetworkDetailsView, proto: MenuContainer.prototype }, {
|
||||
if (!aResponse) {
|
||||
return;
|
||||
}
|
||||
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
|
||||
let { mimeType, text, encoding } = aResponse.content;
|
||||
|
||||
gNetwork.getString(text).then((aString) => {
|
||||
@ -1408,7 +1554,7 @@ create({ constructor: NetworkDetailsView, proto: MenuContainer.prototype }, {
|
||||
|
||||
// Immediately display additional information about the image:
|
||||
// file name, mime type and encoding.
|
||||
$("#response-content-image-name-value").setAttribute("value", uri.fileName);
|
||||
$("#response-content-image-name-value").setAttribute("value", nsIURL(aUrl).fileName);
|
||||
$("#response-content-image-mime-value").setAttribute("value", mimeType);
|
||||
$("#response-content-image-encoding-value").setAttribute("value", encoding);
|
||||
|
||||
@ -1530,15 +1676,27 @@ create({ constructor: NetworkDetailsView, proto: MenuContainer.prototype }, {
|
||||
*/
|
||||
function $(aSelector, aTarget = document) aTarget.querySelector(aSelector);
|
||||
|
||||
/**
|
||||
* Helper for getting an nsIURL instance out of a string.
|
||||
*/
|
||||
function nsIURL(aUrl, aStore = nsIURL.store) {
|
||||
if (aStore.has(aUrl)) {
|
||||
return aStore.get(aUrl);
|
||||
}
|
||||
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
|
||||
aStore.set(aUrl, uri);
|
||||
return uri;
|
||||
}
|
||||
nsIURL.store = new Map();
|
||||
|
||||
/**
|
||||
* Helper for draining a rapid succession of events and invoking a callback
|
||||
* once everything settles down.
|
||||
*/
|
||||
function drain(aId, aWait, aCallback) {
|
||||
window.clearTimeout(drain.store.get(aId));
|
||||
drain.store.set(aId, window.setTimeout(aCallback, aWait));
|
||||
function drain(aId, aWait, aCallback, aStore = drain.store) {
|
||||
window.clearTimeout(aStore.get(aId));
|
||||
aStore.set(aId, window.setTimeout(aCallback, aWait));
|
||||
}
|
||||
|
||||
drain.store = new Map();
|
||||
|
||||
/**
|
||||
|
@ -20,12 +20,23 @@
|
||||
#toolbar-spacer,
|
||||
#details-pane-toggle,
|
||||
#details-pane[pane-collapsed],
|
||||
.requests-menu-waterfall {
|
||||
.requests-menu-waterfall,
|
||||
.requests-menu-footer-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 701px) and (max-width: 1024px) {
|
||||
#body:not([pane-collapsed]) #requests-menu-footer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 701px) {
|
||||
#requests-menu-spacer-start {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#network-table[waterfall-overflows] .requests-menu-waterfall {
|
||||
display: none;
|
||||
}
|
||||
|
@ -17,7 +17,9 @@
|
||||
<script type="text/javascript" src="netmonitor-controller.js"/>
|
||||
<script type="text/javascript" src="netmonitor-view.js"/>
|
||||
|
||||
<box id="body" flex="1" class="devtools-responsive-container">
|
||||
<box id="body"
|
||||
class="devtools-responsive-container"
|
||||
flex="1">
|
||||
<vbox id="network-table" flex="1">
|
||||
<toolbar id="requests-menu-toolbar"
|
||||
class="devtools-toolbar"
|
||||
@ -28,14 +30,14 @@
|
||||
align="center">
|
||||
<button id="requests-menu-status-button"
|
||||
class="requests-menu-header-button requests-menu-status"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('status')">
|
||||
&netmonitorUI.toolbar.status;
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('status')"
|
||||
label="&netmonitorUI.toolbar.status;">
|
||||
</button>
|
||||
<button id="requests-menu-method-button"
|
||||
class="requests-menu-header-button requests-menu-method"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('method')"
|
||||
label="&netmonitorUI.toolbar.method;"
|
||||
flex="1">
|
||||
&netmonitorUI.toolbar.method;
|
||||
</button>
|
||||
</hbox>
|
||||
<hbox id="requests-menu-file-header-box"
|
||||
@ -44,8 +46,8 @@
|
||||
<button id="requests-menu-file-button"
|
||||
class="requests-menu-header-button requests-menu-file"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('file')"
|
||||
label="&netmonitorUI.toolbar.file;"
|
||||
flex="1">
|
||||
&netmonitorUI.toolbar.file;
|
||||
</button>
|
||||
</hbox>
|
||||
<hbox id="requests-menu-domain-header-box"
|
||||
@ -54,8 +56,8 @@
|
||||
<button id="requests-menu-domain-button"
|
||||
class="requests-menu-header-button requests-menu-domain"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('domain')"
|
||||
label="&netmonitorUI.toolbar.domain;"
|
||||
flex="1">
|
||||
&netmonitorUI.toolbar.domain;
|
||||
</button>
|
||||
</hbox>
|
||||
<hbox id="requests-menu-type-header-box"
|
||||
@ -64,8 +66,8 @@
|
||||
<button id="requests-menu-type-button"
|
||||
class="requests-menu-header-button requests-menu-type"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('type')"
|
||||
label="&netmonitorUI.toolbar.type;"
|
||||
flex="1">
|
||||
&netmonitorUI.toolbar.type;
|
||||
</button>
|
||||
</hbox>
|
||||
<hbox id="requests-menu-size-header-box"
|
||||
@ -74,8 +76,8 @@
|
||||
<button id="requests-menu-size-button"
|
||||
class="requests-menu-header-button requests-menu-size"
|
||||
onclick="NetMonitorView.RequestsMenu.sortBy('size')"
|
||||
label="&netmonitorUI.toolbar.size;"
|
||||
flex="1">
|
||||
&netmonitorUI.toolbar.size;
|
||||
</button>
|
||||
</hbox>
|
||||
<hbox id="requests-menu-waterfall-header-box"
|
||||
@ -93,7 +95,7 @@
|
||||
disabled="true"
|
||||
tabindex="0"/>
|
||||
</toolbar>
|
||||
<label class="plain requests-menu-empty-notice"
|
||||
<label id="requests-menu-empty-notice"
|
||||
value="&netmonitorUI.emptyNotice;"/>
|
||||
<vbox id="requests-menu-contents" flex="1">
|
||||
<hbox id="requests-menu-item-template" hidden="true">
|
||||
@ -124,11 +126,66 @@
|
||||
</hbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<hbox id="requests-menu-footer">
|
||||
<spacer id="requests-menu-spacer-start"
|
||||
class="requests-menu-footer-spacer"
|
||||
flex="100"/>
|
||||
<button id="requests-menu-filter-all-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn(null)"
|
||||
label="&netmonitorUI.footer.filterAll;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-html-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('html')"
|
||||
label="&netmonitorUI.footer.filterHTML;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-css-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('css')"
|
||||
label="&netmonitorUI.footer.filterCSS;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-js-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('js')"
|
||||
label="&netmonitorUI.footer.filterJS;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-xhr-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('xhr')"
|
||||
label="&netmonitorUI.footer.filterXHR;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-fonts-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('fonts')"
|
||||
label="&netmonitorUI.footer.filterFonts;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-images-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('images')"
|
||||
label="&netmonitorUI.footer.filterImages;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-media-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('media')"
|
||||
label="&netmonitorUI.footer.filterMedia;">
|
||||
</button>
|
||||
<button id="requests-menu-filter-flash-button"
|
||||
class="requests-menu-footer-button"
|
||||
onclick="NetMonitorView.RequestsMenu.filterOn('flash')"
|
||||
label="&netmonitorUI.footer.filterFlash;">
|
||||
</button>
|
||||
<spacer id="requests-menu-spacer-end"
|
||||
class="requests-menu-footer-spacer"
|
||||
flex="100"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
|
||||
<tabbox id="details-pane" class="devtools-sidebar-tabs" hidden="true">
|
||||
<tabbox id="details-pane"
|
||||
class="devtools-sidebar-tabs"
|
||||
hidden="true">
|
||||
<tabs>
|
||||
<tab label="&netmonitorUI.tab.headers;"/>
|
||||
<tab label="&netmonitorUI.tab.cookies;"/>
|
||||
@ -166,7 +223,7 @@
|
||||
<label class="plain tabpanel-summary-label"
|
||||
value="&netmonitorUI.summary.status;"/>
|
||||
<box id="headers-summary-status-circle"
|
||||
class="requests-menu-status"/>
|
||||
class="requests-menu-status"/>
|
||||
<label id="headers-summary-status-value"
|
||||
class="plain tabpanel-summary-value"
|
||||
crop="end"
|
||||
|
@ -33,6 +33,9 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_net_sort-01.js \
|
||||
browser_net_sort-02.js \
|
||||
browser_net_sort-03.js \
|
||||
browser_net_filter-01.js \
|
||||
browser_net_filter-02.js \
|
||||
browser_net_filter-03.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
@ -47,6 +50,7 @@ MOCHITEST_BROWSER_PAGES = \
|
||||
html_jsonp-test-page.html \
|
||||
html_json-long-test-page.html \
|
||||
html_sorting-test-page.html \
|
||||
html_filter-test-page.html \
|
||||
html_infinite-get-page.html \
|
||||
sjs_simple-test-server.sjs \
|
||||
sjs_content-type-test-server.sjs \
|
||||
|
184
browser/devtools/netmonitor/test/browser_net_filter-01.js
Normal file
184
browser/devtools/netmonitor/test/browser_net_filter-01.js
Normal file
@ -0,0 +1,184 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if filtering items in the network table works correctly.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { $, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 8).then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
|
||||
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should be a selected item in the requests menu.");
|
||||
is(RequestsMenu.selectedIndex, 0,
|
||||
"The first item should be selected in the requests menu.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should not be hidden after toggle button was pressed.");
|
||||
|
||||
testButtons();
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1])
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
|
||||
testButtons("html");
|
||||
return testContents([1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-css-button"));
|
||||
testButtons("css");
|
||||
return testContents([0, 1, 0, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-js-button"));
|
||||
testButtons("js");
|
||||
return testContents([0, 0, 1, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-xhr-button"));
|
||||
testButtons("xhr");
|
||||
return testContents([1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-fonts-button"));
|
||||
testButtons("fonts");
|
||||
return testContents([0, 0, 0, 1, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-images-button"));
|
||||
testButtons("images");
|
||||
return testContents([0, 0, 0, 0, 1, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-media-button"));
|
||||
testButtons("media");
|
||||
return testContents([0, 0, 0, 0, 0, 1, 1, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-flash-button"));
|
||||
testButtons("flash");
|
||||
return testContents([0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
})
|
||||
.then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-all-button"));
|
||||
testButtons();
|
||||
return testContents([1, 1, 1, 1, 1, 1, 1, 1]);
|
||||
})
|
||||
.then(() => {
|
||||
return teardown(aMonitor);
|
||||
})
|
||||
.then(finish);
|
||||
});
|
||||
|
||||
function testButtons(aFilterType) {
|
||||
let doc = aMonitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-filter-" + aFilterType + "-button");
|
||||
let buttons = doc.querySelectorAll(".requests-menu-footer-button");
|
||||
|
||||
for (let button of buttons) {
|
||||
if (button != target) {
|
||||
is(button.hasAttribute("checked"), false,
|
||||
"The " + button.id + " button should not have a 'checked' attribute.");
|
||||
} else {
|
||||
is(button.hasAttribute("checked"), true,
|
||||
"The " + button.id + " button should have a 'checked' attribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testContents(aVisibility) {
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should still be a selected item after filtering.");
|
||||
is(RequestsMenu.selectedIndex, 0,
|
||||
"The first item should be still selected after filtering.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should still be visible after filtering.");
|
||||
|
||||
is(RequestsMenu.allItems.length, aVisibility.length,
|
||||
"There should be a specific amount of items in the requests menu.");
|
||||
is(RequestsMenu.visibleItems.length, aVisibility.filter(e => e).length,
|
||||
"There should be a specific amount of visbile items in the requests menu.");
|
||||
|
||||
for (let i = 0; i < aVisibility.length; i++) {
|
||||
is(RequestsMenu.getItemAtIndex(i).target.hidden, !aVisibility[i],
|
||||
"The item at index " + i + " doesn't have the correct hidden state.");
|
||||
}
|
||||
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=html", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "html",
|
||||
fullMimeType: "text/html; charset=utf-8"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(1),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=css", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "css",
|
||||
fullMimeType: "text/css; charset=utf-8"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(2),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=js", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "js",
|
||||
fullMimeType: "application/javascript; charset=utf-8"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(3),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=font", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "woff",
|
||||
fullMimeType: "font/woff"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(4),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=image", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "png",
|
||||
fullMimeType: "image/png"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(5),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=audio", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "ogg",
|
||||
fullMimeType: "audio/ogg"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(6),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=video", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "webm",
|
||||
fullMimeType: "video/webm"
|
||||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(7),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=flash", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "x-shockwave-flash",
|
||||
fullMimeType: "application/x-shockwave-flash"
|
||||
});
|
||||
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
});
|
||||
}
|
181
browser/devtools/netmonitor/test/browser_net_filter-02.js
Normal file
181
browser/devtools/netmonitor/test/browser_net_filter-02.js
Normal file
@ -0,0 +1,181 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if filtering items in the network table works correctly with new requests.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { $, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 8).then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
|
||||
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should be a selected item in the requests menu.");
|
||||
is(RequestsMenu.selectedIndex, 0,
|
||||
"The first item should be selected in the requests menu.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should not be hidden after toggle button was pressed.");
|
||||
|
||||
testButtons();
|
||||
testContents([1, 1, 1, 1, 1, 1, 1, 1])
|
||||
.then(() => {
|
||||
info("Testing html filtering.");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
|
||||
testButtons("html");
|
||||
return testContents([1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
info("Performing more requests.");
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
return waitForNetworkEvents(aMonitor, 8);
|
||||
})
|
||||
.then(() => {
|
||||
info("Testing html filtering again.");
|
||||
testButtons("html");
|
||||
return testContents([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
info("Performing more requests.");
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
return waitForNetworkEvents(aMonitor, 8);
|
||||
})
|
||||
.then(() => {
|
||||
info("Testing html filtering again.");
|
||||
testButtons("html");
|
||||
return testContents([1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
|
||||
})
|
||||
.then(() => {
|
||||
return teardown(aMonitor);
|
||||
})
|
||||
.then(finish);
|
||||
});
|
||||
|
||||
function testButtons(aFilterType) {
|
||||
let doc = aMonitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-filter-" + aFilterType + "-button");
|
||||
let buttons = doc.querySelectorAll(".requests-menu-footer-button");
|
||||
|
||||
for (let button of buttons) {
|
||||
if (button != target) {
|
||||
is(button.hasAttribute("checked"), false,
|
||||
"The " + button.id + " button should not have a 'checked' attribute.");
|
||||
} else {
|
||||
is(button.hasAttribute("checked"), true,
|
||||
"The " + button.id + " button should have a 'checked' attribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testContents(aVisibility) {
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should still be a selected item after filtering.");
|
||||
is(RequestsMenu.selectedIndex, 0,
|
||||
"The first item should be still selected after filtering.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should still be visible after filtering.");
|
||||
|
||||
is(RequestsMenu.allItems.length, aVisibility.length,
|
||||
"There should be a specific amount of items in the requests menu.");
|
||||
is(RequestsMenu.visibleItems.length, aVisibility.filter(e => e).length,
|
||||
"There should be a specific amount of visbile items in the requests menu.");
|
||||
|
||||
for (let i = 0; i < aVisibility.length; i++) {
|
||||
is(RequestsMenu.getItemAtIndex(i).target.hidden, !aVisibility[i],
|
||||
"The item at index " + i + " doesn't have the correct hidden state.");
|
||||
}
|
||||
|
||||
for (let i = 0; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=html", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "html",
|
||||
fullMimeType: "text/html; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 1; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=css", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "css",
|
||||
fullMimeType: "text/css; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 2; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=js", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "js",
|
||||
fullMimeType: "application/javascript; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 3; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=font", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "woff",
|
||||
fullMimeType: "font/woff"
|
||||
});
|
||||
}
|
||||
for (let i = 4; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=image", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "png",
|
||||
fullMimeType: "image/png"
|
||||
});
|
||||
}
|
||||
for (let i = 5; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=audio", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "ogg",
|
||||
fullMimeType: "audio/ogg"
|
||||
});
|
||||
}
|
||||
for (let i = 6; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=video", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "webm",
|
||||
fullMimeType: "video/webm"
|
||||
});
|
||||
}
|
||||
for (let i = 7; i < aVisibility.length; i += 8) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(i),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=flash", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "x-shockwave-flash",
|
||||
fullMimeType: "application/x-shockwave-flash"
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
aDebuggee.performRequests('{ "getMedia": true, "getFlash": true }');
|
||||
});
|
||||
}
|
187
browser/devtools/netmonitor/test/browser_net_filter-03.js
Normal file
187
browser/devtools/netmonitor/test/browser_net_filter-03.js
Normal file
@ -0,0 +1,187 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if filtering items in the network table works correctly with new requests
|
||||
* and while sorting is enabled.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(FILTERING_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { $, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 7).then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $("#details-pane-toggle"));
|
||||
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should be a selected item in the requests menu.");
|
||||
is(RequestsMenu.selectedIndex, 0,
|
||||
"The first item should be selected in the requests menu.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should not be hidden after toggle button was pressed.");
|
||||
|
||||
testButtons();
|
||||
testContents([0, 1, 2, 3, 4, 5, 6], 7, 0)
|
||||
.then(() => {
|
||||
info("Sorting by size, ascending.");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
|
||||
testButtons();
|
||||
return testContents([6, 4, 5, 0, 1, 2, 3], 7, 6);
|
||||
})
|
||||
.then(() => {
|
||||
info("Testing html filtering.");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-filter-html-button"));
|
||||
testButtons("html");
|
||||
return testContents([6, 4, 5, 0, 1, 2, 3], 1, 6);
|
||||
})
|
||||
.then(() => {
|
||||
info("Performing more requests.");
|
||||
aDebuggee.performRequests('{ "getMedia": true }');
|
||||
return waitForNetworkEvents(aMonitor, 7);
|
||||
})
|
||||
.then(() => {
|
||||
info("Testing html filtering again.");
|
||||
resetSorting();
|
||||
testButtons("html");
|
||||
return testContents([8, 13, 9, 11, 10, 12, 0, 4, 1, 5, 2, 6, 3, 7], 2, 13);
|
||||
})
|
||||
.then(() => {
|
||||
info("Performing more requests.");
|
||||
aDebuggee.performRequests('{ "getMedia": true }');
|
||||
return waitForNetworkEvents(aMonitor, 7);
|
||||
})
|
||||
.then(() => {
|
||||
info("Testing html filtering again.");
|
||||
resetSorting();
|
||||
testButtons("html");
|
||||
return testContents([12, 13, 20, 14, 16, 18, 15, 17, 19, 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11], 3, 20);
|
||||
})
|
||||
.then(() => {
|
||||
return teardown(aMonitor);
|
||||
})
|
||||
.then(finish);
|
||||
});
|
||||
|
||||
function resetSorting() {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, $("#requests-menu-size-button"));
|
||||
}
|
||||
}
|
||||
|
||||
function testButtons(aFilterType) {
|
||||
let doc = aMonitor.panelWin.document;
|
||||
let target = doc.querySelector("#requests-menu-filter-" + aFilterType + "-button");
|
||||
let buttons = doc.querySelectorAll(".requests-menu-footer-button");
|
||||
|
||||
for (let button of buttons) {
|
||||
if (button != target) {
|
||||
is(button.hasAttribute("checked"), false,
|
||||
"The " + button.id + " button should not have a 'checked' attribute.");
|
||||
} else {
|
||||
is(button.hasAttribute("checked"), true,
|
||||
"The " + button.id + " button should have a 'checked' attribute.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testContents(aOrder, aVisible, aSelection) {
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should still be a selected item after filtering.");
|
||||
is(RequestsMenu.selectedIndex, aSelection,
|
||||
"The first item should be still selected after filtering.");
|
||||
is(NetMonitorView.detailsPaneHidden, false,
|
||||
"The details pane should still be visible after filtering.");
|
||||
|
||||
is(RequestsMenu.allItems.length, aOrder.length,
|
||||
"There should be a specific amount of items in the requests menu.");
|
||||
is(RequestsMenu.visibleItems.length, aVisible,
|
||||
"There should be a specific amount of visbile items in the requests menu.");
|
||||
|
||||
for (let i = 0; i < aOrder.length; i++) {
|
||||
is(RequestsMenu.getItemAtIndex(i), RequestsMenu.allItems[i],
|
||||
"The requests menu items aren't ordered correctly. Misplaced item " + i + ".");
|
||||
}
|
||||
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=html", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "html",
|
||||
fullMimeType: "text/html; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=css", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "css",
|
||||
fullMimeType: "text/css; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 2]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=js", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "js",
|
||||
fullMimeType: "application/javascript; charset=utf-8"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 3]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=font", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "woff",
|
||||
fullMimeType: "font/woff"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 4]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=image", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "png",
|
||||
fullMimeType: "image/png"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 5]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=audio", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "ogg",
|
||||
fullMimeType: "audio/ogg"
|
||||
});
|
||||
}
|
||||
for (let i = 0, len = aOrder.length / 7; i < len; i++) {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(aOrder[i + len * 6]),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=video", {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "webm",
|
||||
fullMimeType: "video/webm"
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
let str = "'<p>'" + new Array(10).join(Math.random(10)) + "'</p>'";
|
||||
aDebuggee.performRequests('{ "htmlContent": "' + str + '", "getMedia": true }');
|
||||
});
|
||||
}
|
@ -17,7 +17,7 @@ function test() {
|
||||
is(document.querySelector("#details-pane-toggle")
|
||||
.hasAttribute("disabled"), true,
|
||||
"The pane toggle button should be disabled when the frontend is opened.");
|
||||
is(document.querySelector(".requests-menu-empty-notice")
|
||||
is(document.querySelector("#requests-menu-empty-notice")
|
||||
.hasAttribute("hidden"), false,
|
||||
"An empty notice should be displayed when the frontend is opened.");
|
||||
is(RequestsMenu.itemCount, 0,
|
||||
@ -29,7 +29,7 @@ function test() {
|
||||
is(document.querySelector("#details-pane-toggle")
|
||||
.hasAttribute("disabled"), false,
|
||||
"The pane toggle button should be enabled after the first request.");
|
||||
is(document.querySelector(".requests-menu-empty-notice")
|
||||
is(document.querySelector("#requests-menu-empty-notice")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The empty notice should be hidden after the first request.");
|
||||
is(RequestsMenu.itemCount, 1,
|
||||
@ -41,7 +41,7 @@ function test() {
|
||||
is(document.querySelector("#details-pane-toggle")
|
||||
.hasAttribute("disabled"), false,
|
||||
"The pane toggle button should be still be enabled after a reload.");
|
||||
is(document.querySelector(".requests-menu-empty-notice")
|
||||
is(document.querySelector("#requests-menu-empty-notice")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The empty notice should be still hidden after a reload.");
|
||||
is(RequestsMenu.itemCount, 1,
|
||||
|
@ -142,6 +142,7 @@ function test() {
|
||||
return testContents([3, 4, 0, 1, 2]);
|
||||
})
|
||||
.then(() => {
|
||||
info("Clearing sort.");
|
||||
RequestsMenu.sortBy(null);
|
||||
return testContents([0, 1, 2, 3, 4]);
|
||||
})
|
||||
@ -152,8 +153,6 @@ function test() {
|
||||
});
|
||||
|
||||
function testContents([a, b, c, d, e]) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
is(RequestsMenu.allItems.length, 5,
|
||||
"There should be a total of 5 items in the requests menu.");
|
||||
is(RequestsMenu.visibleItems.length, 5,
|
||||
@ -216,8 +215,7 @@ function test() {
|
||||
time: true
|
||||
});
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
aDebuggee.performRequests();
|
||||
|
@ -149,8 +149,6 @@ function test() {
|
||||
}
|
||||
|
||||
function testContents([a, b, c, d, e]) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should still be a selected item after sorting.");
|
||||
is(RequestsMenu.selectedIndex, a,
|
||||
@ -225,8 +223,7 @@ function test() {
|
||||
time: true
|
||||
});
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
aDebuggee.performRequests();
|
||||
|
@ -91,8 +91,6 @@ function test() {
|
||||
}
|
||||
|
||||
function testContents(aOrder, aSelection) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
isnot(RequestsMenu.selectedItem, null,
|
||||
"There should still be a selected item after sorting.");
|
||||
is(RequestsMenu.selectedIndex, aSelection,
|
||||
@ -171,8 +169,7 @@ function test() {
|
||||
});
|
||||
}
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
return deferred.promise;
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
aDebuggee.performRequests();
|
||||
|
@ -14,8 +14,7 @@ function test() {
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
is(document.querySelector(".requests-menu-empty-notice")
|
||||
.hasAttribute("hidden"), 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.");
|
||||
@ -26,8 +25,7 @@ function test() {
|
||||
"No 2d context should be created when the frontend is opened.");
|
||||
|
||||
waitForNetworkEvents(aMonitor, 1).then(() => {
|
||||
is(document.querySelector(".requests-menu-empty-notice")
|
||||
.hasAttribute("hidden"), true,
|
||||
ok(!document.querySelector("#requests-menu-waterfall-label"),
|
||||
"The timeline label should be hidden after the first request.");
|
||||
ok(document.querySelectorAll(".requests-menu-timings-division").length >= 3,
|
||||
"There should be at least 3 tick labels in the network requests header.");
|
||||
|
@ -22,6 +22,7 @@ const POST_DATA_URL = EXAMPLE_URL + "html_post-data-test-page.html";
|
||||
const JSONP_URL = EXAMPLE_URL + "html_jsonp-test-page.html";
|
||||
const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
|
||||
const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
|
||||
const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
|
||||
const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
|
||||
|
||||
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
|
||||
|
55
browser/devtools/netmonitor/test/html_filter-test-page.html
Normal file
55
browser/devtools/netmonitor/test/html_filter-test-page.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Network Monitor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Filtering test</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
function get(aAddress, aCallback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
// Use a random parameter to defeat caching.
|
||||
xhr.open("GET", aAddress + "&" + Math.random(), true);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == this.DONE) {
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function performRequests(aOptions) {
|
||||
var options = JSON.parse(aOptions);
|
||||
get("sjs_content-type-test-server.sjs?fmt=html&res=" + options.htmlContent, function() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=css", function() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=js", function() {
|
||||
if (!options.getMedia) {
|
||||
return;
|
||||
}
|
||||
get("sjs_content-type-test-server.sjs?fmt=font", function() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=image", function() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=audio", function() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=video", function() {
|
||||
if (!options.getFlash) {
|
||||
return;
|
||||
}
|
||||
get("sjs_content-type-test-server.sjs?fmt=flash", function() {
|
||||
// Done.
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -25,6 +25,14 @@ function handleRequest(request, response) {
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "html": {
|
||||
let content = params.filter((s) => s.contains("res="))[0].split("=")[1];
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
|
||||
response.write(content || "<p>Hello HTML!</p>");
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "css": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/css; charset=utf-8", false);
|
||||
@ -62,6 +70,36 @@ function handleRequest(request, response) {
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "font": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "font/woff", false);
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "image": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "image/png", false);
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "audio": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "audio/ogg", false);
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "video": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "video/webm", false);
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "flash": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "application/x-shockwave-flash", false);
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
response.setStatusLine(request.httpVersion, 404, "Not Found");
|
||||
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
|
||||
|
@ -607,7 +607,7 @@ MenuContainer.prototype = {
|
||||
|
||||
// Sort the items before adding them to this container, if preferred.
|
||||
if (aOptions.sorted) {
|
||||
stagedItems.sort((a, b) => this._sortPredicate(a.item, b.item));
|
||||
stagedItems.sort((a, b) => this._currentSortPredicate(a.item, b.item));
|
||||
}
|
||||
// Append the prepared items to this container.
|
||||
for (let { item, options } of stagedItems) {
|
||||
@ -695,12 +695,32 @@ MenuContainer.prototype = {
|
||||
/**
|
||||
* Toggles all the items in this container hidden or visible.
|
||||
*
|
||||
* This does not change the default filtering predicate, so newly inserted
|
||||
* items will always be visible. Use MenuContainer.prototype.filterContents
|
||||
* if you care.
|
||||
*
|
||||
* @param boolean aVisibleFlag
|
||||
* Specifies the intended visibility.
|
||||
*/
|
||||
toggleContents: function(aVisibleFlag) {
|
||||
for (let [, item] of this._itemsByElement) {
|
||||
item._target.hidden = !aVisibleFlag;
|
||||
for (let [element, item] of this._itemsByElement) {
|
||||
element.hidden = !aVisibleFlag;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles all items in this container hidden or visible based on a predicate.
|
||||
*
|
||||
* @param function aPredicate [optional]
|
||||
* Items are toggled according to the return value of this function,
|
||||
* which will become the new default filtering predicate in this container.
|
||||
* If unspecified, all items will be toggled visible.
|
||||
*/
|
||||
filterContents: function(aPredicate = this._currentFilterPredicate) {
|
||||
this._currentFilterPredicate = aPredicate;
|
||||
|
||||
for (let [element, item] of this._itemsByElement) {
|
||||
element.hidden = !aPredicate(item);
|
||||
}
|
||||
},
|
||||
|
||||
@ -712,8 +732,8 @@ MenuContainer.prototype = {
|
||||
* will become the new default sorting predicate in this container.
|
||||
* If unspecified, all items will be sorted by their label.
|
||||
*/
|
||||
sortContents: function(aPredicate = this._sortPredicate) {
|
||||
let sortedItems = this.allItems.sort(this._sortPredicate = aPredicate);
|
||||
sortContents: function(aPredicate = this._currentSortPredicate) {
|
||||
let sortedItems = this.allItems.sort(this._currentSortPredicate = aPredicate);
|
||||
|
||||
for (let i = 0, len = sortedItems.length; i < len; i++) {
|
||||
this.swapItems(this.getItemAtIndex(i), sortedItems[i]);
|
||||
@ -1123,7 +1143,7 @@ MenuContainer.prototype = {
|
||||
let itemCount = this.itemCount;
|
||||
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
if (this._sortPredicate(this.getItemAtIndex(i), aItem) > 0) {
|
||||
if (this._currentSortPredicate(this.getItemAtIndex(i), aItem) > 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -1160,6 +1180,9 @@ MenuContainer.prototype = {
|
||||
aItem.attachment));
|
||||
|
||||
// Handle any additional options after entangling the item.
|
||||
if (!this._currentFilterPredicate(aItem)) {
|
||||
aItem._target.hidden = true;
|
||||
}
|
||||
if (aOptions.attributes) {
|
||||
aItem.setAttributes(aOptions.attributes, aItem._target);
|
||||
}
|
||||
@ -1217,6 +1240,19 @@ MenuContainer.prototype = {
|
||||
this._itemsByElement.delete(aItem._target);
|
||||
},
|
||||
|
||||
/**
|
||||
* The predicate used when filtering items. By default, all items in this
|
||||
* view are visible.
|
||||
*
|
||||
* @param MenuItem aItem
|
||||
* The filtered menu item.
|
||||
* @return boolean
|
||||
* True if the menu item should be visible, false otherwise.
|
||||
*/
|
||||
_currentFilterPredicate: function(aItem) {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* The predicate used when sorting items. By default, items in this view
|
||||
* are sorted by their label.
|
||||
@ -1230,7 +1266,7 @@ MenuContainer.prototype = {
|
||||
* 0 to leave aFirst and aSecond unchanged with respect to each other
|
||||
* 1 to sort aSecond to a lower index than aFirst
|
||||
*/
|
||||
_sortPredicate: function(aFirst, aSecond) {
|
||||
_currentSortPredicate: function(aFirst, aSecond) {
|
||||
return +(aFirst._label.toLowerCase() > aSecond._label.toLowerCase());
|
||||
},
|
||||
|
||||
|
@ -63,6 +63,42 @@
|
||||
- in the network details pane identifying the timings tab. -->
|
||||
<!ENTITY netmonitorUI.tab.timings "Timings">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterAll): This is the label displayed
|
||||
- in the network details footer for the "All" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterAll "All">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterHTML): This is the label displayed
|
||||
- in the network details footer for the "HTML" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterHTML "HTML">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterCSS): This is the label displayed
|
||||
- in the network details footer for the "CSS" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterCSS "CSS">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterJS): This is the label displayed
|
||||
- in the network details footer for the "JS" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterJS "JS">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterXHR): This is the label displayed
|
||||
- in the network details footer for the "XHR" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterXHR "XHR">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterFonts): This is the label displayed
|
||||
- in the network details footer for the "Fonts" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterFonts "Fonts">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterImages): This is the label displayed
|
||||
- in the network details footer for the "Images" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterImages "Images">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterMedia): This is the label displayed
|
||||
- in the network details footer for the "Media" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterMedia "Media">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterFlash): This is the label displayed
|
||||
- in the network details footer for the "Flash" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterFlash "Flash">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.panesButton.tooltip): This is the tooltip for
|
||||
- the button that toggles the panes visible or hidden in the netmonitor UI. -->
|
||||
<!ENTITY netmonitorUI.panesButton.tooltip "Toggle network info">
|
||||
|
@ -3,13 +3,13 @@
|
||||
* 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/. */
|
||||
|
||||
/* Network requests table */
|
||||
|
||||
#body {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
}
|
||||
|
||||
.requests-menu-empty-notice {
|
||||
/* Network requests table */
|
||||
|
||||
#requests-menu-empty-notice {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
padding: 12px;
|
||||
font-size: 110%;
|
||||
@ -17,19 +17,14 @@
|
||||
}
|
||||
|
||||
#requests-menu-toolbar {
|
||||
padding: 0;
|
||||
-moz-padding-start: 4px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.requests-menu-header:first-child {
|
||||
-moz-padding-start: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.requests-menu-subitem {
|
||||
padding: 4px;
|
||||
}
|
||||
@ -43,12 +38,13 @@
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
min-width: 12px;
|
||||
min-height: 31px; /* Remaining 1px comes from border of the button. */
|
||||
min-width: 20px;
|
||||
min-height: 31px; /* Remaining 1px comes from border of the toolbar. */
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 2px 0px;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
font-weight: inherit !important;
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
@ -80,13 +76,12 @@
|
||||
/* Network requests table: specific column dimensions */
|
||||
|
||||
.requests-menu-status-and-method {
|
||||
width: 6em;
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.requests-menu-status {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 0px 2px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.requests-menu-method {
|
||||
@ -118,6 +113,8 @@
|
||||
|
||||
box.requests-menu-status {
|
||||
background: #fff;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
border-radius: 20px;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255,255,255,0.4) inset,
|
||||
@ -269,12 +266,14 @@ box.requests-menu-status[code^="5"] {
|
||||
0 0 4px 0 rgba(255,255,255,1.0) inset;
|
||||
}
|
||||
|
||||
/* SideMenuWidget */
|
||||
|
||||
.side-menu-widget-item:nth-child(even) {
|
||||
background: rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.side-menu-widget-item-contents {
|
||||
padding: 0px 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Network request details */
|
||||
@ -364,6 +363,51 @@ box.requests-menu-status[code^="5"] {
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
#requests-menu-footer {
|
||||
box-shadow: inset 0 1px 16px hsla(210,8%,5%,.3);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
min-width: 1em;
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 2px 1.5vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button {
|
||||
-moz-appearance: none;
|
||||
background: rgba(0,0,0,0.025);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover {
|
||||
background: rgba(0,0,0,0.20);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover:active {
|
||||
background: rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:not(:active)[checked] {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
background-image: radial-gradient(farthest-side at center top, hsla(200,100%,70%,.7), hsla(200,100%,70%,0.3));
|
||||
background-size: 100% 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.requests-menu-footer-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Responsive sidebar */
|
||||
@media (max-width: 700px) {
|
||||
#requests-menu-toolbar {
|
||||
@ -371,7 +415,13 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
min-height: 25px; /* Remaining 1px comes from border of the button. */
|
||||
min-height: 25px; /* Remaining 1px comes from border of the toolbar. */
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
padding: 2px 2vw;
|
||||
}
|
||||
|
||||
#details-pane {
|
||||
@ -381,13 +431,12 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-status-and-method {
|
||||
width: 14vw;
|
||||
width: 16vw;
|
||||
}
|
||||
|
||||
.requests-menu-file,
|
||||
.requests-menu-domain {
|
||||
width: 30vw;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.requests-menu-type {
|
||||
|
@ -3,13 +3,13 @@
|
||||
* 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/. */
|
||||
|
||||
/* Network requests table */
|
||||
|
||||
#body {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
}
|
||||
|
||||
.requests-menu-empty-notice {
|
||||
/* Network requests table */
|
||||
|
||||
#requests-menu-empty-notice {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
padding: 12px;
|
||||
font-size: 110%;
|
||||
@ -17,19 +17,14 @@
|
||||
}
|
||||
|
||||
#requests-menu-toolbar {
|
||||
padding: 0;
|
||||
-moz-padding-start: 4px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.requests-menu-header:first-child {
|
||||
-moz-padding-start: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.requests-menu-subitem {
|
||||
padding: 4px;
|
||||
}
|
||||
@ -43,12 +38,13 @@
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
min-width: 1em;
|
||||
min-height: 31px; /* Remaining 1px comes from border of the button. */
|
||||
min-width: 20px;
|
||||
min-height: 31px; /* Remaining 1px comes from border of the toolbar. */
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 2px 0px;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
font-weight: inherit !important;
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
@ -84,9 +80,8 @@
|
||||
}
|
||||
|
||||
.requests-menu-status {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin: 0px 2px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.requests-menu-method {
|
||||
@ -118,6 +113,8 @@
|
||||
|
||||
box.requests-menu-status {
|
||||
background: #fff;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
border-radius: 20px;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255,255,255,0.4) inset,
|
||||
@ -269,12 +266,14 @@ box.requests-menu-status[code^="5"] {
|
||||
0 0 4px 0 rgba(255,255,255,1.0) inset;
|
||||
}
|
||||
|
||||
/* SideMenuWidget */
|
||||
|
||||
.side-menu-widget-item:nth-child(even) {
|
||||
background: rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.side-menu-widget-item-contents {
|
||||
padding: 0px 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Network request details */
|
||||
@ -364,6 +363,51 @@ box.requests-menu-status[code^="5"] {
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
#requests-menu-footer {
|
||||
box-shadow: inset 0 1px 16px hsla(210,8%,5%,.3);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
min-width: 1em;
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 2px 1.5vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button {
|
||||
-moz-appearance: none;
|
||||
background: rgba(0,0,0,0.025);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover {
|
||||
background: rgba(0,0,0,0.20);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover:active {
|
||||
background: rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:not(:active)[checked] {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
background-image: radial-gradient(farthest-side at center top, hsla(200,100%,70%,.7), hsla(200,100%,70%,0.3));
|
||||
background-size: 100% 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.requests-menu-footer-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Responsive sidebar */
|
||||
@media (max-width: 700px) {
|
||||
#requests-menu-toolbar {
|
||||
@ -371,7 +415,12 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
min-height: 23px; /* Remaining 1px comes from border of the button. */
|
||||
min-height: 23px; /* Remaining 1px comes from border of the toolbar. */
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
padding: 2px 2vw;
|
||||
}
|
||||
|
||||
#details-pane {
|
||||
@ -381,13 +430,12 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-status-and-method {
|
||||
width: 14vw;
|
||||
width: 16vw;
|
||||
}
|
||||
|
||||
.requests-menu-file,
|
||||
.requests-menu-domain {
|
||||
width: 30vw;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.requests-menu-type {
|
||||
|
@ -3,13 +3,13 @@
|
||||
* 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/. */
|
||||
|
||||
/* Network requests table */
|
||||
|
||||
#body {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
}
|
||||
|
||||
.requests-menu-empty-notice {
|
||||
/* Network requests table */
|
||||
|
||||
#requests-menu-empty-notice {
|
||||
background: url(background-noise-toolbar.png), hsl(208,11%,27%);
|
||||
padding: 12px;
|
||||
font-size: 110%;
|
||||
@ -17,19 +17,14 @@
|
||||
}
|
||||
|
||||
#requests-menu-toolbar {
|
||||
padding: 0;
|
||||
-moz-padding-start: 4px;
|
||||
height: 33px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.requests-menu-header:first-child {
|
||||
-moz-padding-start: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.requests-menu-subitem {
|
||||
padding: 4px;
|
||||
}
|
||||
@ -43,12 +38,13 @@
|
||||
.requests-menu-header-button {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
min-width: 10px;
|
||||
min-height: 32px; /* Remaining 1px comes from border of the button. */
|
||||
min-width: 20px;
|
||||
min-height: 32px; /* Remaining 1px comes from border of the toolbar. */
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 2px 0px;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
font-weight: inherit !important;
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
@ -86,7 +82,6 @@
|
||||
.requests-menu-status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin: 0px 2px;
|
||||
}
|
||||
|
||||
.requests-menu-method {
|
||||
@ -118,6 +113,8 @@
|
||||
|
||||
box.requests-menu-status {
|
||||
background: #fff;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
border-radius: 20px;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(255,255,255,0.4) inset,
|
||||
@ -269,12 +266,14 @@ box.requests-menu-status[code^="5"] {
|
||||
0 0 4px 0 rgba(255,255,255,1.0) inset;
|
||||
}
|
||||
|
||||
/* SideMenuWidget */
|
||||
|
||||
.side-menu-widget-item:nth-child(even) {
|
||||
background: rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.side-menu-widget-item-contents {
|
||||
padding: 0px 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Network request details */
|
||||
@ -364,6 +363,51 @@ box.requests-menu-status[code^="5"] {
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
#requests-menu-footer {
|
||||
box-shadow: inset 0 1px 16px hsla(210,8%,5%,.3);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
min-width: 1em;
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 0px 1.5vw;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.requests-menu-footer-spacer,
|
||||
.requests-menu-footer-button {
|
||||
-moz-border-end: 1px solid hsla(210,8%,5%,.25);
|
||||
box-shadow: 1px 0 0 hsla(210,16%,76%,.1);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button {
|
||||
-moz-appearance: none;
|
||||
background: rgba(0,0,0,0.025);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover {
|
||||
background: rgba(0,0,0,0.20);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:hover:active {
|
||||
background: rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
.requests-menu-footer-button:not(:active)[checked] {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
background-image: radial-gradient(farthest-side at center top, hsla(200,100%,70%,.7), hsla(200,100%,70%,0.3));
|
||||
background-size: 100% 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.requests-menu-footer-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Responsive sidebar */
|
||||
@media (max-width: 700px) {
|
||||
#requests-menu-toolbar {
|
||||
@ -371,7 +415,12 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-header-button {
|
||||
min-height: 23px; /* Remaining 1px comes from border of the button. */
|
||||
min-height: 23px; /* Remaining 1px comes from border of the toolbar. */
|
||||
}
|
||||
|
||||
.requests-menu-footer-button,
|
||||
.requests-menu-footer-label {
|
||||
padding: 0px 2vw;
|
||||
}
|
||||
|
||||
#details-pane {
|
||||
@ -381,13 +430,12 @@ box.requests-menu-status[code^="5"] {
|
||||
}
|
||||
|
||||
.requests-menu-status-and-method {
|
||||
width: 14vw;
|
||||
width: 16vw;
|
||||
}
|
||||
|
||||
.requests-menu-file,
|
||||
.requests-menu-domain {
|
||||
width: 30vw;
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.requests-menu-type {
|
||||
|
@ -1065,6 +1065,7 @@ function NetworkEventActor(aNetworkEvent, aWebConsoleActor)
|
||||
this.conn = this.parent.conn;
|
||||
|
||||
this._startedDateTime = aNetworkEvent.startedDateTime;
|
||||
this._isXHR = aNetworkEvent.isXHR;
|
||||
|
||||
this._request = {
|
||||
method: aNetworkEvent.method,
|
||||
@ -1108,6 +1109,7 @@ NetworkEventActor.prototype =
|
||||
startedDateTime: this._startedDateTime,
|
||||
url: this._request.url,
|
||||
method: this._request.method,
|
||||
isXHR: this._isXHR
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -1936,6 +1936,15 @@ NetworkMonitor.prototype = {
|
||||
event.method = aChannel.requestMethod;
|
||||
event.url = aChannel.URI.spec;
|
||||
|
||||
// Determine if this is an XHR request.
|
||||
try {
|
||||
let callbacks = aChannel.notificationCallbacks;
|
||||
let xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null;
|
||||
event.isXHR = !!xhrRequest;
|
||||
} catch (e) {
|
||||
event.isXHR = false;
|
||||
}
|
||||
|
||||
// Determine the HTTP version.
|
||||
aChannel.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
aChannel.getRequestVersion(httpVersionMaj, httpVersionMin);
|
||||
|
Loading…
Reference in New Issue
Block a user