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";
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: {
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 ;
} else {
var commands = FilterDocs.doc.commands.map(function (c) {
return
{c[0].replace(" ", '\u00a0')} |
{c[1]} |
;
});
commands.push(
mitmproxy docs
|
);
return ;
}
}
});
var FilterInput = React.createClass({
contextTypes: {
returnFocus: React.PropTypes.func
},
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
// finalized, hiding the tooltip just as the user clicks on it.
return {
value: this.props.value,
focus: false,
mousefocus: false
};
},
componentWillReceiveProps: function (nextProps) {
this.setState({value: nextProps.value});
},
onChange: function (e) {
var nextValue = e.target.value;
this.setState({
value: nextValue
});
// Only propagate valid filters upwards.
if (this.isValid(nextValue)) {
this.props.onChange(nextValue);
}
},
isValid: function (filt) {
try {
var str = filt || this.state.value;
if(str){
Filt.parse(filt || this.state.value);
}
return true;
} catch (e) {
return false;
}
},
getDesc: function () {
if(this.state.value) {
try {
return Filt.parse(this.state.value).desc;
} catch (e) {
return "" + e;
}
}
return ;
},
onFocus: function () {
this.setState({focus: true});
},
onBlur: function () {
this.setState({focus: false});
},
onMouseEnter: function () {
this.setState({mousefocus: true});
},
onMouseLeave: function () {
this.setState({mousefocus: false});
},
onKeyDown: function (e) {
if (e.keyCode === Key.ESC || e.keyCode === Key.ENTER) {
this.blur();
// If closed using ESC/ENTER, hide the tooltip.
this.setState({mousefocus: false});
}
e.stopPropagation();
},
blur: function () {
ReactDOM.findDOMNode(this.refs.input).blur();
this.context.returnFocus();
},
select: function () {
ReactDOM.findDOMNode(this.refs.input).select();
},
render: function () {
var isValid = this.isValid();
var icon = "fa fa-fw fa-" + this.props.type;
var groupClassName = "filter-input input-group" + (isValid ? "" : " has-error");
var popover;
if (this.state.focus || this.state.mousefocus) {
popover = (
);
}
return (
{popover}
);
}
});
export var MainMenu = React.createClass({
propTypes: {
settings: React.PropTypes.object.isRequired,
},
statics: {
title: "Start",
route: "flows"
},
onSearchChange: function (val) {
var d = {};
d[Query.SEARCH] = val;
this.props.updateLocation(undefined, d);
},
onHighlightChange: function (val) {
var d = {};
d[Query.HIGHLIGHT] = val;
this.props.updateLocation(undefined, d);
},
onInterceptChange: function (val) {
SettingsActions.update({intercept: val});
},
render: function () {
var search = this.props.query[Query.SEARCH] || "";
var highlight = this.props.query[Query.HIGHLIGHT] || "";
var intercept = this.props.settings.intercept || "";
return (
);
}
});
var ViewMenu = React.createClass({
statics: {
title: "View",
route: "flows"
},
render: function () {
return (
);
}
});
export const OptionMenu = (props) => {
const {mode, intercept, showhost, no_upstream_cert, rawtcp, http2, anticache, anticomp, stickycookie, stickyauth, stream} = props.settings;
return (
SettingsActions.update({showhost: !showhost})}
/>
SettingsActions.update({no_upstream_cert: !no_upstream_cert})}
/>
SettingsActions.update({rawtcp: !rawtcp})}
/>
SettingsActions.update({http2: !http2})}
/>
SettingsActions.update({anticache: !anticache})}
/>
SettingsActions.update({anticomp: !anticomp})}
/>
SettingsActions.update({stickyauth: (!stickyauth ? txt : null)})}
/>
SettingsActions.update({stickycookie: (!stickycookie ? txt : null)})}
/>
SettingsActions.update({stream: (!stream ? txt : null)})}
/>
);
};
OptionMenu.title = "Options";
OptionMenu.propTypes = {
settings: React.PropTypes.object.isRequired
};
var ReportsMenu = React.createClass({
statics: {
title: "Visualization",
route: "reports"
},
render: function () {
return Reports Menu
;
}
});
var FileMenu = React.createClass({
getInitialState: function () {
return {
showFileMenu: false
};
},
handleFileClick: function (e) {
e.preventDefault();
if (!this.state.showFileMenu) {
var close = function () {
this.setState({showFileMenu: false});
document.removeEventListener("click", close);
}.bind(this);
document.addEventListener("click", close);
this.setState({
showFileMenu: true
});
}
},
handleNewClick: function (e) {
e.preventDefault();
if (confirm("Delete all flows?")) {
FlowActions.clear();
}
},
handleOpenClick: function (e) {
e.preventDefault();
console.error("unimplemented: handleOpenClick");
},
handleSaveClick: function (e) {
e.preventDefault();
console.error("unimplemented: handleSaveClick");
},
handleShutdownClick: function (e) {
e.preventDefault();
console.error("unimplemented: handleShutdownClick");
},
render: function () {
var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : "");
return (
);
}
});
var header_entries = [MainMenu, ViewMenu, OptionMenu /*, ReportsMenu */];
export var Header = React.createClass({
propTypes: {
settings: React.PropTypes.object.isRequired,
},
getInitialState: function () {
return {
active: header_entries[0]
};
},
handleClick: function (active, e) {
e.preventDefault();
this.props.updateLocation(active.route);
this.setState({active: active});
},
render: function () {
var header = header_entries.map(function (entry, i) {
var className;
if (entry === this.state.active) {
className = "active";
} else {
className = "";
}
return (
{entry.title}
);
}.bind(this));
return (
);
}
});