import React from "react";
import ReactDOM from 'react-dom';
import _ from "lodash";
import {FlowActions} from "../../actions.js";
import {RequestUtils, isValidHttpVersion, parseUrl, parseHttpVersion} from "../../flow/utils.js";
import {Key, formatTimeStamp} from "../../utils.js";
import ContentView from "./contentview.js";
import {ValueEditor} from "../editor.js";
var Headers = React.createClass({
propTypes: {
onChange: React.PropTypes.func.isRequired,
message: React.PropTypes.object.isRequired
},
onChange: function (row, col, val) {
var nextHeaders = _.cloneDeep(this.props.message.headers);
nextHeaders[row][col] = val;
if (!nextHeaders[row][0] && !nextHeaders[row][1]) {
// do not delete last row
if (nextHeaders.length === 1) {
nextHeaders[0][0] = "Name";
nextHeaders[0][1] = "Value";
} else {
nextHeaders.splice(row, 1);
// manually move selection target if this has been the last row.
if (row === nextHeaders.length) {
this._nextSel = (row - 1) + "-value";
}
}
}
this.props.onChange(nextHeaders);
},
edit: function () {
this.refs["0-key"].focus();
},
onTab: function (row, col, e) {
var headers = this.props.message.headers;
if (row === headers.length - 1 && col === 1) {
e.preventDefault();
var nextHeaders = _.cloneDeep(this.props.message.headers);
nextHeaders.push(["Name", "Value"]);
this.props.onChange(nextHeaders);
this._nextSel = (row + 1) + "-key";
}
},
componentDidUpdate: function () {
if (this._nextSel && this.refs[this._nextSel]) {
this.refs[this._nextSel].focus();
this._nextSel = undefined;
}
},
onRemove: function (row, col, e) {
if (col === 1) {
e.preventDefault();
this.refs[row + "-key"].focus();
} else if (row > 0) {
e.preventDefault();
this.refs[(row - 1) + "-value"].focus();
}
},
render: function () {
var rows = this.props.message.headers.map(function (header, i) {
var kEdit = ;
var vEdit = ;
return (
{kEdit}: |
{vEdit} |
);
}.bind(this));
return (
);
}
});
var HeaderEditor = React.createClass({
render: function () {
return ;
},
focus: function () {
ReactDOM.findDOMNode(this).focus();
},
onKeyDown: function (e) {
switch (e.keyCode) {
case Key.BACKSPACE:
var s = window.getSelection().getRangeAt(0);
if (s.startOffset === 0 && s.endOffset === 0) {
this.props.onRemove(e);
}
break;
case Key.TAB:
if (!e.shiftKey) {
this.props.onTab(e);
}
break;
}
}
});
var RequestLine = React.createClass({
render: function () {
var flow = this.props.flow;
var url = RequestUtils.pretty_url(flow.request);
var httpver = flow.request.http_version;
return
},
isValidUrl: function (url) {
var u = parseUrl(url);
return !!u.host;
},
onMethodChange: function (nextMethod) {
FlowActions.update(
this.props.flow,
{request: {method: nextMethod}}
);
},
onUrlChange: function (nextUrl) {
var props = parseUrl(nextUrl);
props.path = props.path || "";
FlowActions.update(
this.props.flow,
{request: props}
);
},
onHttpVersionChange: function (nextVer) {
var ver = parseHttpVersion(nextVer);
FlowActions.update(
this.props.flow,
{request: {http_version: ver}}
);
}
});
var ResponseLine = React.createClass({
render: function () {
var flow = this.props.flow;
var httpver = flow.response.http_version;
return
;
},
isValidCode: function (code) {
return /^\d+$/.test(code);
},
onHttpVersionChange: function (nextVer) {
var ver = parseHttpVersion(nextVer);
FlowActions.update(
this.props.flow,
{response: {http_version: ver}}
);
},
onMsgChange: function (nextMsg) {
FlowActions.update(
this.props.flow,
{response: {msg: nextMsg}}
);
},
onCodeChange: function (nextCode) {
nextCode = parseInt(nextCode);
FlowActions.update(
this.props.flow,
{response: {code: nextCode}}
);
}
});
export var Request = React.createClass({
render: function () {
var flow = this.props.flow;
return (
);
},
edit: function (k) {
switch (k) {
case "m":
this.refs.requestLine.refs.method.focus();
break;
case "u":
this.refs.requestLine.refs.url.focus();
break;
case "v":
this.refs.requestLine.refs.httpVersion.focus();
break;
case "h":
this.refs.headers.edit();
break;
default:
throw "Unimplemented: " + k;
}
},
onHeaderChange: function (nextHeaders) {
FlowActions.update(this.props.flow, {
request: {
headers: nextHeaders
}
});
}
});
export var Response = React.createClass({
render: function () {
var flow = this.props.flow;
return (
);
},
edit: function (k) {
switch (k) {
case "c":
this.refs.responseLine.refs.status_code.focus();
break;
case "m":
this.refs.responseLine.refs.msg.focus();
break;
case "v":
this.refs.responseLine.refs.httpVersion.focus();
break;
case "h":
this.refs.headers.edit();
break;
default:
throw "Unimplemented: " + k;
}
},
onHeaderChange: function (nextHeaders) {
FlowActions.update(this.props.flow, {
response: {
headers: nextHeaders
}
});
}
});
export var Error = React.createClass({
render: function () {
var flow = this.props.flow;
return (
{flow.error.msg}
{ formatTimeStamp(flow.error.timestamp) }
);
}
});