diff options
author | Maximilian Hils <git@maximilianhils.com> | 2016-06-17 01:53:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-17 01:53:02 -0700 |
commit | fcf5dc8728816bae73a175ee021f8a11a1591567 (patch) | |
tree | 56ff25784a659f0e54894ca616e198cfe1a13ea0 /web/src/js/components/FlowView/Headers.jsx | |
parent | 78785df16be237bfdbf4ee485639b61f06b4a47e (diff) | |
parent | 034287edcf00eb734cb67e62de58c3bfebf6bb44 (diff) | |
download | mitmproxy-fcf5dc8728816bae73a175ee021f8a11a1591567.tar.gz mitmproxy-fcf5dc8728816bae73a175ee021f8a11a1591567.tar.bz2 mitmproxy-fcf5dc8728816bae73a175ee021f8a11a1591567.zip |
Merge pull request #1267 from gzzhanghao/components
[web] Working on components
Diffstat (limited to 'web/src/js/components/FlowView/Headers.jsx')
-rw-r--r-- | web/src/js/components/FlowView/Headers.jsx | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/web/src/js/components/FlowView/Headers.jsx b/web/src/js/components/FlowView/Headers.jsx new file mode 100644 index 00000000..880eeda1 --- /dev/null +++ b/web/src/js/components/FlowView/Headers.jsx @@ -0,0 +1,130 @@ +import React, { Component, PropTypes } from 'react' +import ReactDOM from 'react-dom' +import ValueEditor from '../ValueEditor' +import { Key } from '../../utils.js' + +class HeaderEditor extends Component { + + render() { + return <ValueEditor ref="input" {...this.props} onKeyDown={this.onKeyDown} inline/> + } + + focus() { + ReactDOM.findDOMNode(this).focus() + } + + onKeyDown(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 + } + } +} + +export default class Headers extends Component { + + static propTypes = { + onChange: PropTypes.func.isRequired, + message: PropTypes.object.isRequired, + } + + onChange(row, col, val) { + const 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() { + this.refs['0-key'].focus() + } + + onTab(row, col, e) { + const headers = this.props.message.headers + + if (row !== headers.length - 1 || col !== 1) { + return + } + + e.preventDefault() + + const nextHeaders = _.cloneDeep(this.props.message.headers) + nextHeaders.push(['Name', 'Value']) + this.props.onChange(nextHeaders) + this._nextSel = `${row + 1}-key` + } + + componentDidUpdate() { + if (this._nextSel && this.refs[this._nextSel]) { + this.refs[this._nextSel].focus() + this._nextSel = undefined + } + } + + onRemove(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() { + const { message } = 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> + ))} + </tbody> + </table> + ) + } +} |