From 3e63107e9473e3ec6676c047171a5d23c79b7dcd Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 26 Dec 2014 03:10:24 +0100 Subject: web: integrate filter docs --- libmproxy/web/app.py | 9 ++++++- libmproxy/web/static/css/app.css | 22 +++++++++++++++- libmproxy/web/static/js/app.js | 54 ++++++++++++++++++++++++++++++++++------ 3 files changed, 75 insertions(+), 10 deletions(-) (limited to 'libmproxy/web') 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"}) ) ); } -- cgit v1.2.3