diff options
Diffstat (limited to 'mitmproxy/tools')
-rw-r--r-- | mitmproxy/tools/console/flowview.py | 4 | ||||
-rw-r--r-- | mitmproxy/tools/console/master.py | 15 | ||||
-rw-r--r-- | mitmproxy/tools/console/statusbar.py | 43 | ||||
-rw-r--r-- | mitmproxy/tools/console/window.py | 2 | ||||
-rw-r--r-- | mitmproxy/tools/main.py | 9 | ||||
-rw-r--r-- | mitmproxy/tools/web/master.py | 4 | ||||
-rw-r--r-- | mitmproxy/tools/web/static/app.js | 4 |
7 files changed, 56 insertions, 25 deletions
diff --git a/mitmproxy/tools/console/flowview.py b/mitmproxy/tools/console/flowview.py index 9420c105..650a9366 100644 --- a/mitmproxy/tools/console/flowview.py +++ b/mitmproxy/tools/console/flowview.py @@ -30,12 +30,14 @@ class FlowViewHeader(urwid.WidgetWrap): self.focus_changed() def focus_changed(self): + cols, _ = self.master.ui.get_cols_rows() if self.master.view.focus.flow: self._w = common.format_flow( self.master.view.focus.flow, False, extended=True, - hostheader=self.master.options.showhost + hostheader=self.master.options.showhost, + max_url_len=cols, ) else: self._w = urwid.Pile([]) diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py index 5da6ef0b..de660b17 100644 --- a/mitmproxy/tools/console/master.py +++ b/mitmproxy/tools/console/master.py @@ -1,3 +1,4 @@ +import asyncio import mailcap import mimetypes import os @@ -94,7 +95,9 @@ class ConsoleMaster(master.Master): self.start_err = entry else: signals.status_message.send( - message=(entry.level, "{}: {}".format(entry.level.title(), entry.msg)), + message=(entry.level, + "{}: {}".format(entry.level.title(), + str(entry.msg).lstrip())), expire=5 ) @@ -180,12 +183,6 @@ class ConsoleMaster(master.Master): ) self.ui.clear() - def ticker(self, *userdata): - changed = self.tick(timeout=0) - if changed: - self.loop.draw_screen() - self.loop.set_alarm_in(0.01, self.ticker) - def inject_key(self, key): self.loop.process_input([key]) @@ -204,6 +201,7 @@ class ConsoleMaster(master.Master): ) self.loop = urwid.MainLoop( urwid.SolidFill("x"), + event_loop=urwid.AsyncioEventLoop(loop=asyncio.get_event_loop()), screen = self.ui, handle_mouse = self.options.console_mouse, ) @@ -212,8 +210,6 @@ class ConsoleMaster(master.Master): self.loop.widget = self.window self.window.refresh() - self.loop.set_alarm_in(0.01, self.ticker) - if self.start_err: def display_err(*_): self.sig_add_log(None, self.start_err) @@ -234,6 +230,7 @@ class ConsoleMaster(master.Master): finally: sys.stderr.flush() super().shutdown() + self.addons.trigger("done") def shutdown(self): raise urwid.ExitMainLoop diff --git a/mitmproxy/tools/console/statusbar.py b/mitmproxy/tools/console/statusbar.py index 8553a66f..fa987e94 100644 --- a/mitmproxy/tools/console/statusbar.py +++ b/mitmproxy/tools/console/statusbar.py @@ -49,7 +49,8 @@ class ActionBar(urwid.WidgetWrap): def sig_message(self, sender, message, expire=1): if self.prompting: return - w = urwid.Text(message) + cols, _ = self.master.ui.get_cols_rows() + w = urwid.Text(self.shorten_message(message, cols)) self._w = w if expire: def cb(*args): @@ -60,6 +61,36 @@ class ActionBar(urwid.WidgetWrap): def prep_prompt(self, p): return p.strip() + ": " + def shorten_message(self, msg, max_width): + """ + Shorten message so that it fits into a single line in the statusbar. + """ + if isinstance(msg, tuple): + disp_attr, msg_text = msg + elif isinstance(msg, str): + disp_attr, msg_text = None, msg + else: + return msg + msg_end = "\u2026" # unicode ellipsis for the end of shortened message + prompt = "(more in eventlog)" + + msg_lines = msg_text.split("\n") + first_line = msg_lines[0] + if len(msg_lines) > 1: + # First line of messages with a few lines must end with prompt. + line_length = len(first_line) + len(prompt) + else: + line_length = len(first_line) + + if line_length > max_width: + shortening_index = max(0, max_width - len(prompt) - len(msg_end)) + first_line = first_line[:shortening_index] + msg_end + else: + if len(msg_lines) == 1: + prompt = "" + + return [(disp_attr, first_line), ("warn", prompt)] + def sig_prompt(self, sender, prompt, text, callback, args=()): signals.focus.send(self, section="footer") self._w = urwid.Edit(self.prep_prompt(prompt), text or "") @@ -160,9 +191,7 @@ class StatusBar(urwid.WidgetWrap): r.append(("heading_key", "H")) r.append("eaders]") if len(self.master.options.replacements): - r.append("[") - r.append(("heading_key", "R")) - r.append("eplacing]") + r.append("[%d replacements]" % len(self.master.options.replacements)) if creplay.count(): r.append("[") r.append(("heading_key", "cplayback")) @@ -197,10 +226,8 @@ class StatusBar(urwid.WidgetWrap): r.append("[") r.append(("heading_key", "u")) r.append(":%s]" % self.master.options.stickyauth) - if self.master.options.console_default_contentview != "auto": - r.append("[") - r.append(("heading_key", "M")) - r.append(":%s]" % self.master.options.console_default_contentview) + if self.master.options.console_default_contentview != 'auto': + r.append("[contentview:%s]" % (self.master.options.console_default_contentview)) if self.master.options.has_changed("view_order"): r.append("[") r.append(("heading_key", "o")) diff --git a/mitmproxy/tools/console/window.py b/mitmproxy/tools/console/window.py index f2b6d3f4..7669299c 100644 --- a/mitmproxy/tools/console/window.py +++ b/mitmproxy/tools/console/window.py @@ -294,7 +294,7 @@ class Window(urwid.Frame): if not k: if args[1] == "mouse drag": signals.status_message.send( - message = "Hold down fn, shift, alt or ctrl to select text or use the --no-mouse parameter.", + message = "Hold down fn, shift, alt or ctrl to select text or use the --set console_mouse=false parameter.", expire = 1 ) elif args[1] == "mouse press" and args[2] == 4: diff --git a/mitmproxy/tools/main.py b/mitmproxy/tools/main.py index 330060f7..53c236bb 100644 --- a/mitmproxy/tools/main.py +++ b/mitmproxy/tools/main.py @@ -1,12 +1,13 @@ from __future__ import print_function # this is here for the version check to work on Python 2. +import asyncio import sys -if sys.version_info < (3, 5): +if sys.version_info < (3, 6): # This must be before any mitmproxy imports, as they already break! # Keep all other imports below with the 'noqa' magic comment. print("#" * 49, file=sys.stderr) - print("# mitmproxy only supports Python 3.5 and above! #", file=sys.stderr) + print("# mitmproxy requires Python 3.6 or higher! #", file=sys.stderr) print("#" * 49, file=sys.stderr) import argparse # noqa @@ -117,8 +118,10 @@ def run( def cleankill(*args, **kwargs): master.shutdown() - signal.signal(signal.SIGTERM, cleankill) + loop = asyncio.get_event_loop() + for signame in ('SIGINT', 'SIGTERM'): + loop.add_signal_handler(getattr(signal, signame), master.shutdown) master.run() except exceptions.OptionsError as e: print("%s: %s" % (sys.argv[0], e), file=sys.stderr) diff --git a/mitmproxy/tools/web/master.py b/mitmproxy/tools/web/master.py index 4c597f0e..b7eddcce 100644 --- a/mitmproxy/tools/web/master.py +++ b/mitmproxy/tools/web/master.py @@ -2,6 +2,8 @@ import webbrowser import tornado.httpserver import tornado.ioloop +from tornado.platform.asyncio import AsyncIOMainLoop + from mitmproxy import addons from mitmproxy import log from mitmproxy import master @@ -102,6 +104,7 @@ class WebMaster(master.Master): ) def run(self): # pragma: no cover + AsyncIOMainLoop().install() iol = tornado.ioloop.IOLoop.instance() @@ -109,7 +112,6 @@ class WebMaster(master.Master): http_server.listen(self.options.web_port, self.options.web_iface) iol.add_callback(self.start) - tornado.ioloop.PeriodicCallback(lambda: self.tick(timeout=0), 5).start() web_url = "http://{}:{}/".format(self.options.web_iface, self.options.web_port) self.add_log( diff --git a/mitmproxy/tools/web/static/app.js b/mitmproxy/tools/web/static/app.js index ace3106d..ac3be38c 100644 --- a/mitmproxy/tools/web/static/app.js +++ b/mitmproxy/tools/web/static/app.js @@ -86,7 +86,7 @@ "use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function FileMenu(e){var t=e.clearFlows,r=e.loadFlows,a=e.saveFlows,l=e.openModal;return _react2.default.createElement(_Dropdown2.default,{className:"pull-left",btnClass:"special",text:"mitmproxy"},_react2.default.createElement("a",{href:"#",onClick:function(e){return FileMenu.onNewClick(e,t)}},_react2.default.createElement("i",{className:"fa fa-fw fa-file"})," New"),_react2.default.createElement(_FileChooser2.default,{icon:"fa-folder-open",text:" Open...",onOpenFile:function(e){return r(e)}}),_react2.default.createElement("a",{href:"#",onClick:function(e){e.preventDefault(),a()}},_react2.default.createElement("i",{className:"fa fa-fw fa-floppy-o"})," Save..."),_react2.default.createElement(_HideInStatic2.default,null,_react2.default.createElement("a",{href:"#",onClick:function(e){e.preventDefault(),l()}},_react2.default.createElement("i",{className:"fa fa-fw fa-cog"})," Options"),_react2.default.createElement(_Dropdown.Divider,null),_react2.default.createElement("a",{href:"http://mitm.it/",target:"_blank"},_react2.default.createElement("i",{className:"fa fa-fw fa-external-link"})," Install Certificates...")))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileMenu=FileMenu;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_FileChooser=require("../common/FileChooser"),_FileChooser2=_interopRequireDefault(_FileChooser),_Dropdown=require("../common/Dropdown"),_Dropdown2=_interopRequireDefault(_Dropdown),_flows=require("../../ducks/flows"),flowsActions=_interopRequireWildcard(_flows),_modal=require("../../ducks/ui/modal"),modalActions=_interopRequireWildcard(_modal),_HideInStatic=require("../common/HideInStatic"),_HideInStatic2=_interopRequireDefault(_HideInStatic);FileMenu.propTypes={clearFlows:_propTypes2.default.func.isRequired,loadFlows:_propTypes2.default.func.isRequired,saveFlows:_propTypes2.default.func.isRequired,openModal:_propTypes2.default.func.isRequired},FileMenu.onNewClick=function(e,t){e.preventDefault(),confirm("Delete all flows?")&&t()},exports.default=(0,_reactRedux.connect)(null,{clearFlows:flowsActions.clear,loadFlows:flowsActions.upload,saveFlows:flowsActions.download,openModal:function(){return modalActions.setActiveModal("OptionModal")}})(FileMenu); },{"../../ducks/flows":57,"../../ducks/ui/modal":65,"../common/Dropdown":48,"../common/FileChooser":49,"../common/HideInStatic":50,"prop-types":"prop-types","react":"react","react-redux":"react-redux"}],30:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_utils=require("../../utils"),FilterDocs=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,r));return n.state={doc:t.doc},n}return _inherits(t,e),_createClass(t,[{key:"componentWillMount",value:function(){var e=this;t.xhr||(t.xhr=(0,_utils.fetchApi)("/filter-help").then(function(e){return e.json()}),t.xhr.catch(function(){t.xhr=null})),this.state.doc||t.xhr.then(function(r){t.doc=r,e.setState({doc:r})})}},{key:"render",value:function(){var e=this,t=this.state.doc;return t?_react2.default.createElement("table",{className:"table table-condensed"},_react2.default.createElement("tbody",null,t.commands.map(function(t){return _react2.default.createElement("tr",{key:t[1],onClick:function(r){return e.props.selectHandler(t[0].split(" ")[0]+" ")}},_react2.default.createElement("td",null,t[0].replace(" "," ")),_react2.default.createElement("td",null,t[1]))}),_react2.default.createElement("tr",{key:"docs-link"},_react2.default.createElement("td",{colSpan:"2"},_react2.default.createElement("a",{href:"http://docs.mitmproxy.org/en/stable/features/filters.html",target:"_blank"},_react2.default.createElement("i",{className:"fa fa-external-link"})," mitmproxy docs"))))):_react2.default.createElement("i",{className:"fa fa-spinner fa-spin"})}}]),t}(_react.Component);FilterDocs.xhr=null,FilterDocs.doc=null,exports.default=FilterDocs; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_utils=require("../../utils"),FilterDocs=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,r));return n.state={doc:t.doc},n}return _inherits(t,e),_createClass(t,[{key:"componentWillMount",value:function(){var e=this;t.xhr||(t.xhr=(0,_utils.fetchApi)("/filter-help").then(function(e){return e.json()}),t.xhr.catch(function(){t.xhr=null})),this.state.doc||t.xhr.then(function(r){t.doc=r,e.setState({doc:r})})}},{key:"render",value:function(){var e=this,t=this.state.doc;return t?_react2.default.createElement("table",{className:"table table-condensed"},_react2.default.createElement("tbody",null,t.commands.map(function(t){return _react2.default.createElement("tr",{key:t[1],onClick:function(r){return e.props.selectHandler(t[0].split(" ")[0]+" ")}},_react2.default.createElement("td",null,t[0].replace(" "," ")),_react2.default.createElement("td",null,t[1]))}),_react2.default.createElement("tr",{key:"docs-link"},_react2.default.createElement("td",{colSpan:"2"},_react2.default.createElement("a",{href:"https://mitmproxy.org/docs/latest/concepts-filters/",target:"_blank"},_react2.default.createElement("i",{className:"fa fa-external-link"})," mitmproxy docs"))))):_react2.default.createElement("i",{className:"fa fa-spinner fa-spin"})}}]),t}(_react.Component);FilterDocs.xhr=null,FilterDocs.doc=null,exports.default=FilterDocs; },{"../../utils":71,"react":"react"}],31:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_utils=require("../../utils.js"),_filt=require("../../filt/filt"),_filt2=_interopRequireDefault(_filt),_FilterDocs=require("./FilterDocs"),_FilterDocs2=_interopRequireDefault(_FilterDocs),FilterInput=function(e){function t(e,r){_classCallCheck(this,t);var o=_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,r));return o.state={value:o.props.value,focus:!1,mousefocus:!1},o.onChange=o.onChange.bind(o),o.onFocus=o.onFocus.bind(o),o.onBlur=o.onBlur.bind(o),o.onKeyDown=o.onKeyDown.bind(o),o.onMouseEnter=o.onMouseEnter.bind(o),o.onMouseLeave=o.onMouseLeave.bind(o),o.selectFilter=o.selectFilter.bind(o),o}return _inherits(t,e),_createClass(t,[{key:"componentWillReceiveProps",value:function(e){this.setState({value:e.value})}},{key:"isValid",value:function(e){try{var t=null==e?this.state.value:e;return t&&_filt2.default.parse(t),!0}catch(e){return!1}}},{key:"getDesc",value:function(){if(!this.state.value)return _react2.default.createElement(_FilterDocs2.default,{selectHandler:this.selectFilter});try{return _filt2.default.parse(this.state.value).desc}catch(e){return""+e}}},{key:"onChange",value:function(e){var t=e.target.value;this.setState({value:t}),this.isValid(t)&&this.props.onChange(t)}},{key:"onFocus",value:function(){this.setState({focus:!0})}},{key:"onBlur",value:function(){this.setState({focus:!1})}},{key:"onMouseEnter",value:function(){this.setState({mousefocus:!0})}},{key:"onMouseLeave",value:function(){this.setState({mousefocus:!1})}},{key:"onKeyDown",value:function(e){e.keyCode!==_utils.Key.ESC&&e.keyCode!==_utils.Key.ENTER||(this.blur(),this.setState({mousefocus:!1})),e.stopPropagation()}},{key:"selectFilter",value:function(e){this.setState({value:e}),_reactDom2.default.findDOMNode(this.refs.input).focus()}},{key:"blur",value:function(){_reactDom2.default.findDOMNode(this.refs.input).blur()}},{key:"select",value:function(){_reactDom2.default.findDOMNode(this.refs.input).select()}},{key:"render",value:function(){var e=this.props,t=e.type,r=e.color,o=e.placeholder,n=this.state,a=n.value,s=n.focus,u=n.mousefocus;return _react2.default.createElement("div",{className:(0,_classnames2.default)("filter-input input-group",{"has-error":!this.isValid()})},_react2.default.createElement("span",{className:"input-group-addon"},_react2.default.createElement("i",{className:"fa fa-fw fa-"+t,style:{color:r}})),_react2.default.createElement("input",{type:"text",ref:"input",placeholder:o,className:"form-control",value:a,onChange:this.onChange,onFocus:this.onFocus,onBlur:this.onBlur,onKeyDown:this.onKeyDown}),(s||u)&&_react2.default.createElement("div",{className:"popover bottom",onMouseEnter:this.onMouseEnter,onMouseLeave:this.onMouseLeave},_react2.default.createElement("div",{className:"arrow"}),_react2.default.createElement("div",{className:"popover-content"},this.getDesc())))}}]),t}(_react.Component);exports.default=FilterInput; @@ -137,7 +137,7 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function Button(e){var t=e.onClick,r=e.children,a=e.icon,s=e.disabled,l=e.className,i=e.title;return _react2.default.createElement("div",{className:(0,_classnames2.default)(l,"btn btn-default"),onClick:!s&&t,disabled:s,title:i},a&&_react2.default.createElement("i",{className:"fa fa-fw "+a}),r)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=Button;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames);Button.propTypes={onClick:_propTypes2.default.func.isRequired,children:_propTypes2.default.node.isRequired,icon:_propTypes2.default.string,title:_propTypes2.default.string}; },{"classnames":"classnames","prop-types":"prop-types","react":"react"}],47:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function DocsLink(e){var r=e.children,t=e.resource,a="http://docs.mitmproxy.org/en/stable/"+t;return _react2.default.createElement("a",{target:"_blank",href:a},r||_react2.default.createElement("i",{className:"fa fa-question-circle"}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=DocsLink;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes);DocsLink.propTypes={resource:_propTypes2.default.string.isRequired}; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function DocsLink(e){var r=e.children,t=e.resource,a="https://mitmproxy.org/docs/latest"+t;return _react2.default.createElement("a",{target:"_blank",href:a},r||_react2.default.createElement("i",{className:"fa fa-question-circle"}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=DocsLink;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes);DocsLink.propTypes={resource:_propTypes2.default.string.isRequired}; },{"prop-types":"prop-types","react":"react"}],48:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.Divider=void 0;var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),Divider=exports.Divider=function(){return _react2.default.createElement("hr",{className:"divider"})},Dropdown=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,r));return n.state={open:!1},n.close=n.close.bind(n),n.open=n.open.bind(n),n}return _inherits(t,e),_createClass(t,[{key:"close",value:function(){this.setState({open:!1}),document.removeEventListener("click",this.close)}},{key:"open",value:function(e){e.preventDefault(),this.state.open||(this.setState({open:!this.state.open}),document.addEventListener("click",this.close))}},{key:"render",value:function(){var e=this.props,t=e.dropup,r=e.className,n=e.btnClass,o=e.text,s=e.children;return _react2.default.createElement("div",{className:(0,_classnames2.default)(t?"dropup":"dropdown",r,{open:this.state.open})},_react2.default.createElement("a",{href:"#",className:n,onClick:this.open},o),_react2.default.createElement("ul",{className:"dropdown-menu",role:"menu"},s.map(function(e,t){return _react2.default.createElement("li",{key:t}," ",e," ")})))}}]),t}(_react.Component);Dropdown.propTypes={dropup:_propTypes2.default.bool,className:_propTypes2.default.string,btnClass:_propTypes2.default.string.isRequired},Dropdown.defaultProps={dropup:!1},exports.default=Dropdown; |