aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/.jshintrc3
-rw-r--r--web/gulpfile.js1
-rw-r--r--web/src/js/Connection.es6.js23
-rw-r--r--web/src/js/Dispatcher.es6.js4
-rw-r--r--web/src/js/actions.es6.js7
-rw-r--r--web/src/js/app.js1
-rw-r--r--web/src/js/components/EventLog.react.js21
-rw-r--r--web/src/js/components/Header.react.js14
-rw-r--r--web/src/js/components/ProxyApp.react.js16
-rw-r--r--web/src/js/components/TrafficTable.react.js33
-rw-r--r--web/src/js/stores/EventLogStore.es6.js79
-rw-r--r--web/src/js/stores/SettingsStore.es6.js23
-rw-r--r--web/src/js/stores/base.es6.js2
13 files changed, 134 insertions, 93 deletions
diff --git a/web/.jshintrc b/web/.jshintrc
index acdf04d3..d5eae073 100644
--- a/web/.jshintrc
+++ b/web/.jshintrc
@@ -1,4 +1,5 @@
{
"loopfunc": true,
- "esnext": true
+ "esnext": true,
+ "validthis": true
} \ No newline at end of file
diff --git a/web/gulpfile.js b/web/gulpfile.js
index 939f4fcc..3aebcd95 100644
--- a/web/gulpfile.js
+++ b/web/gulpfile.js
@@ -38,7 +38,6 @@ var path = {
'js/stores/SettingsStore.es6.js',
'js/stores/EventLogStore.es6.js',
'js/Connection.es6.js',
- 'js/connection.es6.js',
'js/components/Header.react.js',
'js/components/TrafficTable.react.js',
'js/components/EventLog.react.js',
diff --git a/web/src/js/Connection.es6.js b/web/src/js/Connection.es6.js
index 9daa82e2..05d86c93 100644
--- a/web/src/js/Connection.es6.js
+++ b/web/src/js/Connection.es6.js
@@ -1,14 +1,17 @@
-class Connection {
- constructor(root){
- if(!root){
+class _Connection {
+ constructor(root) {
+ if (!root) {
root = location.origin + "/api/v1";
}
this.root = root;
+ }
+
+ init() {
this.openWebSocketConnection();
}
- openWebSocketConnection(){
- this.ws = new WebSocket(this.root.replace("http","ws") + "/ws");
+ openWebSocketConnection() {
+ this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws");
var ws = this.ws;
ws.onopen = this.onopen.bind(this);
@@ -17,17 +20,19 @@ class Connection {
ws.onclose = this.onclose.bind(this);
}
- onopen(open){
+ onopen(open) {
console.log("onopen", this, arguments);
}
- onmessage(message){
+ onmessage(message) {
+ //AppDispatcher.dispatchServerAction(...);
console.log("onmessage", this, arguments);
}
- onerror(error){
+ onerror(error) {
console.log("onerror", this, arguments);
}
- onclose(close){
+ onclose(close) {
console.log("onclose", this, arguments);
}
}
+var Connection = new _Connection(); \ No newline at end of file
diff --git a/web/src/js/Dispatcher.es6.js b/web/src/js/Dispatcher.es6.js
index 9bf70878..6ac17f9f 100644
--- a/web/src/js/Dispatcher.es6.js
+++ b/web/src/js/Dispatcher.es6.js
@@ -33,4 +33,8 @@ AppDispatcher = new Dispatcher();
AppDispatcher.dispatchViewAction = function(action){
action.actionSource = PayloadSources.VIEW_ACTION;
this.dispatch(action);
+};
+AppDispatcher.dispatchServerAction = function(action){
+ action.actionSource = PayloadSources.SERVER_ACTION;
+ this.dispatch(action);
}; \ No newline at end of file
diff --git a/web/src/js/actions.es6.js b/web/src/js/actions.es6.js
index b6770074..6b3a5870 100644
--- a/web/src/js/actions.es6.js
+++ b/web/src/js/actions.es6.js
@@ -1,11 +1,14 @@
var ActionTypes = {
SETTINGS_UPDATE: "SETTINGS_UPDATE",
- LOG_ADD: "LOG_ADD"
+ EVENTLOG_ADD: "EVENTLOG_ADD"
};
var SettingsActions = {
update(settings) {
- settings = _.merge({}, SettingsStore.getSettings(), settings);
+ settings = _.merge({}, SettingsStore.getAll(), settings);
+ //TODO: Update server.
+
+ //Facebook Flux: We do an optimistic update on the client already.
AppDispatcher.dispatchViewAction({
actionType: ActionTypes.SETTINGS_UPDATE,
settings: settings
diff --git a/web/src/js/app.js b/web/src/js/app.js
index 2e4557af..2049ef25 100644
--- a/web/src/js/app.js
+++ b/web/src/js/app.js
@@ -1,5 +1,6 @@
$(function(){
+ Connection.init();
app = React.renderComponent(ProxyApp, document.body);
}); \ No newline at end of file
diff --git a/web/src/js/components/EventLog.react.js b/web/src/js/components/EventLog.react.js
index 0ecf40b1..3a7dedc8 100644
--- a/web/src/js/components/EventLog.react.js
+++ b/web/src/js/components/EventLog.react.js
@@ -1,17 +1,36 @@
/** @jsx React.DOM */
var EventLog = React.createClass({
+ getInitialState(){
+ return {
+ log: []
+ };
+ },
+ componentDidMount(){
+ this.log = EventLogStore.getView();
+ this.log.addListener("change",this.onEventLogChange);
+ },
+ componentWillUnmount(){
+ this.log.removeListener("change",this.onEventLogChange);
+ this.log.close();
+ },
+ onEventLogChange(){
+ this.setState({
+ log: this.log.getAll()
+ });
+ },
close(){
SettingsActions.update({
showEventLog: false
});
},
render(){
+ var messages = this.state.log.map(row => <div key={row.id}>{row.message}</div>);
return (
<div className="eventlog">
<pre>
<i className="fa fa-close close-button" onClick={this.close}></i>
- much log.
+ {messages}
</pre>
</div>
);
diff --git a/web/src/js/components/Header.react.js b/web/src/js/components/Header.react.js
index d1f18a82..41202463 100644
--- a/web/src/js/components/Header.react.js
+++ b/web/src/js/components/Header.react.js
@@ -1,15 +1,14 @@
/** @jsx React.DOM */
var MainMenu = React.createClass({
- mixins: [SettingsMixin],
- handleSettingsChange() {
+ toggleEventLog() {
SettingsActions.update({
- showEventLog: !this.state.settings.showEventLog
+ showEventLog: !this.props.settings.showEventLog
});
},
render(){
return <div>
- <button className={"btn " + (this.state.settings.showEventLog ? "btn-primary" : "btn-default")} onClick={this.handleSettingsChange}>
+ <button className={"btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default")} onClick={this.toggleEventLog}>
<i className="fa fa-database"></i> Display Event Log
</button>
</div>;
@@ -46,7 +45,6 @@ var _Header_Entries = {
};
var Header = React.createClass({
- mixins: [SettingsMixin],
getInitialState(){
return {
active: "main"
@@ -69,11 +67,13 @@ var Header = React.createClass({
onClick={this.handleClick.bind(this, item)}>{ _Header_Entries[item].title }</a>);
}
- var menu = _Header_Entries[this.state.active].menu();
+ var menu = _Header_Entries[this.state.active].menu({
+ settings: this.props.settings
+ });
return (
<header>
<div className="title-bar">
- mitmproxy { this.state.settings.version }
+ mitmproxy { this.props.settings.version }
</div>
<nav>
<a href="#" className="special" onClick={this.handleFileClick}> File </a>
diff --git a/web/src/js/components/ProxyApp.react.js b/web/src/js/components/ProxyApp.react.js
index 7953d938..fc21ecd8 100644
--- a/web/src/js/components/ProxyApp.react.js
+++ b/web/src/js/components/ProxyApp.react.js
@@ -10,11 +10,23 @@ var Reports = React.createClass({
var ProxyAppMain = React.createClass({
- mixins: [SettingsMixin],
+ getInitialState(){
+ return { settings: SettingsStore.getAll() };
+ },
+ componentDidMount(){
+ SettingsStore.addListener("change", this.onSettingsChange);
+ },
+ componentWillUnmount(){
+ SettingsStore.removeListener("change", this.onSettingsChange);
+ },
+ onSettingsChange(){
+ console.log("onSettingsChange");
+ this.setState({settings: SettingsStore.getAll()});
+ },
render() {
return (
<div id="container">
- <Header/>
+ <Header settings={this.state.settings}/>
<div id="main"><this.props.activeRouteHandler/></div>
{this.state.settings.showEventLog ? <EventLog/> : null}
<Footer/>
diff --git a/web/src/js/components/TrafficTable.react.js b/web/src/js/components/TrafficTable.react.js
index 442f8da2..d6a4f200 100644
--- a/web/src/js/components/TrafficTable.react.js
+++ b/web/src/js/components/TrafficTable.react.js
@@ -1,36 +1,29 @@
/** @jsx React.DOM */
var TrafficTable = React.createClass({
- /*getInitialState: function(){
+ getInitialState: function(){
return {
flows: []
};
- },*/
- componentDidMount: function () {
- /*var flowStore = new DummyFlowStore([]);
- this.setState({flowStore: flowStore});
-
- flowStore.addChangeListener(this.onFlowsChange);
-
- $.getJSON("/flows.json").success(function (flows) {
- flows.forEach(function (flow, i) {
- window.setTimeout(function () {
- flowStore.addFlow(flow);
- }, _.random(i*400,i*400+1000));
- });
- }.bind(this));*/
},
- componentWillUnmount: function(){
- //this.state.flowStore.close();
+ componentDidMount(){
+ //this.flowStore = FlowStore.getView();
+ //this.flowStore.addListener("change",this.onFlowChange);
+ },
+ componentWillUnmount(){
+ //this.flowStore.removeListener("change",this.onFlowChange);
+ //this.flowStore.close();
},
- onFlowsChange: function(event, flows){
- //this.setState({flows: flows.getAll()});
+ onFlowChange(){
+ this.setState({
+ //flows: this.flowStore.getAll()
+ });
},
render: function () {
/*var flows = this.state.flows.map(function(flow){
return <div>{flow.request.method} {flow.request.scheme}://{flow.request.host}{flow.request.path}</div>;
}); *//**/
- x = "WTF";
+ x = "Flow";
i = 12;
while(i--) x += x;
return <div><pre>{x}</pre></div>;
diff --git a/web/src/js/stores/EventLogStore.es6.js b/web/src/js/stores/EventLogStore.es6.js
index caa9d77d..55401690 100644
--- a/web/src/js/stores/EventLogStore.es6.js
+++ b/web/src/js/stores/EventLogStore.es6.js
@@ -1,17 +1,62 @@
-class _EventLogStore extends EventEmitter {
- constructor() {
- /*jshint validthis: true */
+class EventLogView extends EventEmitter {
+ constructor(store, live){
super();
+ this._store = store;
+ this.live = live;
this.log = [];
+
+ this.add = this.add.bind(this);
+
+ if(live){
+ this._store.addListener("new_entry", this.add);
+ }
+
+ }
+ close() {
+ this._store.removeListener("new_entry", this.add);
}
getAll() {
return this.log;
}
+
+ add(entry){
+ this.log.push(entry);
+ this.emit("change");
+ }
+ add_bulk(messages){
+ var log = messages;
+ var last_id = log[log.length-1].id;
+ var to_add = _.filter(this.log, entry => entry.id > last_id);
+ this.log = log.concat(to_add);
+ this.emit("change");
+ }
+}
+
+class _EventLogStore extends EventEmitter {
+ getView(since){
+ var view = new EventLogView(this, !since);
+
+ //TODO: Really do bulk retrieval of last messages.
+
+ window.setTimeout(function(){
+ view.add_bulk([
+ { id:1, message: "Hello World"},
+ { id:2, message: "I was already transmitted as an event."}
+ ]);
+ }, 100);
+
+ var id = 2;
+ view.add({id:id++, message: "I was already transmitted as an event."});
+ view.add({id:id++, message: "I was only transmitted as an event before the bulk was added.."});
+ window.setInterval(function(){
+ view.add({id: id++, message: "."});
+ }, 1000);
+ return view;
+ }
handle(action) {
switch (action.actionType) {
- case ActionTypes.LOG_ADD:
- this.log.push(action.message);
- this.emit("change");
+ case ActionTypes.EVENTLOG_ADD:
+ this.emit("new_message", action.message);
break;
default:
return;
@@ -19,24 +64,4 @@ class _EventLogStore extends EventEmitter {
}
}
var EventLogStore = new _EventLogStore();
-AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
-
-
-var EventLogMixin = {
- getInitialState(){
- return {
- log: EventLog.getAll()
- };
- },
- componentDidMount(){
- SettingsStore.addListener("change", this._onEventLogChange);
- },
- componentWillUnmount(){
- SettingsStore.removeListener("change", this._onEventLogChange);
- },
- _onEventLogChange(){
- this.setState({
- log: EventLog.getAll()
- });
- }
-}; \ No newline at end of file
+AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); \ No newline at end of file
diff --git a/web/src/js/stores/SettingsStore.es6.js b/web/src/js/stores/SettingsStore.es6.js
index 7f3a6837..dea4597c 100644
--- a/web/src/js/stores/SettingsStore.es6.js
+++ b/web/src/js/stores/SettingsStore.es6.js
@@ -1,10 +1,9 @@
class _SettingsStore extends EventEmitter {
constructor() {
- /*jshint validthis: true */
super();
this.settings = { version: "0.12", showEventLog: true }; //FIXME: Need to get that from somewhere.
}
- getSettings() {
+ getAll() {
return this.settings;
}
handle(action) {
@@ -20,23 +19,3 @@ class _SettingsStore extends EventEmitter {
}
var SettingsStore = new _SettingsStore();
AppDispatcher.register(SettingsStore.handle.bind(SettingsStore));
-
-
-var SettingsMixin = {
- getInitialState(){
- return {
- settings: SettingsStore.getSettings()
- };
- },
- componentDidMount(){
- SettingsStore.addListener("change", this._onSettingsChange);
- },
- componentWillUnmount(){
- SettingsStore.removeListener("change", this._onSettingsChange);
- },
- _onSettingsChange(){
- this.setState({
- settings: SettingsStore.getSettings()
- });
- }
-}; \ No newline at end of file
diff --git a/web/src/js/stores/base.es6.js b/web/src/js/stores/base.es6.js
index 9e9c69aa..d5d0c7ab 100644
--- a/web/src/js/stores/base.es6.js
+++ b/web/src/js/stores/base.es6.js
@@ -7,7 +7,7 @@ class EventEmitter {
return;
}
this.listeners[event].forEach(function(listener) {
- listener(event, this);
+ listener.apply(this, arguments);
}.bind(this));
}
addListener(event, f) {