diff options
author | Maximilian Hils <git@maximilianhils.com> | 2016-02-29 02:16:38 +0100 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2016-02-29 02:16:38 +0100 |
commit | 9192427d7b845a6389c4a44c930e067c479cdf0d (patch) | |
tree | 0ba9d50f38b959bec1f9e8269f6f9f5d4dd92f99 /web/src | |
parent | cbb068edaaa4a91297cc8c6416dcbc274b3e1317 (diff) | |
download | mitmproxy-9192427d7b845a6389c4a44c930e067c479cdf0d.tar.gz mitmproxy-9192427d7b845a6389c4a44c930e067c479cdf0d.tar.bz2 mitmproxy-9192427d7b845a6389c4a44c930e067c479cdf0d.zip |
web: fix router
Diffstat (limited to 'web/src')
-rw-r--r-- | web/src/css/flowtable.less | 3 | ||||
-rw-r--r-- | web/src/js/components/common.js | 57 | ||||
-rw-r--r-- | web/src/js/components/eventlog.js | 19 | ||||
-rw-r--r-- | web/src/js/components/flowview/index.js | 17 | ||||
-rw-r--r-- | web/src/js/components/header.js | 18 | ||||
-rw-r--r-- | web/src/js/components/mainview.js | 32 | ||||
-rw-r--r-- | web/src/js/components/prompt.js | 4 | ||||
-rw-r--r-- | web/src/js/components/proxyapp.js | 23 |
8 files changed, 80 insertions, 93 deletions
diff --git a/web/src/css/flowtable.less b/web/src/css/flowtable.less index 3533983c..1b560eba 100644 --- a/web/src/css/flowtable.less +++ b/web/src/css/flowtable.less @@ -10,7 +10,8 @@ .flow-table { width: 100%; - overflow: auto; + overflow-y: scroll; + overflow-x: hidden; table { width: 100%; diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js index 03b2ef8c..f910b3d8 100644 --- a/web/src/js/components/common.js +++ b/web/src/js/components/common.js @@ -1,15 +1,14 @@ -var React = require("react"); -var ReactDOM = require("react-dom"); -var ReactRouter = require("react-router"); -var _ = require("lodash"); +import React from "react" +import ReactDOM from "react-dom" +import _ from "lodash" // http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) export var AutoScrollMixin = { componentWillUpdate: function () { var node = ReactDOM.findDOMNode(this); this._shouldScrollBottom = ( - node.scrollTop !== 0 && - node.scrollTop + node.clientHeight === node.scrollHeight + node.scrollTop !== 0 && + node.scrollTop + node.clientHeight === node.scrollHeight ); }, componentDidUpdate: function () { @@ -57,7 +56,7 @@ export var ChildFocus = { contextTypes: { returnFocus: React.PropTypes.func }, - returnFocus: function(){ + returnFocus: function () { ReactDOM.findDOMNode(this).blur(); window.getSelection().removeAllRanges(); this.context.returnFocus(); @@ -65,46 +64,32 @@ export var ChildFocus = { }; -export var Navigation = { +export var Router = { contextTypes: { - routerFoo: React.PropTypes.object, + location: React.PropTypes.object, router: React.PropTypes.object.isRequired }, - setQuery: function (dict) { - var q = this.context.routerFoo.location.query; - for (var i in dict) { - if (dict.hasOwnProperty(i)) { - q[i] = dict[i] || undefined; //falsey values shall be removed. - } - } - this.replaceWith(undefined, q); - }, - replaceWith: function (pathname, query) { + updateLocation: function (pathname, queryUpdate) { if (pathname === undefined) { - pathname = this.context.routerFoo.location.pathname; + pathname = this.context.location.pathname; } - if (query === undefined) { - query = this.context.routerFoo.query; + var query = this.context.location.query; + if (queryUpdate !== undefined) { + for (var i in queryUpdate) { + if (queryUpdate.hasOwnProperty(i)) { + query[i] = queryUpdate[i] || undefined; //falsey values shall be removed. + } + } } - console.log({ pathname, query }); - this.context.router.replace({ pathname, query }); - } -}; - -// react-router is fairly good at changing its API regularly. -// We keep the old method for now - if it should turn out that their changes are permanent, -// we may remove this mixin and access react-router directly again. -export var RouterState = { - contextTypes: { - routerFoo: React.PropTypes.object, + this.context.router.replace({pathname, query}); }, getQuery: function () { // For whatever reason, react-router always returns the same object, which makes comparing // the current props with nextProps impossible. As a workaround, we just clone the query object. - return _.clone(this.context.routerFoo.location.query); + return _.clone(this.context.location.query); }, - getParams: function () { - return _.clone(this.context.routerFoo.params); + getParams: function() { + return this.props.routeParams; } }; diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js index 9dcd2c38..0f463eb0 100644 --- a/web/src/js/components/eventlog.js +++ b/web/src/js/components/eventlog.js @@ -1,9 +1,9 @@ -var React = require("react"); -var common = require("./common.js"); -var Query = require("../actions.js").Query; +import React from "react" +import {AutoScrollMixin, Router} from "./common.js" +import {Query} from "../actions.js" import { VirtualScrollMixin } from "./virtualscroll.js" -var views = require("../store/view.js"); -var _ = require("lodash"); +import views from "../store/view.js" +import _ from "lodash" var LogMessage = React.createClass({ render: function () { @@ -34,7 +34,7 @@ var EventLogContents = React.createClass({ contextTypes: { eventStore: React.PropTypes.object.isRequired }, - mixins: [common.AutoScrollMixin, VirtualScrollMixin], + mixins: [AutoScrollMixin, VirtualScrollMixin], getInitialState: function () { var filterFn = function (entry) { return this.props.filter[entry.level]; @@ -108,7 +108,7 @@ var ToggleFilter = React.createClass({ }); var EventLog = React.createClass({ - mixins: [common.Navigation], + mixins: [Router], getInitialState: function () { return { filter: { @@ -121,7 +121,8 @@ var EventLog = React.createClass({ close: function () { var d = {}; d[Query.SHOW_EVENTLOG] = undefined; - this.setQuery(d); + + this.updateLocation(undefined, d); }, toggleLevel: function (level) { var filter = _.extend({}, this.state.filter); @@ -147,4 +148,4 @@ var EventLog = React.createClass({ } }); -module.exports = EventLog;
\ No newline at end of file +export default EventLog;
\ No newline at end of file diff --git a/web/src/js/components/flowview/index.js b/web/src/js/components/flowview/index.js index 91b17dd2..bd34fe8d 100644 --- a/web/src/js/components/flowview/index.js +++ b/web/src/js/components/flowview/index.js @@ -1,7 +1,7 @@ var React = require("react"); var _ = require("lodash"); -var common = require("../common.js"); +import { Router, StickyHeadMixin } from "../common.js" var Nav = require("./nav.js"); var Messages = require("./messages.js"); var Details = require("./details.js"); @@ -16,7 +16,7 @@ var allTabs = { }; var FlowView = React.createClass({ - mixins: [common.StickyHeadMixin, common.Navigation, common.RouterState], + mixins: [StickyHeadMixin, Router], getInitialState: function () { return { prompt: false @@ -34,20 +34,17 @@ var FlowView = React.createClass({ }, nextTab: function (i) { var tabs = this.getTabs(this.props.flow); - var currentIndex = tabs.indexOf(this.getActive()); + var currentIndex = tabs.indexOf(this.props.tab); // JS modulo operator doesn't correct negative numbers, make sure that we are positive. var nextIndex = (currentIndex + i + tabs.length) % tabs.length; this.selectTab(tabs[nextIndex]); }, selectTab: function (panel) { - this.replaceWith(`/flows/${this.getParams().flowId}/${panel}`); - }, - getActive: function(){ - return this.getParams().detailTab; + this.updateLocation(`/flows/${this.getParams().flowId}/${panel}`); }, promptEdit: function () { var options; - switch(this.getActive()){ + switch(this.props.tab){ case "request": options = [ "method", @@ -67,7 +64,7 @@ var FlowView = React.createClass({ case "details": return; default: - throw "Unknown tab for edit: " + this.getActive(); + throw "Unknown tab for edit: " + this.props.tab; } this.setState({ @@ -85,7 +82,7 @@ var FlowView = React.createClass({ render: function () { var flow = this.props.flow; var tabs = this.getTabs(flow); - var active = this.getActive(); + var active = this.props.tab; if (tabs.indexOf(active) < 0) { if (active === "response" && flow.error) { diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index f2cc3fc5..d55c6443 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -4,7 +4,7 @@ var $ = require("jquery"); var Filt = require("../filt/filt.js"); var utils = require("../utils.js"); -var common = require("./common.js"); +import {Router, SettingsState, ChildFocus} from "./common.js"; var actions = require("../actions.js"); var Query = require("../actions.js").Query; @@ -51,7 +51,7 @@ var FilterDocs = React.createClass({ } }); var FilterInput = React.createClass({ - mixins: [common.ChildFocus], + mixins: [ChildFocus], getInitialState: function () { // Consider both focus and mouseover for showing/hiding the tooltip, // because onBlur of the input is triggered before the click on the tooltip @@ -159,7 +159,7 @@ var FilterInput = React.createClass({ }); var MainMenu = React.createClass({ - mixins: [common.Navigation, common.RouterState, common.SettingsState], + mixins: [Router, SettingsState], statics: { title: "Start", route: "flows" @@ -167,12 +167,12 @@ var MainMenu = React.createClass({ onSearchChange: function (val) { var d = {}; d[Query.SEARCH] = val; - this.setQuery(d); + this.updateLocation(undefined, d); }, onHighlightChange: function (val) { var d = {}; d[Query.HIGHLIGHT] = val; - this.setQuery(d); + this.updateLocation(undefined, d); }, onInterceptChange: function (val) { actions.SettingsActions.update({intercept: val}); @@ -219,7 +219,7 @@ var ViewMenu = React.createClass({ title: "View", route: "flows" }, - mixins: [common.Navigation, common.RouterState], + mixins: [Router], toggleEventLog: function () { var d = {}; @@ -229,7 +229,7 @@ var ViewMenu = React.createClass({ d[Query.SHOW_EVENTLOG] = "t"; // any non-false value will do it, keep it short } - this.setQuery(d); + this.updateLocation(undefined, d); }, render: function () { var showEventLog = this.getQuery()[Query.SHOW_EVENTLOG]; @@ -348,7 +348,7 @@ var header_entries = [MainMenu, ViewMenu /*, ReportsMenu */]; var Header = React.createClass({ - mixins: [common.Navigation], + mixins: [Router], getInitialState: function () { return { active: header_entries[0] @@ -356,7 +356,7 @@ var Header = React.createClass({ }, handleClick: function (active, e) { e.preventDefault(); - this.replaceWith(active.route); + this.updateLocation(active.route); this.setState({active: active}); }, render: function () { diff --git a/web/src/js/components/mainview.js b/web/src/js/components/mainview.js index 86666e39..5c9afe0c 100644 --- a/web/src/js/components/mainview.js +++ b/web/src/js/components/mainview.js @@ -5,13 +5,12 @@ var Query = require("../actions.js").Query; var utils = require("../utils.js"); var views = require("../store/view.js"); var Filt = require("../filt/filt.js"); - -var common = require("./common.js"); +import { Router, Splitter} from "./common.js" var FlowTable = require("./flowtable.js"); var FlowView = require("./flowview/index.js"); var MainView = React.createClass({ - mixins: [common.Navigation, common.RouterState], + mixins: [Router], contextTypes: { flowStore: React.PropTypes.object.isRequired, }, @@ -43,24 +42,27 @@ var MainView = React.createClass({ getViewFilt: function () { try { var filtStr = this.getQuery()[Query.SEARCH]; - var filt = filtStr ? Filt.parse(filtStr) : function(){return true}; + var filt = filtStr ? Filt.parse(filtStr) : () => true; var highlightStr = this.getQuery()[Query.HIGHLIGHT]; - var highlight = highlightStr ? Filt.parse(highlightStr) : false; + var highlight = highlightStr ? Filt.parse(highlightStr) : () => false; } catch (e) { console.error("Error when processing filter: " + e); } - return function filter_and_highlight(flow) { + var fun = function filter_and_highlight(flow) { if (!this._highlight) { this._highlight = {}; } - this._highlight[flow.id] = highlight && highlight(flow); + this._highlight[flow.id] = highlight(flow); return filt(flow); }; + fun.highlightStr = highlightStr; + fun.filtStr = filtStr; + return fun; }, componentWillReceiveProps: function (nextProps) { - var filterChanged = (this.props.query[Query.SEARCH] !== nextProps.query[Query.SEARCH]); - var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]); + var filterChanged = this.state.view.filt.filtStr !== nextProps.location.query[Query.SEARCH]; + var highlightChanged = this.state.view.filt.highlightStr !== nextProps.location.query[Query.HIGHLIGHT]; if (filterChanged || highlightChanged) { this.state.view.recalculate(this.getViewFilt(), this.state.sortKeyFun); } @@ -92,10 +94,10 @@ var MainView = React.createClass({ selectFlow: function (flow) { if (flow) { var tab = this.getParams().detailTab || "request"; - this.replaceWith(`/flows/${flow.id}/${tab}`); + this.updateLocation(`/flows/${flow.id}/${tab}`); this.refs.flowTable.scrollIntoView(flow); } else { - this.replaceWith("/flows"); + this.updateLocation("/flows"); } }, selectFlowRelative: function (shift) { @@ -218,8 +220,12 @@ var MainView = React.createClass({ var details; if (selected) { details = [ - <common.Splitter key="splitter"/>, - <FlowView key="flowDetails" ref="flowDetails" flow={selected}/> + <Splitter key="splitter"/>, + <FlowView + key="flowDetails" + ref="flowDetails" + tab={this.getParams().detailTab} + flow={selected}/> ]; } else { details = null; diff --git a/web/src/js/components/prompt.js b/web/src/js/components/prompt.js index 9695bd94..b4777934 100644 --- a/web/src/js/components/prompt.js +++ b/web/src/js/components/prompt.js @@ -3,10 +3,10 @@ var ReactDOM = require('react-dom'); var _ = require("lodash"); var utils = require("../utils.js"); -var common = require("./common.js"); +import {ChildFocus} from "./common.js" var Prompt = React.createClass({ - mixins: [common.ChildFocus], + mixins: [ChildFocus], propTypes: { options: React.PropTypes.array.isRequired, done: React.PropTypes.func.isRequired, diff --git a/web/src/js/components/proxyapp.js b/web/src/js/components/proxyapp.js index 9c2d8714..fe3e0008 100644 --- a/web/src/js/components/proxyapp.js +++ b/web/src/js/components/proxyapp.js @@ -1,13 +1,13 @@ var React = require("react"); var ReactDOM = require("react-dom"); -var ReactRouter = require("react-router"); var _ = require("lodash"); +import {Router, Splitter} from "./common.js" var common = require("./common.js"); var MainView = require("./mainview.js"); var Footer = require("./footer.js"); var header = require("./header.js"); -var EventLog = require("./eventlog.js"); +import EventLog from "./eventlog.js" var store = require("../store/store.js"); var Query = require("../actions.js").Query; var Key = require("../utils.js").Key; @@ -22,13 +22,13 @@ var Reports = React.createClass({ var ProxyAppMain = React.createClass({ - mixins: [common.RouterState], + mixins: [Router], childContextTypes: { settingsStore: React.PropTypes.object.isRequired, flowStore: React.PropTypes.object.isRequired, eventStore: React.PropTypes.object.isRequired, returnFocus: React.PropTypes.func.isRequired, - routerFoo: React.PropTypes.object, + location: React.PropTypes.object.isRequired, }, componentDidMount: function () { this.focus(); @@ -39,10 +39,7 @@ var ProxyAppMain = React.createClass({ flowStore: this.state.flowStore, eventStore: this.state.eventStore, returnFocus: this.focus, - routerFoo: { - location: this.props.location, - params: this.props.params - } + location: this.props.location }; }, getInitialState: function () { @@ -96,7 +93,7 @@ var ProxyAppMain = React.createClass({ var eventlog; if (this.props.location.query[Query.SHOW_EVENTLOG]) { eventlog = [ - <common.Splitter key="splitter" axis="y"/>, + <Splitter key="splitter" axis="y"/>, <EventLog key="eventlog"/> ]; } else { @@ -104,7 +101,7 @@ var ProxyAppMain = React.createClass({ } var children = React.cloneElement( this.props.children, - { ref: "view", query: this.props.location.query } + { ref: "view", location: this.props.location } ); return ( <div id="container" tabIndex="0" onKeyDown={this.onKeydown}> @@ -118,15 +115,15 @@ var ProxyAppMain = React.createClass({ }); -import { Route, Router, hashHistory, Redirect} from "react-router"; +import { Route, Router as ReactRouter, hashHistory, Redirect} from "react-router"; export var app = ( -<Router history={hashHistory}> +<ReactRouter history={hashHistory}> <Redirect from="/" to="/flows" /> <Route path="/" component={ProxyAppMain}> <Route path="flows" component={MainView}/> <Route path="flows/:flowId/:detailTab" component={MainView}/> <Route path="reports" component={Reports}/> </Route> -</Router> +</ReactRouter> );
\ No newline at end of file |