From 8245dd19f4f2f4cdd74a6fdf9b5e051c2cd2fac6 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 17 Sep 2014 15:22:42 +0200 Subject: connect eventlog events to ui --- libmproxy/main.py | 1 - libmproxy/web/__init__.py | 2 +- libmproxy/web/static/css/app.css | 13 +------ libmproxy/web/static/js/app.js | 77 +++++++++++++++++++++------------------- 4 files changed, 43 insertions(+), 50 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/main.py b/libmproxy/main.py index a3c91c02..2d6a0119 100644 --- a/libmproxy/main.py +++ b/libmproxy/main.py @@ -220,7 +220,6 @@ def mitmweb(): # pragma: nocover from . import web check_versions() - assert_utf8_env() web_options, proxy_config = mitmweb_cmdline() server = get_server(web_options.no_server, proxy_config) diff --git a/libmproxy/web/__init__.py b/libmproxy/web/__init__.py index 50b41b80..83a7bde4 100644 --- a/libmproxy/web/__init__.py +++ b/libmproxy/web/__init__.py @@ -101,7 +101,7 @@ class WebMaster(flow.FlowMaster): def handle_log(self, l): app.ClientConnection.broadcast( - "event", { + "add_event", { "message": l.msg, "level": l.level } diff --git a/libmproxy/web/static/css/app.css b/libmproxy/web/static/css/app.css index e5b9d134..6dd17c7d 100644 --- a/libmproxy/web/static/css/app.css +++ b/libmproxy/web/static/css/app.css @@ -69,22 +69,11 @@ header .menu { } .eventlog { flex: 0 0 auto; -} -.eventlog pre { margin: 0; border-radius: 0; height: 200px; overflow: auto; -} -.eventlog .close-button { - float: right; - margin: -9px; - padding: 4px; - cursor: pointer; - color: grey; -} -.eventlog .close-button:hover { - color: black; + overflow-y: scroll; } footer { box-shadow: 0 -1px 3px #d3d3d3; diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js index 84eece87..5bc8de0d 100644 --- a/libmproxy/web/static/js/app.js +++ b/libmproxy/web/static/js/app.js @@ -1,6 +1,20 @@ +// http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) +var AutoScrollMixin = { + componentWillUpdate: function () { + var node = this.getDOMNode(); + this._shouldScrollBottom = node.scrollTop + node.clientHeight === node.scrollHeight; + }, + componentDidUpdate: function () { + if (this._shouldScrollBottom) { + var node = this.getDOMNode(); + node.scrollTop = node.scrollHeight; + } + }, +}; + const PayloadSources = { - VIEW_ACTION: "VIEW_ACTION", - SERVER_ACTION: "SERVER_ACTION" + VIEW: "view", + SERVER: "server" }; @@ -26,17 +40,17 @@ Dispatcher.prototype.dispatch = function (payload) { AppDispatcher = new Dispatcher(); AppDispatcher.dispatchViewAction = function (action) { - action.actionSource = PayloadSources.VIEW_ACTION; + action.source = PayloadSources.VIEW; this.dispatch(action); }; AppDispatcher.dispatchServerAction = function (action) { - action.actionSource = PayloadSources.SERVER_ACTION; + action.source = PayloadSources.SERVER; this.dispatch(action); }; var ActionTypes = { - SETTINGS_UPDATE: "SETTINGS_UPDATE", - EVENTLOG_ADD: "EVENTLOG_ADD" + UPDATE_SETTINGS: "update_settings", + ADD_EVENT: "add_event" }; var SettingsActions = { @@ -46,7 +60,7 @@ var SettingsActions = { //Facebook Flux: We do an optimistic update on the client already. AppDispatcher.dispatchViewAction({ - actionType: ActionTypes.SETTINGS_UPDATE, + type: ActionTypes.UPDATE_SETTINGS, settings: settings }); } @@ -59,8 +73,9 @@ EventEmitter.prototype.emit = function (event) { if (!(event in this.listeners)) { return; } + var args = Array.prototype.slice.call(arguments, 1); this.listeners[event].forEach(function (listener) { - listener.apply(this, arguments); + listener.apply(this, args); }.bind(this)); }; EventEmitter.prototype.addListener = function (event, f) { @@ -92,8 +107,8 @@ _.extend(_SettingsStore.prototype, EventEmitter.prototype, { return this.settings; }, handle: function (action) { - switch (action.actionType) { - case ActionTypes.SETTINGS_UPDATE: + switch (action.type) { + case ActionTypes.UPDATE_SETTINGS: this.settings = action.settings; this.emit("change"); break; @@ -115,19 +130,19 @@ AppDispatcher.register(SettingsStore.handle.bind(SettingsStore)); // See also: components/EventLog.react.js function EventLogView(store, live) { EventEmitter.call(this); - this.$EventLogView_store = store; + this._store = store; this.live = live; this.log = []; this.add = this.add.bind(this); if (live) { - this.$EventLogView_store.addListener("new_entry", this.add); + this._store.addListener(ActionTypes.ADD_EVENT, this.add); } } _.extend(EventLogView.prototype, EventEmitter.prototype, { close: function () { - this.$EventLogView_store.removeListener("new_entry", this.add); + this._store.removeListener(ActionTypes.ADD_EVENT, this.add); }, getAll: function () { return this.log; @@ -154,7 +169,8 @@ function _EventLogStore() { _.extend(_EventLogStore.prototype, EventEmitter.prototype, { getView: function (since) { var view = new EventLogView(this, !since); - + return view; + /* //TODO: Really do bulk retrieval of last messages. window.setTimeout(function () { view.add_bulk([ @@ -185,11 +201,12 @@ _.extend(_EventLogStore.prototype, EventEmitter.prototype, { }); }, 1000); return view; + */ }, handle: function (action) { - switch (action.actionType) { - case ActionTypes.EVENTLOG_ADD: - this.emit("new_message", action.message); + switch (action.type) { + case ActionTypes.ADD_EVENT: + this.emit(ActionTypes.ADD_EVENT, action.data); break; default: return; @@ -222,14 +239,7 @@ _Connection.prototype.onopen = function (open) { _Connection.prototype.onmessage = function (message) { //AppDispatcher.dispatchServerAction(...); var m = JSON.parse(message.data); - switch (m.type){ - case "flow": - console.log("flow", m.data); - break; - case "event": - console.log("event", m.data.message) - break; - } + AppDispatcher.dispatchServerAction(m); }; _Connection.prototype.onerror = function (error) { console.log("onerror", this, arguments); @@ -368,6 +378,7 @@ var TrafficTable = React.createClass({displayName: 'TrafficTable', /** @jsx React.DOM */ var EventLog = React.createClass({displayName: 'EventLog', + mixins:[AutoScrollMixin], getInitialState: function () { return { log: [] @@ -392,16 +403,10 @@ var EventLog = React.createClass({displayName: 'EventLog', }); }, render: function () { - //var messages = this.state.log.map(row => (
{row.message}
)); - var messages = []; - return ( - React.DOM.div({className: "eventlog"}, - React.DOM.pre(null, - React.DOM.i({className: "fa fa-close close-button", onClick: this.close}), - messages - ) - ) - ); + var messages = this.state.log.map(function(row) { + return (React.DOM.div({key: row.id}, row.message)); + }); + return React.DOM.pre({className: "eventlog"}, messages); } }); @@ -447,7 +452,7 @@ var ProxyAppMain = React.createClass({displayName: 'ProxyAppMain', 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, + this.state.settings.showEventLog ? EventLog(null) : null, Footer({settings: this.state.settings}) ) ); -- cgit v1.2.3