aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/web/static
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2014-09-22 03:06:19 +0200
committerMaximilian Hils <git@maximilianhils.com>2014-09-22 03:06:19 +0200
commit45f39c23804e12459e810a1f5014d892e4177b48 (patch)
treeda7dfb5884642968a096b6563a02aff63f19a178 /libmproxy/web/static
parent84e2a028c24f00ea86205dbfe5b9315c57d5ae3f (diff)
downloadmitmproxy-45f39c23804e12459e810a1f5014d892e4177b48.tar.gz
mitmproxy-45f39c23804e12459e810a1f5014d892e4177b48.tar.bz2
mitmproxy-45f39c23804e12459e810a1f5014d892e4177b48.zip
beef up event log
Diffstat (limited to 'libmproxy/web/static')
-rw-r--r--libmproxy/web/static/css/app.css43
-rw-r--r--libmproxy/web/static/js/app.js121
2 files changed, 138 insertions, 26 deletions
diff --git a/libmproxy/web/static/css/app.css b/libmproxy/web/static/css/app.css
index f0ed95dd..8cdfbac6 100644
--- a/libmproxy/web/static/css/app.css
+++ b/libmproxy/web/static/css/app.css
@@ -60,6 +60,7 @@ body,
flex: 1 1 auto;
display: flex;
flex-direction: row;
+ outline: 0;
}
.main-view.vertical {
flex-direction: column;
@@ -212,27 +213,61 @@ header .menu {
table-layout: fixed;
word-break: break-all;
}
-.flow-detail table tr {
+.flow-detail table tr:not(:first-child) {
border-top: 1px solid #f7f7f7;
}
.flow-detail table td {
vertical-align: top;
}
.connection-table td:first-child {
- width: 33%;
+ width: 50%;
padding-right: 1em;
}
.header-table .header-name {
width: 33%;
padding-right: 1em;
}
+.connection-table td,
+.timing-table td {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
.eventlog {
+ height: 200px;
+ flex: 0 0 auto;
+ display: flex;
+ flex-direction: column;
+}
+.eventlog > div {
+ background-color: #F2F2F2;
+ padding: 0 5px;
flex: 0 0 auto;
+}
+.eventlog > pre {
+ flex: 1 1 auto;
margin: 0;
border-radius: 0;
- height: 200px;
- overflow: auto;
+ overflow-x: auto;
overflow-y: scroll;
+ background-color: #fcfcfc;
+}
+.eventlog .fa-close {
+ cursor: pointer;
+ float: right;
+ color: grey;
+ padding: 3px 0;
+ padding-left: 10px;
+}
+.eventlog .fa-close:hover {
+ color: black;
+}
+.eventlog .label {
+ cursor: pointer;
+ vertical-align: middle;
+ display: inline-block;
+ margin-top: -2px;
+ margin-left: 3px;
}
footer {
box-shadow: 0 -1px 3px #d3d3d3;
diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js
index 4fb9f92d..fe317d7f 100644
--- a/libmproxy/web/static/js/app.js
+++ b/libmproxy/web/static/js/app.js
@@ -121,14 +121,15 @@ var SettingsActions = {
}
};
+var event_id = 0;
var EventLogActions = {
- add_event: function(message, level){
+ add_event: function(message){
AppDispatcher.dispatchViewAction({
type: ActionTypes.ADD_EVENT,
data: {
message: message,
- level: level || "info",
- source: "ui"
+ level: "web",
+ id: "viewAction-"+event_id++
}
});
}
@@ -263,7 +264,7 @@ _.extend(EventLogView.prototype, EventEmitter.prototype, {
},
add: function (entry) {
this.log.push(entry);
- if(this.log.length > 50){
+ if(this.log.length > 200){
this.log.shift();
}
this.emit("change");
@@ -334,7 +335,6 @@ _.extend(_EventLogStore.prototype, EventEmitter.prototype, {
var EventLogStore = new _EventLogStore();
AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
-
function FlowView(store, live) {
EventEmitter.call(this);
this._store = store;
@@ -443,7 +443,7 @@ _Connection.prototype.openWebSocketConnection = function () {
ws.onclose = this.onclose.bind(this);
};
_Connection.prototype.onopen = function (open) {
- console.log("onopen", this, arguments);
+ console.debug("onopen", this, arguments);
};
_Connection.prototype.onmessage = function (message) {
//AppDispatcher.dispatchServerAction(...);
@@ -452,11 +452,11 @@ _Connection.prototype.onmessage = function (message) {
};
_Connection.prototype.onerror = function (error) {
EventLogActions.add_event("WebSocket Connection Error.");
- console.log("onerror", this, arguments);
+ console.debug("onerror", this, arguments);
};
_Connection.prototype.onclose = function (close) {
EventLogActions.add_event("WebSocket Connection closed.");
- console.log("onclose", this, arguments);
+ console.debug("onclose", this, arguments);
};
var Connection = new _Connection(location.origin + "/updates");
@@ -1139,7 +1139,7 @@ var Timing = React.createClass({displayName: 'Timing',
return (
React.DOM.div(null,
React.DOM.h4(null, "Timing"),
- React.DOM.table(null,
+ React.DOM.table({className: "timing-table"},
React.DOM.tbody(null,
rows
)
@@ -1214,7 +1214,6 @@ var MainView = React.createClass({displayName: 'MainView',
};
},
componentDidMount: function () {
- console.log("get view");
this.flowStore = FlowStore.getView();
this.flowStore.addListener("change",this.onFlowChange);
},
@@ -1334,7 +1333,32 @@ var MainView = React.createClass({displayName: 'MainView',
});
/** @jsx React.DOM */
-var EventLog = React.createClass({displayName: 'EventLog',
+var LogMessage = React.createClass({displayName: 'LogMessage',
+ render: function(){
+ var entry = this.props.entry;
+ var indicator;
+ switch(entry.level){
+ case "web":
+ indicator = React.DOM.i({className: "fa fa-fw fa-html5"});
+ break;
+ case "debug":
+ indicator = React.DOM.i({className: "fa fa-fw fa-bug"});
+ break;
+ default:
+ indicator = React.DOM.i({className: "fa fa-fw fa-info"});
+ }
+ return (
+ React.DOM.div(null,
+ indicator, " ", entry.message
+ )
+ );
+ },
+ shouldComponentUpdate: function(){
+ return false; // log entries are immutable.
+ }
+});
+
+var EventLogContents = React.createClass({displayName: 'EventLogContents',
mixins:[AutoScrollMixin],
getInitialState: function () {
return {
@@ -1354,23 +1378,76 @@ var EventLog = React.createClass({displayName: 'EventLog',
log: this.log.getAll()
});
},
+ render: function () {
+ var messages = this.state.log.map(function(row) {
+ if(!this.props.filter[row.level]){
+ return null;
+ }
+ return LogMessage({key: row.id, entry: row});
+ }.bind(this));
+ return React.DOM.pre(null, messages);
+ }
+});
+
+var ToggleFilter = React.createClass({displayName: 'ToggleFilter',
+ toggle: function(){
+ return this.props.toggleLevel(this.props.name);
+ },
+ render: function(){
+ var className = "label ";
+ if (this.props.active) {
+ className += "label-primary";
+ } else {
+ className += "label-default";
+ }
+ return (
+ React.DOM.a({
+ href: "#",
+ className: className,
+ onClick: this.toggle},
+ this.props.name
+ )
+ );
+ }
+});
+
+var EventLog = React.createClass({displayName: 'EventLog',
+ getInitialState: function(){
+ return {
+ filter: {
+ "debug": false,
+ "info": true,
+ "web": true
+ }
+ };
+ },
close: function () {
SettingsActions.update({
showEventLog: false
});
},
+ toggleLevel: function(level){
+ var filter = this.state.filter;
+ filter[level] = !filter[level];
+ this.setState({filter: filter});
+ return false;
+ },
render: function () {
- var messages = this.state.log.map(function(row) {
- var indicator = null;
- if(row.source === "ui"){
- indicator = React.DOM.i({className: "fa fa-html5"});
- }
- return (
- React.DOM.div({key: row.id},
- indicator, " ", row.message
- ));
- });
- return React.DOM.pre({className: "eventlog"}, messages);
+ return (
+ React.DOM.div({className: "eventlog"},
+ React.DOM.div(null,
+ "Eventlog",
+ React.DOM.div({className: "pull-right"},
+ ToggleFilter({name: "debug", active: this.state.filter.debug, toggleLevel: this.toggleLevel}),
+ ToggleFilter({name: "info", active: this.state.filter.info, toggleLevel: this.toggleLevel}),
+ ToggleFilter({name: "web", active: this.state.filter.web, toggleLevel: this.toggleLevel}),
+ React.DOM.i({onClick: this.close, className: "fa fa-close"})
+ )
+
+ ),
+ EventLogContents({filter: this.state.filter})
+ )
+ );
}
});
/** @jsx React.DOM */