зеркало из https://github.com/mozilla/gecko-dev.git
Bug 956357 - "Preview Response" tab for HTML in the Network Monitor, r=rcampbell
This commit is contained in:
Родитель
fa745af414
Коммит
c5fceb1e8d
|
@ -57,6 +57,9 @@ const EVENTS = {
|
|||
// When the response body is displayed in the UI.
|
||||
RESPONSE_BODY_DISPLAYED: "NetMonitor:ResponseBodyAvailable",
|
||||
|
||||
// When the html response preview is displayed in the UI.
|
||||
RESPONSE_HTML_PREVIEW_DISPLAYED: "NetMonitor:ResponseHtmlPreviewAvailable",
|
||||
|
||||
// When `onTabSelect` is fired and subsequently rendered.
|
||||
TAB_UPDATED: "NetMonitor:TabUpdated",
|
||||
|
||||
|
@ -412,8 +415,7 @@ TargetEventsHandler.prototype = {
|
|||
case "will-navigate": {
|
||||
// Reset UI.
|
||||
NetMonitorView.RequestsMenu.reset();
|
||||
NetMonitorView.Sidebar.reset();
|
||||
NetMonitorView.NetworkDetails.reset();
|
||||
NetMonitorView.Sidebar.toggle(false);
|
||||
|
||||
// Switch to the default network traffic inspector view.
|
||||
if (NetMonitorController.getCurrentActivity() == ACTIVITY_TYPE.NONE) {
|
||||
|
|
|
@ -1051,6 +1051,9 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
this.filterContents();
|
||||
this.refreshSummary();
|
||||
this.refreshZebra();
|
||||
|
||||
// Rescale all the waterfalls so that everything is visible at once.
|
||||
this._flushWaterfallViews();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1185,14 +1188,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
timingsNode.insertBefore(timingBox, timingsTotal);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't paint things while the waterfall view isn't even visible.
|
||||
if (NetMonitorView.currentFrontendMode != "network-inspector-view") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rescale all the waterfalls so that everything is visible at once.
|
||||
this._flushWaterfallViews();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1202,6 +1197,12 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
* True if this container's width was changed.
|
||||
*/
|
||||
_flushWaterfallViews: function(aReset) {
|
||||
// Don't paint things while the waterfall view isn't even visible,
|
||||
// or there are no items added to this container.
|
||||
if (NetMonitorView.currentFrontendMode != "network-inspector-view" || !this.itemCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To avoid expensive operations like getBoundingClientRect() and
|
||||
// rebuilding the waterfall background each time a new request comes in,
|
||||
// stuff is cached. However, in certain scenarios like when the window
|
||||
|
@ -1429,11 +1430,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
|||
* The resize listener for this container's window.
|
||||
*/
|
||||
_onResize: function(e) {
|
||||
// Don't paint things while the waterfall view isn't even visible.
|
||||
if (NetMonitorView.currentFrontendMode != "network-inspector-view") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow requests to settle down first.
|
||||
setNamedTimeout(
|
||||
"resize-events", RESIZE_REFRESH_RATE, () => this._flushWaterfallViews(true));
|
||||
|
@ -1634,13 +1630,6 @@ SidebarView.prototype = {
|
|||
$("#details-pane").selectedIndex = isCustom ? 0 : 1
|
||||
window.emit(EVENTS.SIDEBAR_POPULATED);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides this container.
|
||||
*/
|
||||
reset: function() {
|
||||
this.toggle(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1837,13 +1826,6 @@ NetworkDetailsView.prototype = {
|
|||
dumpn("Destroying the NetworkDetailsView");
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets this container (removes all the networking information).
|
||||
*/
|
||||
reset: function() {
|
||||
this._dataSrc = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this view with the specified data.
|
||||
*
|
||||
|
@ -1861,6 +1843,18 @@ NetworkDetailsView.prototype = {
|
|||
$("#response-content-textarea-box").hidden = true;
|
||||
$("#response-content-image-box").hidden = true;
|
||||
|
||||
let isHtml = RequestsMenuView.prototype.isHtml({ attachment: aData });
|
||||
|
||||
// Show the "Preview" tabpanel only for plain HTML responses.
|
||||
$("#preview-tab").hidden = !isHtml;
|
||||
$("#preview-tabpanel").hidden = !isHtml;
|
||||
|
||||
// Switch to the "Headers" tabpanel if the "Preview" previously selected
|
||||
// and this is not an HTML response.
|
||||
if (!isHtml && this.widget.selectedIndex == 5) {
|
||||
this.widget.selectedIndex = 0;
|
||||
}
|
||||
|
||||
this._headers.empty();
|
||||
this._cookies.empty();
|
||||
this._params.empty();
|
||||
|
@ -1907,6 +1901,9 @@ NetworkDetailsView.prototype = {
|
|||
case 4: // "Timings"
|
||||
yield view._setTimingsInformation(src.eventTimings);
|
||||
break;
|
||||
case 5: // "Preview"
|
||||
yield view._setHtmlPreview(src.responseContent);
|
||||
break;
|
||||
}
|
||||
populated[tab] = true;
|
||||
window.emit(EVENTS.TAB_UPDATED);
|
||||
|
@ -2345,6 +2342,30 @@ NetworkDetailsView.prototype = {
|
|||
.style.transform = "translateX(" + (scale * (blocked + dns + connect + send + wait)) + "px)";
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the preview for HTML responses shown in this view.
|
||||
*
|
||||
* @param object aResponse
|
||||
* The message received from the server.
|
||||
* @return object
|
||||
* A promise that is resolved when the response body is set
|
||||
*/
|
||||
_setHtmlPreview: function(aResponse) {
|
||||
if (!aResponse) {
|
||||
return promise.resolve();
|
||||
}
|
||||
let { text } = aResponse.content;
|
||||
let iframe = $("#response-preview");
|
||||
|
||||
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);
|
||||
});
|
||||
},
|
||||
|
||||
_dataSrc: null,
|
||||
_headers: null,
|
||||
_cookies: null,
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
%netmonitorDTD;
|
||||
]>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/devtools/theme-switching.js"/>
|
||||
|
@ -238,14 +239,21 @@
|
|||
class="devtools-sidebar-tabs"
|
||||
handleCtrlTab="false">
|
||||
<tabs>
|
||||
<tab label="&netmonitorUI.tab.headers;"/>
|
||||
<tab label="&netmonitorUI.tab.cookies;"/>
|
||||
<tab label="&netmonitorUI.tab.params;"/>
|
||||
<tab label="&netmonitorUI.tab.response;"/>
|
||||
<tab label="&netmonitorUI.tab.timings;"/>
|
||||
<tab id="headers-tab"
|
||||
label="&netmonitorUI.tab.headers;"/>
|
||||
<tab id="cookies-tab"
|
||||
label="&netmonitorUI.tab.cookies;"/>
|
||||
<tab id="params-tab"
|
||||
label="&netmonitorUI.tab.params;"/>
|
||||
<tab id="response-tab"
|
||||
label="&netmonitorUI.tab.response;"/>
|
||||
<tab id="timings-tab"
|
||||
label="&netmonitorUI.tab.timings;"/>
|
||||
<tab id="preview-tab"
|
||||
label="&netmonitorUI.tab.preview;"/>
|
||||
</tabs>
|
||||
<tabpanels flex="1">
|
||||
<tabpanel id="headers-tabppanel"
|
||||
<tabpanel id="headers-tabpanel"
|
||||
class="tabpanel-content">
|
||||
<vbox flex="1">
|
||||
<hbox id="headers-summary-url"
|
||||
|
@ -413,6 +421,12 @@
|
|||
</hbox>
|
||||
</vbox>
|
||||
</tabpanel>
|
||||
<tabpanel id="preview-tabpanel"
|
||||
class="tabpanel-content">
|
||||
<html:iframe id="response-preview"
|
||||
frameborder="0"
|
||||
sandbox=""/>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</deck>
|
||||
|
|
|
@ -44,6 +44,7 @@ support-files =
|
|||
[browser_net_filter-02.js]
|
||||
[browser_net_filter-03.js]
|
||||
[browser_net_footer-summary.js]
|
||||
[browser_net_html-preview.js]
|
||||
[browser_net_json-long.js]
|
||||
[browser_net_json-malformed.js]
|
||||
[browser_net_json_custom_mime.js]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(CONTENT_TYPE_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { document, L10N, Editor, NetMonitorView } = aMonitor.panelWin;
|
||||
|
@ -62,6 +62,7 @@ function test() {
|
|||
});
|
||||
verifyRequestItemTarget(RequestsMenu.getItemAtIndex(5),
|
||||
"GET", TEST_IMAGE, {
|
||||
fuzzyUrl: true,
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
type: "png",
|
||||
|
|
|
@ -11,7 +11,9 @@ function test() {
|
|||
|
||||
let { NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
let imageDataUri = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
|
||||
|
||||
waitForNetworkEvents(aMonitor, 6).then(() => {
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if html responses show and properly populate a "Preview" tab.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(CONTENT_TYPE_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
let { $, document, NetMonitorView } = aMonitor.panelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 6).then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
document.getElementById("details-pane-toggle"));
|
||||
|
||||
is($("#event-details-pane").selectedIndex, 0,
|
||||
"The first tab in the details pane should be selected.");
|
||||
is($("#preview-tab").hidden, true,
|
||||
"The preview tab should be hidden for non html responses.");
|
||||
is($("#preview-tabpanel").hidden, true,
|
||||
"The preview tabpanel should be hidden for non html responses.");
|
||||
|
||||
RequestsMenu.selectedIndex = 4;
|
||||
NetMonitorView.toggleDetailsPane({ visible: true, animated: false }, 5);
|
||||
|
||||
is($("#event-details-pane").selectedIndex, 5,
|
||||
"The fifth tab in the details pane should be selected.");
|
||||
is($("#preview-tab").hidden, false,
|
||||
"The preview tab should be visible now.");
|
||||
is($("#preview-tabpanel").hidden, false,
|
||||
"The preview tabpanel should be visible now.");
|
||||
|
||||
let RESPONSE_HTML_PREVIEW_DISPLAYED = aMonitor.panelWin.EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED;
|
||||
waitFor(aMonitor.panelWin, RESPONSE_HTML_PREVIEW_DISPLAYED).then(() => {
|
||||
let iframe = $("#response-preview");
|
||||
ok(iframe,
|
||||
"There should be a response preview iframe available.");
|
||||
ok(iframe.contentDocument,
|
||||
"The iframe's content document should be available.");
|
||||
is(iframe.contentDocument.querySelector("blink").textContent, "Not Found",
|
||||
"The iframe's content document should be loaded and correct.");
|
||||
|
||||
RequestsMenu.selectedIndex = 5;
|
||||
|
||||
is($("#event-details-pane").selectedIndex, 0,
|
||||
"The first tab in the details pane should be selected again.");
|
||||
is($("#preview-tab").hidden, true,
|
||||
"The preview tab should be hidden again for non html responses.");
|
||||
is($("#preview-tabpanel").hidden, true,
|
||||
"The preview tabpanel should be hidden again for non html responses.");
|
||||
|
||||
teardown(aMonitor).then(finish);
|
||||
});
|
||||
});
|
||||
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
}
|
|
@ -68,6 +68,10 @@
|
|||
- in the network details pane identifying the timings tab. -->
|
||||
<!ENTITY netmonitorUI.tab.timings "Timings">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.tab.preview): This is the label displayed
|
||||
- in the network details pane identifying the preview tab. -->
|
||||
<!ENTITY netmonitorUI.tab.preview "Preview">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.footer.filterAll): This is the label displayed
|
||||
- in the network details footer for the "All" filtering button. -->
|
||||
<!ENTITY netmonitorUI.footer.filterAll "All">
|
||||
|
|
|
@ -458,6 +458,17 @@ box.requests-menu-status {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Preview tabpanel */
|
||||
|
||||
#preview-tabpanel {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#response-preview {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
/* Timings tabpanel */
|
||||
|
||||
#timings-tabpanel .tabpanel-summary-label {
|
||||
|
|
Загрузка…
Ссылка в новой задаче