aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2014-12-27 23:08:56 +1300
committerAldo Cortesi <aldo@nullcube.com>2014-12-27 23:08:56 +1300
commitab06c2436be23c9bfbf3af924f0117ecdb6724b4 (patch)
tree950bec445a85dd4eef9efb8ebe83b94f314345d7
parent8a8437470e224ee53acbd9a353c7d01a83168cd4 (diff)
parent3e63107e9473e3ec6676c047171a5d23c79b7dcd (diff)
downloadmitmproxy-ab06c2436be23c9bfbf3af924f0117ecdb6724b4.tar.gz
mitmproxy-ab06c2436be23c9bfbf3af924f0117ecdb6724b4.tar.bz2
mitmproxy-ab06c2436be23c9bfbf3af924f0117ecdb6724b4.zip
Merge branch 'master' of ssh.github.com:mitmproxy/mitmproxy
-rw-r--r--doc-src/index.py24
-rw-r--r--libmproxy/filt.py23
-rw-r--r--libmproxy/web/app.py9
-rw-r--r--libmproxy/web/static/css/app.css22
-rw-r--r--libmproxy/web/static/js/app.js54
-rw-r--r--web/src/css/header.less42
-rw-r--r--web/src/js/components/header.jsx.js54
7 files changed, 174 insertions, 54 deletions
diff --git a/doc-src/index.py b/doc-src/index.py
index e6064e3a..9eb0ea2b 100644
--- a/doc-src/index.py
+++ b/doc-src/index.py
@@ -40,29 +40,7 @@ def example(s):
ns.example = example
-filt_help = []
-for i in filt.filt_unary:
- filt_help.append(
- ("~%s"%i.code, i.help)
- )
-for i in filt.filt_rex:
- filt_help.append(
- ("~%s regex"%i.code, i.help)
- )
-for i in filt.filt_int:
- filt_help.append(
- ("~%s int"%i.code, i.help)
- )
-filt_help.sort()
-filt_help.extend(
- [
- ("!", "unary not"),
- ("&", "and"),
- ("|", "or"),
- ("(...)", "grouping"),
- ]
-)
-ns.filt_help = filt_help
+ns.filt_help = filt.help
def nav(page, current, state):
diff --git a/libmproxy/filt.py b/libmproxy/filt.py
index 5d259096..40b2f6c9 100644
--- a/libmproxy/filt.py
+++ b/libmproxy/filt.py
@@ -351,3 +351,26 @@ def parse(s):
except ValueError:
return None
+
+help = []
+for i in filt_unary:
+ help.append(
+ ("~%s"%i.code, i.help)
+ )
+for i in filt_rex:
+ help.append(
+ ("~%s regex"%i.code, i.help)
+ )
+for i in filt_int:
+ help.append(
+ ("~%s int"%i.code, i.help)
+ )
+help.sort()
+help.extend(
+ [
+ ("!", "unary not"),
+ ("&", "and"),
+ ("|", "or"),
+ ("(...)", "grouping"),
+ ]
+) \ No newline at end of file
diff --git a/libmproxy/web/app.py b/libmproxy/web/app.py
index 27e9aefc..31cbf2e2 100644
--- a/libmproxy/web/app.py
+++ b/libmproxy/web/app.py
@@ -4,7 +4,7 @@ import tornado.web
import tornado.websocket
import logging
import json
-from .. import version
+from .. import version, filt
class APIError(tornado.web.HTTPError):
@@ -52,6 +52,12 @@ class IndexHandler(RequestHandler):
self.render("index.html")
+class FiltHelp(RequestHandler):
+ def get(self):
+ self.write(dict(
+ commands=filt.help
+ ))
+
class WebSocketEventBroadcaster(tornado.websocket.WebSocketHandler):
connections = None # raise an error if inherited class doesn't specify its own instance.
@@ -194,6 +200,7 @@ class Application(tornado.web.Application):
self.master = master
handlers = [
(r"/", IndexHandler),
+ (r"/filter-help", FiltHelp),
(r"/updates", ClientConnection),
(r"/events", Events),
(r"/flows", Flows),
diff --git a/libmproxy/web/static/css/app.css b/libmproxy/web/static/css/app.css
index 2ec275a3..554fffb1 100644
--- a/libmproxy/web/static/css/app.css
+++ b/libmproxy/web/static/css/app.css
@@ -138,10 +138,30 @@ header .menu {
padding: 10px;
border-bottom: solid #a6a6a6 1px;
}
+.menu-row {
+ margin-left: -2.5px;
+ margin-right: -2.5px;
+}
+.filter-input {
+ position: relative;
+ min-height: 1px;
+ padding-left: 2.5px;
+ padding-right: 2.5px;
+}
+@media (min-width: 992px) {
+ .filter-input {
+ float: left;
+ width: 25%;
+ }
+}
.filter-input .popover {
top: 27px;
display: block;
- width: 100%;
+ max-width: none;
+}
+.filter-input .popover .popover-content {
+ max-height: 500px;
+ overflow-y: auto;
}
.flow-table {
width: 100%;
diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js
index 984db943..c054baa2 100644
--- a/libmproxy/web/static/js/app.js
+++ b/libmproxy/web/static/js/app.js
@@ -2632,6 +2632,48 @@ var VirtualScrollMixin = {
}
},
};
+var FilterDocs = React.createClass({displayName: 'FilterDocs',
+ statics: {
+ xhr: false,
+ doc: false
+ },
+ componentWillMount: function () {
+ if (!FilterDocs.doc) {
+ FilterDocs.xhr = $.getJSON("/filter-help").done(function (doc) {
+ FilterDocs.doc = doc;
+ FilterDocs.xhr = false;
+ });
+ }
+ if (FilterDocs.xhr) {
+ FilterDocs.xhr.done(function () {
+ this.forceUpdate();
+ }.bind(this));
+ }
+ },
+ render: function () {
+ if (!FilterDocs.doc) {
+ return React.createElement("i", {className: "fa fa-spinner fa-spin"});
+ } else {
+ var commands = FilterDocs.doc.commands.map(function (c) {
+ return React.createElement("tr", null,
+ React.createElement("td", null, c[0].replace(" ", '\u00a0')),
+ React.createElement("td", null, c[1])
+ );
+ });
+ commands.push(React.createElement("tr", null,
+ React.createElement("td", {colSpan: "2"},
+ React.createElement("a", {href: "https://mitmproxy.org/doc/features/filters.html",
+ target: "_blank"},
+ React.createElement("i", {className: "fa fa-external-link"}),
+ "  mitmproxy docs")
+ )
+ ));
+ return React.createElement("table", {className: "table table-condensed"},
+ React.createElement("tbody", null, commands)
+ );
+ }
+ }
+});
var FilterInput = React.createClass({displayName: 'FilterInput',
getInitialState: function () {
// Consider both focus and mouseover for showing/hiding the tooltip,
@@ -2675,10 +2717,7 @@ var FilterInput = React.createClass({displayName: 'FilterInput',
return desc;
} else {
return (
- React.createElement("a", {href: "https://mitmproxy.org/doc/features/filters.html", target: "_blank"},
- React.createElement("i", {className: "fa fa-external-link"}),
- "Filter Documentation"
- )
+ React.createElement(FilterDocs, null)
);
}
},
@@ -2768,28 +2807,27 @@ var MainMenu = React.createClass({displayName: 'MainMenu',
return (
React.createElement("div", null,
- React.createElement("form", {className: "form-inline", style: {display: "inline"}},
+ React.createElement("div", {className: "menu-row"},
React.createElement(FilterInput, {
placeholder: "Filter",
type: "filter",
color: "black",
value: filter,
onChange: this.onFilterChange}),
- React.createElement("span", null, " "),
React.createElement(FilterInput, {
placeholder: "Highlight",
type: "tag",
color: "hsl(48, 100%, 50%)",
value: highlight,
onChange: this.onHighlightChange}),
- React.createElement("span", null, " "),
React.createElement(FilterInput, {
placeholder: "Intercept",
type: "pause",
color: "hsl(208, 56%, 53%)",
value: intercept,
onChange: this.onInterceptChange})
- )
+ ),
+ React.createElement("div", {className: "clearfix"})
)
);
}
diff --git a/web/src/css/header.less b/web/src/css/header.less
index ce85d528..3bbd2833 100644
--- a/web/src/css/header.less
+++ b/web/src/css/header.less
@@ -1,21 +1,37 @@
+@import (reference) '../../bower_components/bootstrap/less/variables.less';
+@import (reference) '../../bower_components/bootstrap/less/mixins/grid.less';
+
header {
- background-color: white;
+ background-color: white;
+
+ .title-bar {
+ line-height: 25px;
+ text-align: center;
+ }
- .title-bar {
- line-height: 25px;
- text-align: center;
- }
+ @separator-color: lighten(grey, 15%);
- @separator-color: lighten(grey, 15%);
+ .menu {
+ padding: 10px;
+ border-bottom: solid @separator-color 1px;
+ }
+}
+
+@menu-row-gutter-width: 5px;
+.menu-row {
+ .make-row(@menu-row-gutter-width);
+}
- .menu {
- padding: 10px;
- border-bottom: solid @separator-color 1px;
- }
+.filter-input {
+ .make-md-column(3, @menu-row-gutter-width);
}
.filter-input .popover {
- top: 27px;
- display: block;
- width: 100%;
+ top: 27px;
+ display: block;
+ max-width: none;
+ .popover-content {
+ max-height: 500px;
+ overflow-y: auto;
+ }
} \ No newline at end of file
diff --git a/web/src/js/components/header.jsx.js b/web/src/js/components/header.jsx.js
index ba63f12e..6470aec5 100644
--- a/web/src/js/components/header.jsx.js
+++ b/web/src/js/components/header.jsx.js
@@ -1,3 +1,45 @@
+var FilterDocs = React.createClass({
+ statics: {
+ xhr: false,
+ doc: false
+ },
+ componentWillMount: function () {
+ if (!FilterDocs.doc) {
+ FilterDocs.xhr = $.getJSON("/filter-help").done(function (doc) {
+ FilterDocs.doc = doc;
+ FilterDocs.xhr = false;
+ });
+ }
+ if (FilterDocs.xhr) {
+ FilterDocs.xhr.done(function () {
+ this.forceUpdate();
+ }.bind(this));
+ }
+ },
+ render: function () {
+ if (!FilterDocs.doc) {
+ return <i className="fa fa-spinner fa-spin"></i>;
+ } else {
+ var commands = FilterDocs.doc.commands.map(function (c) {
+ return <tr>
+ <td>{c[0].replace(" ", '\u00a0')}</td>
+ <td>{c[1]}</td>
+ </tr>;
+ });
+ commands.push(<tr>
+ <td colSpan="2">
+ <a href="https://mitmproxy.org/doc/features/filters.html"
+ target="_blank">
+ <i className="fa fa-external-link"></i>
+ &nbsp; mitmproxy docs</a>
+ </td>
+ </tr>);
+ return <table className="table table-condensed">
+ <tbody>{commands}</tbody>
+ </table>;
+ }
+ }
+});
var FilterInput = React.createClass({
getInitialState: function () {
// Consider both focus and mouseover for showing/hiding the tooltip,
@@ -41,10 +83,7 @@ var FilterInput = React.createClass({
return desc;
} else {
return (
- <a href="https://mitmproxy.org/doc/features/filters.html" target="_blank">
- <i className="fa fa-external-link"></i>
- Filter Documentation
- </a>
+ <FilterDocs/>
);
}
},
@@ -134,28 +173,27 @@ var MainMenu = React.createClass({
return (
<div>
- <form className="form-inline" style={{display: "inline"}}>
+ <div className="menu-row">
<FilterInput
placeholder="Filter"
type="filter"
color="black"
value={filter}
onChange={this.onFilterChange} />
- <span> </span>
<FilterInput
placeholder="Highlight"
type="tag"
color="hsl(48, 100%, 50%)"
value={highlight}
onChange={this.onHighlightChange}/>
- <span> </span>
<FilterInput
placeholder="Intercept"
type="pause"
color="hsl(208, 56%, 53%)"
value={intercept}
onChange={this.onInterceptChange}/>
- </form>
+ </div>
+ <div className="clearfix"></div>
</div>
);
}