Bug 1317659 - Implement Preview Panel r=Honza,jsnajdr

MozReview-Commit-ID: G9vmDrz97pR

--HG--
extra : rebase_source : 57d3a35f6432be990288e85c2edb39c033ff402a
This commit is contained in:
Ricky Chien 2016-11-22 21:59:12 +08:00
Родитель 554abfa33e
Коммит c2a23d7e57
9 изменённых файлов: 76 добавлений и 39 удалений

Просмотреть файл

@ -31,7 +31,7 @@ function FilterButtons({
return div({ id: "requests-menu-filter-buttons" }, buttons);
}
FilterButtons.PropTypes = {
FilterButtons.propTypes = {
state: PropTypes.object.isRequired,
triggerFilterType: PropTypes.func.iRequired,
};

Просмотреть файл

@ -29,6 +29,7 @@ const {
const { createFactory } = require("devtools/client/shared/vendor/react");
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider);
const PreviewPanel = createFactory(require("./shared/components/preview-panel"));
const SecurityPanel = createFactory(require("./shared/components/security-panel"));
const TimingsPanel = createFactory(require("./shared/components/timings-panel"));
@ -93,6 +94,13 @@ DetailsView.prototype = {
initialize: function (store) {
dumpn("Initializing the DetailsView");
this._previewPanelNode = $("#react-preview-tabpanel-hook");
ReactDOM.render(Provider(
{ store },
PreviewPanel()
), this._previewPanelNode);
this._securityPanelNode = $("#react-security-tabpanel-hook");
ReactDOM.render(Provider(
@ -152,6 +160,7 @@ DetailsView.prototype = {
*/
destroy: function () {
dumpn("Destroying the DetailsView");
ReactDOM.unmountComponentAtNode(this._previewPanelNode);
ReactDOM.unmountComponentAtNode(this._securityPanelNode);
ReactDOM.unmountComponentAtNode(this._timingsPanelNode);
this.sidebar.destroy();
@ -263,10 +272,6 @@ DetailsView.prototype = {
case 3:
yield view._setResponseBody(src.url, src.responseContent);
break;
// "Preview"
case 6:
yield view._setHtmlPreview(src.responseContent);
break;
}
viewState.updating[tab] = false;
}).then(() => {
@ -697,30 +702,6 @@ DetailsView.prototype = {
window.emit(EVENTS.RESPONSE_BODY_DISPLAYED);
}),
/**
* Sets the preview for HTML responses shown in this view.
*
* @param object response
* The message received from the server.
* @return object
* A promise that is resolved when the html preview is rendered.
*/
_setHtmlPreview: Task.async(function* (response) {
if (!response) {
return promise.resolve();
}
let { text } = response.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;
window.emit(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
return undefined;
}),
_dataSrc: null,
_headers: null,
_cookies: null,

Просмотреть файл

@ -58,9 +58,6 @@ 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 the image response thumbnail is displayed in the UI.
RESPONSE_IMAGE_THUMBNAIL_DISPLAYED:
"NetMonitor:ResponseImageThumbnailAvailable",

Просмотреть файл

@ -272,9 +272,8 @@
</tabpanel>
<tabpanel id="preview-tabpanel"
class="tabpanel-content">
<html:iframe id="response-preview"
frameborder="0"
sandbox=""/>
<html:div xmlns="http://www.w3.org/1999/xhtml"
id="react-preview-tabpanel-hook"/>
</tabpanel>
</tabpanels>
</tabbox>

Просмотреть файл

@ -210,15 +210,16 @@ RequestsMenuView.prototype = {
const action = Actions.updateRequest(id, data, true);
yield this.store.dispatch(action);
const { responseContent, requestPostData } = action.data;
let { responseContent, requestPostData } = action.data;
// Fetch response data if the response is an image (to display thumbnail)
if (responseContent && responseContent.content) {
let request = getRequestById(this.store.getState(), action.id);
let { text, encoding } = responseContent.content;
if (request) {
let { mimeType } = request;
// Fetch response data if the response is an image (to display thumbnail)
if (mimeType.includes("image/")) {
let { text, encoding } = responseContent.content;
let responseBody = yield gNetwork.getString(text);
const dataUri = formDataURI(mimeType, encoding, responseBody);
yield this.store.dispatch(Actions.updateRequest(
@ -227,6 +228,16 @@ RequestsMenuView.prototype = {
true
));
window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
// Fetch response text only if the response is html, but not all text/*
} else if (mimeType.includes("text/html") && typeof text !== "string") {
let responseBody = yield gNetwork.getString(text);
responseContent.content.text = responseBody;
responseContent = Object.assign({}, responseContent);
yield this.store.dispatch(Actions.updateRequest(
action.id,
{ responseContent },
true
));
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'preview-panel.js',
'security-panel.js',
'timings-panel.js',
)

Просмотреть файл

@ -0,0 +1,44 @@
/* 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 { DOM, PropTypes } = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { getSelectedRequest } = require("../../selectors/index");
const { iframe } = DOM;
/*
* Preview panel component
* Display HTML content within a sandbox enabled iframe
*/
function PreviewPanel({
srcDoc = "",
}) {
return iframe({
id: "response-preview",
sandbox: "",
srcDoc,
});
}
PreviewPanel.displayName = "PreviewPanel";
PreviewPanel.propTypes = {
srcDoc: PropTypes.string,
};
module.exports = connect(
(state) => {
const selectedRequest = getSelectedRequest(state);
const htmlBody = selectedRequest && selectedRequest.responseContent ?
selectedRequest.responseContent.content.text : "";
const srcDoc = typeof htmlBody === "string" ? htmlBody : "";
return {
srcDoc,
};
}
)(PreviewPanel);

Просмотреть файл

@ -40,8 +40,9 @@ add_task(function* () {
is($("#preview-tab").hidden, false,
"The preview tab should be visible now.");
yield monitor.panelWin.once(EVENTS.RESPONSE_HTML_PREVIEW_DISPLAYED);
let iframe = $("#response-preview");
yield once(iframe, "DOMContentLoaded");
ok(iframe,
"There should be a response preview iframe available.");
ok(iframe.contentDocument,

Просмотреть файл

@ -742,7 +742,9 @@
}
#response-preview {
border: none;
display: -moz-box;
-moz-box-orient: vertical;
-moz-box-flex: 1;
}
@ -1138,6 +1140,7 @@
* FIXME: normal html block element cannot fill outer XUL element
* This workaround should be removed after sidebar is migrated to react
*/
#react-preview-tabpanel-hook,
#react-security-tabpanel-hook,
#react-timings-tabpanel-hook {
display: -moz-box;