From 698d38b28e43ce0685ce8ce8c119926af2083cbc Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 2 Jun 2016 17:46:18 -0700 Subject: [PATCH] web: :hatching_chick: --- mitmproxy/web/static/app.css | 51 +--- mitmproxy/web/static/app.js | 440 ++++++++++++++---------------- web/src/css/eventlog.less | 8 + web/src/css/header.less | 17 -- web/src/js/app.js | 4 +- web/src/js/components/common.js | 17 +- web/src/js/components/eventlog.js | 136 ++++----- web/src/js/components/header.js | 19 +- web/src/js/components/proxyapp.js | 15 +- web/src/js/ducks/README.md | 1 + web/src/js/ducks/eventLog.js | 39 +++ web/src/js/ducks/index.js | 8 + web/src/js/reducers/eventLog.js | 31 --- web/src/js/reduxActions.js | 13 - 14 files changed, 339 insertions(+), 460 deletions(-) create mode 100644 web/src/js/ducks/README.md create mode 100644 web/src/js/ducks/eventLog.js create mode 100644 web/src/js/ducks/index.js delete mode 100644 web/src/js/reducers/eventLog.js delete mode 100644 web/src/js/reduxActions.js diff --git a/mitmproxy/web/static/app.css b/mitmproxy/web/static/app.css index ae2e963f5..bc3f1a6a3 100644 --- a/mitmproxy/web/static/app.css +++ b/mitmproxy/web/static/app.css @@ -164,49 +164,6 @@ header .menu { max-height: 500px; overflow-y: auto; } -.menu .toggle-btn { - float: left; - width: 33.33333333%; - position: relative; - min-height: 1px; - padding-left: 2.5px; - padding-right: 2.5px; - margin-bottom: 5px; -} -@media (min-width: 768px) { - .menu .toggle-btn { - float: left; - width: 25%; - } -} -@media (min-width: 1200px) { - .menu .toggle-btn { - float: left; - width: 16.66666667%; - } -} -.menu .toggle-btn .btn { - width: 100%; -} -.menu .toggle-input-btn { - position: relative; - min-height: 1px; - padding-left: 2.5px; - padding-right: 2.5px; - margin-bottom: 5px; -} -@media (min-width: 768px) { - .menu .toggle-input-btn { - float: left; - width: 50%; - } -} -@media (min-width: 1200px) { - .menu .toggle-input-btn { - float: left; - width: 33.33333333%; - } -} .flow-table { width: 100%; overflow-y: scroll; @@ -452,6 +409,14 @@ header .menu { .eventlog .fa-close:hover { color: black; } +.eventlog .btn-toggle { + margin-top: -2px; + margin-left: 3px; + padding: 2px 2px; + font-size: 10px; + line-height: 10px; + border-radius: 2px; +} .eventlog .label { cursor: pointer; vertical-align: middle; diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index e517f33ec..b7e0f24e6 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -365,13 +365,13 @@ var SettingsActions = exports.SettingsActions = { data: JSON.stringify(settings) }); - /* - //Facebook Flux: We do an optimistic update on the client already. - AppDispatcher.dispatchViewAction({ - type: ActionTypes.SETTINGS_STORE, - cmd: StoreCmds.UPDATE, - data: settings - }); + /* + //Facebook Flux: We do an optimistic update on the client already. + AppDispatcher.dispatchViewAction({ + type: ActionTypes.SETTINGS_STORE, + cmd: StoreCmds.UPDATE, + data: settings + }); */ } }; @@ -414,15 +414,15 @@ var FlowActions = exports.FlowActions = { _jquery2.default.post("/flows/" + flow.id + "/revert"); }, update: function update(flow, nextProps) { - /* - //Facebook Flux: We do an optimistic update on the client already. - var nextFlow = _.cloneDeep(flow); - _.merge(nextFlow, nextProps); - AppDispatcher.dispatchViewAction({ - type: ActionTypes.FLOW_STORE, - cmd: StoreCmds.UPDATE, - data: nextFlow - }); + /* + //Facebook Flux: We do an optimistic update on the client already. + var nextFlow = _.cloneDeep(flow); + _.merge(nextFlow, nextProps); + AppDispatcher.dispatchViewAction({ + type: ActionTypes.FLOW_STORE, + cmd: StoreCmds.UPDATE, + data: nextFlow + }); */ _jquery2.default.ajax({ type: "PUT", @@ -455,10 +455,6 @@ var _redux = require('redux'); var _reactRedux = require('react-redux'); -var _reducers = require('./reducers'); - -var _reducers2 = _interopRequireDefault(_reducers); - var _jquery = require('jquery'); var _jquery2 = _interopRequireDefault(_jquery); @@ -471,9 +467,13 @@ var _proxyapp = require('./components/proxyapp.js'); var _actions = require('./actions.js'); +var _index = require('./ducks/index'); + +var _index2 = _interopRequireDefault(_index); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var store = (0, _redux.createStore)(_reducers2.default); +var store = (0, _redux.createStore)(_index2.default); (0, _jquery2.default)(function () { window.ws = new _connection2.default("/updates"); @@ -489,7 +489,7 @@ var store = (0, _redux.createStore)(_reducers2.default); ), document.getElementById("mitmproxy")); }); -},{"./actions.js":2,"./components/proxyapp.js":20,"./connection":21,"./reducers":26,"jquery":"jquery","react":"react","react-dom":"react-dom","react-redux":"react-redux","redux":"redux"}],4:[function(require,module,exports){ +},{"./actions.js":2,"./components/proxyapp.js":20,"./connection":21,"./ducks/index":24,"jquery":"jquery","react":"react","react-dom":"react-dom","react-redux":"react-redux","redux":"redux"}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -629,28 +629,23 @@ var Splitter = exports.Splitter = _react2.default.createClass({ } }); -var ToggleButton = exports.ToggleButton = function ToggleButton(props) { +var ToggleButton = exports.ToggleButton = function ToggleButton(_ref) { + var checked = _ref.checked; + var onToggle = _ref.onToggle; + var text = _ref.text; return _react2.default.createElement( "div", - { className: "input-group toggle-btn" }, - _react2.default.createElement( - "div", - { - className: "btn " + (props.checked ? "btn-primary" : "btn-default"), - onClick: props.onToggleChanged }, - _react2.default.createElement( - "span", - { className: "fa " + (props.checked ? "fa-check-square-o" : "fa-square-o") }, - " ", - props.name - ) - ) + { className: "btn btn-toggle " + (checked ? "btn-primary" : "btn-default"), onClick: onToggle }, + _react2.default.createElement("i", { className: "fa fa-fw " + (checked ? "fa-check-square-o" : "fa-square-o") }), + " ", + text ); }; ToggleButton.propTypes = { - name: _react2.default.PropTypes.string.isRequired, - onToggleChanged: _react2.default.PropTypes.func.isRequired + checked: _react2.default.PropTypes.bool.isRequired, + onToggle: _react2.default.PropTypes.func.isRequired, + text: _react2.default.PropTypes.string.isRequired }; var ToggleInputButton = exports.ToggleInputButton = function (_React$Component) { @@ -713,7 +708,7 @@ ToggleInputButton.propTypes = { onToggleChanged: _react2.default.PropTypes.func.isRequired }; -},{"../utils.js":30,"lodash":"lodash","react":"react","react-dom":"react-dom"}],5:[function(require,module,exports){ +},{"../utils.js":29,"lodash":"lodash","react":"react","react-dom":"react-dom"}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -971,12 +966,13 @@ var ValueEditor = exports.ValueEditor = _react2.default.createClass({ } }); -},{"../utils.js":30,"react":"react","react-dom":"react-dom"}],6:[function(require,module,exports){ +},{"../utils.js":29,"react":"react","react-dom":"react-dom"}],6:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.ToggleEventLog = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); @@ -994,9 +990,7 @@ var _shallowequal = require("shallowequal"); var _shallowequal2 = _interopRequireDefault(_shallowequal); -var _actions = require("../actions.js"); - -var _reduxActions = require("../reduxActions"); +var _eventLog = require("../ducks/eventLog"); var _AutoScroll = require("./helpers/AutoScroll"); @@ -1006,6 +1000,8 @@ var _VirtualScroll = require("./helpers/VirtualScroll"); var _view = require("../store/view.js"); +var _common = require("./common"); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -1142,93 +1138,75 @@ EventLogContents.defaultProps = { }; -ToggleFilter.propTypes = { - name: _react2.default.PropTypes.string.isRequired, - toggleLevel: _react2.default.PropTypes.func.isRequired, - active: _react2.default.PropTypes.bool -}; +EventLogContents = (0, _AutoScroll2.default)(EventLogContents); -function ToggleFilter(_ref) { - var name = _ref.name; - var active = _ref.active; - var toggleLevel = _ref.toggleLevel; - - var className = "label "; - if (active) { - className += "label-primary"; - } else { - className += "label-default"; - } - - function onClick(event) { - event.preventDefault(); - toggleLevel(); - } - - return _react2.default.createElement( - "a", - { - href: "#", - className: className, - onClick: onClick }, - name - ); -} - -var mapStateToProps = function mapStateToProps(state, ownProps) { +var EventLogContentsContainer = (0, _reactRedux.connect)(function (state) { return { - active: state.eventLog.visibilityFilter[ownProps.name] + filter: state.eventLog.filter }; -}; +})(EventLogContents); -var mapDispatchToProps = function mapDispatchToProps(dispatch, ownProps) { +var ToggleEventLog = exports.ToggleEventLog = (0, _reactRedux.connect)(function (state) { return { - toggleLevel: function toggleLevel() { - dispatch((0, _reduxActions.toggleEventLogFilter)(ownProps.name)); + checked: state.eventLog.visible + }; +}, function (dispatch) { + return { + onToggle: function onToggle() { + return dispatch((0, _eventLog.toggleEventLogVisibility)()); } }; -}; +})(_common.ToggleButton); -var ToggleEventLogFilter = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ToggleFilter); +var ToggleFilter = (0, _reactRedux.connect)(function (state, ownProps) { + return { + checked: state.eventLog.filter[ownProps.text] + }; +}, function (dispatch, ownProps) { + return { + onToggle: function onToggle() { + return dispatch((0, _eventLog.toggleEventLogFilter)(ownProps.text)); + } + }; +})(_common.ToggleButton); -var AutoScrollEventLog = (0, _AutoScroll2.default)(EventLogContents); - -var VisibleAutoScrollEventLog = (0, _reactRedux.connect)(function mapStateToProps(state, ownProps) { - return { filter: state.eventLog.visibilityFilter }; -})(AutoScrollEventLog); - -var EventLog = _react2.default.createClass({ - displayName: "EventLog", - close: function close() { - var d = {}; - d[_actions.Query.SHOW_EVENTLOG] = undefined; - this.props.updateLocation(undefined, d); - }, - render: function render() { - return _react2.default.createElement( +var EventLog = function EventLog(_ref) { + var close = _ref.close; + return _react2.default.createElement( + "div", + { className: "eventlog" }, + _react2.default.createElement( "div", - { className: "eventlog" }, + null, + "Eventlog", _react2.default.createElement( "div", - null, - "Eventlog", - _react2.default.createElement( - "div", - { className: "pull-right" }, - _react2.default.createElement(ToggleEventLogFilter, { name: "debug" }), - _react2.default.createElement(ToggleEventLogFilter, { name: "info" }), - _react2.default.createElement(ToggleEventLogFilter, { name: "web" }), - _react2.default.createElement("i", { onClick: this.close, className: "fa fa-close" }) - ) - ), - _react2.default.createElement(VisibleAutoScrollEventLog, null) - ); - } -}); + { className: "pull-right" }, + _react2.default.createElement(ToggleFilter, { text: "debug" }), + _react2.default.createElement(ToggleFilter, { text: "info" }), + _react2.default.createElement(ToggleFilter, { text: "web" }), + _react2.default.createElement("i", { onClick: close, className: "fa fa-close" }) + ) + ), + _react2.default.createElement(EventLogContentsContainer, null) + ); +}; -exports.default = EventLog; +EventLog.propTypes = { + close: _react2.default.PropTypes.func.isRequired +}; -},{"../actions.js":2,"../reduxActions":27,"../store/view.js":29,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"react":"react","react-dom":"react-dom","react-redux":"react-redux","shallowequal":"shallowequal"}],7:[function(require,module,exports){ +var EventLogContainer = (0, _reactRedux.connect)(undefined, function (dispatch) { + return { + close: function close() { + return dispatch((0, _eventLog.toggleEventLogVisibility)()); + } + }; +})(EventLog); + +exports.default = EventLogContainer; + +},{"../ducks/eventLog":23,"../store/view.js":28,"./common":4,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"react":"react","react-dom":"react-dom","react-redux":"react-redux","shallowequal":"shallowequal"}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1497,7 +1475,7 @@ var all_columns = [TLSColumn, IconColumn, PathColumn, MethodColumn, StatusColumn exports.default = all_columns; -},{"../flow/utils.js":24,"../utils.js":30,"react":"react"}],8:[function(require,module,exports){ +},{"../flow/utils.js":26,"../utils.js":29,"react":"react"}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -1789,7 +1767,7 @@ FlowTable.defaultProps = { }; exports.default = (0, _AutoScroll2.default)(FlowTable); -},{"../utils.js":30,"./flowtable-columns.js":7,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"classnames":"classnames","lodash":"lodash","react":"react","react-dom":"react-dom","shallowequal":"shallowequal"}],9:[function(require,module,exports){ +},{"../utils.js":29,"./flowtable-columns.js":7,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"classnames":"classnames","lodash":"lodash","react":"react","react-dom":"react-dom","shallowequal":"shallowequal"}],9:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -2143,7 +2121,7 @@ var ContentView = _react2.default.createClass({ exports.default = ContentView; -},{"../../flow/utils.js":24,"../../utils.js":30,"lodash":"lodash","react":"react"}],10:[function(require,module,exports){ +},{"../../flow/utils.js":26,"../../utils.js":29,"lodash":"lodash","react":"react"}],10:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -2411,7 +2389,7 @@ var Details = _react2.default.createClass({ exports.default = Details; -},{"../../utils.js":30,"lodash":"lodash","react":"react"}],11:[function(require,module,exports){ +},{"../../utils.js":29,"lodash":"lodash","react":"react"}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -2905,7 +2883,7 @@ var Error = exports.Error = _react2.default.createClass({ } }); -},{"../../actions.js":2,"../../flow/utils.js":24,"../../utils.js":30,"../editor.js":5,"./contentview.js":9,"lodash":"lodash","react":"react","react-dom":"react-dom"}],13:[function(require,module,exports){ +},{"../../actions.js":2,"../../flow/utils.js":26,"../../utils.js":29,"../editor.js":5,"./contentview.js":9,"lodash":"lodash","react":"react","react-dom":"react-dom"}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3088,7 +3066,7 @@ function Footer(_ref) { ); } -},{"../utils.js":30,"./common.js":4,"react":"react"}],15:[function(require,module,exports){ +},{"../utils.js":29,"./common.js":4,"react":"react"}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -3108,6 +3086,8 @@ var _jquery = require("jquery"); var _jquery2 = _interopRequireDefault(_jquery); +var _reactRedux = require("react-redux"); + var _filt = require("../filt/filt.js"); var _filt2 = _interopRequireDefault(_filt); @@ -3118,6 +3098,8 @@ var _common = require("./common.js"); var _actions = require("../actions.js"); +var _eventlog = require("./eventlog"); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var FilterDocs = _react2.default.createClass({ @@ -3371,29 +3353,14 @@ var ViewMenu = _react2.default.createClass({ title: "View", route: "flows" }, - toggleEventLog: function toggleEventLog() { - var d = {}; - if (this.props.query[_actions.Query.SHOW_EVENTLOG]) { - d[_actions.Query.SHOW_EVENTLOG] = undefined; - } else { - d[_actions.Query.SHOW_EVENTLOG] = "t"; // any non-false value will do it, keep it short - } - - this.props.updateLocation(undefined, d); - console.log('toggleevent'); - }, render: function render() { - var showEventLog = this.props.query[_actions.Query.SHOW_EVENTLOG]; return _react2.default.createElement( "div", null, _react2.default.createElement( "div", { className: "menu-row" }, - _react2.default.createElement(_common.ToggleButton, { - checked: showEventLog, - name: "Show Eventlog", - onToggleChanged: this.toggleEventLog }) + _react2.default.createElement(_eventlog.ToggleEventLog, { text: "Show Event Log" }) ), _react2.default.createElement("div", { className: "clearfix" }) ); @@ -3642,7 +3609,7 @@ var Header = exports.Header = _react2.default.createClass({ } }); -},{"../actions.js":2,"../filt/filt.js":23,"../utils.js":30,"./common.js":4,"jquery":"jquery","react":"react","react-dom":"react-dom"}],16:[function(require,module,exports){ +},{"../actions.js":2,"../filt/filt.js":25,"../utils.js":29,"./common.js":4,"./eventlog":6,"jquery":"jquery","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4058,7 +4025,7 @@ var MainView = _react2.default.createClass({ exports.default = MainView; -},{"../actions.js":2,"../filt/filt.js":23,"../store/view.js":29,"../utils.js":30,"./common.js":4,"./flowtable.js":8,"./flowview/index.js":11,"react":"react"}],19:[function(require,module,exports){ +},{"../actions.js":2,"../filt/filt.js":25,"../store/view.js":28,"../utils.js":29,"./common.js":4,"./flowtable.js":8,"./flowview/index.js":11,"react":"react"}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4194,7 +4161,7 @@ var Prompt = _react2.default.createClass({ exports.default = Prompt; -},{"../utils.js":30,"lodash":"lodash","react":"react","react-dom":"react-dom"}],20:[function(require,module,exports){ +},{"../utils.js":29,"lodash":"lodash","react":"react","react-dom":"react-dom"}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4214,6 +4181,10 @@ var _lodash = require("lodash"); var _lodash2 = _interopRequireDefault(_lodash); +var _reactRedux = require("react-redux"); + +var _reactRouter = require("react-router"); + var _common = require("./common.js"); var _mainview = require("./mainview.js"); @@ -4232,12 +4203,8 @@ var _eventlog2 = _interopRequireDefault(_eventlog); var _store = require("../store/store.js"); -var _actions = require("../actions.js"); - var _utils = require("../utils.js"); -var _reactRouter = require("react-router"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } //TODO: Move out of here, just a stub. @@ -4355,8 +4322,8 @@ var ProxyAppMain = _react2.default.createClass({ render: function render() { var query = this.getQuery(); var eventlog; - if (this.props.location.query[_actions.Query.SHOW_EVENTLOG]) { - eventlog = [_react2.default.createElement(_common.Splitter, { key: "splitter", axis: "y" }), _react2.default.createElement(_eventlog2.default, { key: "eventlog", updateLocation: this.updateLocation })]; + if (this.props.showEventLog) { + eventlog = [_react2.default.createElement(_common.Splitter, { key: "splitter", axis: "y" }), _react2.default.createElement(_eventlog2.default, { key: "eventlog" })]; } else { eventlog = null; } @@ -4371,20 +4338,26 @@ var ProxyAppMain = _react2.default.createClass({ } }); +var AppContainer = (0, _reactRedux.connect)(function (state) { + return { + showEventLog: state.eventLog.visible + }; +})(ProxyAppMain); + var App = exports.App = _react2.default.createElement( _reactRouter.Router, { history: _reactRouter.hashHistory }, _react2.default.createElement(_reactRouter.Redirect, { from: "/", to: "/flows" }), _react2.default.createElement( _reactRouter.Route, - { path: "/", component: ProxyAppMain }, + { path: "/", component: AppContainer }, _react2.default.createElement(_reactRouter.Route, { path: "flows", component: _mainview2.default }), _react2.default.createElement(_reactRouter.Route, { path: "flows/:flowId/:detailTab", component: _mainview2.default }), _react2.default.createElement(_reactRouter.Route, { path: "reports", component: Reports }) ) ); -},{"../actions.js":2,"../store/store.js":28,"../utils.js":30,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":18,"lodash":"lodash","react":"react","react-dom":"react-dom","react-router":"react-router"}],21:[function(require,module,exports){ +},{"../store/store.js":27,"../utils.js":29,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":18,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux","react-router":"react-router"}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -4451,6 +4424,78 @@ AppDispatcher.dispatchServerAction = function (action) { }; },{"flux":"flux"}],23:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + +exports.default = reducer; +exports.toggleEventLogFilter = toggleEventLogFilter; +exports.toggleEventLogVisibility = toggleEventLogVisibility; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER'; +var TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY'; + +var defaultState = { + visible: false, + filter: { + "debug": false, + "info": true, + "web": true + } +}; +function reducer() { + var state = arguments.length <= 0 || arguments[0] === undefined ? defaultState : arguments[0]; + var action = arguments[1]; + + switch (action.type) { + case TOGGLE_FILTER: + return _extends({}, state, { + filter: _extends({}, state.filter, _defineProperty({}, action.filter, !state.filter[action.filter])) + }); + case TOGGLE_VISIBILITY: + return _extends({}, state, { + visible: !state.visible + }); + default: + return state; + } +} + +function toggleEventLogFilter(filter) { + return { type: TOGGLE_FILTER, filter: filter }; +} +function toggleEventLogVisibility() { + return { type: TOGGLE_VISIBILITY }; +} + +},{}],24:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _redux = require('redux'); + +var _eventLog = require('./eventLog.js'); + +var _eventLog2 = _interopRequireDefault(_eventLog); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var rootReducer = (0, _redux.combineReducers)({ + eventLog: _eventLog2.default +}); + +exports.default = rootReducer; + +},{"./eventLog.js":23,"redux":"redux"}],25:[function(require,module,exports){ "use strict"; module.exports = function () { @@ -6354,7 +6399,7 @@ module.exports = function () { }; }(); -},{"../flow/utils.js":24}],24:[function(require,module,exports){ +},{"../flow/utils.js":26}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6488,96 +6533,7 @@ var parseHttpVersion = exports.parseHttpVersion = function parseHttpVersion(http }); }; -},{"jquery":"jquery","lodash":"lodash"}],25:[function(require,module,exports){ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _redux = require("redux"); - -var _reduxActions = require("../reduxActions"); - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var defaultVisibility = { - "debug": false, - "info": true, - "web": true -}; - -var visibilityFilter = function visibilityFilter() { - var state = arguments.length <= 0 || arguments[0] === undefined ? defaultVisibility : arguments[0]; - var action = arguments[1]; - - switch (action.type) { - case _reduxActions.TOGGLE_EVENTLOG_FILTER: - return _extends({}, state, _defineProperty({}, action.filter, !state[action.filter])); - default: - return state; - } -}; - -var entries = function entries() { - var state = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; - var action = arguments[1]; - - return state; -}; - -var eventLog = (0, _redux.combineReducers)({ - visibilityFilter: visibilityFilter, - entries: entries -}); - -exports.default = eventLog; - -},{"../reduxActions":27,"redux":"redux"}],26:[function(require,module,exports){ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _redux = require('redux'); - -var _eventlog = require('./eventlog'); - -var _eventlog2 = _interopRequireDefault(_eventlog); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var mitmproxyApp = (0, _redux.combineReducers)({ - eventLog: _eventlog2.default -}); - -exports.default = mitmproxyApp; - -},{"./eventlog":25,"redux":"redux"}],27:[function(require,module,exports){ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.toggleEventLogFilter = toggleEventLogFilter; -var TOGGLE_EVENTLOG_FILTER = exports.TOGGLE_EVENTLOG_FILTER = 'TOGGLE_EVENTLOG_FILTER'; -var HIDE_EVENTLOG = exports.HIDE_EVENTLOG = 'HIDE_EVENTLOG'; -var SHOW_EVENTLOG = exports.SHOW_EVENTLOG = 'SHOW_EVENTLOG'; - -var EventLogFilters = exports.EventLogFilters = { - DEBUG: 'debug', - INFO: 'info', - WEB: 'web' -}; - -function toggleEventLogFilter(filter) { - return { type: TOGGLE_EVENTLOG_FILTER, filter: filter }; -} - -},{}],28:[function(require,module,exports){ +},{"jquery":"jquery","lodash":"lodash"}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6764,7 +6720,7 @@ _lodash2.default.extend(EventLogStore.prototype, LiveListStore.prototype, { } }); -},{"../actions.js":2,"../dispatcher.js":22,"events":1,"jquery":"jquery","lodash":"lodash"}],29:[function(require,module,exports){ +},{"../actions.js":2,"../dispatcher.js":22,"events":1,"jquery":"jquery","lodash":"lodash"}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -6894,7 +6850,7 @@ _lodash2.default.extend(StoreView.prototype, _events.EventEmitter.prototype, { } }); -},{"../utils.js":30,"events":1,"lodash":"lodash"}],30:[function(require,module,exports){ +},{"../utils.js":29,"events":1,"lodash":"lodash"}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { diff --git a/web/src/css/eventlog.less b/web/src/css/eventlog.less index 26dea3ccd..908312cd5 100644 --- a/web/src/css/eventlog.less +++ b/web/src/css/eventlog.less @@ -33,6 +33,14 @@ } } + .btn-toggle { + margin-top: -2px; + margin-left: 3px; + padding: 2px 2px; + font-size: 10px; + line-height: 10px; + border-radius: 2px; + } .label { cursor: pointer; vertical-align: middle; diff --git a/web/src/css/header.less b/web/src/css/header.less index b1bd9c041..4813b9333 100644 --- a/web/src/css/header.less +++ b/web/src/css/header.less @@ -32,20 +32,3 @@ header { overflow-y: auto; } } - -.menu .toggle-btn { - .make-xs-column(4, @menu-row-gutter-width); - .make-sm-column(3, @menu-row-gutter-width); - .make-lg-column(2, @menu-row-gutter-width); - margin-bottom:5px; -} - -.menu .toggle-btn .btn { - width: 100%; -} - -.menu .toggle-input-btn { - .make-sm-column(6, @menu-row-gutter-width); - .make-lg-column(4, @menu-row-gutter-width); - margin-bottom:5px; -} \ No newline at end of file diff --git a/web/src/js/app.js b/web/src/js/app.js index 308976868..5b5d1fc8a 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -2,14 +2,14 @@ import React from "react" import {render} from 'react-dom' import {createStore} from 'redux' import {Provider} from 'react-redux' -import mitmproxyApp from './reducers' import $ from "jquery" import Connection from "./connection" import {App} from "./components/proxyapp.js" import {EventLogActions} from "./actions.js" +import rootReducer from './ducks/index'; -let store = createStore(mitmproxyApp); +let store = createStore(rootReducer); $(function () { window.ws = new Connection("/updates"); diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js index 87c34ffc1..3496f1de9 100644 --- a/web/src/js/components/common.js +++ b/web/src/js/components/common.js @@ -108,18 +108,17 @@ export var Splitter = React.createClass({ } }); -export const ToggleButton = (props) => -
-
-  {props.name} -
+export const ToggleButton = ({checked, onToggle, text}) => +
+ +   + {text}
; ToggleButton.propTypes = { - name: React.PropTypes.string.isRequired, - onToggleChanged: React.PropTypes.func.isRequired + checked: React.PropTypes.bool.isRequired, + onToggle: React.PropTypes.func.isRequired, + text: React.PropTypes.string.isRequired }; export class ToggleInputButton extends React.Component { diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js index 687c5265d..a2e6a0c1d 100644 --- a/web/src/js/components/eventlog.js +++ b/web/src/js/components/eventlog.js @@ -1,12 +1,12 @@ import React from "react" import ReactDOM from "react-dom" -import { connect } from 'react-redux' +import {connect} from 'react-redux' import shallowEqual from "shallowequal" -import {Query} from "../actions.js" -import {toggleEventLogFilter} from "../reduxActions" +import {toggleEventLogFilter, toggleEventLogVisibility} from "../ducks/eventLog" import AutoScroll from "./helpers/AutoScroll"; import {calcVScroll} from "./helpers/VirtualScroll" import {StoreView} from "../store/view.js" +import {ToggleButton} from "./common"; class EventLogContents extends React.Component { @@ -27,7 +27,7 @@ class EventLogContents extends React.Component { ); this.heights = {}; - this.state = { entries: this.view.list, vScroll: calcVScroll() }; + this.state = {entries: this.view.list, vScroll: calcVScroll()}; this.onChange = this.onChange.bind(this); this.onViewportUpdate = this.onViewportUpdate.bind(this); @@ -71,12 +71,12 @@ class EventLogContents extends React.Component { }); if (!shallowEqual(this.state.vScroll, vScroll)) { - this.setState({ vScroll }); + this.setState({vScroll}); } } onChange() { - this.setState({ entries: this.view.list }); + this.setState({entries: this.view.list}); } setHeight(id, ref) { @@ -90,7 +90,7 @@ class EventLogContents extends React.Component { } getIcon(level) { - return { web: "html5", debug: "bug" }[level] || "info"; + return {web: "html5", debug: "bug"}[level] || "info"; } render() { @@ -112,87 +112,59 @@ class EventLogContents extends React.Component { } } -ToggleFilter.propTypes = { - name: React.PropTypes.string.isRequired, - toggleLevel: React.PropTypes.func.isRequired, - active: React.PropTypes.bool, -}; - -function ToggleFilter ({ name, active, toggleLevel }) { - let className = "label "; - if (active) { - className += "label-primary"; - } else { - className += "label-default"; - } - - function onClick(event) { - event.preventDefault(); - toggleLevel(); - } - - return ( - - {name} - - ); -} - -const mapStateToProps = (state, ownProps) => { - return { - active: state.eventLog.visibilityFilter[ownProps.name] - } -}; - -const mapDispatchToProps = (dispatch, ownProps) => { - return { - toggleLevel: () => { - dispatch(toggleEventLogFilter(ownProps.name)) - } - } -}; - -const ToggleEventLogFilter = connect( - mapStateToProps, - mapDispatchToProps -)(ToggleFilter); +EventLogContents = AutoScroll(EventLogContents); -const AutoScrollEventLog = AutoScroll(EventLogContents); +const EventLogContentsContainer = connect( + state => ({ + filter: state.eventLog.filter + }) +)(EventLogContents); -const VisibleAutoScrollEventLog = connect( - function mapStateToProps(state, ownProps) { - return {filter: state.eventLog.visibilityFilter} - })(AutoScrollEventLog); +export const ToggleEventLog = connect( + state => ({ + checked: state.eventLog.visible + }), + dispatch => ({ + onToggle: () => dispatch(toggleEventLogVisibility()) + }) +)(ToggleButton); -var EventLog = React.createClass({ - close() { - var d = {}; - d[Query.SHOW_EVENTLOG] = undefined; - this.props.updateLocation(undefined, d); - }, - render() { - return ( -
-
- Eventlog -
- - - - -
+const ToggleFilter = connect( + (state, ownProps) => ({ + checked: state.eventLog.filter[ownProps.text] + }), + (dispatch, ownProps) => ({ + onToggle: () => dispatch(toggleEventLogFilter(ownProps.text)) + }) +)(ToggleButton); -
- + +const EventLog = ({close}) => +
+
+ Eventlog +
+ + + +
- ); - } -}); +
+ +
; -export default EventLog; +EventLog.propTypes = { + close: React.PropTypes.func.isRequired +}; + +const EventLogContainer = connect( + undefined, + dispatch => ({ + close: () => dispatch(toggleEventLogVisibility()) + }) +)(EventLog); + +export default EventLogContainer; diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js index 643659c37..76c4744a9 100644 --- a/web/src/js/components/header.js +++ b/web/src/js/components/header.js @@ -1,6 +1,7 @@ import React from "react"; import ReactDOM from 'react-dom'; import $ from "jquery"; +import {connect} from 'react-redux' import Filt from "../filt/filt.js"; import {Key} from "../utils.js"; @@ -8,6 +9,7 @@ import {ToggleInputButton, ToggleButton} from "./common.js"; import {SettingsActions, FlowActions} from "../actions.js"; import {Query} from "../actions.js"; import {SettingsState} from "./common.js"; +import {ToggleEventLog} from "./eventlog" var FilterDocs = React.createClass({ statics: { @@ -224,26 +226,11 @@ var ViewMenu = React.createClass({ title: "View", route: "flows" }, - toggleEventLog: function () { - var d = {}; - if (this.props.query[Query.SHOW_EVENTLOG]) { - d[Query.SHOW_EVENTLOG] = undefined; - } else { - d[Query.SHOW_EVENTLOG] = "t"; // any non-false value will do it, keep it short - } - - this.props.updateLocation(undefined, d); - console.log('toggleevent'); - }, render: function () { - var showEventLog = this.props.query[Query.SHOW_EVENTLOG]; return (
- +
diff --git a/web/src/js/components/proxyapp.js b/web/src/js/components/proxyapp.js index 4c790d3dc..99b64580b 100644 --- a/web/src/js/components/proxyapp.js +++ b/web/src/js/components/proxyapp.js @@ -1,6 +1,8 @@ import React from "react"; import ReactDOM from "react-dom"; import _ from "lodash"; +import {connect} from 'react-redux' +import { Route, Router as ReactRouter, hashHistory, Redirect} from "react-router" import {Splitter} from "./common.js" import MainView from "./mainview.js"; @@ -8,7 +10,6 @@ import Footer from "./footer.js"; import {Header, MainMenu} from "./header.js"; import EventLog from "./eventlog.js" import {EventLogStore, FlowStore, SettingsStore} from "../store/store.js"; -import {Query} from "../actions.js"; import {Key} from "../utils.js"; @@ -120,10 +121,10 @@ var ProxyAppMain = React.createClass({ render: function () { var query = this.getQuery(); var eventlog; - if (this.props.location.query[Query.SHOW_EVENTLOG]) { + if (this.props.showEventLog) { eventlog = [ , - + ]; } else { eventlog = null; @@ -142,13 +143,17 @@ var ProxyAppMain = React.createClass({ } }); +const AppContainer = connect( + state => ({ + showEventLog: state.eventLog.visible + }) +)(ProxyAppMain); -import { Route, Router as ReactRouter, hashHistory, Redirect} from "react-router"; export var App = ( - + diff --git a/web/src/js/ducks/README.md b/web/src/js/ducks/README.md new file mode 100644 index 000000000..9d005f35f --- /dev/null +++ b/web/src/js/ducks/README.md @@ -0,0 +1 @@ +https://github.com/erikras/ducks-modular-redux \ No newline at end of file diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js new file mode 100644 index 000000000..5bae252a0 --- /dev/null +++ b/web/src/js/ducks/eventLog.js @@ -0,0 +1,39 @@ +const TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER' +const TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY' + + +const defaultState = { + visible: false, + filter: { + "debug": false, + "info": true, + "web": true + } +} +export default function reducer(state = defaultState, action) { + switch (action.type) { + case TOGGLE_FILTER: + return { + ...state, + filter: { + ...state.filter, + [action.filter]: !state.filter[action.filter] + } + } + case TOGGLE_VISIBILITY: + return { + ...state, + visible: !state.visible + } + default: + return state + } +} + + +export function toggleEventLogFilter(filter) { + return {type: TOGGLE_FILTER, filter} +} +export function toggleEventLogVisibility() { + return {type: TOGGLE_VISIBILITY} +} \ No newline at end of file diff --git a/web/src/js/ducks/index.js b/web/src/js/ducks/index.js new file mode 100644 index 000000000..c82d42bb1 --- /dev/null +++ b/web/src/js/ducks/index.js @@ -0,0 +1,8 @@ +import {combineReducers} from 'redux' +import eventLog from './eventLog.js'; + +const rootReducer = combineReducers({ + eventLog +}) + +export default rootReducer \ No newline at end of file diff --git a/web/src/js/reducers/eventLog.js b/web/src/js/reducers/eventLog.js deleted file mode 100644 index 9d078c140..000000000 --- a/web/src/js/reducers/eventLog.js +++ /dev/null @@ -1,31 +0,0 @@ -import {combineReducers} from 'redux' -import {TOGGLE_EVENTLOG_FILTER} from "../reduxActions" - -const defaultVisibility = { - "debug": false, - "info": true, - "web": true -}; - -const visibilityFilter = (state = defaultVisibility, action) => { - switch (action.type) { - case TOGGLE_EVENTLOG_FILTER: - return { - ...state, - [action.filter]: !state[action.filter] - }; - default: - return state; - } -}; - -const entries = (state = [], action) => { - return state; -}; - -const eventLog = combineReducers({ - visibilityFilter, - entries -}); - -export default eventLog diff --git a/web/src/js/reduxActions.js b/web/src/js/reduxActions.js deleted file mode 100644 index c5902f80d..000000000 --- a/web/src/js/reduxActions.js +++ /dev/null @@ -1,13 +0,0 @@ -export const TOGGLE_EVENTLOG_FILTER = 'TOGGLE_EVENTLOG_FILTER'; -export const HIDE_EVENTLOG = 'HIDE_EVENTLOG'; -export const SHOW_EVENTLOG = 'SHOW_EVENTLOG'; - -export const EventLogFilters = { - DEBUG: 'debug', - INFO: 'info', - WEB: 'web' -}; - -export function toggleEventLogFilter(filter) { - return {type: TOGGLE_EVENTLOG_FILTER, filter} -}