зеркало из https://github.com/mozilla/gecko-dev.git
Bug 989417 - Use Task.spawn in Netmonitor code to improve code readability, r=rcampbell
This commit is contained in:
Родитель
78b7a846a4
Коммит
3572271153
|
@ -191,7 +191,7 @@ let NetMonitorController = {
|
|||
* @return object
|
||||
* A promise that is resolved when the monitor finishes connecting.
|
||||
*/
|
||||
connect: function() {
|
||||
connect: Task.async(function*() {
|
||||
if (this._connection) {
|
||||
return this._connection;
|
||||
}
|
||||
|
@ -207,11 +207,9 @@ let NetMonitorController = {
|
|||
this._startMonitoringTab(client, form, deferred.resolve);
|
||||
}
|
||||
|
||||
return deferred.promise.then((result) => {
|
||||
window.emit(EVENTS.CONNECTED);
|
||||
return result;
|
||||
});
|
||||
},
|
||||
yield deferred.promise;
|
||||
window.emit(EVENTS.CONNECTED);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Disconnects the debugger client and removes event handlers as necessary.
|
||||
|
|
|
@ -528,6 +528,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
*/
|
||||
copyAsCurl: function() {
|
||||
let selected = this.selectedItem.attachment;
|
||||
|
||||
Task.spawn(function*() {
|
||||
// Create a sanitized object for the Curl command generator.
|
||||
let data = {
|
||||
|
@ -595,8 +596,8 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let selected = this.selectedItem.attachment;
|
||||
|
||||
let data = {
|
||||
method: selected.method,
|
||||
url: selected.url,
|
||||
method: selected.method,
|
||||
httpVersion: selected.httpVersion,
|
||||
};
|
||||
if (selected.requestHeaders) {
|
||||
|
@ -1216,8 +1217,10 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
* The type of information that is to be updated.
|
||||
* @param any aValue
|
||||
* The new value to be shown.
|
||||
* @return object
|
||||
* A promise that is resolved once the information is displayed.
|
||||
*/
|
||||
updateMenuView: function(aItem, aKey, aValue) {
|
||||
updateMenuView: Task.async(function*(aItem, aKey, aValue) {
|
||||
let target = aItem.target || aItem;
|
||||
|
||||
switch (aKey) {
|
||||
|
@ -1279,13 +1282,13 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let { text, encoding } = aValue.content;
|
||||
|
||||
if (mimeType.contains("image/")) {
|
||||
gNetwork.getString(text).then(aString => {
|
||||
let node = $(".requests-menu-icon", aItem.target);
|
||||
node.src = "data:" + mimeType + ";" + encoding + "," + aString;
|
||||
node.setAttribute("type", "thumbnail");
|
||||
node.removeAttribute("hidden");
|
||||
window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
|
||||
});
|
||||
let responseBody = yield gNetwork.getString(text);
|
||||
let node = $(".requests-menu-icon", aItem.target);
|
||||
node.src = "data:" + mimeType + ";" + encoding + "," + responseBody;
|
||||
node.setAttribute("type", "thumbnail");
|
||||
node.removeAttribute("hidden");
|
||||
|
||||
window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1297,7 +1300,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Creates a waterfall representing timing information in a network request item view.
|
||||
|
@ -1596,7 +1599,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
|
||||
let resendElement = $("#request-menu-context-resend");
|
||||
resendElement.hidden = !NetMonitorController.supportsCustomRequest ||
|
||||
!selectedItem || selectedItem.attachment.isCustom;
|
||||
!selectedItem || selectedItem.attachment.isCustom;
|
||||
|
||||
let copyUrlElement = $("#request-menu-context-copy-url");
|
||||
copyUrlElement.hidden = !selectedItem;
|
||||
|
@ -1777,17 +1780,17 @@ SidebarView.prototype = {
|
|||
* @return object
|
||||
* Returns a promise that resolves upon population of the subview.
|
||||
*/
|
||||
populate: function(aData) {
|
||||
populate: Task.async(function*(aData) {
|
||||
let isCustom = aData.isCustom;
|
||||
let view = isCustom ?
|
||||
NetMonitorView.CustomRequest :
|
||||
NetMonitorView.NetworkDetails;
|
||||
|
||||
return view.populate(aData).then(() => {
|
||||
$("#details-pane").selectedIndex = isCustom ? 0 : 1;
|
||||
window.emit(EVENTS.SIDEBAR_POPULATED);
|
||||
});
|
||||
}
|
||||
yield view.populate(aData);
|
||||
$("#details-pane").selectedIndex = isCustom ? 0 : 1;
|
||||
|
||||
window.emit(EVENTS.SIDEBAR_POPULATED);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1825,29 +1828,22 @@ CustomRequestView.prototype = {
|
|||
* @return object
|
||||
* Returns a promise that resolves upon population the view.
|
||||
*/
|
||||
populate: function(aData) {
|
||||
populate: Task.async(function*(aData) {
|
||||
$("#custom-url-value").value = aData.url;
|
||||
$("#custom-method-value").value = aData.method;
|
||||
$("#custom-headers-value").value =
|
||||
writeHeaderText(aData.requestHeaders.headers);
|
||||
|
||||
let view = this;
|
||||
let postDataPromise = null;
|
||||
this.updateCustomQuery(aData.url);
|
||||
|
||||
if (aData.requestHeaders) {
|
||||
let headers = aData.requestHeaders.headers;
|
||||
$("#custom-headers-value").value = writeHeaderText(headers);
|
||||
}
|
||||
if (aData.requestPostData) {
|
||||
let body = aData.requestPostData.postData.text;
|
||||
|
||||
postDataPromise = gNetwork.getString(body).then(aString => {
|
||||
$("#custom-postdata-value").value = aString;
|
||||
});
|
||||
} else {
|
||||
postDataPromise = promise.resolve();
|
||||
let postData = aData.requestPostData.postData.text;
|
||||
$("#custom-postdata-value").value = yield gNetwork.getString(postData);
|
||||
}
|
||||
|
||||
return postDataPromise
|
||||
.then(() => view.updateCustomQuery(aData.url))
|
||||
.then(() => window.emit(EVENTS.CUSTOMREQUESTVIEW_POPULATED));
|
||||
},
|
||||
window.emit(EVENTS.CUSTOMREQUESTVIEW_POPULATED);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Handle user input in the custom request form.
|
||||
|
@ -1895,7 +1891,7 @@ CustomRequestView.prototype = {
|
|||
* Update the query string field based on the url.
|
||||
*
|
||||
* @param object aUrl
|
||||
* url to extract query string from.
|
||||
* The URL to extract query string from.
|
||||
*/
|
||||
updateCustomQuery: function(aUrl) {
|
||||
let paramsArray = parseQueryString(nsIURL(aUrl).query);
|
||||
|
@ -1911,7 +1907,7 @@ CustomRequestView.prototype = {
|
|||
* Update the url based on the query string field.
|
||||
*
|
||||
* @param object aQueryText
|
||||
* contents of the query string field.
|
||||
* The contents of the query string field.
|
||||
*/
|
||||
updateCustomUrl: function(aQueryText) {
|
||||
let params = parseQueryText(aQueryText);
|
||||
|
@ -2123,20 +2119,14 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that resolves when request headers are set.
|
||||
*/
|
||||
_setRequestHeaders: function(aHeadersResponse, aHeadersFromUploadStream) {
|
||||
let outstanding = [];
|
||||
|
||||
_setRequestHeaders: Task.async(function*(aHeadersResponse, aHeadersFromUploadStream) {
|
||||
if (aHeadersResponse && aHeadersResponse.headers.length) {
|
||||
outstanding.push(
|
||||
this._addHeaders(this._requestHeaders, aHeadersResponse));
|
||||
yield this._addHeaders(this._requestHeaders, aHeadersResponse);
|
||||
}
|
||||
if (aHeadersFromUploadStream && aHeadersFromUploadStream.headers.length) {
|
||||
outstanding.push(
|
||||
this._addHeaders(this._requestHeadersFromUpload, aHeadersFromUploadStream));
|
||||
yield this._addHeaders(this._requestHeadersFromUpload, aHeadersFromUploadStream);
|
||||
}
|
||||
|
||||
return promise.all(outstanding);
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the network response headers shown in this view.
|
||||
|
@ -2146,13 +2136,12 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that resolves when response headers are set.
|
||||
*/
|
||||
_setResponseHeaders: function(aResponse) {
|
||||
_setResponseHeaders: Task.async(function*(aResponse) {
|
||||
if (aResponse && aResponse.headers.length) {
|
||||
aResponse.headers.sort((a, b) => a.name > b.name);
|
||||
return this._addHeaders(this._responseHeaders, aResponse);
|
||||
yield this._addHeaders(this._responseHeaders, aResponse);
|
||||
}
|
||||
return promise.resolve();
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Populates the headers container in this view with the specified data.
|
||||
|
@ -2164,18 +2153,20 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that resolves when headers are added.
|
||||
*/
|
||||
_addHeaders: function(aName, aResponse) {
|
||||
_addHeaders: Task.async(function*(aName, aResponse) {
|
||||
let kb = aResponse.headersSize / 1024;
|
||||
let size = L10N.numberWithDecimals(kb, HEADERS_SIZE_DECIMALS);
|
||||
let text = L10N.getFormatStr("networkMenu.sizeKB", size);
|
||||
|
||||
let headersScope = this._headers.addScope(aName + " (" + text + ")");
|
||||
headersScope.expanded = true;
|
||||
|
||||
return promise.all(aResponse.headers.map(header => {
|
||||
for (let header of aResponse.headers) {
|
||||
let headerVar = headersScope.addItem(header.name, {}, true);
|
||||
return gNetwork.getString(header.value).then(aString => headerVar.setGrip(aString));
|
||||
}));
|
||||
},
|
||||
let headerValue = yield gNetwork.getString(header.value);
|
||||
headerVar.setGrip(headerValue);
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the network request cookies shown in this view.
|
||||
|
@ -2185,13 +2176,12 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that is resolved when the request cookies are set.
|
||||
*/
|
||||
_setRequestCookies: function(aResponse) {
|
||||
_setRequestCookies: Task.async(function*(aResponse) {
|
||||
if (aResponse && aResponse.cookies.length) {
|
||||
aResponse.cookies.sort((a, b) => a.name > b.name);
|
||||
return this._addCookies(this._requestCookies, aResponse);
|
||||
yield this._addCookies(this._requestCookies, aResponse);
|
||||
}
|
||||
return promise.resolve();
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the network response cookies shown in this view.
|
||||
|
@ -2201,12 +2191,11 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that is resolved when the response cookies are set.
|
||||
*/
|
||||
_setResponseCookies: function(aResponse) {
|
||||
_setResponseCookies: Task.async(function*(aResponse) {
|
||||
if (aResponse && aResponse.cookies.length) {
|
||||
return this._addCookies(this._responseCookies, aResponse);
|
||||
yield this._addCookies(this._responseCookies, aResponse);
|
||||
}
|
||||
return promise.resolve();
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Populates the cookies container in this view with the specified data.
|
||||
|
@ -2218,35 +2207,34 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* Returns a promise that resolves upon the adding of cookies.
|
||||
*/
|
||||
_addCookies: function(aName, aResponse) {
|
||||
_addCookies: Task.async(function*(aName, aResponse) {
|
||||
let cookiesScope = this._cookies.addScope(aName);
|
||||
cookiesScope.expanded = true;
|
||||
|
||||
return promise.all(aResponse.cookies.map(cookie => {
|
||||
for (let cookie of aResponse.cookies) {
|
||||
let cookieVar = cookiesScope.addItem(cookie.name, {}, true);
|
||||
return gNetwork.getString(cookie.value).then(aString => {
|
||||
cookieVar.setGrip(aString);
|
||||
let cookieValue = yield gNetwork.getString(cookie.value);
|
||||
cookieVar.setGrip(cookieValue);
|
||||
|
||||
// By default the cookie name and value are shown. If this is the only
|
||||
// information available, then nothing else is to be displayed.
|
||||
let cookieProps = Object.keys(cookie);
|
||||
if (cookieProps.length == 2) {
|
||||
return;
|
||||
}
|
||||
// By default the cookie name and value are shown. If this is the only
|
||||
// information available, then nothing else is to be displayed.
|
||||
let cookieProps = Object.keys(cookie);
|
||||
if (cookieProps.length == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Display any other information other than the cookie name and value
|
||||
// which may be available.
|
||||
let rawObject = Object.create(null);
|
||||
let otherProps = cookieProps.filter(e => e != "name" && e != "value");
|
||||
for (let prop of otherProps) {
|
||||
rawObject[prop] = cookie[prop];
|
||||
}
|
||||
cookieVar.populate(rawObject);
|
||||
cookieVar.twisty = true;
|
||||
cookieVar.expanded = true;
|
||||
});
|
||||
}));
|
||||
},
|
||||
// Display any other information other than the cookie name and value
|
||||
// which may be available.
|
||||
let rawObject = Object.create(null);
|
||||
let otherProps = cookieProps.filter(e => e != "name" && e != "value");
|
||||
for (let prop of otherProps) {
|
||||
rawObject[prop] = cookie[prop];
|
||||
}
|
||||
cookieVar.populate(rawObject);
|
||||
cookieVar.twisty = true;
|
||||
cookieVar.expanded = true;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the network request get params shown in this view.
|
||||
|
@ -2273,59 +2261,58 @@ NetworkDetailsView.prototype = {
|
|||
* @return object
|
||||
* A promise that is resolved when the request post params are set.
|
||||
*/
|
||||
_setRequestPostParams: function(aHeadersResponse, aHeadersFromUploadStream, aPostDataResponse) {
|
||||
_setRequestPostParams: Task.async(function*(aHeadersResponse, aHeadersFromUploadStream, aPostDataResponse) {
|
||||
if (!aHeadersResponse || !aHeadersFromUploadStream || !aPostDataResponse) {
|
||||
return promise.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
let { headers: requestHeaders } = aHeadersResponse;
|
||||
let { headers: payloadHeaders } = aHeadersFromUploadStream;
|
||||
let allHeaders = [...payloadHeaders, ...requestHeaders];
|
||||
|
||||
let contentTypeHeader = allHeaders.filter(e => e.name.toLowerCase() == "content-type")[0];
|
||||
let contentTypeHeader = allHeaders.find(e => e.name.toLowerCase() == "content-type");
|
||||
let contentTypeLongString = contentTypeHeader ? contentTypeHeader.value : "";
|
||||
let postDataLongString = aPostDataResponse.postData.text;
|
||||
|
||||
return promise.all([
|
||||
gNetwork.getString(postDataLongString),
|
||||
gNetwork.getString(contentTypeLongString)
|
||||
])
|
||||
.then(([aPostData, aContentType]) => {
|
||||
// Handle query strings (e.g. "?foo=bar&baz=42").
|
||||
if (aContentType.contains("x-www-form-urlencoded")) {
|
||||
for (let section of aPostData.split(/\r\n|\r|\n/)) {
|
||||
// Before displaying it, make sure this section of the POST data
|
||||
// isn't a line containing upload stream headers.
|
||||
if (payloadHeaders.every(header => !section.startsWith(header.name))) {
|
||||
this._addParams(this._paramsFormData, section);
|
||||
}
|
||||
let postData = yield gNetwork.getString(postDataLongString);
|
||||
let contentType = yield gNetwork.getString(contentTypeLongString);
|
||||
|
||||
// Handle query strings (e.g. "?foo=bar&baz=42").
|
||||
if (contentType.contains("x-www-form-urlencoded")) {
|
||||
for (let section of postData.split(/\r\n|\r|\n/)) {
|
||||
// Before displaying it, make sure this section of the POST data
|
||||
// isn't a line containing upload stream headers.
|
||||
if (payloadHeaders.every(header => !section.startsWith(header.name))) {
|
||||
this._addParams(this._paramsFormData, section);
|
||||
}
|
||||
}
|
||||
// Handle actual forms ("multipart/form-data" content type).
|
||||
else {
|
||||
// This is really awkward, but hey, it works. Let's show an empty
|
||||
// scope in the params view and place the source editor containing
|
||||
// the raw post data directly underneath.
|
||||
$("#request-params-box").removeAttribute("flex");
|
||||
let paramsScope = this._params.addScope(this._paramsPostPayload);
|
||||
paramsScope.expanded = true;
|
||||
paramsScope.locked = true;
|
||||
}
|
||||
// Handle actual forms ("multipart/form-data" content type).
|
||||
else {
|
||||
// This is really awkward, but hey, it works. Let's show an empty
|
||||
// scope in the params view and place the source editor containing
|
||||
// the raw post data directly underneath.
|
||||
$("#request-params-box").removeAttribute("flex");
|
||||
let paramsScope = this._params.addScope(this._paramsPostPayload);
|
||||
paramsScope.expanded = true;
|
||||
paramsScope.locked = true;
|
||||
|
||||
$("#request-post-data-textarea-box").hidden = false;
|
||||
return NetMonitorView.editor("#request-post-data-textarea").then(aEditor => {
|
||||
// Most POST bodies are usually JSON, so they can be neatly
|
||||
// syntax highlighted as JS. Otheriwse, fall back to plain text.
|
||||
try {
|
||||
JSON.parse(aPostData);
|
||||
aEditor.setMode(Editor.modes.js);
|
||||
} catch (e) {
|
||||
aEditor.setMode(Editor.modes.text);
|
||||
} finally {
|
||||
aEditor.setText(aPostData);
|
||||
}
|
||||
});
|
||||
$("#request-post-data-textarea-box").hidden = false;
|
||||
let editor = yield NetMonitorView.editor("#request-post-data-textarea");
|
||||
// Most POST bodies are usually JSON, so they can be neatly
|
||||
// syntax highlighted as JS. Otheriwse, fall back to plain text.
|
||||
try {
|
||||
JSON.parse(postData);
|
||||
editor.setMode(Editor.modes.js);
|
||||
} catch (e) {
|
||||
editor.setMode(Editor.modes.text);
|
||||
} finally {
|
||||
editor.setText(postData);
|
||||
}
|
||||
}).then(() => window.emit(EVENTS.REQUEST_POST_PARAMS_DISPLAYED));
|
||||
},
|
||||
}
|
||||
|
||||
window.emit(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Populates the params container in this view with the specified data.
|
||||
|
@ -2357,118 +2344,112 @@ NetworkDetailsView.prototype = {
|
|||
* @param object aResponse
|
||||
* The message received from the server.
|
||||
* @return object
|
||||
* A promise that is resolved when the response body is set
|
||||
* A promise that is resolved when the response body is set.
|
||||
*/
|
||||
_setResponseBody: function(aUrl, aResponse) {
|
||||
_setResponseBody: Task.async(function*(aUrl, aResponse) {
|
||||
if (!aResponse) {
|
||||
return promise.resolve();
|
||||
return;
|
||||
}
|
||||
let { mimeType, text, encoding } = aResponse.content;
|
||||
let responseBody = yield gNetwork.getString(text);
|
||||
|
||||
return gNetwork.getString(text).then(aString => {
|
||||
// Handle json, which we tentatively identify by checking the MIME type
|
||||
// for "json" after any word boundary. This works for the standard
|
||||
// "application/json", and also for custom types like "x-bigcorp-json".
|
||||
// Additionally, we also directly parse the response text content to
|
||||
// verify whether it's json or not, to handle responses incorrectly
|
||||
// labeled as text/plain instead.
|
||||
let jsonMimeType, jsonObject, jsonObjectParseError;
|
||||
try {
|
||||
// Test the mime type *and* parse the string, because "JSONP" responses
|
||||
// (json with callback) aren't actually valid json.
|
||||
jsonMimeType = /\bjson/.test(mimeType);
|
||||
jsonObject = JSON.parse(aString);
|
||||
} catch (e) {
|
||||
jsonObjectParseError = e;
|
||||
}
|
||||
if (jsonMimeType || jsonObject) {
|
||||
// Extract the actual json substring in case this might be a "JSONP".
|
||||
// This regex basically parses a function call and captures the
|
||||
// function name and arguments in two separate groups.
|
||||
let jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
|
||||
let [_, callbackPadding, jsonpString] = aString.match(jsonpRegex) || [];
|
||||
// Handle json, which we tentatively identify by checking the MIME type
|
||||
// for "json" after any word boundary. This works for the standard
|
||||
// "application/json", and also for custom types like "x-bigcorp-json".
|
||||
// Additionally, we also directly parse the response text content to
|
||||
// verify whether it's json or not, to handle responses incorrectly
|
||||
// labeled as text/plain instead.
|
||||
let jsonMimeType, jsonObject, jsonObjectParseError;
|
||||
try {
|
||||
jsonMimeType = /\bjson/.test(mimeType);
|
||||
jsonObject = JSON.parse(responseBody);
|
||||
} catch (e) {
|
||||
jsonObjectParseError = e;
|
||||
}
|
||||
if (jsonMimeType || jsonObject) {
|
||||
// Extract the actual json substring in case this might be a "JSONP".
|
||||
// This regex basically parses a function call and captures the
|
||||
// function name and arguments in two separate groups.
|
||||
let jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
|
||||
let [_, callbackPadding, jsonpString] = responseBody.match(jsonpRegex) || [];
|
||||
|
||||
// Make sure this is a valid JSON object first. If so, nicely display
|
||||
// the parsing results in a variables view. Otherwise, simply show
|
||||
// the contents as plain text.
|
||||
if (callbackPadding && jsonpString) {
|
||||
try {
|
||||
jsonObject = JSON.parse(jsonpString);
|
||||
} catch (e) {
|
||||
jsonObjectParseError = e;
|
||||
}
|
||||
}
|
||||
|
||||
// Valid JSON or JSONP.
|
||||
if (jsonObject) {
|
||||
$("#response-content-json-box").hidden = false;
|
||||
let jsonScopeName = callbackPadding
|
||||
? L10N.getFormatStr("jsonpScopeName", callbackPadding)
|
||||
: L10N.getStr("jsonScopeName");
|
||||
|
||||
return this._json.controller.setSingleVariable({
|
||||
label: jsonScopeName,
|
||||
rawObject: jsonObject,
|
||||
}).expanded;
|
||||
}
|
||||
// Malformed JSON.
|
||||
else {
|
||||
$("#response-content-textarea-box").hidden = false;
|
||||
let infoHeader = $("#response-content-info-header");
|
||||
infoHeader.setAttribute("value", jsonObjectParseError);
|
||||
infoHeader.setAttribute("tooltiptext", jsonObjectParseError);
|
||||
infoHeader.hidden = false;
|
||||
return NetMonitorView.editor("#response-content-textarea").then(aEditor => {
|
||||
aEditor.setMode(Editor.modes.js);
|
||||
aEditor.setText(aString);
|
||||
});
|
||||
// Make sure this is a valid JSON object first. If so, nicely display
|
||||
// the parsing results in a variables view. Otherwise, simply show
|
||||
// the contents as plain text.
|
||||
if (callbackPadding && jsonpString) {
|
||||
try {
|
||||
jsonObject = JSON.parse(jsonpString);
|
||||
} catch (e) {
|
||||
jsonObjectParseError = e;
|
||||
}
|
||||
}
|
||||
// Handle images.
|
||||
else if (mimeType.contains("image/")) {
|
||||
$("#response-content-image-box").setAttribute("align", "center");
|
||||
$("#response-content-image-box").setAttribute("pack", "center");
|
||||
$("#response-content-image-box").hidden = false;
|
||||
$("#response-content-image").src =
|
||||
"data:" + mimeType + ";" + encoding + "," + aString;
|
||||
|
||||
// Immediately display additional information about the image:
|
||||
// file name, mime type and encoding.
|
||||
$("#response-content-image-name-value").setAttribute("value", nsIURL(aUrl).fileName);
|
||||
$("#response-content-image-mime-value").setAttribute("value", mimeType);
|
||||
$("#response-content-image-encoding-value").setAttribute("value", encoding);
|
||||
// Valid JSON or JSONP.
|
||||
if (jsonObject) {
|
||||
$("#response-content-json-box").hidden = false;
|
||||
let jsonScopeName = callbackPadding
|
||||
? L10N.getFormatStr("jsonpScopeName", callbackPadding)
|
||||
: L10N.getStr("jsonScopeName");
|
||||
|
||||
// Wait for the image to load in order to display the width and height.
|
||||
$("#response-content-image").onload = e => {
|
||||
// XUL images are majestic so they don't bother storing their dimensions
|
||||
// in width and height attributes like the rest of the folk. Hack around
|
||||
// this by getting the bounding client rect and subtracting the margins.
|
||||
let { width, height } = e.target.getBoundingClientRect();
|
||||
let dimensions = (width - 2) + " x " + (height - 2);
|
||||
$("#response-content-image-dimensions-value").setAttribute("value", dimensions);
|
||||
};
|
||||
let jsonVar = { label: jsonScopeName, rawObject: jsonObject };
|
||||
yield this._json.controller.setSingleVariable(jsonVar).expanded;
|
||||
}
|
||||
// Handle anything else.
|
||||
// Malformed JSON.
|
||||
else {
|
||||
$("#response-content-textarea-box").hidden = false;
|
||||
return NetMonitorView.editor("#response-content-textarea").then(aEditor => {
|
||||
aEditor.setMode(Editor.modes.text);
|
||||
aEditor.setText(aString);
|
||||
let infoHeader = $("#response-content-info-header");
|
||||
infoHeader.setAttribute("value", jsonObjectParseError);
|
||||
infoHeader.setAttribute("tooltiptext", jsonObjectParseError);
|
||||
infoHeader.hidden = false;
|
||||
|
||||
// Maybe set a more appropriate mode in the Source Editor if possible,
|
||||
// but avoid doing this for very large files.
|
||||
if (aString.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
|
||||
for (let key in CONTENT_MIME_TYPE_MAPPINGS) {
|
||||
if (mimeType.contains(key)) {
|
||||
aEditor.setMode(CONTENT_MIME_TYPE_MAPPINGS[key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let editor = yield NetMonitorView.editor("#response-content-textarea");
|
||||
editor.setMode(Editor.modes.js);
|
||||
editor.setText(responseBody);
|
||||
}
|
||||
}).then(() => window.emit(EVENTS.RESPONSE_BODY_DISPLAYED));
|
||||
},
|
||||
}
|
||||
// Handle images.
|
||||
else if (mimeType.contains("image/")) {
|
||||
$("#response-content-image-box").setAttribute("align", "center");
|
||||
$("#response-content-image-box").setAttribute("pack", "center");
|
||||
$("#response-content-image-box").hidden = false;
|
||||
$("#response-content-image").src =
|
||||
"data:" + mimeType + ";" + encoding + "," + responseBody;
|
||||
|
||||
// Immediately display additional information about the image:
|
||||
// file name, mime type and encoding.
|
||||
$("#response-content-image-name-value").setAttribute("value", nsIURL(aUrl).fileName);
|
||||
$("#response-content-image-mime-value").setAttribute("value", mimeType);
|
||||
$("#response-content-image-encoding-value").setAttribute("value", encoding);
|
||||
|
||||
// Wait for the image to load in order to display the width and height.
|
||||
$("#response-content-image").onload = e => {
|
||||
// XUL images are majestic so they don't bother storing their dimensions
|
||||
// in width and height attributes like the rest of the folk. Hack around
|
||||
// this by getting the bounding client rect and subtracting the margins.
|
||||
let { width, height } = e.target.getBoundingClientRect();
|
||||
let dimensions = (width - 2) + " x " + (height - 2);
|
||||
$("#response-content-image-dimensions-value").setAttribute("value", dimensions);
|
||||
};
|
||||
}
|
||||
// Handle anything else.
|
||||
else {
|
||||
$("#response-content-textarea-box").hidden = false;
|
||||
let editor = yield NetMonitorView.editor("#response-content-textarea");
|
||||
editor.setMode(Editor.modes.text);
|
||||
editor.setText(responseBody);
|
||||
|
||||
// Maybe set a more appropriate mode in the Source Editor if possible,
|
||||
// but avoid doing this for very large files.
|
||||
if (responseBody.length < SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
|
||||
let mapping = Object.keys(CONTENT_MIME_TYPE_MAPPINGS).find(key => mimeType.contains(key));
|
||||
if (mapping) {
|
||||
editor.setMode(CONTENT_MIME_TYPE_MAPPINGS[mapping]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.emit(EVENTS.RESPONSE_BODY_DISPLAYED);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Sets the timings information shown in this view.
|
||||
|
@ -2545,23 +2526,22 @@ NetworkDetailsView.prototype = {
|
|||
* @param object aResponse
|
||||
* The message received from the server.
|
||||
* @return object
|
||||
* A promise that is resolved when the response body is set
|
||||
* A promise that is resolved when the html preview is rendered.
|
||||
*/
|
||||
_setHtmlPreview: function(aResponse) {
|
||||
_setHtmlPreview: Task.async(function*(aResponse) {
|
||||
if (!aResponse) {
|
||||
return promise.resolve();
|
||||
}
|
||||
let { text } = aResponse.content;
|
||||
let responseBody = yield gNetwork.getString(text);
|
||||
|
||||
// Always disable JS when previewing HTML responses.
|
||||
let iframe = $("#response-preview");
|
||||
iframe.contentDocument.docShell.allowJavascript = false;
|
||||
iframe.contentDocument.documentElement.innerHTML = responseBody;
|
||||
|
||||
return gNetwork.getString(text).then(aString => {
|
||||
// Always disable JS when previewing HTML responses.
|
||||
iframe.contentDocument.docShell.allowJavascript = false;
|
||||
iframe.contentDocument.documentElement.innerHTML = aString;
|
||||
|
||||
window.emit(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
|
||||
});
|
||||
},
|
||||
window.emit(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
|
||||
}),
|
||||
|
||||
_dataSrc: null,
|
||||
_headers: null,
|
||||
|
|
|
@ -184,7 +184,7 @@ this.CurlUtils = {
|
|||
|
||||
let contentType = this.findHeader(aData.headers, "content-type");
|
||||
|
||||
return (contentType &&
|
||||
return (contentType &&
|
||||
contentType.toLowerCase().contains("multipart/form-data;"));
|
||||
},
|
||||
|
||||
|
@ -228,7 +228,7 @@ this.CurlUtils = {
|
|||
|
||||
/**
|
||||
* Returns the boundary string for a multipart request.
|
||||
*
|
||||
*
|
||||
* @param string aData
|
||||
* The data source. See the description in the Curl object.
|
||||
* @return string
|
||||
|
@ -243,7 +243,7 @@ this.CurlUtils = {
|
|||
return contentType.match(boundaryRe)[1];
|
||||
}
|
||||
// Temporary workaround. As of 2014-03-11 the requestHeaders array does not
|
||||
// always contain the Content-Type header for mulitpart requests. See bug 978144.
|
||||
// always contain the Content-Type header for mulitpart requests. See bug 978144.
|
||||
// Find the header from the request payload.
|
||||
let boundaryString = aData.postDataText.match(boundaryRe)[1];
|
||||
if (boundaryString) {
|
||||
|
@ -393,4 +393,4 @@ this.CurlUtils = {
|
|||
.replace(/\\/g, "\\\\")
|
||||
.replace(/[\r\n]+/g, "\"^$&\"") + "\"";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче