Bug 859136 - Requests with an image response should display a thumbnail near the file name, r=rcampbell

This commit is contained in:
Victor Porof 2014-02-14 14:22:06 -05:00
parent ea260086f2
commit 6064c0397d
11 changed files with 107 additions and 22 deletions

View File

@ -60,7 +60,10 @@ const EVENTS = {
// When the html response preview is displayed in the UI.
RESPONSE_HTML_PREVIEW_DISPLAYED: "NetMonitor:ResponseHtmlPreviewAvailable",
// When `onTabSelect` is fired and subsequently rendered.
// When the image response thumbnail is displayed in the UI.
RESPONSE_IMAGE_THUMBNAIL_DISPLAYED: "NetMonitor:ResponseImageThumbnailAvailable",
// When a tab is selected in the NetworkDetailsView and subsequently rendered.
TAB_UPDATED: "NetMonitor:TabUpdated",
// Fired when Sidebar has finished being populated.

View File

@ -1010,13 +1010,14 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
this.updateMenuView(requestItem, key, value);
break;
case "responseContent":
requestItem.attachment.responseContent = value;
// If there's no mime type available when the response content
// is received, assume text/plain as a fallback.
if (!requestItem.attachment.mimeType) {
requestItem.attachment.mimeType = "text/plain";
this.updateMenuView(requestItem, "mimeType", "text/plain");
}
requestItem.attachment.responseContent = value;
this.updateMenuView(requestItem, key, value);
break;
case "totalTime":
requestItem.attachment.totalTime = value;
@ -1112,9 +1113,9 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let nameWithQuery = this._getUriNameWithQuery(uri);
let hostPort = this._getUriHostPort(uri);
let node = $(".requests-menu-file", target);
node.setAttribute("value", nameWithQuery);
node.setAttribute("tooltiptext", nameWithQuery);
let file = $(".requests-menu-file", target);
file.setAttribute("value", nameWithQuery);
file.setAttribute("tooltiptext", nameWithQuery);
let domain = $(".requests-menu-domain", target);
domain.setAttribute("value", hostPort);
@ -1148,6 +1149,21 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
node.setAttribute("tooltiptext", aValue);
break;
}
case "responseContent": {
let { mimeType } = aItem.attachment;
let { text, encoding } = aValue.content;
if (mimeType.contains("image/")) {
gNetwork.getString(text).then(aString => {
let node = $(".requests-menu-icon", target);
node.src = "data:" + mimeType + ";" + encoding + "," + aString;
node.setAttribute("type", "thumbnail");
node.removeAttribute("hidden");
window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
});
}
break;
}
case "totalTime": {
let node = $(".requests-menu-timings-total", target);
let text = L10N.getFormatStr("networkMenu.totalMS", aValue); // integer
@ -1626,7 +1642,7 @@ SidebarView.prototype = {
NetMonitorView.NetworkDetails;
return view.populate(aData).then(() => {
$("#details-pane").selectedIndex = isCustom ? 0 : 1
$("#details-pane").selectedIndex = isCustom ? 0 : 1;
window.emit(EVENTS.SIDEBAR_POPULATED);
});
}
@ -1906,6 +1922,7 @@ NetworkDetailsView.prototype = {
}
populated[tab] = true;
window.emit(EVENTS.TAB_UPDATED);
NetMonitorView.RequestsMenu.ensureSelectedItemIsVisible();
});
},

View File

@ -60,7 +60,7 @@
-moz-box-flex: 1;
}
#network-table[domain-overflows] .requests-menu-file {
#network-table[domain-overflows] .requests-menu-icon-and-file {
-moz-box-flex: 1;
}
}

View File

@ -68,8 +68,8 @@
flex="1">
</button>
</hbox>
<hbox id="requests-menu-file-header-box"
class="requests-menu-header requests-menu-file"
<hbox id="requests-menu-icon-and-file-header-box"
class="requests-menu-header requests-menu-icon-and-file"
align="center">
<button id="requests-menu-file-button"
class="requests-menu-header-button requests-menu-file"
@ -152,8 +152,13 @@
crop="end"
flex="1"/>
</hbox>
<label class="plain requests-menu-subitem requests-menu-file"
crop="end"/>
<hbox class="requests-menu-subitem requests-menu-icon-and-file"
align="center">
<image class="requests-menu-icon" hidden="true"/>
<label class="plain requests-menu-file"
crop="end"
flex="1"/>
</hbox>
<label class="plain requests-menu-subitem requests-menu-domain"
crop="end"/>
<label class="plain requests-menu-subitem requests-menu-type"

View File

@ -47,6 +47,7 @@ support-files =
[browser_net_filter-03.js]
[browser_net_footer-summary.js]
[browser_net_html-preview.js]
[browser_net_icon-preview.js]
[browser_net_json-long.js]
[browser_net_json-malformed.js]
[browser_net_json_custom_mime.js]

View File

@ -14,13 +14,11 @@ function test() {
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(() => {
let requestItem = RequestsMenu.getItemAtIndex(5);
RequestsMenu.selectedItem = requestItem;
waitForClipboard(imageDataUri, function setup() {
waitForClipboard(TEST_IMAGE_DATA_URI, function setup() {
RequestsMenu.copyImageAsDataUri();
}, function onSuccess() {
ok(true, "Clipboard contains the currently selected image as data uri.");

View File

@ -9,7 +9,7 @@ function test() {
initNetMonitor(CONTENT_TYPE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { $, document, NetMonitorView } = aMonitor.panelWin;
let { $, document, EVENTS, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
@ -35,8 +35,7 @@ function test() {
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(() => {
waitFor(aMonitor.panelWin, EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED).then(() => {
let iframe = $("#response-preview");
ok(iframe,
"There should be a response preview iframe available.");

View File

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if image responses show a thumbnail in the requests menu.
*/
function test() {
initNetMonitor(CONTENT_TYPE_WITHOUT_CACHE_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { $, $all, EVENTS, NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
promise.all([
waitForNetworkEvents(aMonitor, 6),
waitFor(aMonitor.panelWin, EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED)
]).then(() => {
is($all(".requests-menu-icon[type=thumbnail]").length, 1,
"There should be only one image request with a thumbnail displayed.");
is($(".requests-menu-icon[type=thumbnail]").src, TEST_IMAGE_DATA_URI,
"The image requests-menu-icon thumbnail is displayed correctly.");
is($(".requests-menu-icon[type=thumbnail]").hidden, false,
"The image requests-menu-icon thumbnail should not be hidden.");
teardown(aMonitor).then(finish);
});
aDebuggee.performRequests();
});
}

View File

@ -40,6 +40,7 @@ const STATUS_CODES_SJS = EXAMPLE_URL + "sjs_status-codes-test-server.sjs";
const SORTING_SJS = EXAMPLE_URL + "sjs_sorting-test-server.sjs";
const TEST_IMAGE = EXAMPLE_URL + "test-image.png";
const TEST_IMAGE_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==";
// All tests are asynchronous.
waitForExplicitFinish();

View File

@ -769,6 +769,13 @@ this.WidgetMethods = {
this.ensureItemIsVisible(this.getItemAtIndex(aIndex));
},
/**
* Sugar for ensuring the selected item is visible in this container.
*/
ensureSelectedItemIsVisible: function() {
this.ensureItemIsVisible(this.selectedItem);
},
/**
* If supported by the widget, the label string temporarily added to this
* container when there are no child items present.

View File

@ -126,11 +126,31 @@
font-weight: 600;
}
.requests-menu-file {
.requests-menu-icon-and-file {
width: 20vw;
min-width: 4em;
}
.requests-menu-icon {
background: #fff;
width: calc(1em + 4px);
height: calc(1em + 4px);
margin: -4px 0px;
-moz-margin-end: 4px;
}
.theme-dark .requests-menu-icon {
outline: 1px solid @table_itemDarkStartBorder@;
}
.theme-light .requests-menu-icon {
outline: 1px solid @table_itemLightStartBorder@;
}
.requests-menu-file {
text-align: start;
}
.requests-menu-domain {
width: 14vw;
min-width: 10em;
@ -288,8 +308,6 @@ box.requests-menu-status {
-moz-padding-end: 4px;
background-repeat: repeat-y; /* Background created on a <canvas> in js. */
background-position: -1px center;
margin-top: -1px; /* Compensate borders. */
margin-bottom: -1px;
}
.requests-menu-subitem.requests-menu-waterfall:-moz-locale-dir(rtl) {
@ -771,7 +789,10 @@ box.requests-menu-status {
width: 16vw;
}
.requests-menu-file,
.requests-menu-icon-and-file {
width: 30vw;
}
.requests-menu-domain {
width: 30vw;
}
@ -797,7 +818,7 @@ box.requests-menu-status {
right border and box-shadow of "Domain" column should be hidden. */
}
#network-table[domain-overflows] .requests-menu-file {
#network-table[domain-overflows] .requests-menu-icon-and-file {
border-width: 0 !important;
box-shadow: none !important;
/* The "Domain" header is not visible anymore, and thus the