var React = require("react");
var _ = require("lodash");
var MessageUtils = require("../../flow/utils.js").MessageUtils;
var utils = require("../../utils.js");
var image_regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i;
var ViewImage = React.createClass({
statics: {
matches: function (message) {
return image_regex.test(MessageUtils.getContentType(message));
}
},
render: function () {
var url = MessageUtils.getContentURL(this.props.flow, this.props.message);
return
;
}
});
var RawMixin = {
getInitialState: function () {
return {
content: undefined,
request: undefined
}
},
requestContent: function (nextProps) {
if (this.state.request) {
this.state.request.abort();
}
var request = MessageUtils.getContent(nextProps.flow, nextProps.message);
this.setState({
content: undefined,
request: request
});
request.done(function (data) {
this.setState({content: data});
}.bind(this)).fail(function (jqXHR, textStatus, errorThrown) {
if (textStatus === "abort") {
return;
}
this.setState({content: "AJAX Error: " + textStatus + "\r\n" + errorThrown});
}.bind(this)).always(function () {
this.setState({request: undefined});
}.bind(this));
},
componentWillMount: function () {
this.requestContent(this.props);
},
componentWillReceiveProps: function (nextProps) {
if (nextProps.message !== this.props.message) {
this.requestContent(nextProps);
}
},
componentWillUnmount: function () {
if (this.state.request) {
this.state.request.abort();
}
},
render: function () {
if (!this.state.content) {
return
;
}
return this.renderContent();
}
};
var ViewRaw = React.createClass({
mixins: [RawMixin],
statics: {
matches: function (message) {
return true;
}
},
renderContent: function () {
return
{this.state.content}
;
}
});
var json_regex = /^application\/json$/i;
var ViewJSON = React.createClass({
mixins: [RawMixin],
statics: {
matches: function (message) {
return json_regex.test(MessageUtils.getContentType(message));
}
},
renderContent: function () {
var json = this.state.content;
try {
json = JSON.stringify(JSON.parse(json), null, 2);
} catch (e) {
}
return
{json}
;
}
});
var ViewAuto = React.createClass({
statics: {
matches: function () {
return false; // don't match itself
},
findView: function (message) {
for (var i = 0; i < all.length; i++) {
if (all[i].matches(message)) {
return all[i];
}
}
return all[all.length - 1];
}
},
render: function () {
var View = ViewAuto.findView(this.props.message);
return ;
}
});
var all = [ViewAuto, ViewImage, ViewJSON, ViewRaw];
var ContentEmpty = React.createClass({
render: function () {
var message_name = this.props.flow.request === this.props.message ? "request" : "response";
return
No {message_name} content.
;
}
});
var ContentMissing = React.createClass({
render: function () {
var message_name = this.props.flow.request === this.props.message ? "Request" : "Response";
return
{message_name} content missing.
;
}
});
var TooLarge = React.createClass({
statics: {
isTooLarge: function (message) {
var max_mb = ViewImage.matches(message) ? 10 : 0.2;
return message.contentLength > 1024 * 1024 * max_mb;
}
},
render: function () {
var size = utils.formatSize(this.props.message.contentLength);
return
{size} content size.
;
}
});
var ViewSelector = React.createClass({
render: function () {
var views = [];
for (var i = 0; i < all.length; i++) {
var view = all[i];
var className = "btn btn-default";
if (view === this.props.active) {
className += " active";
}
var text;
if (view === ViewAuto) {
text = "auto: " + ViewAuto.findView(this.props.message).displayName.toLowerCase().replace("view", "");
} else {
text = view.displayName.toLowerCase().replace("view", "");
}
views.push(
);
}
return
{views}
;
}
});
var ContentView = React.createClass({
getInitialState: function () {
return {
displayLarge: false,
View: ViewAuto
};
},
propTypes: {
// It may seem a bit weird at the first glance:
// Every view takes the flow and the message as props, e.g.
//
flow: React.PropTypes.object.isRequired,
message: React.PropTypes.object.isRequired,
},
selectView: function (view) {
this.setState({
View: view
});
},
displayLarge: function () {
this.setState({displayLarge: true});
},
componentWillReceiveProps: function (nextProps) {
if (nextProps.message !== this.props.message) {
this.setState(this.getInitialState());
}
},
render: function () {
var message = this.props.message;
if (message.contentLength === 0) {
return ;
} else if (message.contentLength === null) {
return ;
} else if (!this.state.displayLarge && TooLarge.isTooLarge(message)) {
return ;
}
var downloadUrl = MessageUtils.getContentURL(this.props.flow, message);
return