diff options
Diffstat (limited to 'libmproxy')
-rw-r--r-- | libmproxy/web/static/js/app.js | 459 |
1 files changed, 238 insertions, 221 deletions
diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js index 92d6c4c8..8c898673 100644 --- a/libmproxy/web/static/js/app.js +++ b/libmproxy/web/static/js/app.js @@ -1,172 +1,188 @@ const PayloadSources = { - VIEW_ACTION: "VIEW_ACTION", - SERVER_ACTION: "SERVER_ACTION" + VIEW_ACTION: "VIEW_ACTION", + SERVER_ACTION: "SERVER_ACTION" }; - - function Dispatcher() {"use strict"; - this.callbacks = []; - } - - Dispatcher.prototype.register=function(callback){"use strict"; - this.callbacks.push(callback); - }; - - Dispatcher.prototype.unregister=function(callback){"use strict"; - var index = this.callbacks.indexOf(f); - if (index >= 0) { - this.callbacks.splice(this.callbacks.indexOf(f), 1); + function Dispatcher() {"use strict"; + this.callbacks = []; } - }; - - Dispatcher.prototype.dispatch=function(payload){"use strict"; - console.debug("dispatch", payload); - this.callbacks.forEach(function(callback) { - callback(payload); - }); - }; - + Dispatcher.prototype.register=function(callback) {"use strict"; + this.callbacks.push(callback); + }; + Dispatcher.prototype.unregister=function(callback) {"use strict"; + var index = this.callbacks.indexOf(f); + if (index >= 0) { + this.callbacks.splice(this.callbacks.indexOf(f), 1); + } + }; + Dispatcher.prototype.dispatch=function(payload) {"use strict"; + console.debug("dispatch", payload); + this.callbacks.forEach(function(callback) { + callback(payload); + }); + }; AppDispatcher = new Dispatcher(); -AppDispatcher.dispatchViewAction = function(action){ - action.actionSource = PayloadSources.VIEW_ACTION; - this.dispatch(action); +AppDispatcher.dispatchViewAction = function(action) { + action.actionSource = PayloadSources.VIEW_ACTION; + this.dispatch(action); }; -AppDispatcher.dispatchServerAction = function(action){ - action.actionSource = PayloadSources.SERVER_ACTION; - this.dispatch(action); +AppDispatcher.dispatchServerAction = function(action) { + action.actionSource = PayloadSources.SERVER_ACTION; + this.dispatch(action); }; var ActionTypes = { - SETTINGS_UPDATE: "SETTINGS_UPDATE", - EVENTLOG_ADD: "EVENTLOG_ADD" + SETTINGS_UPDATE: "SETTINGS_UPDATE", + EVENTLOG_ADD: "EVENTLOG_ADD" }; var SettingsActions = { - update:function(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 - }); - } + update:function(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 + }); + } }; - function EventEmitter() {"use strict"; - this.listeners = {}; - } - EventEmitter.prototype.emit=function(event) {"use strict"; - if (!(event in this.listeners)) { - return; - } - this.listeners[event].forEach(function(listener) { - listener.apply(this, arguments); - }.bind(this)); - }; - EventEmitter.prototype.addListener=function(event, f) {"use strict"; - this.listeners[event] = this.listeners[event] || []; - this.listeners[event].push(f); - }; - EventEmitter.prototype.removeListener=function(event, f) {"use strict"; - if (!(event in this.listeners)) { - return false; - } - var index = this.listeners[event].indexOf(f); - if (index >= 0) { - this.listeners[event].splice(index, 1); - } - }; + function EventEmitter() {"use strict"; + this.listeners = {}; + } + EventEmitter.prototype.emit=function(event) {"use strict"; + if (!(event in this.listeners)) { + return; + } + this.listeners[event].forEach(function(listener) { + listener.apply(this, arguments); + }.bind(this)); + }; + EventEmitter.prototype.addListener=function(event, f) {"use strict"; + this.listeners[event] = this.listeners[event] || []; + this.listeners[event].push(f); + }; + EventEmitter.prototype.removeListener=function(event, f) {"use strict"; + if (!(event in this.listeners)) { + return false; + } + var index = this.listeners[event].indexOf(f); + if (index >= 0) { + this.listeners[event].splice(index, 1); + } + }; for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){_SettingsStore[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}var ____SuperProtoOfEventEmitter=EventEmitter===null?null:EventEmitter.prototype;_SettingsStore.prototype=Object.create(____SuperProtoOfEventEmitter);_SettingsStore.prototype.constructor=_SettingsStore;_SettingsStore.__superConstructor__=EventEmitter; - function _SettingsStore() {"use strict"; - EventEmitter.call(this); - this.settings = { version: "0.12", showEventLog: true }; //FIXME: Need to get that from somewhere. - } - _SettingsStore.prototype.getAll=function() {"use strict"; - return this.settings; - }; - _SettingsStore.prototype.handle=function(action) {"use strict"; - switch (action.actionType) { - case ActionTypes.SETTINGS_UPDATE: - this.settings = action.settings; - this.emit("change"); - break; - default: - return; - } - }; + function _SettingsStore() {"use strict"; + EventEmitter.call(this); + + //FIXME: What do we do if we haven't requested anything from the server yet? + this.settings = { + version: "0.12", + showEventLog: true + }; + } + _SettingsStore.prototype.getAll=function() {"use strict"; + return this.settings; + }; + _SettingsStore.prototype.handle=function(action) {"use strict"; + switch (action.actionType) { + case ActionTypes.SETTINGS_UPDATE: + this.settings = action.settings; + this.emit("change"); + break; + default: + return; + } + }; var SettingsStore = new _SettingsStore(); AppDispatcher.register(SettingsStore.handle.bind(SettingsStore)); +// +// We have an EventLogView and an EventLogStore: +// The basic architecture is that one can request views on the event log +// from the store, which returns a view object and then deals with getting the data required for the view. +// The view object is accessed by React components and distributes updates etc. +// +// See also: components/EventLog.react.js for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){EventLogView[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}var ____SuperProtoOfEventEmitter=EventEmitter===null?null:EventEmitter.prototype;EventLogView.prototype=Object.create(____SuperProtoOfEventEmitter);EventLogView.prototype.constructor=EventLogView;EventLogView.__superConstructor__=EventEmitter; - function EventLogView(store, live){"use strict"; - EventEmitter.call(this); - this.$EventLogView_store = store; - this.live = live; - this.log = []; - - this.add = this.add.bind(this); - - if(live){ - this.$EventLogView_store.addListener("new_entry", this.add); - } - - } - EventLogView.prototype.close=function() {"use strict"; - this.$EventLogView_store.removeListener("new_entry", this.add); - }; - EventLogView.prototype.getAll=function() {"use strict"; - return this.log; - }; - - EventLogView.prototype.add=function(entry){"use strict"; - this.log.push(entry); - this.emit("change"); - }; - EventLogView.prototype.add_bulk=function(messages){"use strict"; - var log = messages; - var last_id = log[log.length-1].id; - var to_add = _.filter(this.log, function(entry) {return entry.id > last_id;}); - this.log = log.concat(to_add); - this.emit("change"); - }; + function EventLogView(store, live) {"use strict"; + EventEmitter.call(this); + this.$EventLogView_store = store; + this.live = live; + this.log = []; + + this.add = this.add.bind(this); + + if (live) { + this.$EventLogView_store.addListener("new_entry", this.add); + } + } + EventLogView.prototype.close=function() {"use strict"; + this.$EventLogView_store.removeListener("new_entry", this.add); + }; + EventLogView.prototype.getAll=function() {"use strict"; + return this.log; + }; + EventLogView.prototype.add=function(entry) {"use strict"; + this.log.push(entry); + this.emit("change"); + }; + EventLogView.prototype.add_bulk=function(messages) {"use strict"; + var log = messages; + var last_id = log[log.length - 1].id; + var to_add = _.filter(this.log, function(entry) {return entry.id > last_id;}); + this.log = log.concat(to_add); + this.emit("change"); + }; for(EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){_EventLogStore[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}_EventLogStore.prototype=Object.create(____SuperProtoOfEventEmitter);_EventLogStore.prototype.constructor=_EventLogStore;_EventLogStore.__superConstructor__=EventEmitter;function _EventLogStore(){"use strict";if(EventEmitter!==null){EventEmitter.apply(this,arguments);}} - _EventLogStore.prototype.getView=function(since){"use strict"; - 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; - }; - _EventLogStore.prototype.handle=function(action) {"use strict"; - switch (action.actionType) { - case ActionTypes.EVENTLOG_ADD: - this.emit("new_message", action.message); - break; - default: - return; - } - }; + _EventLogStore.prototype.getView=function(since) {"use strict"; + 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; + }; + _EventLogStore.prototype.handle=function(action) {"use strict"; + switch (action.actionType) { + case ActionTypes.EVENTLOG_ADD: + this.emit("new_message", action.message); + break; + default: + return; + } + }; var EventLogStore = new _EventLogStore(); AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); @@ -177,11 +193,9 @@ AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); } this.root = root; } - _Connection.prototype.init=function() {"use strict"; this.openWebSocketConnection(); }; - _Connection.prototype.openWebSocketConnection=function() {"use strict"; this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws"); var ws = this.ws; @@ -191,7 +205,6 @@ AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); ws.onerror = this.onerror.bind(this); ws.onclose = this.onclose.bind(this); }; - _Connection.prototype.onopen=function(open) {"use strict"; console.log("onopen", this, arguments); }; @@ -206,7 +219,6 @@ AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); console.log("onclose", this, arguments); }; - var Connection = new _Connection(); /** @jsx React.DOM */ @@ -217,21 +229,23 @@ var MainMenu = React.createClass({displayName: 'MainMenu', }); }, render:function(){ - return React.DOM.div(null, - React.DOM.button({className: "btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default"), onClick: this.toggleEventLog}, + return ( + React.DOM.div(null, + React.DOM.button({className: "btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default"), onClick: this.toggleEventLog}, React.DOM.i({className: "fa fa-database"}), " Display Event Log" + ) ) - ); + ); } }); var ToolsMenu = React.createClass({displayName: 'ToolsMenu', render:function(){ - return (React.DOM.div(null, "Tools Menu")); + return React.DOM.div(null, "Tools Menu"); } }); var ReportsMenu = React.createClass({displayName: 'ReportsMenu', render:function(){ - return (React.DOM.div(null, "Reports Menu")); + return React.DOM.div(null, "Reports Menu"); } }); @@ -268,7 +282,6 @@ var Header = React.createClass({displayName: 'Header', handleFileClick:function(){ console.log("File click"); }, - render:function(){ var header = []; for(var item in _Header_Entries){ @@ -292,74 +305,78 @@ var Header = React.createClass({displayName: 'Header', React.DOM.div({className: "menu"}, menu ) - )); + ) + ); } }); /** @jsx React.DOM */ var TrafficTable = React.createClass({displayName: 'TrafficTable', - getInitialState: function(){ + getInitialState:function() { return { flows: [] }; }, - componentDidMount:function(){ + componentDidMount:function() { //this.flowStore = FlowStore.getView(); //this.flowStore.addListener("change",this.onFlowChange); }, - componentWillUnmount:function(){ + componentWillUnmount:function() { //this.flowStore.removeListener("change",this.onFlowChange); //this.flowStore.close(); }, - onFlowChange:function(){ + onFlowChange:function() { 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 = "Flow"; - i = 12; - while(i--) x += x; - return React.DOM.div(null, React.DOM.pre(null, x)); - } + 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>; + }); */ + //Dummy Text for layout testing + x = "Flow"; + i = 12; + while (i--) x += x; + return ( + React.DOM.div(null, React.DOM.pre(null, " ", x, " ")) + ); + } }); /** @jsx React.DOM */ var EventLog = React.createClass({displayName: 'EventLog', - getInitialState:function(){ - return { - log: [] - }; - }, - componentDidMount:function(){ - this.log = EventLogStore.getView(); - this.log.addListener("change",this.onEventLogChange); - }, - componentWillUnmount:function(){ - this.log.removeListener("change",this.onEventLogChange); - this.log.close(); - }, - onEventLogChange:function(){ - this.setState({ - log: this.log.getAll() - }); - }, - close:function(){ - SettingsActions.update({ - showEventLog: false - }); - }, - render:function(){ - var messages = this.state.log.map(function(row) {return React.DOM.div({key: row.id}, row.message);}); + getInitialState:function() { + return { + log: [] + }; + }, + componentDidMount:function() { + this.log = EventLogStore.getView(); + this.log.addListener("change", this.onEventLogChange); + }, + componentWillUnmount:function() { + this.log.removeListener("change", this.onEventLogChange); + this.log.close(); + }, + onEventLogChange:function() { + this.setState({ + log: this.log.getAll() + }); + }, + close:function() { + SettingsActions.update({ + showEventLog: false + }); + }, + render:function() { + var messages = this.state.log.map(function(row) {return React.DOM.div({key: row.id}, row.message);}); return ( React.DOM.div({className: "eventlog"}, - React.DOM.pre(null, - React.DOM.i({className: "fa fa-close close-button", onClick: this.close}), - messages - ) + React.DOM.pre(null, + React.DOM.i({className: "fa fa-close close-button", onClick: this.close}), + messages + ) ) ); } @@ -379,54 +396,54 @@ var Footer = React.createClass({displayName: 'Footer', //TODO: Move out of here, just a stub. var Reports = React.createClass({displayName: 'Reports', - render:function(){ - return (React.DOM.div(null, "Report Editor")); - } + render:function(){ + return React.DOM.div(null, "Report Editor"); + } }); var ProxyAppMain = React.createClass({displayName: 'ProxyAppMain', getInitialState:function(){ - return { settings: SettingsStore.getAll() }; + return { settings: SettingsStore.getAll() }; }, componentDidMount:function(){ - SettingsStore.addListener("change", this.onSettingsChange); + SettingsStore.addListener("change", this.onSettingsChange); }, componentWillUnmount:function(){ - SettingsStore.removeListener("change", this.onSettingsChange); + SettingsStore.removeListener("change", this.onSettingsChange); }, onSettingsChange:function(){ - console.log("onSettingsChange"); - this.setState({settings: SettingsStore.getAll()}); + console.log("onSettingsChange"); + this.setState({settings: SettingsStore.getAll()}); }, render:function() { - return ( - React.DOM.div({id: "container"}, - Header({settings: this.state.settings}), - React.DOM.div({id: "main"}, this.props.activeRouteHandler(null)), - this.state.settings.showEventLog ? EventLog(null) : null, - Footer(null) - ) - ); + return ( + React.DOM.div({id: "container"}, + Header({settings: this.state.settings}), + React.DOM.div({id: "main"}, this.props.activeRouteHandler(null)), + this.state.settings.showEventLog ? EventLog(null) : null, + Footer(null) + ) + ); } }); var ProxyApp = ( - ReactRouter.Routes({location: "hash"}, - ReactRouter.Route({name: "app", path: "/", handler: ProxyAppMain}, - ReactRouter.Route({name: "main", handler: TrafficTable}), - ReactRouter.Route({name: "reports", handler: Reports}), - ReactRouter.Redirect({to: "main"}) + ReactRouter.Routes({location: "hash"}, + ReactRouter.Route({name: "app", path: "/", handler: ProxyAppMain}, + ReactRouter.Route({name: "main", handler: TrafficTable}), + ReactRouter.Route({name: "reports", handler: Reports}), + ReactRouter.Redirect({to: "main"}) + ) ) - ) ); -$(function(){ +$(function() { - Connection.init(); - app = React.renderComponent(ProxyApp, document.body); + Connection.init(); + app = React.renderComponent(ProxyApp, document.body); }); //# sourceMappingURL=app.js.map
\ No newline at end of file |