зеркало из https://github.com/mozilla/gecko-dev.git
Bug 861335 - Link network requests from console to network panel. r=vporof
This commit is contained in:
Родитель
855619a1d6
Коммит
3f57def558
|
@ -16,7 +16,6 @@ browser.jar:
|
|||
content/browser/devtools/netmonitor.css (netmonitor/netmonitor.css)
|
||||
content/browser/devtools/netmonitor-controller.js (netmonitor/netmonitor-controller.js)
|
||||
content/browser/devtools/netmonitor-view.js (netmonitor/netmonitor-view.js)
|
||||
content/browser/devtools/NetworkPanel.xhtml (webconsole/NetworkPanel.xhtml)
|
||||
content/browser/devtools/webconsole.xul (webconsole/webconsole.xul)
|
||||
* content/browser/devtools/scratchpad.xul (scratchpad/scratchpad.xul)
|
||||
content/browser/devtools/scratchpad.js (scratchpad/scratchpad.js)
|
||||
|
|
|
@ -322,6 +322,37 @@ let NetMonitorController = {
|
|||
return promise.reject(new Error("Invalid activity type"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the specified request in the waterfall and opens the details view.
|
||||
*
|
||||
* @param string requestId
|
||||
* The actor ID of the request to inspect.
|
||||
* @return object
|
||||
* A promise resolved once the task finishes.
|
||||
*/
|
||||
inspectRequest: function(requestId) {
|
||||
// Look for the request in the existing ones or wait for it to appear, if
|
||||
// the network monitor is still loading.
|
||||
let deferred = promise.defer();
|
||||
let request = null;
|
||||
let inspector = function() {
|
||||
let predicate = i => i.value === requestId;
|
||||
request = NetMonitorView.RequestsMenu.getItemForPredicate(predicate);
|
||||
if (request) {
|
||||
window.off(EVENTS.REQUEST_ADDED, inspector);
|
||||
NetMonitorView.RequestsMenu.filterOn("all");
|
||||
NetMonitorView.RequestsMenu.selectedItem = request;
|
||||
deferred.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
inspector();
|
||||
if (!request) {
|
||||
window.on(EVENTS.REQUEST_ADDED, inspector);
|
||||
}
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter that tells if the server supports sending custom network requests.
|
||||
* @type boolean
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
<?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://browser/locale/devtools/webConsole.dtd" >
|
||||
%webConsoleDTD;
|
||||
]>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- 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/. -->
|
||||
|
||||
|
||||
<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://browser/skin/devtools/webconsole_networkpanel.css" type="text/css"/>
|
||||
</head>
|
||||
<body role="application">
|
||||
<table id="header">
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.requestURLColon;</th>
|
||||
<td class="property-value"
|
||||
id="headUrl"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.requestMethodColon;</th>
|
||||
<td class="property-value"
|
||||
id="headMethod"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.statusCodeColon;</th>
|
||||
<td class="property-value"
|
||||
id="headStatus"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="group">
|
||||
<h1>
|
||||
&networkPanel.requestHeaders;
|
||||
<span id="requestHeadersInfo" class="info"></span>
|
||||
</h1>
|
||||
<table class="property-table" id="requestHeadersContent"></table>
|
||||
|
||||
<div id="requestCookie" style="display:none">
|
||||
<h1>&networkPanel.requestCookie;</h1>
|
||||
<table class="property-table" id="requestCookieContent"></table>
|
||||
</div>
|
||||
|
||||
<div id="requestBody" style="display:none">
|
||||
<h1>&networkPanel.requestBody;</h1>
|
||||
<table class="property-table" id="requestBodyContent"></table>
|
||||
</div>
|
||||
<div id="requestFormData" style="display:none">
|
||||
<h1>&networkPanel.requestFormData;</h1>
|
||||
<table class="property-table" id="requestFormDataContent"></table>
|
||||
</div>
|
||||
<p id="requestBodyFetchLink" style="display:none"></p>
|
||||
</div>
|
||||
|
||||
<div class="group" id="responseContainer" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseHeaders;
|
||||
<span id="responseHeadersInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseHeadersContent"></table>
|
||||
|
||||
<div id="responseCookie" style="display:none">
|
||||
<h1>&networkPanel.responseCookie;</h1>
|
||||
<table class="property-table" id="responseCookieContent"></table>
|
||||
</div>
|
||||
|
||||
<div id="responseBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBody;
|
||||
<span class="info" id="responseBodyInfo">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyContent"></table>
|
||||
</div>
|
||||
<div id="responseBodyCached" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBodyCached;
|
||||
<span class="info" id="responseBodyCachedInfo">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyCachedContent"></table>
|
||||
</div>
|
||||
<div id="responseNoBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseNoBody;
|
||||
<span id="responseNoBodyInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="responseBodyUnknownType" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBodyUnknownType;
|
||||
<span id="responseBodyUnknownTypeInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyUnknownTypeContent"></table>
|
||||
</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>
|
||||
<p id="responseBodyFetchLink" style="display:none"></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -10,7 +10,6 @@ EXTRA_JS_MODULES.devtools.webconsole += [
|
|||
'console-commands.js',
|
||||
'console-output.js',
|
||||
'hudservice.js',
|
||||
'network-panel.js',
|
||||
'panel.js',
|
||||
'webconsole.js',
|
||||
]
|
||||
|
|
|
@ -1,835 +0,0 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
|
||||
loader.lazyGetter(this, "NetworkHelper", () => require("devtools/toolkit/webconsole/network-helper"));
|
||||
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||
loader.lazyServiceGetter(this, "mimeService", "@mozilla.org/mime;1", "nsIMIMEService");
|
||||
|
||||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
|
||||
const STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
let l10n = new WebConsoleUtils.l10n(STRINGS_URI);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new NetworkPanel.
|
||||
*
|
||||
* @constructor
|
||||
* @param nsIDOMNode aParent
|
||||
* Parent node to append the created panel to.
|
||||
* @param object aHttpActivity
|
||||
* HttpActivity to display in the panel.
|
||||
* @param object aWebConsoleFrame
|
||||
* The parent WebConsoleFrame object that owns this network panel
|
||||
* instance.
|
||||
*/
|
||||
function NetworkPanel(aParent, aHttpActivity, aWebConsoleFrame)
|
||||
{
|
||||
let doc = aParent.ownerDocument;
|
||||
this.httpActivity = aHttpActivity;
|
||||
this.webconsole = aWebConsoleFrame;
|
||||
this._responseBodyFetch = this._responseBodyFetch.bind(this);
|
||||
this._requestBodyFetch = this._requestBodyFetch.bind(this);
|
||||
|
||||
// Create the underlaying panel
|
||||
this.panel = createElement(doc, "panel", {
|
||||
label: l10n.getStr("NetworkPanel.label"),
|
||||
titlebar: "normal",
|
||||
noautofocus: "true",
|
||||
noautohide: "true",
|
||||
close: "true"
|
||||
});
|
||||
|
||||
// Create the iframe that displays the NetworkPanel XHTML.
|
||||
this.iframe = createAndAppendElement(this.panel, "iframe", {
|
||||
src: "chrome://browser/content/devtools/NetworkPanel.xhtml",
|
||||
type: "content",
|
||||
flex: "1"
|
||||
});
|
||||
|
||||
let self = this;
|
||||
|
||||
// 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.iframe = null;
|
||||
self.httpActivity = null;
|
||||
self.webconsole = null;
|
||||
|
||||
if (self.linkNode) {
|
||||
self.linkNode._panelOpen = false;
|
||||
self.linkNode = null;
|
||||
}
|
||||
}, false);
|
||||
|
||||
// Set the document object and update the content once the panel is loaded.
|
||||
this.iframe.addEventListener("load", function onLoad() {
|
||||
if (!self.iframe) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iframe.removeEventListener("load", onLoad, true);
|
||||
self.update();
|
||||
}, true);
|
||||
|
||||
this.panel.addEventListener("popupshown", function onPopupShown() {
|
||||
self.panel.removeEventListener("popupshown", onPopupShown, true);
|
||||
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);
|
||||
}
|
||||
exports.NetworkPanel = NetworkPanel;
|
||||
|
||||
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,
|
||||
|
||||
_fromDataRegExp: /Content-Type\:\s*application\/x-www-form-urlencoded/,
|
||||
|
||||
_contentType: null,
|
||||
|
||||
/**
|
||||
* Function callback invoked whenever the panel content is updated. This is
|
||||
* used only by tests.
|
||||
*
|
||||
* @private
|
||||
* @type function
|
||||
*/
|
||||
_onUpdate: null,
|
||||
|
||||
get document() {
|
||||
return this.iframe && this.iframe.contentWindow ?
|
||||
this.iframe.contentWindow.document : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Small helper function that is nearly equal to l10n.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 l10n.getFormatStr("NetworkPanel." + aName, aArray);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the content type of the response body. This is based on the
|
||||
* response.content.mimeType property. If this value is not available, then
|
||||
* the content type is guessed by the file extension of the request URL.
|
||||
*
|
||||
* @return string
|
||||
* Content type or empty string if no content type could be figured
|
||||
* out.
|
||||
*/
|
||||
get contentType()
|
||||
{
|
||||
if (this._contentType) {
|
||||
return this._contentType;
|
||||
}
|
||||
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
let contentType = "";
|
||||
let types = response.content ?
|
||||
(response.content.mimeType || "").split(/,|;/) : [];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
if (types[i] in NetworkHelper.mimeCategoryMap) {
|
||||
contentType = types[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType) {
|
||||
this._contentType = contentType;
|
||||
return contentType;
|
||||
}
|
||||
|
||||
// Try to get the content type from the request file extension.
|
||||
let uri = NetUtil.newURI(request.url);
|
||||
if ((uri instanceof Ci.nsIURL) && uri.fileExtension) {
|
||||
try {
|
||||
contentType = mimeService.getTypeFromExtension(uri.fileExtension);
|
||||
}
|
||||
catch(ex) {
|
||||
// Added to prevent failures on OS X 64. No Flash?
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
this._contentType = contentType;
|
||||
return contentType;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* True if the response is an image, false otherwise.
|
||||
*/
|
||||
get _responseIsImage()
|
||||
{
|
||||
return this.contentType &&
|
||||
NetworkHelper.mimeCategoryMap[this.contentType] == "image";
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* True if the response body contains text, false otherwise.
|
||||
*/
|
||||
get _isResponseBodyTextData()
|
||||
{
|
||||
return this.contentType ?
|
||||
NetworkHelper.isTextMimeType(this.contentType) : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the server response is cached.
|
||||
*
|
||||
* @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 == 304;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the request body includes form data.
|
||||
*
|
||||
* @returns boolean
|
||||
* Returns true if the posted body contains form data.
|
||||
*/
|
||||
get _isRequestBodyFormData()
|
||||
{
|
||||
let requestBody = this.httpActivity.request.postData.text;
|
||||
if (typeof requestBody == "object" && requestBody.type == "longString") {
|
||||
requestBody = requestBody.initial;
|
||||
}
|
||||
return this._fromDataRegExp.test(requestBody);
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends the node with id=aId by the text aValue.
|
||||
*
|
||||
* @private
|
||||
* @param string aId
|
||||
* @param string aValue
|
||||
* @return nsIDOMElement
|
||||
* The DOM element with id=aId.
|
||||
*/
|
||||
_appendTextNode: function NP__appendTextNode(aId, aValue)
|
||||
{
|
||||
let textNode = this.document.createTextNode(aValue);
|
||||
let elem = this.document.getElementById(aId);
|
||||
elem.appendChild(textNode);
|
||||
return elem;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 array aList
|
||||
* Array that holds the objects you want to display. Each object must
|
||||
* have two properties: name and value.
|
||||
* @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;
|
||||
|
||||
aList.sort(function(a, b) {
|
||||
return a.name.toLowerCase() < b.name.toLowerCase();
|
||||
});
|
||||
|
||||
aList.forEach((aItem) => {
|
||||
let name = aItem.name;
|
||||
if (aIgnoreCookie && (name == "Cookie" || name == "Set-Cookie")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let value = aItem.value;
|
||||
let longString = null;
|
||||
if (typeof value == "object" && value.type == "longString") {
|
||||
value = value.initial;
|
||||
longString = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following code creates the HTML:
|
||||
* <tr>
|
||||
* <th scope="row" class="property-name">${line}:</th>
|
||||
* <td class="property-value">${aList[line]}</td>
|
||||
* </tr>
|
||||
* and adds it to parent.
|
||||
*/
|
||||
let row = doc.createElement("tr");
|
||||
let textNode = doc.createTextNode(name + ":");
|
||||
let th = doc.createElement("th");
|
||||
th.setAttribute("scope", "row");
|
||||
th.setAttribute("class", "property-name");
|
||||
th.appendChild(textNode);
|
||||
row.appendChild(th);
|
||||
|
||||
textNode = doc.createTextNode(value);
|
||||
let td = doc.createElement("td");
|
||||
td.setAttribute("class", "property-value");
|
||||
td.appendChild(textNode);
|
||||
|
||||
if (longString) {
|
||||
let a = doc.createElement("a");
|
||||
a.href = "#";
|
||||
a.className = "longStringEllipsis";
|
||||
a.addEventListener("mousedown", this._longStringClick.bind(this, aItem));
|
||||
a.textContent = l10n.getStr("longStringEllipsis");
|
||||
td.appendChild(a);
|
||||
}
|
||||
|
||||
row.appendChild(td);
|
||||
|
||||
parent.appendChild(row);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The click event handler for the ellipsis which allows the user to retrieve
|
||||
* the full header value.
|
||||
*
|
||||
* @private
|
||||
* @param object aHeader
|
||||
* The header object with the |name| and |value| properties.
|
||||
* @param nsIDOMEvent aEvent
|
||||
* The DOM click event object.
|
||||
*/
|
||||
_longStringClick: function NP__longStringClick(aHeader, aEvent)
|
||||
{
|
||||
aEvent.preventDefault();
|
||||
|
||||
let longString = this.webconsole.webConsoleClient.longString(aHeader.value);
|
||||
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
function NP__onLongStringSubstring(aResponse)
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHeader.value = aHeader.value.initial + aResponse.substring;
|
||||
|
||||
let textNode = aEvent.target.previousSibling;
|
||||
textNode.textContent += aResponse.substring;
|
||||
textNode.parentNode.removeChild(aEvent.target);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the node with id=aId.
|
||||
*
|
||||
* @private
|
||||
* @param string aId
|
||||
* @return nsIDOMElement
|
||||
* The element with id=aId.
|
||||
*/
|
||||
_displayNode: function NP__displayNode(aId)
|
||||
{
|
||||
let elem = this.document.getElementById(aId);
|
||||
elem.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 request = this.httpActivity.request;
|
||||
let requestTime = new Date(this.httpActivity.startedDateTime);
|
||||
|
||||
this._appendTextNode("headUrl", request.url);
|
||||
this._appendTextNode("headMethod", request.method);
|
||||
this._appendTextNode("requestHeadersInfo",
|
||||
l10n.timestampString(requestTime));
|
||||
|
||||
this._appendList("requestHeadersContent", request.headers, true);
|
||||
|
||||
if (request.cookies.length > 0) {
|
||||
this._displayNode("requestCookie");
|
||||
this._appendList("requestCookieContent", request.cookies);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the request body section of the NetworkPanel and set the request
|
||||
* body content on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestBody: function NP__displayRequestBody()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData;
|
||||
this._displayNode("requestBody");
|
||||
this._appendTextNode("requestBodyContent", postData.text);
|
||||
},
|
||||
|
||||
/*
|
||||
* Displays the `sent form data` section. Parses the request header for the
|
||||
* submitted form data displays it inside of the `sent form data` section.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestForm: function NP__processRequestForm()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData.text;
|
||||
let requestBodyLines = postData.split("\n");
|
||||
let formData = requestBodyLines[requestBodyLines.length - 1].
|
||||
replace(/\+/g, " ").split("&");
|
||||
|
||||
function unescapeText(aText)
|
||||
{
|
||||
try {
|
||||
return decodeURIComponent(aText);
|
||||
}
|
||||
catch (ex) {
|
||||
return decodeURIComponent(unescape(aText));
|
||||
}
|
||||
}
|
||||
|
||||
let formDataArray = [];
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
let data = formData[i];
|
||||
let idx = data.indexOf("=");
|
||||
let key = data.substring(0, idx);
|
||||
let value = data.substring(idx + 1);
|
||||
formDataArray.push({
|
||||
name: unescapeText(key),
|
||||
value: unescapeText(value)
|
||||
});
|
||||
}
|
||||
|
||||
this._appendList("requestFormDataContent", formDataArray);
|
||||
this._displayNode("requestFormData");
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.timings;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
this._appendTextNode("headStatus",
|
||||
[response.httpVersion, response.status,
|
||||
response.statusText].join(" "));
|
||||
|
||||
// Calculate how much time it took from the request start, until the
|
||||
// response started to be received.
|
||||
let deltaDuration = 0;
|
||||
["dns", "connect", "send", "wait"].forEach(function (aValue) {
|
||||
let ms = timing[aValue];
|
||||
if (ms > -1) {
|
||||
deltaDuration += ms;
|
||||
}
|
||||
});
|
||||
|
||||
this._appendTextNode("responseHeadersInfo",
|
||||
this._format("durationMS", [deltaDuration]));
|
||||
|
||||
this._displayNode("responseContainer");
|
||||
this._appendList("responseHeadersContent", response.headers, true);
|
||||
|
||||
if (response.cookies.length > 0) {
|
||||
this._displayNode("responseCookie");
|
||||
this._appendList("responseCookieContent", response.cookies);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.timings;
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
let cached = "";
|
||||
|
||||
if (this._isResponseCached) {
|
||||
cached = "Cached";
|
||||
}
|
||||
|
||||
let imageNode = this.document.getElementById("responseImage" +
|
||||
cached + "Node");
|
||||
|
||||
let text = response.content.text;
|
||||
if (typeof text == "object" && text.type == "longString") {
|
||||
this._showResponseBodyFetchLink();
|
||||
}
|
||||
else {
|
||||
imageNode.setAttribute("src",
|
||||
"data:" + this.contentType + ";base64," + text);
|
||||
}
|
||||
|
||||
// This function is called to set the imageInfo.
|
||||
function setImageInfo() {
|
||||
self._appendTextNode("responseImage" + cached + "Info",
|
||||
self._format("imageSizeDeltaDurationMS",
|
||||
[ imageNode.width, imageNode.height, timing.receive ]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// 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.timings;
|
||||
let response = this.httpActivity.response;
|
||||
let cached = this._isResponseCached ? "Cached" : "";
|
||||
|
||||
this._appendTextNode("responseBody" + cached + "Info",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
|
||||
this._displayNode("responseBody" + cached);
|
||||
|
||||
let text = response.content.text;
|
||||
if (typeof text == "object") {
|
||||
text = text.initial;
|
||||
this._showResponseBodyFetchLink();
|
||||
}
|
||||
|
||||
this._appendTextNode("responseBody" + cached + "Content", text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the "fetch response body" link.
|
||||
* @private
|
||||
*/
|
||||
_showResponseBodyFetchLink: function NP__showResponseBodyFetchLink()
|
||||
{
|
||||
let content = this.httpActivity.response.content;
|
||||
|
||||
let elem = this._appendTextNode("responseBodyFetchLink",
|
||||
this._format("fetchRemainingResponseContentLink",
|
||||
[content.text.length - content.text.initial.length]));
|
||||
|
||||
elem.style.display = "block";
|
||||
elem.addEventListener("mousedown", this._responseBodyFetch);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event handler for the link that allows users to fetch the remaining
|
||||
* response body.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMEvent aEvent
|
||||
*/
|
||||
_responseBodyFetch: function NP__responseBodyFetch(aEvent)
|
||||
{
|
||||
aEvent.target.style.display = "none";
|
||||
aEvent.target.removeEventListener("mousedown", this._responseBodyFetch);
|
||||
|
||||
let content = this.httpActivity.response.content;
|
||||
let longString = this.webconsole.webConsoleClient.longString(content.text);
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
(aResponse) =>
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
content.text = content.text.initial + aResponse.substring;
|
||||
let cached = this._isResponseCached ? "Cached" : "";
|
||||
|
||||
if (this._responseIsImage) {
|
||||
let imageNode = this.document.getElementById("responseImage" +
|
||||
cached + "Node");
|
||||
imageNode.src =
|
||||
"data:" + this.contentType + ";base64," + content.text;
|
||||
}
|
||||
else {
|
||||
this._appendTextNode("responseBody" + cached + "Content",
|
||||
aResponse.substring);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the `Unknown Content-Type hint` and sets the duration between the
|
||||
* receiving of the response header on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseBodyUnknownType: function NP__displayResponseBodyUnknownType()
|
||||
{
|
||||
let timing = this.httpActivity.timings;
|
||||
|
||||
this._displayNode("responseBodyUnknownType");
|
||||
this._appendTextNode("responseBodyUnknownTypeInfo",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
|
||||
this._appendTextNode("responseBodyUnknownTypeContent",
|
||||
this._format("responseBodyUnableToDisplay.content", [this.contentType]));
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.timings;
|
||||
|
||||
this._displayNode("responseNoBody");
|
||||
this._appendTextNode("responseNoBodyInfo",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the content of the NetworkPanel's iframe.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
update: function NP_update()
|
||||
{
|
||||
if (!this.document || this.document.readyState != "complete") {
|
||||
return;
|
||||
}
|
||||
|
||||
let updates = this.httpActivity.updates;
|
||||
let timing = this.httpActivity.timings;
|
||||
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 (!this.httpActivity.discardRequestBody && request.postData.text) {
|
||||
this._updateRequestBody();
|
||||
this._state = this._DISPLAYED_REQUEST_BODY;
|
||||
}
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_REQUEST_BODY:
|
||||
if (!response.headers.length || !Object.keys(timing).length) {
|
||||
break;
|
||||
}
|
||||
this._displayResponseHeader();
|
||||
this._state = this._DISPLAYED_RESPONSE_HEADER;
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_RESPONSE_HEADER:
|
||||
if (updates.indexOf("responseContent") == -1 ||
|
||||
updates.indexOf("eventTimings") == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
this._state = this._TRANSITION_CLOSED;
|
||||
if (this.httpActivity.discardResponseBody) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!response.content || !response.content.text) {
|
||||
this._displayNoResponseBody();
|
||||
}
|
||||
else if (this._responseIsImage) {
|
||||
this._displayResponseImage();
|
||||
}
|
||||
else if (!this._isResponseBodyTextData) {
|
||||
this._displayResponseBodyUnknownType();
|
||||
}
|
||||
else if (response.content.text) {
|
||||
this._displayResponseBody();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (this._onUpdate) {
|
||||
this._onUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the panel to hold the current information we have about the request
|
||||
* body.
|
||||
* @private
|
||||
*/
|
||||
_updateRequestBody: function NP__updateRequestBody()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData;
|
||||
if (typeof postData.text == "object" && postData.text.type == "longString") {
|
||||
let elem = this._appendTextNode("requestBodyFetchLink",
|
||||
this._format("fetchRemainingRequestContentLink",
|
||||
[postData.text.length - postData.text.initial.length]));
|
||||
|
||||
elem.style.display = "block";
|
||||
elem.addEventListener("mousedown", this._requestBodyFetch);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we send some form data. If so, display the form data special.
|
||||
if (this._isRequestBodyFormData) {
|
||||
this._displayRequestForm();
|
||||
}
|
||||
else {
|
||||
this._displayRequestBody();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event handler for the link that allows users to fetch the remaining
|
||||
* request body.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMEvent aEvent
|
||||
*/
|
||||
_requestBodyFetch: function NP__requestBodyFetch(aEvent)
|
||||
{
|
||||
aEvent.target.style.display = "none";
|
||||
aEvent.target.removeEventListener("mousedown", this._responseBodyFetch);
|
||||
|
||||
let postData = this.httpActivity.request.postData;
|
||||
let longString = this.webconsole.webConsoleClient.longString(postData.text);
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
(aResponse) =>
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
postData.text = postData.text.initial + aResponse.substring;
|
||||
this._updateRequestBody();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (aAttributes) {
|
||||
for (let 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;
|
||||
}
|
|
@ -189,8 +189,6 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_eval_in_debugger_stackframe2.js]
|
||||
[browser_jsterm_inspect.js]
|
||||
[browser_longstring_hang.js]
|
||||
[browser_netpanel_longstring_expand.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_output_breaks_after_console_dir_uninspectable.js]
|
||||
[browser_output_longstring_expand.js]
|
||||
[browser_repeated_messages_accuracy.js]
|
||||
|
@ -227,7 +225,6 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_592442_closing_brackets.js]
|
||||
[browser_webconsole_bug_593003_iframe_wrong_hud.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_594477_clickable_output.js]
|
||||
[browser_webconsole_bug_594497_history_arrow_keys.js]
|
||||
[browser_webconsole_bug_595223_file_uri.js]
|
||||
[browser_webconsole_bug_595350_multiple_windows_and_tabs.js]
|
||||
|
@ -245,8 +242,6 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_601177_log_levels.js]
|
||||
[browser_webconsole_bug_601352_scroll.js]
|
||||
[browser_webconsole_bug_601667_filter_buttons.js]
|
||||
[browser_webconsole_bug_602572_log_bodies_checkbox.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_603750_websocket.js]
|
||||
[browser_webconsole_bug_611795.js]
|
||||
[browser_webconsole_bug_613013_console_api_iframe.js]
|
||||
|
@ -255,7 +250,6 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_613642_prune_scroll.js]
|
||||
[browser_webconsole_bug_614793_jsterm_scroll.js]
|
||||
[browser_webconsole_bug_618078_network_exceptions.js]
|
||||
[browser_webconsole_bug_618311_close_panels.js]
|
||||
[browser_webconsole_bug_621644_jsterm_dollar.js]
|
||||
[browser_webconsole_bug_622303_persistent_filters.js]
|
||||
[browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js]
|
||||
|
@ -334,7 +328,6 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
|||
[browser_webconsole_live_filtering_on_search_strings.js]
|
||||
[browser_webconsole_message_node_id.js]
|
||||
[browser_webconsole_netlogging.js]
|
||||
[browser_webconsole_network_panel.js]
|
||||
[browser_webconsole_notifications.js]
|
||||
[browser_webconsole_open-links-without-callback.js]
|
||||
[browser_webconsole_promise.js]
|
||||
|
|
|
@ -1,312 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
// Tests that the network panel works with LongStringActors.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-image.png";
|
||||
|
||||
const TEST_IMG_BASE64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAVRJ" +
|
||||
"REFUOI2lk7FLw0AUxr+YpC1CBqcMWfsvCCLdXFzqEJCgDl1EQRGxg9AhSBEJONhFhG52UCuF" +
|
||||
"Djq5dxD8FwoO0qGDOBQkl7vLOeWa2EQDffDBvTu+373Hu1OEEJgntGgxGD6J+7fLXKbt5VNU" +
|
||||
"yhsKAChRBQcPFVFeWskFGH694mZroCQqCLlAwPxcgJBP254CmAD5B7C7dgHLMLF3uzoL4DQE" +
|
||||
"od+Z5sP1FizDxGgyBqfhLID9AahX29J89bwPFgMsSEAQglAf9WobhPpScbPXr4FQHyzIADTs" +
|
||||
"DizDRMPuIOC+zEeTMZo9BwH3EfAMACccbtfGaDKGZZg423yUZrdrg3EqxQlPr0BTdTR7joRE" +
|
||||
"N2uqnlBmCwW1hIJagtev4f3zA16/JvfiigMSYyzqJXlw/XKUyOORMUaBor6YavgdjKa8xGOn" +
|
||||
"idadmwtwsnMu18q83/kHSou+bFNDDr4AAAAASUVORK5CYII=";
|
||||
|
||||
let testDriver;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(testNetworkPanel);
|
||||
});
|
||||
}
|
||||
|
||||
function testNetworkPanel() {
|
||||
testDriver = testGen();
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
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 headers = node.querySelectorAll("th");
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
if (headers[i].textContent == (aKey + ":")) {
|
||||
is(headers[i].nextElementSibling.textContent, aValue,
|
||||
"checking content of " + aId + " for key " + aKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ok(false, "content check failed for " + aId + ", key " + aKey);
|
||||
}
|
||||
|
||||
function* testGen() {
|
||||
let hud = HUDService.getHudByWindow(content);
|
||||
let filterBox = hud.ui.filterBox;
|
||||
|
||||
let headerValue = (new Array(456)).join("fooz bar");
|
||||
let headerValueGrip = {
|
||||
type: "longString",
|
||||
initial: headerValue.substr(0, 123),
|
||||
length: headerValue.length,
|
||||
actor: "faktor",
|
||||
_fullString: headerValue,
|
||||
};
|
||||
|
||||
let imageContentGrip = {
|
||||
type: "longString",
|
||||
initial: TEST_IMG_BASE64.substr(0, 143),
|
||||
length: TEST_IMG_BASE64.length,
|
||||
actor: "faktor2",
|
||||
_fullString: TEST_IMG_BASE64,
|
||||
};
|
||||
|
||||
let postDataValue = (new Array(123)).join("post me");
|
||||
let postDataGrip = {
|
||||
type: "longString",
|
||||
initial: postDataValue.substr(0, 172),
|
||||
length: postDataValue.length,
|
||||
actor: "faktor3",
|
||||
_fullString: postDataValue,
|
||||
};
|
||||
|
||||
let httpActivity = {
|
||||
updates: ["responseContent", "eventTimings"],
|
||||
discardRequestBody: false,
|
||||
discardResponseBody: false,
|
||||
startedDateTime: (new Date()).toISOString(),
|
||||
request: {
|
||||
url: TEST_IMG,
|
||||
method: "GET",
|
||||
cookies: [],
|
||||
headers: [
|
||||
{ name: "foo", value: "bar" },
|
||||
{ name: "loongstring", value: headerValueGrip },
|
||||
],
|
||||
postData: { text: postDataGrip },
|
||||
},
|
||||
response: {
|
||||
httpVersion: "HTTP/3.14",
|
||||
status: 2012,
|
||||
statusText: "ddahl likes tacos :)",
|
||||
headers: [
|
||||
{ name: "Content-Type", value: "image/png" },
|
||||
],
|
||||
content: { mimeType: "image/png", text: imageContentGrip },
|
||||
cookies: [],
|
||||
},
|
||||
timings: { wait: 15, receive: 23 },
|
||||
};
|
||||
|
||||
let networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on the anchor object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("test 1: check if a header value is expandable");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
requestBody: false,
|
||||
requestBodyFetchLink: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: true,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: true,
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "foo", "bar");
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "loongstring",
|
||||
headerValueGrip.initial + "[\u2026]");
|
||||
|
||||
let webConsoleClient = networkPanel.webconsole.webConsoleClient;
|
||||
let longStringFn = webConsoleClient.longString;
|
||||
|
||||
let expectedGrip = headerValueGrip;
|
||||
|
||||
function longStringClientProvider(aLongString) {
|
||||
is(aLongString, expectedGrip,
|
||||
"longString grip is correct");
|
||||
|
||||
return {
|
||||
initial: expectedGrip.initial,
|
||||
length: expectedGrip.length,
|
||||
substring: function(aStart, aEnd, aCallback) {
|
||||
is(aStart, expectedGrip.initial.length,
|
||||
"substring start is correct");
|
||||
is(aEnd, expectedGrip.length,
|
||||
"substring end is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
aCallback({
|
||||
substring: expectedGrip._fullString.substring(aStart, aEnd),
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
webConsoleClient.longString = longStringClientProvider;
|
||||
|
||||
let clickable = networkPanel.document
|
||||
.querySelector("#requestHeadersContent .longStringEllipsis");
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
clickable = networkPanel.document
|
||||
.querySelector("#requestHeadersContent .longStringEllipsis");
|
||||
ok(!clickable, "long string ellipsis is not shown");
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "loongstring",
|
||||
expectedGrip._fullString);
|
||||
|
||||
info("test 2: check that response body image fetching works");
|
||||
expectedGrip = imageContentGrip;
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
ok(!imgNode.getAttribute("src"), "no image is displayed");
|
||||
|
||||
clickable = networkPanel.document.querySelector("#responseBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"displayed image is correct");
|
||||
is(clickable.style.display, "none", "#responseBodyFetchLink is not visible");
|
||||
|
||||
info("test 3: expand the request body");
|
||||
|
||||
expectedGrip = postDataGrip;
|
||||
|
||||
clickable = networkPanel.document.querySelector("#requestBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
yield undefined;
|
||||
|
||||
is(clickable.style.display, "none", "#requestBodyFetchLink is not visible");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestBodyFetchLink: false,
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "requestBodyContent",
|
||||
expectedGrip._fullString);
|
||||
|
||||
webConsoleClient.longString = longStringFn;
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
info("test 4: reponse body long text");
|
||||
|
||||
httpActivity.response.content.mimeType = "text/plain";
|
||||
httpActivity.response.headers[0].value = "text/plain";
|
||||
|
||||
expectedGrip = imageContentGrip;
|
||||
|
||||
// Reset response.content.text to avoid caching of the full string.
|
||||
httpActivity.response.content.text = expectedGrip;
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
requestBody: true,
|
||||
requestBodyFetchLink: false,
|
||||
responseContainer: true,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: true,
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "responseBodyContent", expectedGrip.initial);
|
||||
|
||||
webConsoleClient.longString = longStringClientProvider;
|
||||
|
||||
clickable = networkPanel.document.querySelector("#responseBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
webConsoleClient.longString = longStringFn;
|
||||
is(clickable.style.display, "none", "#responseBodyFetchLink is not visible");
|
||||
checkNodeContent(networkPanel, "responseBodyContent",
|
||||
expectedGrip._fullString);
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// All done!
|
||||
testDriver = null;
|
||||
executeSoon(finishTest);
|
||||
|
||||
yield undefined;
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
let HUD;
|
||||
let outputItem;
|
||||
let outputNode;
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
HUD = yield openConsole();
|
||||
outputNode = HUD.outputNode;
|
||||
|
||||
// reload the tab
|
||||
BrowserReload();
|
||||
yield loadBrowser(gBrowser.selectedBrowser);
|
||||
|
||||
let event = yield clickEvents();
|
||||
yield testClickAgain(event);
|
||||
yield networkPanelHidden();
|
||||
|
||||
HUD = outputItem = outputNode = null;
|
||||
});
|
||||
|
||||
function clickEvents() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForMessages({
|
||||
webconsole: HUD,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(([result]) => {
|
||||
let msg = [...result.matched][0];
|
||||
outputItem = msg.querySelector(".message-body .url");
|
||||
ok(outputItem, "found a network message");
|
||||
document.addEventListener("popupshown", function onPanelShown(event) {
|
||||
document.removeEventListener("popupshown", onPanelShown, false);
|
||||
deferred.resolve(event);
|
||||
}, false);
|
||||
|
||||
// Send the mousedown and click events such that the network panel opens.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testClickAgain(event) {
|
||||
info("testClickAgain");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
document.addEventListener("popupshown", networkPanelShowFailure, false);
|
||||
|
||||
// The network panel should not open for the second time.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
|
||||
executeSoon(function() {
|
||||
document.addEventListener("popuphidden", function onHidden() {
|
||||
document.removeEventListener("popuphidden", onHidden, false);
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
event.target.hidePopup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function networkPanelShowFailure() {
|
||||
ok(false, "the network panel should not show");
|
||||
}
|
||||
|
||||
function networkPanelHidden() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
info("networkPanelHidden");
|
||||
|
||||
// The network panel should not show because this is a mouse event that starts
|
||||
// in a position and ends in another.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", clientX: 3, clientY: 4},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", clientX: 5, clientY: 6},
|
||||
outputItem);
|
||||
|
||||
// The network panel should not show because this is a middle-click.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", button: 1},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", button: 1},
|
||||
outputItem);
|
||||
|
||||
// The network panel should not show because this is a right-click.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", button: 2},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", button: 2},
|
||||
outputItem);
|
||||
|
||||
executeSoon(function() {
|
||||
document.removeEventListener("popupshown", networkPanelShowFailure, false);
|
||||
|
||||
// Done with the network output. Now test the jsterm output and the property
|
||||
// panel.
|
||||
HUD.jsterm.execute("document").then((msg) => {
|
||||
info("jsterm execute 'document' callback");
|
||||
|
||||
HUD.jsterm.once("variablesview-open", deferred.resolve);
|
||||
outputItem = msg.querySelector(".message-body a");
|
||||
ok(outputItem, "jsterm output message found");
|
||||
|
||||
// Send the mousedown and click events such that the property panel opens.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
let menuitems = [];
|
||||
let menupopups = [];
|
||||
let huds = [];
|
||||
let tabs = [];
|
||||
let runCount = 0;
|
||||
|
||||
const TEST_URI1 = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 602572: log bodies checkbox. tab 1";
|
||||
const TEST_URI2 = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 602572: log bodies checkbox. tab 2";
|
||||
|
||||
function test() {
|
||||
if (runCount == 0) {
|
||||
requestLongerTimeout(2);
|
||||
}
|
||||
|
||||
// open tab 2
|
||||
function openTab() {
|
||||
loadTab(TEST_URI2).then((tab) => {
|
||||
tabs.push(tab.tab);
|
||||
openConsole().then((hud) => {
|
||||
hud.iframeWindow.requestAnimationFrame(startTest);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// open tab 1
|
||||
loadTab(TEST_URI1).then((tab) => {
|
||||
tabs.push(tab.tab);
|
||||
openConsole().then((hud) => {
|
||||
hud.iframeWindow.requestAnimationFrame(() => {
|
||||
info("iframe1 root height " + hud.ui.rootElement.clientHeight);
|
||||
|
||||
openTab();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
// Find the relevant elements in the Web Console of tab 2.
|
||||
let win2 = tabs[runCount * 2 + 1].linkedBrowser.contentWindow;
|
||||
huds[1] = HUDService.getHudByWindow(win2);
|
||||
info("startTest: iframe2 root height " + huds[1].ui.rootElement.clientHeight);
|
||||
|
||||
if (runCount == 0) {
|
||||
menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodies");
|
||||
} else {
|
||||
menuitems[1] = huds[1].ui.rootElement
|
||||
.querySelector("#saveBodiesContextMenu");
|
||||
}
|
||||
menupopups[1] = menuitems[1].parentNode;
|
||||
|
||||
// Open the context menu from tab 2.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2, false);
|
||||
executeSoon(function() {
|
||||
menupopups[1].openPopup();
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown2(evt) {
|
||||
menupopups[1].removeEventListener(evt.type, onpopupshown2, false);
|
||||
|
||||
// By default bodies are not logged.
|
||||
isnot(menuitems[1].getAttribute("checked"), "true",
|
||||
"menuitems[1] is not checked");
|
||||
|
||||
ok(!huds[1].ui._saveRequestAndResponseBodies, "bodies are not logged");
|
||||
|
||||
// Enable body logging.
|
||||
huds[1].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Reopen the context menu.
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2b(evtPopup));
|
||||
menupopups[1].openPopup();
|
||||
}, false);
|
||||
}
|
||||
|
||||
function testpopup2b() {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Switch to tab 1 and open the Web Console context menu from there.
|
||||
gBrowser.selectedTab = tabs[runCount * 2];
|
||||
waitForFocus(function() {
|
||||
// Find the relevant elements in the Web Console of tab 1.
|
||||
let win1 = tabs[runCount * 2].linkedBrowser.contentWindow;
|
||||
huds[0] = HUDService.getHudByWindow(win1);
|
||||
|
||||
info("iframe1 root height " + huds[0].ui.rootElement.clientHeight);
|
||||
|
||||
menuitems[0] = huds[0].ui.rootElement.querySelector("#saveBodies");
|
||||
menupopups[0] = huds[0].ui.rootElement.querySelector("menupopup");
|
||||
|
||||
menupopups[0].addEventListener("popupshown", onpopupshown1, false);
|
||||
executeSoon(() => menupopups[0].openPopup());
|
||||
}, tabs[runCount * 2].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown1(evt) {
|
||||
menupopups[0].removeEventListener(evt.type, onpopupshown1, false);
|
||||
|
||||
// The menuitem checkbox must not be in sync with the other tabs.
|
||||
isnot(menuitems[0].getAttribute("checked"), "true",
|
||||
"menuitems[0] is not checked");
|
||||
|
||||
// Enable body logging for tab 1 as well.
|
||||
huds[0].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[0].hidePopup();
|
||||
});
|
||||
|
||||
// Close the menu, and switch back to tab 2.
|
||||
menupopups[0].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[0].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[0] hidden");
|
||||
|
||||
gBrowser.selectedTab = tabs[runCount * 2 + 1];
|
||||
waitForFocus(function() {
|
||||
// Reopen the context menu from tab 2.
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2c(evtPopup));
|
||||
menupopups[1].openPopup();
|
||||
}, tabs[runCount * 2 + 1].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function testpopup2c() {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Done if on second run
|
||||
closeConsole(gBrowser.selectedTab).then(function() {
|
||||
if (runCount == 0) {
|
||||
runCount++;
|
||||
info("start second run");
|
||||
executeSoon(test);
|
||||
} else {
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[2];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[1];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
gBrowser.removeCurrentTab();
|
||||
huds = menuitems = menupopups = tabs = null;
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
BrowserReload();
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
yield performTest(hud, results);
|
||||
});
|
||||
|
||||
function performTest(HUD, results) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let networkMessage = [...results[0].matched][0];
|
||||
ok(networkMessage, "network message element");
|
||||
|
||||
let networkLink = networkMessage.querySelector(".url");
|
||||
ok(networkLink, "found network message link");
|
||||
|
||||
let popupset = document.getElementById("mainPopupSet");
|
||||
ok(popupset, "found #mainPopupSet");
|
||||
|
||||
let popupsShown = 0;
|
||||
let hiddenPopups = 0;
|
||||
|
||||
let onpopupshown = function() {
|
||||
document.removeEventListener("popupshown", onpopupshown, false);
|
||||
popupsShown++;
|
||||
|
||||
executeSoon(function() {
|
||||
let popups = popupset.querySelectorAll("panel[hudId=" + HUD.hudId + "]");
|
||||
is(popups.length, 1, "found one popup");
|
||||
|
||||
document.addEventListener("popuphidden", onpopuphidden, false);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(hiddenPopups, 1, "correct number of popups hidden");
|
||||
if (hiddenPopups != 1) {
|
||||
document.removeEventListener("popuphidden", onpopuphidden, false);
|
||||
}
|
||||
});
|
||||
|
||||
executeSoon(closeConsole);
|
||||
});
|
||||
};
|
||||
|
||||
let onpopuphidden = function() {
|
||||
document.removeEventListener("popuphidden", onpopuphidden, false);
|
||||
hiddenPopups++;
|
||||
|
||||
executeSoon(function() {
|
||||
let popups = popupset.querySelectorAll("panel[hudId=" + HUD.hudId + "]");
|
||||
is(popups.length, 0, "no popups found");
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("popupshown", onpopupshown, false);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(popupsShown, 1, "correct number of popups shown");
|
||||
if (popupsShown != 1) {
|
||||
document.removeEventListener("popupshown", onpopupshown, false);
|
||||
}
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, networkLink,
|
||||
HUD.iframeWindow);
|
||||
EventUtils.sendMouseEvent({ type: "mouseup" }, networkLink, HUD.iframeWindow);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, networkLink, HUD.iframeWindow);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -191,20 +191,22 @@ function testFormSubmission() {
|
|||
function testNetworkPanel() {
|
||||
// Open the NetworkPanel. The functionality of the NetworkPanel is tested
|
||||
// within separate test files.
|
||||
let networkPanel = hud.ui.openNetworkPanel(hud.ui.filterBox, lastRequest);
|
||||
|
||||
networkPanel.panel.addEventListener("popupshown", function onPopupShown() {
|
||||
networkPanel.panel.removeEventListener("popupshown", onPopupShown, true);
|
||||
|
||||
is(hud.ui.filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on anchor node");
|
||||
ok(true, "NetworkPanel was opened");
|
||||
hud.ui.openNetworkPanel(lastRequest.actor).then(() => {
|
||||
let toolbox = gDevTools.getToolbox(hud.target);
|
||||
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let selected = panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
|
||||
is(selected.attachment.method, lastRequest.request.method,
|
||||
"The correct request is selected");
|
||||
is(selected.attachment.url, lastRequest.request.url,
|
||||
"The correct request is definitely selected");
|
||||
|
||||
// All tests are done. Shutdown.
|
||||
networkPanel.panel.hidePopup();
|
||||
lastRequest = null;
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
browser = requestCallback = hud = null;
|
||||
executeSoon(finishTest);
|
||||
}, true);
|
||||
}).then(null, error => {
|
||||
ok(false, "Got an error: " + error.message + "\n" + error.stack);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,551 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
// Tests that the network panel works.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-image.png";
|
||||
const TEST_ENCODING_ISO_8859_1 = "http://example.com/browser/browser/" +
|
||||
"devtools/webconsole/test/" +
|
||||
"test-encoding-ISO-8859-1.html";
|
||||
|
||||
const TEST_IMG_BASE64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAVRJ" +
|
||||
"REFUOI2lk7FLw0AUxr+YpC1CBqcMWfsvCCLdXFzqEJCgDl1EQRGxg9AhSBEJONhFhG52UCuF" +
|
||||
"Djq5dxD8FwoO0qGDOBQkl7vLOeWa2EQDffDBvTu+373Hu1OEEJgntGgxGD6J+7fLXKbt5VNU" +
|
||||
"yhsKAChRBQcPFVFeWskFGH694mZroCQqCLlAwPxcgJBP254CmAD5B7C7dgHLMLF3uzoL4DQE" +
|
||||
"od+Z5sP1FizDxGgyBqfhLID9AahX29J89bwPFgMsSEAQglAf9WobhPpScbPXr4FQHyzIADTs" +
|
||||
"DizDRMPuIOC+zEeTMZo9BwH3EfAMACccbtfGaDKGZZg423yUZrdrg3EqxQlPr0BTdTR7joRE" +
|
||||
"N2uqnlBmCwW1hIJagtev4f3zA16/JvfiigMSYyzqJXlw/XKUyOORMUaBor6YavgdjKa8xGOn" +
|
||||
"idadmwtwsnMu18q83/kHSou+bFNDDr4AAAAASUVORK5CYII=";
|
||||
|
||||
let testDriver, hud;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(testNetworkPanel);
|
||||
});
|
||||
}
|
||||
|
||||
function testNetworkPanel(aHud) {
|
||||
hud = aHud;
|
||||
testDriver = testGen();
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
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 headers = node.querySelectorAll("th");
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
if (headers[i].textContent == (aKey + ":")) {
|
||||
is(headers[i].nextElementSibling.textContent, aValue,
|
||||
"checking content of " + aId + " for key " + aKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ok(false, "content check failed for " + aId + ", key " + aKey);
|
||||
}
|
||||
|
||||
function* testGen() {
|
||||
let filterBox = hud.ui.filterBox;
|
||||
|
||||
let httpActivity = {
|
||||
updates: [],
|
||||
discardRequestBody: true,
|
||||
discardResponseBody: true,
|
||||
startedDateTime: (new Date()).toISOString(),
|
||||
request: {
|
||||
url: "http://www.testpage.com",
|
||||
method: "GET",
|
||||
cookies: [],
|
||||
headers: [
|
||||
{ name: "foo", value: "bar" },
|
||||
],
|
||||
},
|
||||
response: {
|
||||
headers: [],
|
||||
content: {},
|
||||
cookies: [],
|
||||
},
|
||||
timings: {},
|
||||
};
|
||||
|
||||
let networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on the anchor object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("test 1");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: 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.
|
||||
info("test 2: request body");
|
||||
httpActivity.discardRequestBody = false;
|
||||
httpActivity.request.postData = { text: "hello world" };
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: false,
|
||||
responseContainer: false,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
checkNodeContent(networkPanel, "requestBodyContent", "hello world");
|
||||
|
||||
// Test response header.
|
||||
info("test 3: response header");
|
||||
httpActivity.timings.wait = 10;
|
||||
httpActivity.response.httpVersion = "HTTP/3.14";
|
||||
httpActivity.response.status = 999;
|
||||
httpActivity.response.statusText = "earthquake win";
|
||||
httpActivity.response.content.mimeType = "text/html";
|
||||
httpActivity.response.headers.push(
|
||||
{ name: "Content-Type", value: "text/html" },
|
||||
{ name: "leaveHouses", value: "true" }
|
||||
);
|
||||
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "header", "HTTP/3.14 999 earthquake win");
|
||||
checkNodeKeyValue(networkPanel, "responseHeadersContent", "leaveHouses",
|
||||
"true");
|
||||
checkNodeContent(networkPanel, "responseHeadersInfo", "10ms");
|
||||
|
||||
info("test 4");
|
||||
|
||||
httpActivity.discardResponseBody = false;
|
||||
httpActivity.timings.receive = 2;
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
info("test 5");
|
||||
|
||||
httpActivity.updates.push("responseContent", "eventTimings");
|
||||
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.
|
||||
info("test 6: cookies and response body");
|
||||
httpActivity.request.cookies.push(
|
||||
{ name: "foo", value: "bar" },
|
||||
{ name: "hello", value: "world" }
|
||||
);
|
||||
httpActivity.response.content.text = "get out here";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseCookie: false,
|
||||
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();
|
||||
|
||||
// Third run: Test for response cookies.
|
||||
info("test 6b: response cookies");
|
||||
httpActivity.response.cookies.push(
|
||||
{ name: "foobar", value: "boom" },
|
||||
{ name: "foobaz", value: "omg" }
|
||||
);
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseCookie: true,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: false,
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "responseCookieContent", "foobar", "boom");
|
||||
checkNodeKeyValue(networkPanel, "responseCookieContent", "foobaz", "omg");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Check image request.
|
||||
info("test 7: image request");
|
||||
httpActivity.response.headers[1].value = "image/png";
|
||||
httpActivity.response.content.mimeType = "image/png";
|
||||
httpActivity.response.content.text = TEST_IMG_BASE64;
|
||||
httpActivity.request.url = TEST_IMG;
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: true,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: false,
|
||||
});
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"Displayed image is correct");
|
||||
|
||||
function checkImageResponseInfo() {
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "2ms");
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "16x16px");
|
||||
}
|
||||
|
||||
// Check if the image is loaded already.
|
||||
imgNode.addEventListener("load", function onLoad() {
|
||||
imgNode.removeEventListener("load", onLoad, false);
|
||||
checkImageResponseInfo();
|
||||
networkPanel.panel.hidePopup();
|
||||
testDriver.next();
|
||||
}, false);
|
||||
yield undefined;
|
||||
|
||||
// Check cached image request.
|
||||
info("test 8: cached image request");
|
||||
httpActivity.response.httpVersion = "HTTP/1.1";
|
||||
httpActivity.response.status = 304;
|
||||
httpActivity.response.statusText = "Not Modified";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
imgNode = networkPanel.document.getElementById("responseImageCachedNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"Displayed image is correct");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test sent form data.
|
||||
info("test 9: sent form data");
|
||||
httpActivity.request.postData.text = [
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
"Content-Length: 59",
|
||||
"name=rob&age=20"
|
||||
].join("\n");
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestFormDataContent", "name", "rob");
|
||||
checkNodeKeyValue(networkPanel, "requestFormDataContent", "age", "20");
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test no space after Content-Type:
|
||||
info("test 10: no space after Content-Type header in post data");
|
||||
httpActivity.request.postData.text = "Content-Type:application/x-www-" +
|
||||
"form-urlencoded\n";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test cached data.
|
||||
|
||||
info("test 11: cached data");
|
||||
|
||||
httpActivity.request.url = TEST_ENCODING_ISO_8859_1;
|
||||
httpActivity.response.headers[1].value = "application/json";
|
||||
httpActivity.response.content.mimeType = "application/json";
|
||||
httpActivity.response.content.text = "my cached data is here!";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "responseBodyCachedContent",
|
||||
"my cached data is here!");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test a response with a content type that can't be displayed in the
|
||||
// NetworkPanel.
|
||||
info("test 12: unknown content type");
|
||||
httpActivity.response.headers[1].value = "application/x-shockwave-flash";
|
||||
httpActivity.response.content.mimeType = "application/x-shockwave-flash";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: false,
|
||||
responseBodyUnknownType: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
let responseString =
|
||||
WCUL10n.getFormatStr("NetworkPanel.responseBodyUnableToDisplay.content",
|
||||
["application/x-shockwave-flash"]);
|
||||
checkNodeContent(networkPanel,
|
||||
"responseBodyUnknownTypeContent",
|
||||
responseString);
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
/*
|
||||
|
||||
// This test disabled. See bug 603620.
|
||||
|
||||
// Test if the NetworkPanel figures out the content type based on an URL as
|
||||
// well.
|
||||
delete httpActivity.response.header["Content-Type"];
|
||||
httpActivity.url = "http://www.test.com/someCrazyFile.swf?done=right&ending=txt";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel.isDoneCallback = function NP_doneCallback() {
|
||||
networkPanel.isDoneCallback = null;
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: false,
|
||||
responseBodyUnknownType: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
// Systems without Flash installed will return an empty string here. Ignore.
|
||||
if (networkPanel.document.getElementById("responseBodyUnknownTypeContent").textContent !== "")
|
||||
checkNodeContent(networkPanel, "responseBodyUnknownTypeContent", responseString);
|
||||
else
|
||||
ok(true, "Flash not installed");
|
||||
|
||||
networkPanel.panel.hidePopup(); */
|
||||
|
||||
// All done!
|
||||
testDriver = hud = null;
|
||||
executeSoon(finishTest);
|
||||
|
||||
yield undefined;
|
||||
}
|
|
@ -20,8 +20,6 @@ loader.lazyGetter(this, "AutocompletePopup",
|
|||
() => require("devtools/shared/autocomplete-popup").AutocompletePopup);
|
||||
loader.lazyGetter(this, "ToolSidebar",
|
||||
() => require("devtools/framework/sidebar").ToolSidebar);
|
||||
loader.lazyGetter(this, "NetworkPanel",
|
||||
() => require("devtools/webconsole/network-panel").NetworkPanel);
|
||||
loader.lazyGetter(this, "ConsoleOutput",
|
||||
() => require("devtools/webconsole/console-output").ConsoleOutput);
|
||||
loader.lazyGetter(this, "Messages",
|
||||
|
@ -1673,11 +1671,7 @@ WebConsoleFrame.prototype = {
|
|||
statusNode.className = "status";
|
||||
body.appendChild(statusNode);
|
||||
|
||||
let onClick = () => {
|
||||
if (!messageNode._panelOpen) {
|
||||
this.openNetworkPanel(messageNode, networkInfo);
|
||||
}
|
||||
};
|
||||
let onClick = () => this.openNetworkPanel(networkInfo.actor);
|
||||
|
||||
this._addMessageLinkCallback(urlNode, onClick);
|
||||
this._addMessageLinkCallback(statusNode, onClick);
|
||||
|
@ -1969,134 +1963,17 @@ WebConsoleFrame.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Opens a NetworkPanel.
|
||||
* Opens the network monitor and highlights the specified request.
|
||||
*
|
||||
* @param nsIDOMNode aNode
|
||||
* The message node you want the panel to be anchored to.
|
||||
* @param object aHttpActivity
|
||||
* The HTTP activity object that holds network request and response
|
||||
* information. This object is given to the NetworkPanel constructor.
|
||||
* @return object
|
||||
* The new NetworkPanel instance.
|
||||
* @param string requestId
|
||||
* The actor ID of the network request.
|
||||
*/
|
||||
openNetworkPanel: function WCF_openNetworkPanel(aNode, aHttpActivity)
|
||||
openNetworkPanel: function WCF_openNetworkPanel(requestId)
|
||||
{
|
||||
let actor = aHttpActivity.actor;
|
||||
|
||||
if (actor) {
|
||||
this.webConsoleClient.getRequestHeaders(actor, (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestHeaders:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.headers = aResponse.headers;
|
||||
|
||||
this.webConsoleClient.getRequestCookies(actor, onRequestCookies);
|
||||
});
|
||||
}
|
||||
|
||||
let onRequestCookies = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestCookies:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.cookies = aResponse.cookies;
|
||||
|
||||
this.webConsoleClient.getResponseHeaders(actor, onResponseHeaders);
|
||||
};
|
||||
|
||||
let onResponseHeaders = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseHeaders:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.headers = aResponse.headers;
|
||||
|
||||
this.webConsoleClient.getResponseCookies(actor, onResponseCookies);
|
||||
};
|
||||
|
||||
let onResponseCookies = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseCookies:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.cookies = aResponse.cookies;
|
||||
|
||||
this.webConsoleClient.getRequestPostData(actor, onRequestPostData);
|
||||
};
|
||||
|
||||
let onRequestPostData = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestPostData:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.postData = aResponse.postData;
|
||||
aHttpActivity.discardRequestBody = aResponse.postDataDiscarded;
|
||||
|
||||
this.webConsoleClient.getResponseContent(actor, onResponseContent);
|
||||
};
|
||||
|
||||
let onResponseContent = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseContent:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.content = aResponse.content;
|
||||
aHttpActivity.discardResponseBody = aResponse.contentDiscarded;
|
||||
|
||||
this.webConsoleClient.getEventTimings(actor, onEventTimings);
|
||||
};
|
||||
|
||||
let onEventTimings = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getEventTimings:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.timings = aResponse.timings;
|
||||
|
||||
openPanel();
|
||||
};
|
||||
|
||||
let openPanel = () => {
|
||||
aNode._netPanel = netPanel;
|
||||
|
||||
let panel = netPanel.panel;
|
||||
panel.openPopup(aNode, "after_pointer", 0, 0, false, false);
|
||||
panel.sizeTo(450, 500);
|
||||
panel.setAttribute("hudId", this.hudId);
|
||||
|
||||
panel.addEventListener("popuphiding", function WCF_netPanel_onHide() {
|
||||
panel.removeEventListener("popuphiding", WCF_netPanel_onHide);
|
||||
|
||||
aNode._panelOpen = false;
|
||||
aNode._netPanel = null;
|
||||
});
|
||||
|
||||
aNode._panelOpen = true;
|
||||
};
|
||||
|
||||
let netPanel = new NetworkPanel(this.popupset, aHttpActivity, this);
|
||||
netPanel.linkNode = aNode;
|
||||
|
||||
if (!actor) {
|
||||
openPanel();
|
||||
}
|
||||
|
||||
return netPanel;
|
||||
let toolbox = gDevTools.getToolbox(this.owner.target);
|
||||
return toolbox.selectTool("netmonitor").then(panel => {
|
||||
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,24 +11,6 @@
|
|||
<!ENTITY window.title "Web Console">
|
||||
<!ENTITY browserConsole.title "Browser Console">
|
||||
|
||||
<!ENTITY networkPanel.requestURLColon "Request URL:">
|
||||
<!ENTITY networkPanel.requestMethodColon "Request Method:">
|
||||
<!ENTITY networkPanel.statusCodeColon "Status Code:">
|
||||
|
||||
<!ENTITY networkPanel.requestHeaders "Request Headers">
|
||||
<!ENTITY networkPanel.requestCookie "Sent Cookie">
|
||||
<!ENTITY networkPanel.requestBody "Request Body">
|
||||
<!ENTITY networkPanel.requestFormData "Sent Form Data">
|
||||
|
||||
<!ENTITY networkPanel.responseHeaders "Response Headers">
|
||||
<!ENTITY networkPanel.responseCookie "Received Cookie">
|
||||
<!ENTITY networkPanel.responseBody "Response Body">
|
||||
<!ENTITY networkPanel.responseBodyCached "Cached Data">
|
||||
<!ENTITY networkPanel.responseBodyUnknownType "Unknown Content Type">
|
||||
<!ENTITY networkPanel.responseNoBody "No Response Body">
|
||||
<!ENTITY networkPanel.responseImage "Received Image">
|
||||
<!ENTITY networkPanel.responseImageCached "Cached Image">
|
||||
|
||||
<!-- LOCALIZATION NOTE (saveBodies.label): You can see this string in the Web
|
||||
- Console context menu. -->
|
||||
<!ENTITY saveBodies.label "Log Request and Response Bodies">
|
||||
|
|
|
@ -40,29 +40,12 @@ webConsoleCmd.accesskey=W
|
|||
timestampFormat=%02S:%02S:%02S.%03S
|
||||
|
||||
helperFuncUnsupportedTypeError=Can't call pprint on this type of object.
|
||||
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 response
|
||||
# header or response header and response body). Parameters: %S is the duration.
|
||||
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. Parameters:
|
||||
# %1$S is the width of the inspected image, %2$S is the height of the
|
||||
# inspected image, %3$S is the duration between the response header and the
|
||||
# response body event. Example: 150x100px, Δ50ms.
|
||||
NetworkPanel.imageSizeDeltaDurationMS=%1$Sx%2$Spx, Δ%3$Sms
|
||||
|
||||
# LOCALIZATION NOTE (NetworkPanel.responseBodyUnableToDisplay.content): this
|
||||
# string is displayed within the response body section of the NetworkPanel if
|
||||
# the content type of the network request can't be displayed. E.g. any kind of
|
||||
# text is easy to display, but some audio or flash data received from the
|
||||
# server can't be displayed. Parameters: %S is the content type that can't be
|
||||
# displayed, examples are application/x-shockwave-flash, music/crescendo.
|
||||
NetworkPanel.responseBodyUnableToDisplay.content=Unable to display responses of type "%S"
|
||||
|
||||
ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page.
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleWindowTitleAndURL): the Web Console floating
|
||||
|
|
|
@ -330,7 +330,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/alerticon-warning@2x.png (../shared/devtools/images/alerticon-warning@2x.png)
|
||||
* skin/classic/browser/devtools/ruleview.css (../shared/devtools/ruleview.css)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/commandline.css (../shared/devtools/commandline.css)
|
||||
skin/classic/browser/devtools/markup-view.css (../shared/devtools/markup-view.css)
|
||||
|
|
|
@ -432,7 +432,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/editor-debug-location.png (../shared/devtools/images/editor-debug-location.png)
|
||||
skin/classic/browser/devtools/editor-debug-location@2x.png (../shared/devtools/images/editor-debug-location@2x.png)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#header {
|
||||
padding: 5px;
|
||||
overflow-x:auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
padding: 3px 10px;
|
||||
vertical-align: bottom;
|
||||
margin: 0px;
|
||||
background: linear-gradient(#BBB, #999);
|
||||
border-radius: 2px;
|
||||
text-shadow: #FFF 0px 1px 0px;
|
||||
}
|
||||
|
||||
h1 .info {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
vertical-align: bottom;
|
||||
float: right;
|
||||
color: #333;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.property-table {
|
||||
padding: 2px 5px;
|
||||
background: linear-gradient(#FFF, #F8F8F8);
|
||||
color: #333;
|
||||
width: 100%;
|
||||
max-height: 330px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding-right: 4px;
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
text-align: end;
|
||||
vertical-align: top;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
padding-right: 5px;
|
||||
font-size: 11px;
|
||||
word-wrap: break-word;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
div.group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.group,
|
||||
#header {
|
||||
background: #FFF;
|
||||
border-color: #E1E1E1;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-shadow: 0 1px 1.5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
img#responseImageNode {
|
||||
box-shadow: rgba(0,0,0,0.2) 0px 3px 3.5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#responseImageNodeDiv {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#responseBodyFetchLink, #requestBodyFetchLink {
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.longStringEllipsis {
|
||||
margin-left: 0.6em;
|
||||
}
|
|
@ -457,7 +457,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/editor-debug-location.png (../shared/devtools/images/editor-debug-location.png)
|
||||
skin/classic/browser/devtools/editor-debug-location@2x.png (../shared/devtools/images/editor-debug-location@2x.png)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
|
|
Загрузка…
Ссылка в новой задаче