diff options
author | Clemens <cle1000.cb@gmail.com> | 2016-07-13 18:16:31 +0200 |
---|---|---|
committer | Clemens <cle1000.cb@gmail.com> | 2016-07-13 18:16:31 +0200 |
commit | f84098554a3d50ec02255603bb0a145b3aa0c6b2 (patch) | |
tree | e778b465346d9c96c27cd7663c2a95451710c262 /web | |
parent | 544b1e32389d28df4a40013ea6886f1f9d61e37d (diff) | |
download | mitmproxy-f84098554a3d50ec02255603bb0a145b3aa0c6b2.tar.gz mitmproxy-f84098554a3d50ec02255603bb0a145b3aa0c6b2.tar.bz2 mitmproxy-f84098554a3d50ec02255603bb0a145b3aa0c6b2.zip |
added code editor and file upload
Diffstat (limited to 'web')
-rw-r--r-- | web/package.json | 4 | ||||
-rw-r--r-- | web/src/js/app.jsx | 2 | ||||
-rw-r--r-- | web/src/js/components/ContentView.jsx | 24 | ||||
-rw-r--r-- | web/src/js/components/ContentView/ContentViews.jsx | 30 | ||||
-rw-r--r-- | web/src/js/components/common/Button.jsx | 6 | ||||
-rw-r--r-- | web/src/js/components/common/CodeEditor.jsx | 41 | ||||
-rw-r--r-- | web/src/js/components/common/MonacoEditor.jsx | 34 | ||||
-rw-r--r-- | web/src/js/ducks/flows.js | 8 |
8 files changed, 99 insertions, 50 deletions
diff --git a/web/package.json b/web/package.json index 1484961d..7cfd3d90 100644 --- a/web/package.json +++ b/web/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "test": "jest", - "build": "gulp dev", + "build": "gulp prod", "start": "gulp" }, "jest": { @@ -29,7 +29,7 @@ "redux-logger": "^2.6.1", "redux-thunk": "^2.1.0", "shallowequal": "^0.2.2", - "monaco-editor": "^0.5.1" + "react-ace": "^3.5.0" }, "devDependencies": { "babel-core": "^6.7.7", diff --git a/web/src/js/app.jsx b/web/src/js/app.jsx index 51b2b639..5acf5dd4 100644 --- a/web/src/js/app.jsx +++ b/web/src/js/app.jsx @@ -12,7 +12,7 @@ import { add as addLog } from './ducks/eventLog' const middlewares = [thunk]; -if (process.env.NODE_ENV === 'development' || true) { +if (process.env.NODE_ENV === 'development' ) { const createLogger = require('redux-logger'); middlewares.push(createLogger()); } diff --git a/web/src/js/components/ContentView.jsx b/web/src/js/components/ContentView.jsx index f6dbe90a..6c9d9b26 100644 --- a/web/src/js/components/ContentView.jsx +++ b/web/src/js/components/ContentView.jsx @@ -4,6 +4,7 @@ import { ViewAuto, ViewImage } from './ContentView/ContentViews' import * as MetaViews from './ContentView/MetaViews' import ContentLoader from './ContentView/ContentLoader' import ViewSelector from './ContentView/ViewSelector' +import * as flowsActions from '../ducks/flows' export default class ContentView extends Component { @@ -40,6 +41,15 @@ export default class ContentView extends Component { return msg.contentLength > 1024 * 1024 * (ViewImage.matches(msg) ? 10 : 0.2) } + onOpenFile(e) { + if (e.target.files.length > 0) { + //alert(e.target.files[0]) + flowsActions.update_content(this.props.flow, e.target.files[0]) + //this.fileInput.value = '' + } + e.preventDefault() + } + render() { const { flow, message } = this.props const { displayLarge, View } = this.state @@ -60,10 +70,10 @@ export default class ContentView extends Component { <div> {View.textView ? ( <ContentLoader flow={flow} message={message}> - <this.state.View onChange={this.props.onChange} content="" /> + <this.state.View update_content={content => flowsActions.update_content(this.props.flow, content)} content="" /> </ContentLoader> ) : ( - <View flow={flow} onChange={this.props.onChange} message={message} /> + <View flow={flow} update_content={content => flowsActions.update_content(this.props.flow, content)} message={message} /> )} <div className="view-options text-center"> <ViewSelector onSelectView={this.selectView} active={View} message={message}/> @@ -71,6 +81,16 @@ export default class ContentView extends Component { <a className="btn btn-default btn-xs" href={MessageUtils.getContentURL(flow, message)}> <i className="fa fa-download"/> </a> + + <a className="btn btn-default btn-xs" href="#" onClick={e => {this.fileInput.click(); e.preventDefault();}}> + <i className="fa fa-upload"/> + </a> + <input + ref={ref => this.fileInput = ref} + className="hidden" + type="file" + onChange={e => this.onOpenFile(e)} + /> </div> </div> ) diff --git a/web/src/js/components/ContentView/ContentViews.jsx b/web/src/js/components/ContentView/ContentViews.jsx index e5a864bf..617ed242 100644 --- a/web/src/js/components/ContentView/ContentViews.jsx +++ b/web/src/js/components/ContentView/ContentViews.jsx @@ -1,10 +1,12 @@ import React, { PropTypes } from 'react' import ContentLoader from './ContentLoader' import { MessageUtils } from '../../flow/utils.js' -import Button from '../common/Button' +import CodeEditor from '../common/CodeEditor' +import {formatSize} from '../../utils.js' -const views = [ViewAuto, ViewImage, ViewJSON, ViewRaw] + +const views = [ViewAuto, ViewImage, ViewJSON, ViewRaw, ViewFile] ViewImage.regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i ViewImage.matches = msg => ViewImage.regex.test(MessageUtils.getContentType(msg)) @@ -30,12 +32,9 @@ ViewRaw.propTypes = { content: React.PropTypes.string.isRequired, } -export function ViewRaw({ content, onChange }) { +export function ViewRaw({ content, update_content }) { return ( - <div> - <textarea onKeyDown={e => e.stopPropagation()} ref={ref => ViewRaw.input = ref}>{content}</textarea> - <Button onClick={(e) => onChange(ViewRaw.input.value)} text="Update"/> - </div> + <CodeEditor value={content} onSave={update_content}/> ) } @@ -66,13 +65,26 @@ ViewAuto.propTypes = { flow: React.PropTypes.object.isRequired, } -export function ViewAuto({ message, flow, onChange }) { +export function ViewAuto({ message, flow, update_content }) { const View = ViewAuto.findView(message) if (View.textView) { - return <ContentLoader message={message} flow={flow}><View onChange={onChange} content="" /></ContentLoader> + return <ContentLoader message={message} flow={flow}><View update_content={update_content} content="" /></ContentLoader> } else { return <View message={message} flow={flow} /> } } +ViewFile.matches = () => false + +ViewFile.propTypes = { + message: React.PropTypes.object.isRequired, + flow: React.PropTypes.object.isRequired, +} + +export function ViewFile({ message, flow }) { + return <div className="alert alert-info"> + {formatSize(message.contentLength)} content size. + </div> +} + export default views diff --git a/web/src/js/components/common/Button.jsx b/web/src/js/components/common/Button.jsx index 574288df..221c6ace 100644 --- a/web/src/js/components/common/Button.jsx +++ b/web/src/js/components/common/Button.jsx @@ -10,8 +10,10 @@ export default function Button({ onClick, text, icon, disabled }) { <div className={"btn btn-default"} onClick={onClick} disabled={disabled}> - <i className={"fa fa-fw " + icon}/> - + <span hidden={!icon}> + <i className={"fa fa-fw " + icon}/> + + </span> {text} </div> ) diff --git a/web/src/js/components/common/CodeEditor.jsx b/web/src/js/components/common/CodeEditor.jsx new file mode 100644 index 00000000..d7e6aabb --- /dev/null +++ b/web/src/js/components/common/CodeEditor.jsx @@ -0,0 +1,41 @@ +import React, { Component, PropTypes } from 'react' +import { render } from 'react-dom'; +import brace from 'brace'; +import AceEditor from 'react-ace'; +import Button from './Button' + + +import 'brace/mode/javascript'; +import 'brace/mode/json'; +import 'brace/theme/monokai'; + + + + +export default class CodeEditor extends Component{ + constructor( props ) { + super(props) + this.state = {value: this.props.value} + } + + onChange(newValue) { + this.setState({value: newValue}) + } + + render() { + return ( + <div onKeyDown={e => e.stopPropagation()}> + <AceEditor + onChange={e => this.onChange(e)} + mode="javascript" + theme="monokai" + value={this.state.value} + width="100%" + name="codeEditor" + editorProps={{$blockScrolling: Infinity}} + /> + <Button onClick={(e) => this.props.onSave(this.state.value)} text="Update"/> + </div> + ) + } +} diff --git a/web/src/js/components/common/MonacoEditor.jsx b/web/src/js/components/common/MonacoEditor.jsx deleted file mode 100644 index a0e8d58c..00000000 --- a/web/src/js/components/common/MonacoEditor.jsx +++ /dev/null @@ -1,34 +0,0 @@ -//not working -import React, { Component, PropTypes } from 'react' - -export default class MonacoEditor extends Component { - - constructor(props) { - super(props) - } - - onLoad(){ - window.MonacoEnvironment = { - getWorkerUrl: function(workerId, label) { - return 'worker-loader-proxy.js'; - } - }; - require.config({ - paths: { - vs: '../release/min/vs' - } - }); - - } - - - render() { - return ( - <div id="container" - ref={ref => this.editor = ref} - style="width:800px;height:600px;border:1px solid grey" - onLoad={this.onLoad()}> - </div> - ) - } -} diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index f0b09530..36274f39 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -117,6 +117,14 @@ export function update(flow, data) { return { type: REQUEST_ACTION } } +export function update_content(flow, file) { + const body = new FormData() + body.append('file', file) + fetchApi(`/flows/${flow.id}/response/content`, {method: 'post', body} ) + return { type: REQUEST_ACTION } +} + + /** * @public */ |