зеркало из https://github.com/mozilla/gecko-dev.git
Bug 859055 - Display JSON as plain text when encountering errors when parsing, r=rcampbell
This commit is contained in:
Родитель
22652cc944
Коммит
80155ced75
|
@ -1315,6 +1315,7 @@ NetworkDetailsView.prototype = {
|
|||
$("#request-params-box").setAttribute("flex", "1");
|
||||
$("#request-params-box").hidden = false;
|
||||
$("#request-post-data-textarea-box").hidden = true;
|
||||
$("#response-content-info-header").hidden = true;
|
||||
$("#response-content-json-box").hidden = true;
|
||||
$("#response-content-textarea-box").hidden = true;
|
||||
$("#response-content-image-box").hidden = true;
|
||||
|
@ -1612,18 +1613,42 @@ NetworkDetailsView.prototype = {
|
|||
gNetwork.getString(text).then((aString) => {
|
||||
// Handle json.
|
||||
if (mimeType.contains("/json")) {
|
||||
$("#response-content-json-box").hidden = false;
|
||||
let jsonpRegex = /^[a-zA-Z0-9_$]+\(|\)$/g; // JSONP with callback.
|
||||
let sanitizedJSON = aString.replace(jsonpRegex, "");
|
||||
let callbackPadding = aString.match(jsonpRegex);
|
||||
|
||||
let jsonScopeName = callbackPadding
|
||||
? L10N.getFormatStr("jsonpScopeName", callbackPadding[0].slice(0, -1))
|
||||
: L10N.getStr("jsonScopeName");
|
||||
// Make sure this is an valid JSON object first. If so, nicely display
|
||||
// the parsing results in a variables view. Otherwise, simply show
|
||||
// the contents as plain text.
|
||||
try {
|
||||
var jsonObject = JSON.parse(sanitizedJSON);
|
||||
} catch (e) {
|
||||
var parsingError = e;
|
||||
}
|
||||
|
||||
let jsonScope = this._json.addScope(jsonScopeName);
|
||||
jsonScope.addVar().populate(JSON.parse(sanitizedJSON), { expanded: true });
|
||||
jsonScope.expanded = true;
|
||||
// Valid JSON.
|
||||
if (jsonObject) {
|
||||
$("#response-content-json-box").hidden = false;
|
||||
let jsonScopeName = callbackPadding
|
||||
? L10N.getFormatStr("jsonpScopeName", callbackPadding[0].slice(0, -1))
|
||||
: L10N.getStr("jsonScopeName");
|
||||
|
||||
let jsonScope = this._json.addScope(jsonScopeName);
|
||||
jsonScope.addVar().populate(jsonObject, { expanded: true });
|
||||
jsonScope.expanded = true;
|
||||
}
|
||||
// Malformed JSON.
|
||||
else {
|
||||
$("#response-content-textarea-box").hidden = false;
|
||||
NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
|
||||
aEditor.setMode(SourceEditor.MODES.JAVASCRIPT);
|
||||
aEditor.setText(aString);
|
||||
});
|
||||
let infoHeader = $("#response-content-info-header");
|
||||
infoHeader.setAttribute("value", parsingError);
|
||||
infoHeader.setAttribute("tooltiptext", parsingError);
|
||||
infoHeader.hidden = false;
|
||||
}
|
||||
}
|
||||
// Handle images.
|
||||
else if (mimeType.contains("image/")) {
|
||||
|
|
|
@ -272,6 +272,7 @@
|
|||
<tabpanel id="response-tabpanel"
|
||||
class="tabpanel-content">
|
||||
<vbox flex="1">
|
||||
<label id="response-content-info-header"/>
|
||||
<vbox id="response-content-json-box" flex="1" hidden="true">
|
||||
<vbox id="response-content-json" flex="1"/>
|
||||
</vbox>
|
||||
|
|
|
@ -31,6 +31,7 @@ MOCHITEST_BROWSER_TESTS = \
|
|||
browser_net_post-data-02.js \
|
||||
browser_net_jsonp.js \
|
||||
browser_net_json-long.js \
|
||||
browser_net_json-malformed.js \
|
||||
browser_net_timeline_ticks.js \
|
||||
browser_net_sort-01.js \
|
||||
browser_net_sort-02.js \
|
||||
|
@ -55,6 +56,7 @@ MOCHITEST_BROWSER_PAGES = \
|
|||
html_post-raw-test-page.html \
|
||||
html_jsonp-test-page.html \
|
||||
html_json-long-test-page.html \
|
||||
html_json-malformed-test-page.html \
|
||||
html_sorting-test-page.html \
|
||||
html_filter-test-page.html \
|
||||
html_infinite-get-page.html \
|
||||
|
|
|
@ -109,14 +109,15 @@ function test() {
|
|||
"The response tab in the network details pane should be selected.");
|
||||
|
||||
function checkVisibility(aBox) {
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response info header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-json-box")
|
||||
.hasAttribute("hidden"), aBox != "json",
|
||||
"The response content json box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-textarea-box")
|
||||
.hasAttribute("hidden"), aBox != "textarea",
|
||||
"The response content textarea box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-image-box")
|
||||
.hasAttribute("hidden"), aBox != "image",
|
||||
"The response content image box doesn't have the intended visibility.");
|
||||
|
|
|
@ -46,14 +46,15 @@ function test() {
|
|||
is(tab.getAttribute("selected"), "true",
|
||||
"The response tab in the network details pane should be selected.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response info header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-json-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The response content json box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-textarea-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content textarea box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-image-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content image box doesn't have the intended visibility.");
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if malformed JSON responses are handled correctly.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(JSON_MALFORMED_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { document, SourceEditor, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 1).then(() => {
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(0),
|
||||
"GET", CONTENT_TYPE_SJS + "?fmt=json-malformed", {
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "json",
|
||||
fullMimeType: "text/json; charset=utf-8"
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.querySelectorAll("#details-pane tab")[3]);
|
||||
|
||||
let tab = document.querySelectorAll("#details-pane tab")[3];
|
||||
let tabpanel = document.querySelectorAll("#details-pane tabpanel")[3];
|
||||
|
||||
is(tab.getAttribute("selected"), "true",
|
||||
"The response tab in the network details pane should be selected.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The response info header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.getAttribute("value"),
|
||||
"SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data",
|
||||
"The response info header doesn't have the intended value attribute.");
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.getAttribute("tooltiptext"),
|
||||
"SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data",
|
||||
"The response info header doesn't have the intended tooltiptext attribute.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-json-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content json box doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-textarea-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The response content textarea box doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-image-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content image box doesn't have the intended visibility.");
|
||||
|
||||
NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
|
||||
is(aEditor.getText(), "{ \"greeting\": \"Hello malformed JSON!\" },",
|
||||
"The text shown in the source editor is incorrect.");
|
||||
is(aEditor.getMode(), SourceEditor.MODES.JAVASCRIPT,
|
||||
"The mode active in the source editor is incorrect.");
|
||||
|
||||
teardown(aMonitor).then(finish);
|
||||
});
|
||||
});
|
||||
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
}
|
|
@ -40,14 +40,15 @@ function test() {
|
|||
is(tab.getAttribute("selected"), "true",
|
||||
"The response tab in the network details pane should be selected.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response info header doesn't have the intended visibility.");
|
||||
is(tabpanel.querySelector("#response-content-json-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The response content json box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-textarea-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content textarea box doesn't have the intended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-image-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content image box doesn't have the intended visibility.");
|
||||
|
|
|
@ -61,7 +61,6 @@ function test() {
|
|||
is(tabpanel.querySelector("#request-params-box")
|
||||
.hasAttribute("hidden"), !aBox.contains("params"),
|
||||
"The request params box doesn't have the indended visibility.");
|
||||
|
||||
is(tabpanel.querySelector("#request-post-data-textarea-box")
|
||||
.hasAttribute("hidden"), !aBox.contains("textarea"),
|
||||
"The request post data textarea box doesn't have the indended visibility.");
|
||||
|
|
|
@ -163,7 +163,6 @@ function test() {
|
|||
is(tabpanel.querySelector("#request-params-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The request params box should not be hidden.");
|
||||
|
||||
is(tabpanel.querySelector("#request-post-data-textarea-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The request post data textarea box should be hidden.");
|
||||
|
@ -179,14 +178,15 @@ function test() {
|
|||
is(tab.getAttribute("selected"), "true",
|
||||
"The response tab in the network details pane should be selected.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-info-header")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response info header should be hidden.");
|
||||
is(tabpanel.querySelector("#response-content-json-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content json box should be hidden.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-textarea-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The response content textarea box should not be hidden.");
|
||||
|
||||
is(tabpanel.querySelector("#response-content-image-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The response content image box should be hidden.");
|
||||
|
|
|
@ -144,7 +144,6 @@ function test() {
|
|||
is(tabpanel.querySelector("#request-params-box")
|
||||
.hasAttribute("hidden"), false,
|
||||
"The request params box should not be hidden.");
|
||||
|
||||
is(tabpanel.querySelector("#request-post-data-textarea-box")
|
||||
.hasAttribute("hidden"), true,
|
||||
"The request post data textarea box should be hidden.");
|
||||
|
|
|
@ -22,6 +22,7 @@ const POST_DATA_URL = EXAMPLE_URL + "html_post-data-test-page.html";
|
|||
const POST_RAW_URL = EXAMPLE_URL + "html_post-raw-test-page.html";
|
||||
const JSONP_URL = EXAMPLE_URL + "html_jsonp-test-page.html";
|
||||
const JSON_LONG_URL = EXAMPLE_URL + "html_json-long-test-page.html";
|
||||
const JSON_MALFORMED_URL = EXAMPLE_URL + "html_json-malformed-test-page.html";
|
||||
const SORTING_URL = EXAMPLE_URL + "html_sorting-test-page.html";
|
||||
const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
|
||||
const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Network Monitor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>JSON malformed test</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
function get(aAddress, aCallback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", aAddress, true);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == this.DONE) {
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function performRequests() {
|
||||
get("sjs_content-type-test-server.sjs?fmt=json-malformed", function() {
|
||||
// Done.
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -78,6 +78,13 @@ function handleRequest(request, response) {
|
|||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "json-malformed": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/json; charset=utf-8", false);
|
||||
response.write("{ \"greeting\": \"Hello malformed JSON!\" },");
|
||||
response.finish();
|
||||
break;
|
||||
}
|
||||
case "font": {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "font/woff", false);
|
||||
|
|
|
@ -381,6 +381,17 @@ box.requests-menu-status[code^="5"] {
|
|||
|
||||
/* Response tabpanel */
|
||||
|
||||
#response-content-info-header {
|
||||
background:
|
||||
url(background-noise-toolbar.png),
|
||||
linear-gradient(hsl(0,61%,40%), hsl(0,61%,31%)) repeat-x top left;
|
||||
box-shadow:
|
||||
inset 0 1px 0 hsla(210,40%,83%,.15),
|
||||
inset 0 -1px 0 hsla(210,40%,83%,.05);
|
||||
margin: 0;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
#response-content-image-box {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
|
|
@ -381,6 +381,17 @@ box.requests-menu-status[code^="5"] {
|
|||
|
||||
/* Response tabpanel */
|
||||
|
||||
#response-content-info-header {
|
||||
background:
|
||||
url(background-noise-toolbar.png),
|
||||
linear-gradient(hsl(0,61%,40%), hsl(0,61%,31%)) repeat-x top left;
|
||||
box-shadow:
|
||||
inset 0 1px 0 hsla(210,40%,83%,.15),
|
||||
inset 0 -1px 0 hsla(210,40%,83%,.05);
|
||||
margin: 0;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
#response-content-image-box {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
|
|
@ -381,6 +381,17 @@ box.requests-menu-status[code^="5"] {
|
|||
|
||||
/* Response tabpanel */
|
||||
|
||||
#response-content-info-header {
|
||||
background:
|
||||
url(background-noise-toolbar.png),
|
||||
linear-gradient(hsl(0,61%,40%), hsl(0,61%,31%)) repeat-x top left;
|
||||
box-shadow:
|
||||
inset 0 1px 0 hsla(210,40%,83%,.15),
|
||||
inset 0 -1px 0 hsla(210,40%,83%,.05);
|
||||
margin: 0;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
#response-content-image-box {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
|
|
Загрузка…
Ссылка в новой задаче