mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 573103 - Implement WebConsole Network Panel, r=dietrich, a=blocking2.0 (beta5)
This commit is contained in:
parent
ec21282fad
commit
48694b9903
@ -241,6 +241,15 @@ ResponseListener.prototype =
|
||||
if (HUDService.lastFinishedRequestCallback) {
|
||||
HUDService.lastFinishedRequestCallback(this.httpActivity);
|
||||
}
|
||||
|
||||
// Call update on all panels.
|
||||
this.httpActivity.panels.forEach(function(weakRef) {
|
||||
let panel = weakRef.get();
|
||||
if (panel) {
|
||||
panel.update();
|
||||
}
|
||||
});
|
||||
this.httpActivity.response.isDone = true;
|
||||
this.httpActivity = null;
|
||||
},
|
||||
|
||||
@ -457,6 +466,471 @@ var NetworkHelper =
|
||||
|
||||
// FIREBUG CODE END.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// Helper for creating the network panel.
|
||||
|
||||
/**
|
||||
* Creates a DOMNode and sets all the attributes of aAttributes on the created
|
||||
* element.
|
||||
*
|
||||
* @param nsIDOMDocument aDocument
|
||||
* Document to create the new DOMNode.
|
||||
* @param string aTag
|
||||
* Name of the tag for the DOMNode.
|
||||
* @param object aAttributes
|
||||
* Attributes set on the created DOMNode.
|
||||
*
|
||||
* @returns nsIDOMNode
|
||||
*/
|
||||
function createElement(aDocument, aTag, aAttributes)
|
||||
{
|
||||
let node = aDocument.createElement(aTag);
|
||||
for (var attr in aAttributes) {
|
||||
node.setAttribute(attr, aAttributes[attr]);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DOMNode and appends it to aParent.
|
||||
*
|
||||
* @param nsIDOMNode aParent
|
||||
* A parent node to append the created element.
|
||||
* @param string aTag
|
||||
* Name of the tag for the DOMNode.
|
||||
* @param object aAttributes
|
||||
* Attributes set on the created DOMNode.
|
||||
*
|
||||
* @returns nsIDOMNode
|
||||
*/
|
||||
function createAndAppendElement(aParent, aTag, aAttributes)
|
||||
{
|
||||
let node = createElement(aParent.ownerDocument, aTag, aAttributes);
|
||||
aParent.appendChild(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// NetworkPanel
|
||||
|
||||
/**
|
||||
* Creates a new NetworkPanel.
|
||||
*
|
||||
* @param nsIDOMNode aParent
|
||||
* Parent node to append the created panel to.
|
||||
* @param object aHttpActivity
|
||||
* HttpActivity to display in the panel.
|
||||
*/
|
||||
function NetworkPanel(aParent, aHttpActivity)
|
||||
{
|
||||
let doc = aParent.ownerDocument;
|
||||
this.httpActivity = aHttpActivity;
|
||||
|
||||
// Create the underlaying panel
|
||||
this.panel = createElement(doc, "panel", {
|
||||
label: HUDService.getStr("NetworkPanel.label"),
|
||||
titlebar: "normal",
|
||||
noautofocus: "true",
|
||||
noautohide: "true",
|
||||
close: "true"
|
||||
});
|
||||
|
||||
// Create the browser that displays the NetworkPanel XHTML.
|
||||
this.browser = createAndAppendElement(this.panel, "browser", {
|
||||
src: "chrome://global/content/NetworkPanel.xhtml",
|
||||
disablehistory: "true",
|
||||
flex: "1"
|
||||
});
|
||||
|
||||
// Destroy the panel when it's closed.
|
||||
this.panel.addEventListener("popuphidden", function onPopupHide() {
|
||||
self.panel.removeEventListener("popuphidden", onPopupHide, false);
|
||||
self.panel.parentNode.removeChild(self.panel);
|
||||
self.panel = null;
|
||||
self.browser = null;
|
||||
self.document = null;
|
||||
self.httpActivity = null;
|
||||
}, false);
|
||||
|
||||
// Set the document object and update the content once the panel is loaded.
|
||||
let self = this;
|
||||
this.panel.addEventListener("load", function onLoad() {
|
||||
self.panel.removeEventListener("load", onLoad, true)
|
||||
self.document = self.browser.contentWindow.document;
|
||||
self.update();
|
||||
}, true);
|
||||
|
||||
// Create the footer.
|
||||
let footer = createElement(doc, "hbox", { align: "end" });
|
||||
createAndAppendElement(footer, "spacer", { flex: 1 });
|
||||
|
||||
createAndAppendElement(footer, "resizer", { dir: "bottomend" });
|
||||
this.panel.appendChild(footer);
|
||||
|
||||
aParent.appendChild(this.panel);
|
||||
}
|
||||
|
||||
NetworkPanel.prototype =
|
||||
{
|
||||
/**
|
||||
* The current state of the output.
|
||||
*/
|
||||
_state: 0,
|
||||
|
||||
/**
|
||||
* State variables.
|
||||
*/
|
||||
_INIT: 0,
|
||||
_DISPLAYED_REQUEST_HEADER: 1,
|
||||
_DISPLAYED_REQUEST_BODY: 2,
|
||||
_DISPLAYED_RESPONSE_HEADER: 3,
|
||||
_TRANSITION_CLOSED: 4,
|
||||
|
||||
/**
|
||||
* Small helper function that is nearly equal to HUDService.getFormatStr
|
||||
* except that it prefixes aName with "NetworkPanel.".
|
||||
*
|
||||
* @param string aName
|
||||
* The name of an i10n string to format. This string is prefixed with
|
||||
* "NetworkPanel." before calling the HUDService.getFormatStr function.
|
||||
* @param array aArray
|
||||
* Values used as placeholder for the i10n string.
|
||||
* @returns string
|
||||
* The i10n formated string.
|
||||
*/
|
||||
_format: function NP_format(aName, aArray)
|
||||
{
|
||||
return HUDService.getFormatStr("NetworkPanel." + aName, aArray);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* True if the response is an image, false otherwise.
|
||||
*/
|
||||
get _responseIsImage()
|
||||
{
|
||||
let response = this.httpActivity.response;
|
||||
if (!response || !response.header || !response.header["Content-Type"]) {
|
||||
let request = this.httpActivity.request;
|
||||
if (request.header["Accept"] &&
|
||||
request.header["Accept"].indexOf("image/") != -1) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return response.header["Content-Type"].indexOf("image/") != -1;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* Returns true if the server responded that the request is already
|
||||
* in the browser's cache, false otherwise.
|
||||
*/
|
||||
get _isResponseCached()
|
||||
{
|
||||
return this.httpActivity.response.status.indexOf("304") != -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends the node with id=aId by the text aValue.
|
||||
*
|
||||
* @param string aId
|
||||
* @param string aValue
|
||||
* @returns void
|
||||
*/
|
||||
_appendTextNode: function NP_appendTextNode(aId, aValue)
|
||||
{
|
||||
let textNode = this.document.createTextNode(aValue);
|
||||
this.document.getElementById(aId).appendChild(textNode);
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates some HTML to display the key-value pair of the aList data. The
|
||||
* generated HTML is added to node with id=aParentId.
|
||||
*
|
||||
* @param string aParentId
|
||||
* Id of the parent node to append the list to.
|
||||
* @oaram object aList
|
||||
* Object that holds the key-value information to display in aParentId.
|
||||
* @param boolean aIgnoreCookie
|
||||
* If true, the key-value named "Cookie" is not added to the list.
|
||||
* @returns void
|
||||
*/
|
||||
_appendList: function NP_appendList(aParentId, aList, aIgnoreCookie)
|
||||
{
|
||||
let parent = this.document.getElementById(aParentId);
|
||||
let doc = this.document;
|
||||
|
||||
let sortedList = {};
|
||||
Object.keys(aList).sort().forEach(function(aKey) {
|
||||
sortedList[aKey] = aList[aKey];
|
||||
});
|
||||
|
||||
for (let key in sortedList) {
|
||||
if (aIgnoreCookie && key == "Cookie") {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following code creates the HTML:
|
||||
*
|
||||
* <span class="property-name">${line}:</span>
|
||||
* <span class="property-value">${aList[line]}</span><br>
|
||||
*
|
||||
* and adds it to parent.
|
||||
*/
|
||||
let textNode = doc.createTextNode(key + ":");
|
||||
let span = doc.createElement("span");
|
||||
span.setAttribute("class", "property-name");
|
||||
span.appendChild(textNode);
|
||||
parent.appendChild(span);
|
||||
|
||||
textNode = doc.createTextNode(sortedList[key]);
|
||||
span = doc.createElement("span");
|
||||
span.setAttribute("class", "property-value");
|
||||
span.appendChild(textNode);
|
||||
parent.appendChild(span);
|
||||
|
||||
parent.appendChild(doc.createElement("br"));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the node with id=aId.
|
||||
*
|
||||
* @param string aId
|
||||
* @returns void
|
||||
*/
|
||||
_displayNode: function NP_displayNode(aId)
|
||||
{
|
||||
this.document.getElementById(aId).style.display = "block";
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the request URL, request method, the timing information when the
|
||||
* request started and the request header content on the NetworkPanel.
|
||||
* If the request header contains cookie data, a list of sent cookies is
|
||||
* generated and a special sent cookie section is displayed + the cookie list
|
||||
* added to it.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestHeader: function NP_displayRequestHeader()
|
||||
{
|
||||
let timing = this.httpActivity.timing;
|
||||
let request = this.httpActivity.request;
|
||||
|
||||
this._appendTextNode("headUrl", this.httpActivity.url);
|
||||
this._appendTextNode("headMethod", this.httpActivity.method);
|
||||
|
||||
this._appendTextNode("requestHeadersInfo",
|
||||
ConsoleUtils.timestampString(timing.REQUEST_HEADER/1000));
|
||||
|
||||
this._appendList("requestHeadersContent", request.header, true);
|
||||
|
||||
if ("Cookie" in request.header) {
|
||||
this._displayNode("requestCookie");
|
||||
|
||||
let cookies = request.header.Cookie.split(";");
|
||||
let cookieList = {};
|
||||
let cookieListSorted = {};
|
||||
cookies.forEach(function(cookie) {
|
||||
let name, value;
|
||||
[name, value] = cookie.trim().split("=");
|
||||
cookieList[name] = value;
|
||||
});
|
||||
this._appendList("requestCookieContent", cookieList);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the request body section of the NetworkPanel and set the request
|
||||
* body content on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestBody: function NP_displayRequestBody() {
|
||||
this._displayNode("requestBody");
|
||||
this._appendTextNode("requestBodyContent", this.httpActivity.request.body);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the response section of the NetworkPanel, sets the response status,
|
||||
* the duration between the start of the request and the receiving of the
|
||||
* response header as well as the response header content on the the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseHeader: function NP_displayResponseHeader()
|
||||
{
|
||||
let timing = this.httpActivity.timing;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
this._appendTextNode("headStatus", response.status);
|
||||
|
||||
let deltaDuration =
|
||||
Math.round((timing.RESPONSE_HEADER - timing.REQUEST_HEADER) / 1000);
|
||||
this._appendTextNode("responseHeadersInfo",
|
||||
this._format("durationMS", [deltaDuration]));
|
||||
|
||||
this._displayNode("responseContainer");
|
||||
this._appendList("responseHeadersContent", response.header);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the respones image section, sets the source of the image displayed
|
||||
* in the image response section to the request URL and the duration between
|
||||
* the receiving of the response header and the end of the request. Once the
|
||||
* image is loaded, the size of the requested image is set.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseImage: function NP_displayResponseImage()
|
||||
{
|
||||
let self = this;
|
||||
let timing = this.httpActivity.timing;
|
||||
let response = this.httpActivity.response;
|
||||
let cached = "";
|
||||
|
||||
if (this._isResponseCached) {
|
||||
cached = "Cached";
|
||||
}
|
||||
|
||||
let imageNode = this.document.getElementById("responseImage" + cached +"Node");
|
||||
imageNode.setAttribute("src", this.httpActivity.url);
|
||||
|
||||
// This function is called to set the imageInfo.
|
||||
function setImageInfo() {
|
||||
let deltaDuration =
|
||||
Math.round((timing.RESPONSE_COMPLETE - timing.RESPONSE_HEADER) / 1000);
|
||||
self._appendTextNode("responseImage" + cached + "Info",
|
||||
self._format("imageSizeDeltaDurationMS", [
|
||||
imageNode.width, imageNode.height, deltaDuration
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
// Check if the image is already loaded.
|
||||
if (imageNode.width != 0) {
|
||||
setImageInfo();
|
||||
}
|
||||
else {
|
||||
// Image is not loaded yet therefore add a load event.
|
||||
imageNode.addEventListener("load", function imageNodeLoad() {
|
||||
imageNode.removeEventListener("load", imageNodeLoad, false);
|
||||
setImageInfo();
|
||||
}, false);
|
||||
}
|
||||
|
||||
this._displayNode("responseImage" + cached);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the response body section, sets the the duration between
|
||||
* the receiving of the response header and the end of the request as well as
|
||||
* the content of the response body on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseBody: function NP_displayResponseBody()
|
||||
{
|
||||
let timing = this.httpActivity.timing;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
let deltaDuration =
|
||||
Math.round((timing.RESPONSE_COMPLETE - timing.RESPONSE_HEADER) / 1000);
|
||||
this._appendTextNode("responseBodyInfo",
|
||||
this._format("durationMS", [deltaDuration]));
|
||||
|
||||
this._displayNode("responseBody");
|
||||
this._appendTextNode("responseBodyContent", response.body);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the `no response body` section and sets the the duration between
|
||||
* the receiving of the response header and the end of the request.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayNoResponseBody: function NP_displayNoResponseBody()
|
||||
{
|
||||
let timing = this.httpActivity.timing;
|
||||
|
||||
this._displayNode("responseNoBody");
|
||||
let deltaDuration =
|
||||
Math.round((timing.RESPONSE_COMPLETE - timing.RESPONSE_HEADER) / 1000);
|
||||
this._appendTextNode("responseNoBodyInfo",
|
||||
this._format("durationMS", [deltaDuration]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the content of the NetworkPanel's browser.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
update: function NP_update()
|
||||
{
|
||||
/**
|
||||
* After the browser contentWindow is ready, the document object is set.
|
||||
* If the document object isn't set yet, then the page is loaded and nothing
|
||||
* can be updated.
|
||||
*/
|
||||
if (!this.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timing = this.httpActivity.timing;
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
switch (this._state) {
|
||||
case this._INIT:
|
||||
this._displayRequestHeader();
|
||||
this._state = this._DISPLAYED_REQUEST_HEADER;
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_REQUEST_HEADER:
|
||||
// Process the request body if there is one.
|
||||
if (request.body) {
|
||||
this._displayRequestBody();
|
||||
this._state = this._DISPLAYED_REQUEST_BODY;
|
||||
}
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_REQUEST_BODY:
|
||||
// There is always a response header. Therefore we can skip here if
|
||||
// we don't have a response header yet and don't have to try updating
|
||||
// anything else in the NetworkPanel.
|
||||
if (!response.header) {
|
||||
break
|
||||
}
|
||||
this._displayResponseHeader();
|
||||
this._state = this._DISPLAYED_RESPONSE_HEADER;
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_RESPONSE_HEADER:
|
||||
// Check if the transition is done.
|
||||
if (timing.TRANSACTION_CLOSE && response.isDone) {
|
||||
if (this._responseIsImage) {
|
||||
this._displayResponseImage();
|
||||
}
|
||||
else if (response.body) {
|
||||
this._displayResponseBody();
|
||||
}
|
||||
else {
|
||||
this._displayNoResponseBody();
|
||||
}
|
||||
this._state = this._TRANSITION_CLOSED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function HUD_SERVICE()
|
||||
{
|
||||
// TODO: provide mixins for FENNEC: bug 568621
|
||||
@ -1008,6 +1482,11 @@ HUD_SERVICE.prototype =
|
||||
*/
|
||||
unregisterDisplay: function HS_unregisterDisplay(aId)
|
||||
{
|
||||
// Remove children from the output. If the output is not cleared, there can
|
||||
// be leaks as some nodes has node.onclick = function; set and GC can't
|
||||
// remove the nodes then.
|
||||
HUDService.clearDisplay(aId);
|
||||
|
||||
// remove HUD DOM node and
|
||||
// remove display references from local registries get the outputNode
|
||||
var outputNode = this.mixins.getOutputNodeById(aId);
|
||||
@ -1366,6 +1845,28 @@ HUD_SERVICE.prototype =
|
||||
*/
|
||||
lastFinishedRequestCallback: null,
|
||||
|
||||
/**
|
||||
* Opens a NetworkPanel.
|
||||
*
|
||||
* @param nsIDOMNode aNode
|
||||
* DOMNode to display the panel next to.
|
||||
* @param object aHttpActivity
|
||||
* httpActivity object. The data of this object is displayed in the
|
||||
* NetworkPanel.
|
||||
* @returns NetworkPanel
|
||||
*/
|
||||
openNetworkPanel: function (aNode, aHttpActivity) {
|
||||
let doc = aNode.ownerDocument;
|
||||
let parent = doc.getElementById("mainPopupSet");
|
||||
let netPanel = new NetworkPanel(parent, aHttpActivity);
|
||||
|
||||
let panel = netPanel.panel;
|
||||
panel.openPopup(aNode, "after_pointer", 0, 0, false, false);
|
||||
panel.sizeTo(350, 400);
|
||||
aHttpActivity.panels.push(Cu.getWeakReference(netPanel));
|
||||
return netPanel;
|
||||
},
|
||||
|
||||
/**
|
||||
* Begin observing HTTP traffic that we care about,
|
||||
* namely traffic that originates inside any context that a Heads Up Display
|
||||
@ -1413,6 +1914,7 @@ HUD_SERVICE.prototype =
|
||||
method: aChannel.requestMethod,
|
||||
channel: aChannel,
|
||||
|
||||
panels: [],
|
||||
request: {
|
||||
header: { }
|
||||
},
|
||||
@ -1450,6 +1952,13 @@ HUD_SERVICE.prototype =
|
||||
// Store the loggedNode and the httpActivity object for later reuse.
|
||||
httpActivity.messageObject = loggedNode;
|
||||
self.openRequests[httpActivity.id] = httpActivity;
|
||||
|
||||
// Make the network span clickable.
|
||||
let linkNode = loggedNode.messageNode;
|
||||
linkNode.setAttribute("aria-haspopup", "true");
|
||||
linkNode.onclick = function() {
|
||||
self.openNetworkPanel(linkNode, httpActivity);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Iterate over all currently ongoing requests. If aChannel can't
|
||||
@ -1467,7 +1976,7 @@ HUD_SERVICE.prototype =
|
||||
return;
|
||||
}
|
||||
|
||||
let msgObject;
|
||||
let msgObject, updatePanel = false;
|
||||
let data, textNode;
|
||||
// Store the time information for this activity subtype.
|
||||
httpActivity.timing[transCodes[aActivitySubtype]] = aTimestamp;
|
||||
@ -1481,7 +1990,7 @@ HUD_SERVICE.prototype =
|
||||
if (!sentBody) {
|
||||
// If the request URL is the same as the current page url, then
|
||||
// we can try to get the posted text from the page directly.
|
||||
// This is necessary as otherwise the
|
||||
// This check is necessary as otherwise the
|
||||
// NetworkHelper.readPostTextFromPage
|
||||
// function is called for image requests as well but these
|
||||
// are not web pages and as such don't store the posted text
|
||||
@ -1549,8 +2058,18 @@ HUD_SERVICE.prototype =
|
||||
self.getFormatStr("networkUrlWithStatusAndDuration", data)));
|
||||
|
||||
delete self.openRequests[item.id];
|
||||
updatePanel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (updatePanel) {
|
||||
httpActivity.panels.forEach(function(weakRef) {
|
||||
let panel = weakRef.get();
|
||||
if (panel) {
|
||||
panel.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
121
toolkit/components/console/hudservice/NetworkPanel.xhtml
Normal file
121
toolkit/components/console/hudservice/NetworkPanel.xhtml
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://global/locale/webConsole.dtd" >
|
||||
%webConsoleDTD;
|
||||
]>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is DevTools WebConsole Code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Foundation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2010
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Joe Walker <jwalker@mozilla.com>
|
||||
- Julian Viereck <jviereck@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" href="chrome://global/skin/webConsole_networkPanel.css" type="text/css"/>
|
||||
</head>
|
||||
<body role="application">
|
||||
<div id="header">
|
||||
<span class="property-name">&networkPanel.requestURL;:</span>
|
||||
<span class="property-value" id="headUrl"></span><br />
|
||||
<span class="property-name">&networkPanel.requestMethod;:</span>
|
||||
<span class="property-value" id="headMethod"></span><br />
|
||||
<span class="property-name">&networkPanel.statusCode;:</span>
|
||||
<span class="property-value" id="headStatus"></span>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h1>
|
||||
&networkPanel.requestHeaders;
|
||||
<span id="requestHeadersInfo" class="info"></span>
|
||||
</h1>
|
||||
<div class="property-header" id="requestHeadersContent"></div>
|
||||
|
||||
<div id="requestCookie" style="display:none">
|
||||
<h1>&networkPanel.requestCookie;</h1>
|
||||
<div class="property-header" id="requestCookieContent"></div>
|
||||
</div>
|
||||
|
||||
<div id="requestBody" style="display:none">
|
||||
<h1>&networkPanel.requestBody;</h1>
|
||||
<div class="property-header" id="requestBodyContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group" id="responseContainer" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseHeaders;
|
||||
<span id="responseHeadersInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
<div class="property-header" id="responseHeadersContent"></div>
|
||||
|
||||
<div id="responseBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBody;
|
||||
<span class="info" id="responseBodyInfo">Δ</span>
|
||||
</h1>
|
||||
<div class="property-header" id="responseBodyContent"></div>
|
||||
</div>
|
||||
<div id="responseNoBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseNoBody;
|
||||
<span id="responseNoBodyInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="responseImage" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseImage;
|
||||
<span id="responseImageInfo" class="info"></span>
|
||||
</h1>
|
||||
<div id="responseImageNodeDiv">
|
||||
<img id="responseImageNode" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="responseImageCached" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseImageCached;
|
||||
<span id="responseImageCachedInfo" class="info"></span>
|
||||
</h1>
|
||||
<div id="responseImageNodeDiv">
|
||||
<img id="responseImageCachedNode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -70,6 +70,8 @@ const TEST_ERROR_URI = "http://example.com/browser/toolkit/components/console/hu
|
||||
|
||||
const TEST_DUPLICATE_ERROR_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-duplicate-error.html";
|
||||
|
||||
const TEST_IMG = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-image.png";
|
||||
|
||||
function noCacheUriSpec(aUriSpec) {
|
||||
return aUriSpec + "?_=" + Date.now();
|
||||
}
|
||||
@ -569,6 +571,254 @@ function testConsoleHistory()
|
||||
is (input.value, executeList[idxLast], "check history next idx:" + idxLast);
|
||||
}
|
||||
|
||||
function testNetworkPanel()
|
||||
{
|
||||
function checkIsVisible(aPanel, aList) {
|
||||
for (let id in aList) {
|
||||
let node = aPanel.document.getElementById(id);
|
||||
let isVisible = aList[id];
|
||||
is(node.style.display, (isVisible ? "block" : "none"), id + " isVisible=" + isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeContent(aPanel, aId, aContent) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
if (node == null) {
|
||||
ok(false, "Tried to access node " + aId + " that doesn't exist!");
|
||||
}
|
||||
else if (node.textContent.indexOf(aContent) != -1) {
|
||||
ok(true, "checking content of " + aId);
|
||||
}
|
||||
else {
|
||||
ok(false, "Got false value for " + aId + ": " + node.textContent + " doesn't have " + aContent);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeKeyValue(aPanel, aId, aKey, aValue) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
|
||||
let testHTML = '<span xmlns="http://www.w3.org/1999/xhtml" class="property-name">' + aKey + ':</span>';
|
||||
testHTML += '<span xmlns="http://www.w3.org/1999/xhtml" class="property-value">' + aValue + '</span>';
|
||||
isnot(node.innerHTML.indexOf(testHTML), -1, "checking content of " + aId);
|
||||
}
|
||||
|
||||
let testDriver;
|
||||
function testGen() {
|
||||
var httpActivity = {
|
||||
url: "http://www.testpage.com",
|
||||
method: "GET",
|
||||
|
||||
panels: [],
|
||||
request: {
|
||||
header: {
|
||||
foo: "bar"
|
||||
}
|
||||
},
|
||||
response: { },
|
||||
timing: {
|
||||
"REQUEST_HEADER": 0
|
||||
}
|
||||
};
|
||||
|
||||
let networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
|
||||
|
||||
is (networkPanel, httpActivity.panels[0].get(), "Network panel stored on httpActivity object");
|
||||
networkPanel.panel.addEventListener("load", function onLoad() {
|
||||
networkPanel.panel.removeEventListener("load", onLoad, true);
|
||||
testDriver.next();
|
||||
}, true);
|
||||
yield;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestBody: false,
|
||||
responseContainer: false,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "header", "http://www.testpage.com");
|
||||
checkNodeContent(networkPanel, "header", "GET");
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "foo", "bar");
|
||||
|
||||
// Test request body.
|
||||
httpActivity.request.body = "hello world";
|
||||
networkPanel.update();
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
responseContainer: false,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
checkNodeContent(networkPanel, "requestBodyContent", "hello world");
|
||||
|
||||
// Test response header.
|
||||
httpActivity.timing.RESPONSE_HEADER = 1000;
|
||||
httpActivity.response.status = "999 earthquake win";
|
||||
httpActivity.response.header = {
|
||||
leaveHouses: "true"
|
||||
}
|
||||
networkPanel.update();
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "header", "999 earthquake win");
|
||||
checkNodeKeyValue(networkPanel, "responseHeadersContent", "leaveHouses", "true");
|
||||
checkNodeContent(networkPanel, "responseHeadersInfo", "1ms");
|
||||
|
||||
httpActivity.timing.RESPONSE_COMPLETE = 2500;
|
||||
// This is necessary to show that the request is done.
|
||||
httpActivity.timing.TRANSACTION_CLOSE = 2500;
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
httpActivity.response.isDone = true;
|
||||
networkPanel.update();
|
||||
|
||||
checkNodeContent(networkPanel, "responseNoBodyInfo", "2ms");
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: true,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Second run: Test for cookies and response body.
|
||||
httpActivity.request.header.Cookie = "foo=bar; hello=world";
|
||||
httpActivity.response.body = "get out here";
|
||||
|
||||
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
|
||||
is (networkPanel, httpActivity.panels[1].get(), "Network panel stored on httpActivity object");
|
||||
networkPanel.panel.addEventListener("load", function onLoad() {
|
||||
networkPanel.panel.removeEventListener("load", onLoad, true);
|
||||
testDriver.next();
|
||||
}, true);
|
||||
yield;
|
||||
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestCookieContent", "foo", "bar");
|
||||
checkNodeKeyValue(networkPanel, "requestCookieContent", "hello", "world");
|
||||
checkNodeContent(networkPanel, "responseBodyContent", "get out here");
|
||||
checkNodeContent(networkPanel, "responseBodyInfo", "2ms");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Check image request.
|
||||
httpActivity.response.header["Content-Type"] = "image/png";
|
||||
httpActivity.url = TEST_IMG;
|
||||
|
||||
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel.panel.addEventListener("load", function onLoad() {
|
||||
networkPanel.panel.removeEventListener("load", onLoad, true);
|
||||
testDriver.next();
|
||||
}, true);
|
||||
yield;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: true,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
is(imgNode.getAttribute("src"), TEST_IMG, "Displayed image is correct");
|
||||
|
||||
function checkImageResponseInfo() {
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "2ms");
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "16x16px");
|
||||
}
|
||||
|
||||
// Check if the image is loaded already.
|
||||
if (imgNode.width == 0) {
|
||||
imgNode.addEventListener("load", function onLoad() {
|
||||
imgNode.removeEventListener("load", onLoad, false);
|
||||
checkImageResponseInfo();
|
||||
networkPanel.panel.hidePopup();
|
||||
testDriver.next();
|
||||
}, false);
|
||||
// Wait until the image is loaded.
|
||||
yield;
|
||||
}
|
||||
else {
|
||||
checkImageResponseInfo();
|
||||
networkPanel.panel.hidePopup();
|
||||
}
|
||||
|
||||
// Check cached image request.
|
||||
httpActivity.response.status = "HTTP/1.1 304 Not Modified";
|
||||
|
||||
networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel.panel.addEventListener("load", function onLoad() {
|
||||
networkPanel.panel.removeEventListener("load", onLoad, true);
|
||||
testDriver.next();
|
||||
}, true);
|
||||
yield;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageCachedNode");
|
||||
is(imgNode.getAttribute("src"), TEST_IMG, "Displayed image is correct");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Run the next test.
|
||||
testErrorOnPageReload();
|
||||
|
||||
yield;
|
||||
};
|
||||
|
||||
testDriver = testGen();
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
// test property provider
|
||||
function testPropertyProvider()
|
||||
{
|
||||
@ -829,7 +1079,7 @@ function testPageReload() {
|
||||
is(typeof console.error, "function", "console.error is a function");
|
||||
is(typeof console.exception, "function", "console.exception is a function");
|
||||
|
||||
testErrorOnPageReload();
|
||||
testNetworkPanel();
|
||||
}, false);
|
||||
|
||||
content.location.reload();
|
||||
|
@ -17,6 +17,8 @@ Cu.import("resource://gre/modules/HUDService.jsm");
|
||||
|
||||
const TEST_NETWORK_REQUEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network-request.html";
|
||||
|
||||
const TEST_IMG = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-image.png";
|
||||
|
||||
const TEST_DATA_JSON_CONTENT =
|
||||
'{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] }';
|
||||
|
||||
@ -29,7 +31,7 @@ function testOpenWebConsole()
|
||||
is(HUDService.displaysIndex().length, 1, "WebConsole was opened");
|
||||
|
||||
hudId = HUDService.displaysIndex()[0];
|
||||
hud = HUDService.hudWeakReferences[hudId].get();
|
||||
hud = HUDService.getHeadsUpDisplay(hudId);
|
||||
|
||||
testNetworkLogging();
|
||||
}
|
||||
@ -145,11 +147,24 @@ function testNetworkLogging()
|
||||
|
||||
lastFinishedRequest = null
|
||||
|
||||
// Open the NetworkPanel. The functionality of the NetworkPanel is tested
|
||||
// within the testNetworkPanel() function.
|
||||
let filterBox = hud.querySelectorAll(".hud-filter-box")[0];
|
||||
let networkPanel = HUDService.openNetworkPanel(filterBox, httpActivity);
|
||||
is (networkPanel, httpActivity.panels[0].get(), "Network panel stored on httpActivity object");
|
||||
networkPanel.panel.addEventListener("load", function onLoad() {
|
||||
networkPanel.panel.removeEventListener("load", onLoad, true);
|
||||
|
||||
ok(true, "NetworkPanel was opened");
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// All tests are done. Shutdown.
|
||||
browser = null;
|
||||
lastFinishedRequest = null;
|
||||
HUDService.lastFinishedRequestCallback = null;
|
||||
|
||||
finishTest();
|
||||
}, true);
|
||||
}
|
||||
|
||||
loggingGen = loggingGeneratorFunc();
|
||||
|
@ -1,5 +1,6 @@
|
||||
toolkit.jar:
|
||||
*+ content/global/console.js (content/console.js)
|
||||
*+ content/global/console.xul (content/console.xul)
|
||||
+ content/global/NetworkPanel.xhtml (hudservice/NetworkPanel.xhtml)
|
||||
+ content/global/console.css (content/console.css)
|
||||
+ content/global/consoleBindings.xml (content/consoleBindings.xml)
|
||||
|
@ -84,3 +84,18 @@ networkUrlWithStatus=%1$S [%2$S
|
||||
# %2$S = response status code from the server (e.g. `HTTP/1.1 200 OK`)
|
||||
# %3$S = duration for the complete network request in milliseconds
|
||||
networkUrlWithStatusAndDuration=%1$S [%2$S %3$Sms]
|
||||
NetworkPanel.label=Inspect Network Request
|
||||
# LOCALIZATION NOTE (NetworkPanel.deltaDurationMS):
|
||||
#
|
||||
# This string is used to show the duration between two network events (e.g
|
||||
# request and respones header or response header and response body).
|
||||
NetworkPanel.durationMS=%Sms
|
||||
# LOCALIZATION NOTE (NetworkPanel.imageSizeDeltaDurationMS):
|
||||
# This string is used to show the duration between the response header and the
|
||||
# response body event. It also shows the size of the received or cached image.
|
||||
#
|
||||
# The first %S is replace by the width of the inspected image.
|
||||
# The second %S is replaced by the height of the inspected image.
|
||||
# The third %S is replaced by the duration between the response header and the
|
||||
# response body event.
|
||||
NetworkPanel.imageSizeDeltaDurationMS=%Sx%Spx, Δ%Sms
|
||||
|
12
toolkit/locales/en-US/chrome/global/webConsole.dtd
Normal file
12
toolkit/locales/en-US/chrome/global/webConsole.dtd
Normal file
@ -0,0 +1,12 @@
|
||||
<!ENTITY networkPanel.requestURL "Request URL">
|
||||
<!ENTITY networkPanel.requestMethod "Request Method">
|
||||
<!ENTITY networkPanel.statusCode "Status Code">
|
||||
|
||||
<!ENTITY networkPanel.requestHeaders "Request Headers">
|
||||
<!ENTITY networkPanel.requestCookie "Sent Cookie">
|
||||
<!ENTITY networkPanel.requestBody "Request Body">
|
||||
<!ENTITY networkPanel.responseHeaders "Response Headers">
|
||||
<!ENTITY networkPanel.responseBody "Response Body">
|
||||
<!ENTITY networkPanel.responseNoBody "No Response Body">
|
||||
<!ENTITY networkPanel.responseImage "Received Image">
|
||||
<!ENTITY networkPanel.responseImageCached "Cached Image">
|
@ -37,6 +37,7 @@
|
||||
+ locale/@AB_CD@/global/finddialog.properties (%chrome/global/finddialog.properties)
|
||||
locale/@AB_CD@/global/globalKeys.dtd (%chrome/global/globalKeys.dtd)
|
||||
+ locale/@AB_CD@/global/headsUpDisplay.properties (%chrome/global/headsUpDisplay.properties)
|
||||
+ locale/@AB_CD@/global/webConsole.dtd (%chrome/global/webConsole.dtd)
|
||||
+ locale/@AB_CD@/global/intl.css (%chrome/global/intl.css)
|
||||
+ locale/@AB_CD@/global/intl.properties (%chrome/global/intl.properties)
|
||||
+ locale/@AB_CD@/global/keys.properties (%chrome/global/keys.properties)
|
||||
|
@ -28,6 +28,7 @@ toolkit.jar:
|
||||
+ skin/classic/global/toolbarbutton.css
|
||||
+ skin/classic/global/tree.css
|
||||
+ skin/classic/global/webConsole.css
|
||||
+ skin/classic/global/webConsole_networkPanel.css
|
||||
+ skin/classic/global/alerts/alert.css (alerts/alert.css)
|
||||
+ skin/classic/global/console/console.css (console/console.css)
|
||||
+ skin/classic/global/console/console.png (console/console.png)
|
||||
|
108
toolkit/themes/gnomestripe/global/webConsole_networkPanel.css
Normal file
108
toolkit/themes/gnomestripe/global/webConsole_networkPanel.css
Normal file
@ -0,0 +1,108 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is DevTools code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Walker <jwalker@mozilla.com>
|
||||
* Julian Viereck <jviereck@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
div#header {
|
||||
padding: 5px;
|
||||
overflow-x:auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
margin: 0px;
|
||||
background: -moz-linear-gradient(top, #BBB, #999);
|
||||
-moz-border-radius: 2px;
|
||||
text-shadow: #FFF 0px 1px 0px;
|
||||
}
|
||||
|
||||
h1 .info {
|
||||
font-size: 11px;
|
||||
float: right;
|
||||
color: #333;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
div.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #FFF, #F8F8F8);
|
||||
color: #333;
|
||||
max-height: 330px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
span.property-name {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding-right: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
span.property-value {
|
||||
padding-right: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
div.group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.group, div#header {
|
||||
background: #FFF;
|
||||
border-color: #E1E1E1;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-moz-border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
img#responseImageNode {
|
||||
-moz-box-shadow: rgba(0,0,0,0.2) 0px 3px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#responseImageNodeDiv {
|
||||
padding: 5px;
|
||||
}
|
@ -50,6 +50,7 @@ toolkit.jar:
|
||||
skin/classic/global/tree.css
|
||||
* skin/classic/global/viewbuttons.css
|
||||
* skin/classic/global/webConsole.css
|
||||
* skin/classic/global/webConsole_networkPanel.css
|
||||
skin/classic/global/wizard.css
|
||||
skin/classic/global/arrow/arrow-dn-dis.gif (arrow/arrow-dn-dis.gif)
|
||||
skin/classic/global/arrow/arrow-dn-dis.png (arrow/arrow-dn-dis.png)
|
||||
|
108
toolkit/themes/pinstripe/global/webConsole_networkPanel.css
Normal file
108
toolkit/themes/pinstripe/global/webConsole_networkPanel.css
Normal file
@ -0,0 +1,108 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is DevTools code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Walker <jwalker@mozilla.com>
|
||||
* Julian Viereck <jviereck@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
div#header {
|
||||
padding: 5px;
|
||||
overflow-x:auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
margin: 0px;
|
||||
background: -moz-linear-gradient(top, #BBB, #999);
|
||||
-moz-border-radius: 2px;
|
||||
text-shadow: #FFF 0px 1px 0px;
|
||||
}
|
||||
|
||||
h1 .info {
|
||||
font-size: 11px;
|
||||
float: right;
|
||||
color: #333;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
div.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #FFF, #F8F8F8);
|
||||
color: #333;
|
||||
max-height: 330px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
span.property-name {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding-right: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
span.property-value {
|
||||
padding-right: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
div.group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.group, div#header {
|
||||
background: #FFF;
|
||||
border-color: #E1E1E1;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-moz-border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
img#responseImageNode {
|
||||
-moz-box-shadow: rgba(0,0,0,0.2) 0px 3px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#responseImageNodeDiv {
|
||||
padding: 5px;
|
||||
}
|
@ -54,6 +54,7 @@ toolkit.jar:
|
||||
skin/classic/global/toolbarbutton.css
|
||||
skin/classic/global/tree.css
|
||||
* skin/classic/global/webConsole.css
|
||||
* skin/classic/global/webConsole_networkPanel.css
|
||||
skin/classic/global/wizard.css
|
||||
skin/classic/global/alerts/alert.css (alerts/alert.css)
|
||||
skin/classic/global/arrow/arrow-dn.gif (arrow/arrow-dn.gif)
|
||||
@ -222,6 +223,7 @@ toolkit.jar:
|
||||
* skin/classic/aero/global/toolbarbutton.css (toolbarbutton-aero.css)
|
||||
* skin/classic/aero/global/tree.css (tree-aero.css)
|
||||
* skin/classic/aero/global/webConsole.css
|
||||
* skin/classic/global/webConsole_networkPanel.css
|
||||
skin/classic/aero/global/wizard.css
|
||||
skin/classic/aero/global/alerts/alert.css (alerts/alert.css)
|
||||
skin/classic/aero/global/arrow/arrow-dn.gif (arrow/arrow-dn.gif)
|
||||
|
108
toolkit/themes/winstripe/global/webConsole_networkPanel.css
Normal file
108
toolkit/themes/winstripe/global/webConsole_networkPanel.css
Normal file
@ -0,0 +1,108 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is DevTools code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Walker <jwalker@mozilla.com>
|
||||
* Julian Viereck <jviereck@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
body {
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
div#header {
|
||||
padding: 5px;
|
||||
overflow-x:auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
margin: 0px;
|
||||
background: -moz-linear-gradient(top, #BBB, #999);
|
||||
-moz-border-radius: 2px;
|
||||
text-shadow: #FFF 0px 1px 0px;
|
||||
}
|
||||
|
||||
h1 .info {
|
||||
font-size: 11px;
|
||||
float: right;
|
||||
color: #333;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
div.property-header {
|
||||
padding: 2px 5px;
|
||||
background: -moz-linear-gradient(top, #FFF, #F8F8F8);
|
||||
color: #333;
|
||||
max-height: 330px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
span.property-name {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding-right: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
span.property-value {
|
||||
padding-right: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
div.group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.group, div#header {
|
||||
background: #FFF;
|
||||
border-color: #E1E1E1;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
-moz-border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
img#responseImageNode {
|
||||
-moz-box-shadow: rgba(0,0,0,0.2) 0px 3px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#responseImageNodeDiv {
|
||||
padding: 5px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user