diff options
author | Maximilian Hils <git@maximilianhils.com> | 2016-07-21 01:14:55 -0700 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2016-07-21 01:14:55 -0700 |
commit | 8a3a21bba1e6706295cc22e1b3a876a7a86cb705 (patch) | |
tree | 9408324d45850fd4def75c60cf3537a12f632217 /web/src/js/components/FlowView | |
parent | 427fffbcb82ba16dd65a4fee4000a05215e859b8 (diff) | |
download | mitmproxy-8a3a21bba1e6706295cc22e1b3a876a7a86cb705.tar.gz mitmproxy-8a3a21bba1e6706295cc22e1b3a876a7a86cb705.tar.bz2 mitmproxy-8a3a21bba1e6706295cc22e1b3a876a7a86cb705.zip |
web: fix ValueEditor, clean up code
Diffstat (limited to 'web/src/js/components/FlowView')
-rw-r--r-- | web/src/js/components/FlowView/FlowEditorButton.jsx | 39 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Headers.jsx | 71 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Messages.jsx | 226 | ||||
-rw-r--r-- | web/src/js/components/FlowView/ToggleEdit.jsx | 38 |
4 files changed, 199 insertions, 175 deletions
diff --git a/web/src/js/components/FlowView/FlowEditorButton.jsx b/web/src/js/components/FlowView/FlowEditorButton.jsx deleted file mode 100644 index 3d0d1d16..00000000 --- a/web/src/js/components/FlowView/FlowEditorButton.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { PropTypes, Component } from 'react' -import { connect } from 'react-redux' - -import {closeFlowEditor} from '../../ducks/ui.js' -import {openFlowEditor} from '../../ducks/ui.js' - -FlowEditorButton.propTypes = { - isFlowEditorOpen: PropTypes.bool.isRequired, - content: PropTypes.string.isRequired, - onContentChange: PropTypes.func.isRequired -} - -function FlowEditorButton ({ isFlowEditorOpen, closeFlowEditor, openFlowEditor, onContentChange, content }) { - return ( - <div className="edit-flow-container"> - {isFlowEditorOpen ? - <a className="edit-flow" onClick={() => {onContentChange(content); closeFlowEditor()}}> - <i className="fa fa-check"/> - </a> - : - <a className="edit-flow" onClick={() => openFlowEditor()}> - <i className="fa fa-pencil"/> - </a> - } - </div> - ) -} - -export default connect( - state => ({ - isFlowEditorOpen: state.ui.isFlowEditorOpen, - content: state.ui.modifiedFlow.content - }), - { - closeFlowEditor, - openFlowEditor - - } -)(FlowEditorButton) diff --git a/web/src/js/components/FlowView/Headers.jsx b/web/src/js/components/FlowView/Headers.jsx index 880eeda1..706dd404 100644 --- a/web/src/js/components/FlowView/Headers.jsx +++ b/web/src/js/components/FlowView/Headers.jsx @@ -1,12 +1,21 @@ import React, { Component, PropTypes } from 'react' import ReactDOM from 'react-dom' -import ValueEditor from '../ValueEditor' -import { Key } from '../../utils.js' +import ValueEditor from '../ValueEditor/ValueEditor' +import { Key } from '../../utils' class HeaderEditor extends Component { + constructor(props) { + super(props) + this.onKeyDown = this.onKeyDown.bind(this) + } + render() { - return <ValueEditor ref="input" {...this.props} onKeyDown={this.onKeyDown} inline/> + let { onTab, ...props } = this.props + return <ValueEditor + {...props} + onKeyDown={this.onKeyDown} + /> } focus() { @@ -21,6 +30,7 @@ class HeaderEditor extends Component { this.props.onRemove(e) } break + case Key.ENTER: case Key.TAB: if (!e.shiftKey) { this.props.onTab(e) @@ -66,7 +76,12 @@ export default class Headers extends Component { onTab(row, col, e) { const headers = this.props.message.headers - if (row !== headers.length - 1 || col !== 1) { + if (col === 0) { + this._nextSel = `${row}-value` + return + } + if (row !== headers.length - 1) { + this._nextSel = `${row + 1}-key` return } @@ -96,33 +111,35 @@ export default class Headers extends Component { } render() { - const { message } = this.props + const { message, readonly } = this.props return ( <table className="header-table"> <tbody> - {message.headers.map((header, i) => ( - <tr key={i}> - <td className="header-name"> - <HeaderEditor - ref={`${i}-key`} - content={header[0]} - onDone={val => this.onChange(i, 0, val)} - onRemove={event => this.onRemove(i, 0, event)} - onTab={event => this.onTab(i, 0, event)} - />: - </td> - <td className="header-value"> - <HeaderEditor - ref={`${i}-value`} - content={header[1]} - onDone={val => this.onChange(i, 1, val)} - onRemove={event => this.onRemove(i, 1, event)} - onTab={event => this.onTab(i, 1, event)} - /> - </td> - </tr> - ))} + {message.headers.map((header, i) => ( + <tr key={i}> + <td className="header-name"> + <HeaderEditor + ref={`${i}-key`} + content={header[0]} + readonly={readonly} + onDone={val => this.onChange(i, 0, val)} + onRemove={event => this.onRemove(i, 0, event)} + onTab={event => this.onTab(i, 0, event)} + />: + </td> + <td className="header-value"> + <HeaderEditor + ref={`${i}-value`} + content={header[1]} + readonly={readonly} + onDone={val => this.onChange(i, 1, val)} + onRemove={event => this.onRemove(i, 1, event)} + onTab={event => this.onTab(i, 1, event)} + /> + </td> + </tr> + ))} </tbody> </table> ) diff --git a/web/src/js/components/FlowView/Messages.jsx b/web/src/js/components/FlowView/Messages.jsx index 2f03c712..133b2883 100644 --- a/web/src/js/components/FlowView/Messages.jsx +++ b/web/src/js/components/FlowView/Messages.jsx @@ -1,172 +1,180 @@ import React, { Component, PropTypes } from 'react' -import _ from 'lodash' - -import { RequestUtils, isValidHttpVersion, parseUrl, parseHttpVersion } from '../../flow/utils.js' -import { Key, formatTimeStamp } from '../../utils.js' -import ContentView from '../ContentView' -import ValueEditor from '../ValueEditor' -import Headers from './Headers' -import * as flowActions from '../../ducks/flows' -import FlowEditorButton from './FlowEditorButton' +import { connect } from 'react-redux' -class RequestLine extends Component { +import { RequestUtils, isValidHttpVersion, parseUrl } from '../../flow/utils.js' +import { formatTimeStamp } from '../../utils.js' +import ContentView from '../ContentView' +import ValidateEditor from '../ValueEditor/ValidateEditor' +import ValueEditor from '../ValueEditor/ValueEditor' - render() { - const { flow, updateFlow } = this.props +import Headers from './Headers' +import { startEdit, updateEdit } from '../../ducks/ui/flow' +import ToggleEdit from './ToggleEdit' - return ( - <div className="first-line request-line"> +function RequestLine({ flow, readonly, updateFlow }) { + return ( + <div className="first-line request-line"> + <div> <ValueEditor - ref="method" content={flow.request.method} + readonly={readonly} onDone={method => updateFlow({ request: { method } })} - inline /> - <ValueEditor - ref="url" + <ValidateEditor content={RequestUtils.pretty_url(flow.request)} - onDone={url => updateFlow({ request: Object.assign({ path: '' }, parseUrl(url)) })} + readonly={readonly} + onDone={url => updateFlow({ request: {path: '', ...parseUrl(url)}})} isValid={url => !!parseUrl(url).host} - inline /> - <ValueEditor - ref="httpVersion" + <ValidateEditor content={flow.request.http_version} - onDone={ver => updateFlow({ request: { http_version: parseHttpVersion(ver) } })} + readonly={readonly} + onDone={http_version => updateFlow({ request: { http_version } })} isValid={isValidHttpVersion} - inline /> </div> - ) - } + </div> + ) } -class ResponseLine extends Component { - - render() { - const { flow, updateFlow } = this.props +function ResponseLine({ flow, readonly, updateFlow }) { + return ( + <div className="first-line response-line"> + <ValidateEditor + content={flow.response.http_version} + readonly={readonly} + onDone={nextVer => updateFlow({ response: { http_version: nextVer } })} + isValid={isValidHttpVersion} + /> + + <ValidateEditor + content={flow.response.status_code + ''} + readonly={readonly} + onDone={code => updateFlow({ response: { code: parseInt(code) } })} + isValid={code => /^\d+$/.test(code)} + /> + + <ValueEditor + content={flow.response.reason} + readonly={readonly} + onDone={msg => updateFlow({ response: { msg } })} + /> + </div> + ) +} - return ( - <div className="first-line response-line"> - <ValueEditor - ref="httpVersion" - content={flow.response.http_version} - onDone={nextVer => updateFlow({ response: { http_version: parseHttpVersion(nextVer) } })} - isValid={isValidHttpVersion} - inline - /> - - <ValueEditor - ref="code" - content={flow.response.status_code + ''} - onDone={code => updateFlow({ response: { code: parseInt(code) } })} - isValid={code => /^\d+$/.test(code)} - inline - /> - - <ValueEditor - ref="msg" - content={flow.response.reason} - onDone={msg => updateFlow({ response: { msg } })} - inline - /> - </div> - ) +const Message = connect( + state => ({ + flow: state.ui.flow.modifiedFlow || state.flows.byId[state.flows.selected[0]], + isEdit: !!state.ui.flow.modifiedFlow, + }), + { + updateFlow: updateEdit, } -} +) export class Request extends Component { - render() { - const { flow, updateFlow } = this.props - let onContentChange = content => flowActions.updateContent(this.props.flow, content, "request") + render() { + const { flow, isEdit, updateFlow } = this.props return ( <section className="request"> - <FlowEditorButton onContentChange={onContentChange}/> - <RequestLine ref="requestLine" flow={flow} updateFlow={updateFlow} /> + <ToggleEdit/> + <RequestLine + flow={flow} + readonly={!isEdit} + updateFlow={updateFlow}/> <Headers - ref="headers" message={flow.request} + readonly={!isEdit} onChange={headers => updateFlow({ request: { headers } })} /> <hr/> - <ContentView flow={flow} - onContentChange={onContentChange} - message={flow.request} - /> + <ContentView flow={flow} message={flow.request}/> </section> ) } + edit(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 new Error(`Unimplemented: ${k}`) - } + throw "unimplemented" + /* + 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 new Error(`Unimplemented: ${k}`) + } + */ } + } -export class Response extends Component { +Request = Message(Request) +export class Response extends Component { render() { - const { flow, updateFlow } = this.props - let onContentChange = content => flowActions.updateContent(this.props.flow, content, "response") + const { flow, isEdit, updateFlow } = this.props return ( <section className="response"> - <FlowEditorButton onContentChange={onContentChange}/> - <ResponseLine ref="responseLine" flow={flow} updateFlow={updateFlow} /> + <ToggleEdit/> + <ResponseLine + flow={flow} + readonly={!isEdit} + updateFlow={updateFlow}/> <Headers - ref="headers" message={flow.response} + readonly={!isEdit} onChange={headers => updateFlow({ response: { headers } })} /> <hr/> - <ContentView flow={flow} - onContentChange={onContentChange} - message={flow.response} - /> + <ContentView flow={flow} message={flow.response}/> </section> ) } edit(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 new Error(`'Unimplemented: ${k}`) - } + throw "unimplemented" + /* + 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 new Error(`'Unimplemented: ${k}`) + } + */ } } +Response = Message(Response) + + ErrorView.propTypes = { flow: PropTypes.object.isRequired, } diff --git a/web/src/js/components/FlowView/ToggleEdit.jsx b/web/src/js/components/FlowView/ToggleEdit.jsx new file mode 100644 index 00000000..0c8cbbd8 --- /dev/null +++ b/web/src/js/components/FlowView/ToggleEdit.jsx @@ -0,0 +1,38 @@ +import React, { PropTypes, Component } from 'react' +import { connect } from 'react-redux' + +import { startEdit, stopEdit } from '../../ducks/ui/flow' + +ToggleEdit.propTypes = { + isEdit: PropTypes.bool.isRequired, + flow: PropTypes.object.isRequired, + startEdit: PropTypes.func.isRequired, + stopEdit: PropTypes.func.isRequired, +} + +function ToggleEdit({ isEdit, startEdit, stopEdit, flow }) { + return ( + <div className="edit-flow-container"> + {isEdit ? + <a className="edit-flow" onClick={() => stopEdit(flow)}> + <i className="fa fa-check"/> + </a> + : + <a className="edit-flow" onClick={() => startEdit(flow)}> + <i className="fa fa-pencil"/> + </a> + } + </div> + ) +} + +export default connect( + state => ({ + isEdit: !!state.ui.flow.modifiedFlow, + flow: state.ui.flow.modifiedFlow || state.flows.byId[state.flows.selected[0]] + }), + { + startEdit, + stopEdit, + } +)(ToggleEdit) |