diff options
| author | Maximilian Hils <git@maximilianhils.com> | 2016-02-15 14:58:46 +0100 | 
|---|---|---|
| committer | Maximilian Hils <git@maximilianhils.com> | 2016-02-15 14:58:46 +0100 | 
| commit | 33fa49277a821b9d38e8c9bf0bcf2adcfa2f6f04 (patch) | |
| tree | 31914a601302579ff817504019296fd7e9e46765 /web/src/js | |
| parent | 36f34f701991b5d474c005ec45e3b66e20f326a8 (diff) | |
| download | mitmproxy-33fa49277a821b9d38e8c9bf0bcf2adcfa2f6f04.tar.gz mitmproxy-33fa49277a821b9d38e8c9bf0bcf2adcfa2f6f04.tar.bz2 mitmproxy-33fa49277a821b9d38e8c9bf0bcf2adcfa2f6f04.zip  | |
move mitmproxy
Diffstat (limited to 'web/src/js')
27 files changed, 0 insertions, 5688 deletions
diff --git a/web/src/js/actions.js b/web/src/js/actions.js deleted file mode 100644 index 2455a52e..00000000 --- a/web/src/js/actions.js +++ /dev/null @@ -1,137 +0,0 @@ -var $ = require("jquery"); -var _ = require("lodash"); -var AppDispatcher = require("./dispatcher.js").AppDispatcher; - -var ActionTypes = { -    // Connection -    CONNECTION_OPEN: "connection_open", -    CONNECTION_CLOSE: "connection_close", -    CONNECTION_ERROR: "connection_error", - -    // Stores -    SETTINGS_STORE: "settings", -    EVENT_STORE: "events", -    FLOW_STORE: "flows", -}; - -var StoreCmds = { -    ADD: "add", -    UPDATE: "update", -    REMOVE: "remove", -    RESET: "reset" -}; - -var ConnectionActions = { -    open: function () { -        AppDispatcher.dispatchViewAction({ -            type: ActionTypes.CONNECTION_OPEN -        }); -    }, -    close: function () { -        AppDispatcher.dispatchViewAction({ -            type: ActionTypes.CONNECTION_CLOSE -        }); -    }, -    error: function () { -        AppDispatcher.dispatchViewAction({ -            type: ActionTypes.CONNECTION_ERROR -        }); -    } -}; - -var SettingsActions = { -    update: function (settings) { - -        $.ajax({ -            type: "PUT", -            url: "/settings", -            contentType: 'application/json', -            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 -        }); -        */ -    } -}; - -var EventLogActions_event_id = 0; -var EventLogActions = { -    add_event: function (message) { -        AppDispatcher.dispatchViewAction({ -            type: ActionTypes.EVENT_STORE, -            cmd: StoreCmds.ADD, -            data: { -                message: message, -                level: "web", -                id: "viewAction-" + EventLogActions_event_id++ -            } -        }); -    } -}; - -var FlowActions = { -    accept: function (flow) { -        $.post("/flows/" + flow.id + "/accept"); -    }, -    accept_all: function(){ -        $.post("/flows/accept"); -    }, -    "delete": function(flow){ -        $.ajax({ -            type:"DELETE", -            url: "/flows/" + flow.id -        }); -    }, -    duplicate: function(flow){ -        $.post("/flows/" + flow.id + "/duplicate"); -    }, -    replay: function(flow){ -        $.post("/flows/" + flow.id + "/replay"); -    }, -    revert: function(flow){ -        $.post("/flows/" + flow.id + "/revert"); -    }, -    update: function (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 -        }); -        */ -        $.ajax({ -            type: "PUT", -            url: "/flows/" + flow.id, -            contentType: 'application/json', -            data: JSON.stringify(nextProps) -        }); -    }, -    clear: function(){ -        $.post("/clear"); -    } -}; - -var Query = { -    SEARCH: "s", -    HIGHLIGHT: "h", -    SHOW_EVENTLOG: "e" -}; - -module.exports = { -    ActionTypes: ActionTypes, -    ConnectionActions: ConnectionActions, -    FlowActions: FlowActions, -    StoreCmds: StoreCmds, -    SettingsActions: SettingsActions, -    EventLogActions: EventLogActions, -    Query: Query -};
\ No newline at end of file diff --git a/web/src/js/app.js b/web/src/js/app.js deleted file mode 100644 index 9fb868b8..00000000 --- a/web/src/js/app.js +++ /dev/null @@ -1,19 +0,0 @@ -var React = require("react"); -var ReactRouter = require("react-router"); -var $ = require("jquery"); -var Connection = require("./connection"); -var proxyapp = require("./components/proxyapp.js"); -var EventLogActions = require("./actions.js").EventLogActions; - -$(function () { -    window.ws = new Connection("/updates"); - -    window.onerror = function (msg) { -        EventLogActions.add_event(msg); -    }; - -    ReactRouter.run(proxyapp.routes, function (Handler, state) { -        React.render(<Handler/>, document.body); -    }); -}); - diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js deleted file mode 100644 index 965ae9a7..00000000 --- a/web/src/js/components/common.js +++ /dev/null @@ -1,219 +0,0 @@ -var React = require("react"); -var ReactRouter = require("react-router"); -var _ = require("lodash"); - -// http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) -var AutoScrollMixin = { -    componentWillUpdate: function () { -        var node = this.getDOMNode(); -        this._shouldScrollBottom = ( -        node.scrollTop !== 0 && -        node.scrollTop + node.clientHeight === node.scrollHeight -        ); -    }, -    componentDidUpdate: function () { -        if (this._shouldScrollBottom) { -            var node = this.getDOMNode(); -            node.scrollTop = node.scrollHeight; -        } -    }, -}; - - -var StickyHeadMixin = { -    adjustHead: function () { -        // Abusing CSS transforms to set the element -        // referenced as head into some kind of position:sticky. -        var head = this.refs.head.getDOMNode(); -        head.style.transform = "translate(0," + this.getDOMNode().scrollTop + "px)"; -    } -}; - -var SettingsState = { -    contextTypes: { -        settingsStore: React.PropTypes.object.isRequired -    }, -    getInitialState: function () { -        return { -            settings: this.context.settingsStore.dict -        }; -    }, -    componentDidMount: function () { -        this.context.settingsStore.addListener("recalculate", this.onSettingsChange); -    }, -    componentWillUnmount: function () { -        this.context.settingsStore.removeListener("recalculate", this.onSettingsChange); -    }, -    onSettingsChange: function () { -        this.setState({ -            settings: this.context.settingsStore.dict -        }); -    }, -}; - - -var ChildFocus = { -    contextTypes: { -        returnFocus: React.PropTypes.func -    }, -    returnFocus: function(){ -        React.findDOMNode(this).blur(); -        window.getSelection().removeAllRanges(); -        this.context.returnFocus(); -    } -}; - - -var Navigation = _.extend({}, ReactRouter.Navigation, { -    setQuery: function (dict) { -        var q = this.context.router.getCurrentQuery(); -        for (var i in dict) { -            if (dict.hasOwnProperty(i)) { -                q[i] = dict[i] || undefined; //falsey values shall be removed. -            } -        } -        this.replaceWith(this.context.router.getCurrentPath(), this.context.router.getCurrentParams(), q); -    }, -    replaceWith: function (routeNameOrPath, params, query) { -        if (routeNameOrPath === undefined) { -            routeNameOrPath = this.context.router.getCurrentPath(); -        } -        if (params === undefined) { -            params = this.context.router.getCurrentParams(); -        } -        if (query === undefined) { -            query = this.context.router.getCurrentQuery(); -        } - -        this.context.router.replaceWith(routeNameOrPath, params, 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. -var RouterState = _.extend({}, ReactRouter.State, { -    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.router.getCurrentQuery()); -    }, -    getParams: function () { -        return _.clone(this.context.router.getCurrentParams()); -    } -}); - -var Splitter = React.createClass({ -    getDefaultProps: function () { -        return { -            axis: "x" -        }; -    }, -    getInitialState: function () { -        return { -            applied: false, -            startX: false, -            startY: false -        }; -    }, -    onMouseDown: function (e) { -        this.setState({ -            startX: e.pageX, -            startY: e.pageY -        }); -        window.addEventListener("mousemove", this.onMouseMove); -        window.addEventListener("mouseup", this.onMouseUp); -        // Occasionally, only a dragEnd event is triggered, but no mouseUp. -        window.addEventListener("dragend", this.onDragEnd); -    }, -    onDragEnd: function () { -        this.getDOMNode().style.transform = ""; -        window.removeEventListener("dragend", this.onDragEnd); -        window.removeEventListener("mouseup", this.onMouseUp); -        window.removeEventListener("mousemove", this.onMouseMove); -    }, -    onMouseUp: function (e) { -        this.onDragEnd(); - -        var node = this.getDOMNode(); -        var prev = node.previousElementSibling; -        var next = node.nextElementSibling; - -        var dX = e.pageX - this.state.startX; -        var dY = e.pageY - this.state.startY; -        var flexBasis; -        if (this.props.axis === "x") { -            flexBasis = prev.offsetWidth + dX; -        } else { -            flexBasis = prev.offsetHeight + dY; -        } - -        prev.style.flex = "0 0 " + Math.max(0, flexBasis) + "px"; -        next.style.flex = "1 1 auto"; - -        this.setState({ -            applied: true -        }); -        this.onResize(); -    }, -    onMouseMove: function (e) { -        var dX = 0, dY = 0; -        if (this.props.axis === "x") { -            dX = e.pageX - this.state.startX; -        } else { -            dY = e.pageY - this.state.startY; -        } -        this.getDOMNode().style.transform = "translate(" + dX + "px," + dY + "px)"; -    }, -    onResize: function () { -        // Trigger a global resize event. This notifies components that employ virtual scrolling -        // that their viewport may have changed. -        window.setTimeout(function () { -            window.dispatchEvent(new CustomEvent("resize")); -        }, 1); -    }, -    reset: function (willUnmount) { -        if (!this.state.applied) { -            return; -        } -        var node = this.getDOMNode(); -        var prev = node.previousElementSibling; -        var next = node.nextElementSibling; - -        prev.style.flex = ""; -        next.style.flex = ""; - -        if (!willUnmount) { -            this.setState({ -                applied: false -            }); -        } -        this.onResize(); -    }, -    componentWillUnmount: function () { -        this.reset(true); -    }, -    render: function () { -        var className = "splitter"; -        if (this.props.axis === "x") { -            className += " splitter-x"; -        } else { -            className += " splitter-y"; -        } -        return ( -            <div className={className}> -                <div onMouseDown={this.onMouseDown} draggable="true"></div> -            </div> -        ); -    } -}); - -module.exports = { -    ChildFocus: ChildFocus, -    RouterState: RouterState, -    Navigation: Navigation, -    StickyHeadMixin: StickyHeadMixin, -    AutoScrollMixin: AutoScrollMixin, -    Splitter: Splitter, -    SettingsState: SettingsState -};
\ No newline at end of file diff --git a/web/src/js/components/editor.js b/web/src/js/components/editor.js deleted file mode 100644 index f2d44566..00000000 --- a/web/src/js/components/editor.js +++ /dev/null @@ -1,240 +0,0 @@ -var React = require("react"); -var common = require("./common.js"); -var utils = require("../utils.js"); - -var contentToHtml = function (content) { -    return _.escape(content); -}; -var nodeToContent = function (node) { -    return node.textContent; -}; - -/* - Basic Editor Functionality - */ -var EditorBase = React.createClass({ -    propTypes: { -        content: React.PropTypes.string.isRequired, -        onDone: React.PropTypes.func.isRequired, -        contentToHtml: React.PropTypes.func, -        nodeToContent: React.PropTypes.func, // content === nodeToContent( Node<innerHTML=contentToHtml(content)> ) -        onStop: React.PropTypes.func, -        submitOnEnter: React.PropTypes.bool, -        className: React.PropTypes.string, -        tag: React.PropTypes.string -    }, -    getDefaultProps: function () { -        return { -            contentToHtml: contentToHtml, -            nodeToContent: nodeToContent, -            submitOnEnter: true, -            className: "", -            tag: "div" -        }; -    }, -    getInitialState: function () { -        return { -            editable: false -        }; -    }, -    render: function () { -        var className = "inline-input " + this.props.className; -        var html = {__html: this.props.contentToHtml(this.props.content)}; -        var Tag = this.props.tag; -        return <Tag -            {...this.props} -            tabIndex="0" -            className={className} -            contentEditable={this.state.editable || undefined } // workaround: use undef instead of false to remove attr -            onFocus={this.onFocus} -            onMouseDown={this.onMouseDown} -            onClick={this.onClick} -            onBlur={this._stop} -            onKeyDown={this.onKeyDown} -            onInput={this.onInput} -            onPaste={this.onPaste} -            dangerouslySetInnerHTML={html} -        />; -    }, -    onPaste: function (e) { -        e.preventDefault(); -        var content = e.clipboardData.getData("text/plain"); -        document.execCommand("insertHTML", false, content); -    }, -    onMouseDown: function (e) { -        this._mouseDown = true; -        window.addEventListener("mouseup", this.onMouseUp); -        this.props.onMouseDown && this.props.onMouseDown(e); -    }, -    onMouseUp: function () { -        if (this._mouseDown) { -            this._mouseDown = false; -            window.removeEventListener("mouseup", this.onMouseUp) -        } -    }, -    onClick: function (e) { -        this.onMouseUp(); -        this.onFocus(e); -    }, -    onFocus: function (e) { -        console.log("onFocus", this._mouseDown, this._ignore_events, this.state.editable); -        if (this._mouseDown || this._ignore_events || this.state.editable) { -            return; -        } - -        //contenteditable in FireFox is more or less broken. -        // - we need to blur() and then focus(), otherwise the caret is not shown. -        // - blur() + focus() == we need to save the caret position before -        //   Firefox sometimes just doesn't set a caret position => use caretPositionFromPoint -        var sel = window.getSelection(); -        var range; -        if (sel.rangeCount > 0) { -            range = sel.getRangeAt(0); -        } else if (document.caretPositionFromPoint && e.clientX && e.clientY) { -            var pos = document.caretPositionFromPoint(e.clientX, e.clientY); -            range = document.createRange(); -            range.setStart(pos.offsetNode, pos.offset); -        } else if (document.caretRangeFromPoint && e.clientX && e.clientY) { -            range = document.caretRangeFromPoint(e.clientX, e.clientY); -        } else { -            range = document.createRange(); -            range.selectNodeContents(React.findDOMNode(this)); -        } - -        this._ignore_events = true; -        this.setState({editable: true}, function () { -            var node = React.findDOMNode(this); -            node.blur(); -            node.focus(); -            this._ignore_events = false; -            //sel.removeAllRanges(); -            //sel.addRange(range); - - -        }); -    }, -    stop: function () { -        // a stop would cause a blur as a side-effect. -        // but a blur event must trigger a stop as well. -        // to fix this, make stop = blur and do the actual stop in the onBlur handler. -        React.findDOMNode(this).blur(); -        this.props.onStop && this.props.onStop(); -    }, -    _stop: function (e) { -        if (this._ignore_events) { -            return; -        } -        console.log("_stop", _.extend({}, e)); -        window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur -        var node = React.findDOMNode(this); -        var content = this.props.nodeToContent(node); -        this.setState({editable: false}); -        this.props.onDone(content); -        this.props.onBlur && this.props.onBlur(e); -    }, -    reset: function () { -        React.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content); -    }, -    onKeyDown: function (e) { -        e.stopPropagation(); -        switch (e.keyCode) { -            case utils.Key.ESC: -                e.preventDefault(); -                this.reset(); -                this.stop(); -                break; -            case utils.Key.ENTER: -                if (this.props.submitOnEnter && !e.shiftKey) { -                    e.preventDefault(); -                    this.stop(); -                } -                break; -            default: -                break; -        } -    }, -    onInput: function () { -        var node = React.findDOMNode(this); -        var content = this.props.nodeToContent(node); -        this.props.onInput && this.props.onInput(content); -    } -}); - -/* - Add Validation to EditorBase - */ -var ValidateEditor = React.createClass({ -    propTypes: { -        content: React.PropTypes.string.isRequired, -        onDone: React.PropTypes.func.isRequired, -        onInput: React.PropTypes.func, -        isValid: React.PropTypes.func, -        className: React.PropTypes.string, -    }, -    getInitialState: function () { -        return { -            currentContent: this.props.content -        }; -    }, -    componentWillReceiveProps: function () { -        this.setState({currentContent: this.props.content}); -    }, -    onInput: function (content) { -        this.setState({currentContent: content}); -        this.props.onInput && this.props.onInput(content); -    }, -    render: function () { -        var className = this.props.className || ""; -        if (this.props.isValid) { -            if (this.props.isValid(this.state.currentContent)) { -                className += " has-success"; -            } else { -                className += " has-warning" -            } -        } -        return <EditorBase -            {...this.props} -            ref="editor" -            className={className} -            onDone={this.onDone} -            onInput={this.onInput} -        />; -    }, -    onDone: function (content) { -        if (this.props.isValid && !this.props.isValid(content)) { -            this.refs.editor.reset(); -            content = this.props.content; -        } -        this.props.onDone(content); -    } -}); - -/* - Text Editor with mitmweb-specific convenience features - */ -var ValueEditor = React.createClass({ -    mixins: [common.ChildFocus], -    propTypes: { -        content: React.PropTypes.string.isRequired, -        onDone: React.PropTypes.func.isRequired, -        inline: React.PropTypes.bool, -    }, -    render: function () { -        var tag = this.props.inline ? "span" : "div"; -        return <ValidateEditor -            {...this.props} -            onStop={this.onStop} -            tag={tag} -        />; -    }, -    focus: function () { -        React.findDOMNode(this).focus(); -    }, -    onStop: function () { -        this.returnFocus(); -    } -}); - -module.exports = { -    ValueEditor: ValueEditor -};
\ No newline at end of file diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js deleted file mode 100644 index fea7b247..00000000 --- a/web/src/js/components/eventlog.js +++ /dev/null @@ -1,150 +0,0 @@ -var React = require("react"); -var common = require("./common.js"); -var Query = require("../actions.js").Query; -var VirtualScrollMixin = require("./virtualscroll.js"); -var views = require("../store/view.js"); -var _ = require("lodash"); - -var LogMessage = React.createClass({ -    render: function () { -        var entry = this.props.entry; -        var indicator; -        switch (entry.level) { -            case "web": -                indicator = <i className="fa fa-fw fa-html5"></i>; -                break; -            case "debug": -                indicator = <i className="fa fa-fw fa-bug"></i>; -                break; -            default: -                indicator = <i className="fa fa-fw fa-info"></i>; -        } -        return ( -            <div> -                { indicator } {entry.message} -            </div> -        ); -    }, -    shouldComponentUpdate: function () { -        return false; // log entries are immutable. -    } -}); - -var EventLogContents = React.createClass({ -    contextTypes: { -        eventStore: React.PropTypes.object.isRequired -    }, -    mixins: [common.AutoScrollMixin, VirtualScrollMixin], -    getInitialState: function () { -        var filterFn = function (entry) { -            return this.props.filter[entry.level]; -        }; -        var view = new views.StoreView(this.context.eventStore, filterFn.bind(this)); -        view.addListener("add", this.onEventLogChange); -        view.addListener("recalculate", this.onEventLogChange); - -        return { -            view: view -        }; -    }, -    componentWillUnmount: function () { -        this.state.view.close(); -    }, -    filter: function (entry) { -        return this.props.filter[entry.level]; -    }, -    onEventLogChange: function () { -        this.forceUpdate(); -    }, -    componentWillReceiveProps: function (nextProps) { -        if (nextProps.filter !== this.props.filter) { -            this.props.filter = nextProps.filter; // Dirty: Make sure that view filter sees the update. -            this.state.view.recalculate(); -        } -    }, -    getDefaultProps: function () { -        return { -            rowHeight: 45, -            rowHeightMin: 15, -            placeholderTagName: "div" -        }; -    }, -    renderRow: function (elem) { -        return <LogMessage key={elem.id} entry={elem}/>; -    }, -    render: function () { -        var entries = this.state.view.list; -        var rows = this.renderRows(entries); - -        return <pre onScroll={this.onScroll}> -            { this.getPlaceholderTop(entries.length) } -            {rows} -            { this.getPlaceholderBottom(entries.length) } -        </pre>; -    } -}); - -var ToggleFilter = React.createClass({ -    toggle: function (e) { -        e.preventDefault(); -        return this.props.toggleLevel(this.props.name); -    }, -    render: function () { -        var className = "label "; -        if (this.props.active) { -            className += "label-primary"; -        } else { -            className += "label-default"; -        } -        return ( -            <a -                href="#" -                className={className} -                onClick={this.toggle}> -                {this.props.name} -            </a> -        ); -    } -}); - -var EventLog = React.createClass({ -    mixins: [common.Navigation], -    getInitialState: function () { -        return { -            filter: { -                "debug": false, -                "info": true, -                "web": true -            } -        }; -    }, -    close: function () { -        var d = {}; -        d[Query.SHOW_EVENTLOG] = undefined; -        this.setQuery(d); -    }, -    toggleLevel: function (level) { -        var filter = _.extend({}, this.state.filter); -        filter[level] = !filter[level]; -        this.setState({filter: filter}); -    }, -    render: function () { -        return ( -            <div className="eventlog"> -                <div> -                    Eventlog -                    <div className="pull-right"> -                        <ToggleFilter name="debug" active={this.state.filter.debug} toggleLevel={this.toggleLevel}/> -                        <ToggleFilter name="info" active={this.state.filter.info} toggleLevel={this.toggleLevel}/> -                        <ToggleFilter name="web" active={this.state.filter.web} toggleLevel={this.toggleLevel}/> -                        <i onClick={this.close} className="fa fa-close"></i> -                    </div> - -                </div> -                <EventLogContents filter={this.state.filter}/> -            </div> -        ); -    } -}); - -module.exports = EventLog;
\ No newline at end of file diff --git a/web/src/js/components/flowtable-columns.js b/web/src/js/components/flowtable-columns.js deleted file mode 100644 index 74d96216..00000000 --- a/web/src/js/components/flowtable-columns.js +++ /dev/null @@ -1,201 +0,0 @@ -var React = require("react"); -var RequestUtils = require("../flow/utils.js").RequestUtils; -var ResponseUtils = require("../flow/utils.js").ResponseUtils; -var utils = require("../utils.js"); - -var TLSColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-tls " + (this.props.className || "") }></th>; -            } -        }), -        sortKeyFun: function(flow){ -            return flow.request.scheme; -        } -    }, -    render: function () { -        var flow = this.props.flow; -        var ssl = (flow.request.scheme === "https"); -        var classes; -        if (ssl) { -            classes = "col-tls col-tls-https"; -        } else { -            classes = "col-tls col-tls-http"; -        } -        return <td className={classes}></td>; -    } -}); - - -var IconColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-icon " + (this.props.className || "") }></th>; -            } -        }) -    }, -    render: function () { -        var flow = this.props.flow; - -        var icon; -        if (flow.response) { -            var contentType = ResponseUtils.getContentType(flow.response); - -            //TODO: We should assign a type to the flow somewhere else. -            if (flow.response.status_code === 304) { -                icon = "resource-icon-not-modified"; -            } else if (300 <= flow.response.status_code && flow.response.status_code < 400) { -                icon = "resource-icon-redirect"; -            } else if (contentType && contentType.indexOf("image") >= 0) { -                icon = "resource-icon-image"; -            } else if (contentType && contentType.indexOf("javascript") >= 0) { -                icon = "resource-icon-js"; -            } else if (contentType && contentType.indexOf("css") >= 0) { -                icon = "resource-icon-css"; -            } else if (contentType && contentType.indexOf("html") >= 0) { -                icon = "resource-icon-document"; -            } -        } -        if (!icon) { -            icon = "resource-icon-plain"; -        } - - -        icon += " resource-icon"; -        return <td className="col-icon"> -            <div className={icon}></div> -        </td>; -    } -}); - -var PathColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-path " + (this.props.className || "") }>Path</th>; -            } -        }), -        sortKeyFun: function(flow){ -            return RequestUtils.pretty_url(flow.request); -        } -    }, -    render: function () { -        var flow = this.props.flow; -        return <td className="col-path"> -            {flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null} -            {flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null} -            { RequestUtils.pretty_url(flow.request) } -        </td>; -    } -}); - - -var MethodColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-method " + (this.props.className || "") }>Method</th>; -            } -        }), -        sortKeyFun: function(flow){ -            return flow.request.method; -        } -    }, -    render: function () { -        var flow = this.props.flow; -        return <td className="col-method">{flow.request.method}</td>; -    } -}); - - -var StatusColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-status " + (this.props.className || "") }>Status</th>; -            } -        }), -        sortKeyFun: function(flow){ -            return flow.response ? flow.response.status_code : undefined; -        } -    }, -    render: function () { -        var flow = this.props.flow; -        var status; -        if (flow.response) { -            status = flow.response.status_code; -        } else { -            status = null; -        } -        return <td className="col-status">{status}</td>; -    } -}); - - -var SizeColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-size " + (this.props.className || "") }>Size</th>; -            } -        }), -        sortKeyFun: function(flow){ -            var total = flow.request.contentLength; -            if (flow.response) { -                total += flow.response.contentLength || 0; -            } -            return total; -        } -    }, -    render: function () { -        var flow = this.props.flow; - -        var total = flow.request.contentLength; -        if (flow.response) { -            total += flow.response.contentLength || 0; -        } -        var size = utils.formatSize(total); -        return <td className="col-size">{size}</td>; -    } -}); - - -var TimeColumn = React.createClass({ -    statics: { -        Title: React.createClass({ -            render: function(){ -                return <th {...this.props} className={"col-time " + (this.props.className || "") }>Time</th>; -            } -        }), -        sortKeyFun: function(flow){ -            if(flow.response) { -                return flow.response.timestamp_end - flow.request.timestamp_start; -            } -        } -    }, -    render: function () { -        var flow = this.props.flow; -        var time; -        if (flow.response) { -            time = utils.formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start)); -        } else { -            time = "..."; -        } -        return <td className="col-time">{time}</td>; -    } -}); - - -var all_columns = [ -    TLSColumn, -    IconColumn, -    PathColumn, -    MethodColumn, -    StatusColumn, -    SizeColumn, -    TimeColumn -]; - -module.exports = all_columns; diff --git a/web/src/js/components/flowtable.js b/web/src/js/components/flowtable.js deleted file mode 100644 index 609034f6..00000000 --- a/web/src/js/components/flowtable.js +++ /dev/null @@ -1,187 +0,0 @@ -var React = require("react"); -var common = require("./common.js"); -var utils = require("../utils.js"); -var _ = require("lodash"); - -var VirtualScrollMixin = require("./virtualscroll.js"); -var flowtable_columns = require("./flowtable-columns.js"); - -var FlowRow = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        var columns = this.props.columns.map(function (Column) { -            return <Column key={Column.displayName} flow={flow}/>; -        }.bind(this)); -        var className = ""; -        if (this.props.selected) { -            className += " selected"; -        } -        if (this.props.highlighted) { -            className += " highlighted"; -        } -        if (flow.intercepted) { -            className += " intercepted"; -        } -        if (flow.request) { -            className += " has-request"; -        } -        if (flow.response) { -            className += " has-response"; -        } - -        return ( -            <tr className={className} onClick={this.props.selectFlow.bind(null, flow)}> -                {columns} -            </tr>); -    }, -    shouldComponentUpdate: function (nextProps) { -        return true; -        // Further optimization could be done here -        // by calling forceUpdate on flow updates, selection changes and column changes. -        //return ( -        //(this.props.columns.length !== nextProps.columns.length) || -        //(this.props.selected !== nextProps.selected) -        //); -    } -}); - -var FlowTableHead = React.createClass({ -    getInitialState: function(){ -        return { -            sortColumn: undefined, -            sortDesc: false -        }; -    }, -    onClick: function(Column){ -        var sortDesc = this.state.sortDesc; -        var hasSort = Column.sortKeyFun; -        if(Column === this.state.sortColumn){ -            sortDesc = !sortDesc; -            this.setState({ -                sortDesc: sortDesc -            }); -        } else { -            this.setState({ -                sortColumn: hasSort && Column, -                sortDesc: false -            }) -        } -        var sortKeyFun; -        if(!sortDesc){ -            sortKeyFun = Column.sortKeyFun; -        } else { -            sortKeyFun = hasSort && function(){ -                var k = Column.sortKeyFun.apply(this, arguments); -                if(_.isString(k)){ -                    return utils.reverseString(""+k); -                } else { -                    return -k; -                } -            } -        } -        this.props.setSortKeyFun(sortKeyFun); -    }, -    render: function () { -        var columns = this.props.columns.map(function (Column) { -            var onClick = this.onClick.bind(this, Column); -            var className; -            if(this.state.sortColumn === Column) { -                if(this.state.sortDesc){ -                    className = "sort-desc"; -                } else { -                    className = "sort-asc"; -                } -            } -            return <Column.Title -                        key={Column.displayName} -                        onClick={onClick} -                        className={className} />; -        }.bind(this)); -        return <thead> -            <tr>{columns}</tr> -        </thead>; -    } -}); - - -var ROW_HEIGHT = 32; - -var FlowTable = React.createClass({ -    mixins: [common.StickyHeadMixin, common.AutoScrollMixin, VirtualScrollMixin], -    contextTypes: { -        view: React.PropTypes.object.isRequired -    }, -    getInitialState: function () { -        return { -            columns: flowtable_columns -        }; -    }, -    componentWillMount: function () { -        this.context.view.addListener("add", this.onChange); -        this.context.view.addListener("update", this.onChange); -        this.context.view.addListener("remove", this.onChange); -        this.context.view.addListener("recalculate", this.onChange); -    }, -    componentWillUnmount: function(){ -        this.context.view.removeListener("add", this.onChange); -        this.context.view.removeListener("update", this.onChange); -        this.context.view.removeListener("remove", this.onChange); -        this.context.view.removeListener("recalculate", this.onChange); -    }, -    getDefaultProps: function () { -        return { -            rowHeight: ROW_HEIGHT -        }; -    }, -    onScrollFlowTable: function () { -        this.adjustHead(); -        this.onScroll(); -    }, -    onChange: function () { -        this.forceUpdate(); -    }, -    scrollIntoView: function (flow) { -        this.scrollRowIntoView( -            this.context.view.index(flow), -            this.refs.body.getDOMNode().offsetTop -        ); -    }, -    renderRow: function (flow) { -        var selected = (flow === this.props.selected); -        var highlighted = -            ( -            this.context.view._highlight && -            this.context.view._highlight[flow.id] -            ); - -        return <FlowRow key={flow.id} -            ref={flow.id} -            flow={flow} -            columns={this.state.columns} -            selected={selected} -            highlighted={highlighted} -            selectFlow={this.props.selectFlow} -        />; -    }, -    render: function () { -        var flows = this.context.view.list; -        var rows = this.renderRows(flows); - -        return ( -            <div className="flow-table" onScroll={this.onScrollFlowTable}> -                <table> -                    <FlowTableHead ref="head" -                        columns={this.state.columns} -                        setSortKeyFun={this.props.setSortKeyFun}/> -                    <tbody ref="body"> -                        { this.getPlaceholderTop(flows.length) } -                        {rows} -                        { this.getPlaceholderBottom(flows.length) } -                    </tbody> -                </table> -            </div> -        ); -    } -}); - -module.exports = FlowTable; diff --git a/web/src/js/components/flowview/contentview.js b/web/src/js/components/flowview/contentview.js deleted file mode 100644 index 63d22c1c..00000000 --- a/web/src/js/components/flowview/contentview.js +++ /dev/null @@ -1,237 +0,0 @@ -var React = require("react"); -var _ = require("lodash"); - -var MessageUtils = require("../../flow/utils.js").MessageUtils; -var utils = require("../../utils.js"); - -var image_regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i; -var ViewImage = React.createClass({ -    statics: { -        matches: function (message) { -            return image_regex.test(MessageUtils.getContentType(message)); -        } -    }, -    render: function () { -        var url = MessageUtils.getContentURL(this.props.flow, this.props.message); -        return <div className="flowview-image"> -            <img src={url} alt="preview" className="img-thumbnail"/> -        </div>; -    } -}); - -var RawMixin = { -    getInitialState: function () { -        return { -            content: undefined, -            request: undefined -        } -    }, -    requestContent: function (nextProps) { -        if (this.state.request) { -            this.state.request.abort(); -        } -        var request = MessageUtils.getContent(nextProps.flow, nextProps.message); -        this.setState({ -            content: undefined, -            request: request -        }); -        request.done(function (data) { -            this.setState({content: data}); -        }.bind(this)).fail(function (jqXHR, textStatus, errorThrown) { -            if (textStatus === "abort") { -                return; -            } -            this.setState({content: "AJAX Error: " + textStatus + "\r\n" + errorThrown}); -        }.bind(this)).always(function () { -            this.setState({request: undefined}); -        }.bind(this)); - -    }, -    componentWillMount: function () { -        this.requestContent(this.props); -    }, -    componentWillReceiveProps: function (nextProps) { -        if (nextProps.message !== this.props.message) { -            this.requestContent(nextProps); -        } -    }, -    componentWillUnmount: function () { -        if (this.state.request) { -            this.state.request.abort(); -        } -    }, -    render: function () { -        if (!this.state.content) { -            return <div className="text-center"> -                <i className="fa fa-spinner fa-spin"></i> -            </div>; -        } -        return this.renderContent(); -    } -}; - -var ViewRaw = React.createClass({ -    mixins: [RawMixin], -    statics: { -        matches: function (message) { -            return true; -        } -    }, -    renderContent: function () { -        return <pre>{this.state.content}</pre>; -    } -}); - -var json_regex = /^application\/json$/i; -var ViewJSON = React.createClass({ -    mixins: [RawMixin], -    statics: { -        matches: function (message) { -            return json_regex.test(MessageUtils.getContentType(message)); -        } -    }, -    renderContent: function () { -        var json = this.state.content; -        try { -            json = JSON.stringify(JSON.parse(json), null, 2); -        } catch (e) { -        } -        return <pre>{json}</pre>; -    } -}); - -var ViewAuto = React.createClass({ -    statics: { -        matches: function () { -            return false; // don't match itself -        }, -        findView: function (message) { -            for (var i = 0; i < all.length; i++) { -                if (all[i].matches(message)) { -                    return all[i]; -                } -            } -            return all[all.length - 1]; -        } -    }, -    render: function () { -        var View = ViewAuto.findView(this.props.message); -        return <View {...this.props}/>; -    } -}); - -var all = [ViewAuto, ViewImage, ViewJSON, ViewRaw]; - - -var ContentEmpty = React.createClass({ -    render: function () { -        var message_name = this.props.flow.request === this.props.message ? "request" : "response"; -        return <div className="alert alert-info">No {message_name} content.</div>; -    } -}); - -var ContentMissing = React.createClass({ -    render: function () { -        var message_name = this.props.flow.request === this.props.message ? "Request" : "Response"; -        return <div className="alert alert-info">{message_name} content missing.</div>; -    } -}); - -var TooLarge = React.createClass({ -    statics: { -        isTooLarge: function (message) { -            var max_mb = ViewImage.matches(message) ? 10 : 0.2; -            return message.contentLength > 1024 * 1024 * max_mb; -        } -    }, -    render: function () { -        var size = utils.formatSize(this.props.message.contentLength); -        return <div className="alert alert-warning"> -            <button onClick={this.props.onClick} className="btn btn-xs btn-warning pull-right">Display anyway</button> -            {size} content size. -        </div>; -    } -}); - -var ViewSelector = React.createClass({ -    render: function () { -        var views = []; -        for (var i = 0; i < all.length; i++) { -            var view = all[i]; -            var className = "btn btn-default"; -            if (view === this.props.active) { -                className += " active"; -            } -            var text; -            if (view === ViewAuto) { -                text = "auto: " + ViewAuto.findView(this.props.message).displayName.toLowerCase().replace("view", ""); -            } else { -                text = view.displayName.toLowerCase().replace("view", ""); -            } -            views.push( -                <button -                    key={view.displayName} -                    onClick={this.props.selectView.bind(null, view)} -                    className={className}> -                    {text} -                </button> -            ); -        } - -        return <div className="view-selector btn-group btn-group-xs">{views}</div>; -    } -}); - -var ContentView = React.createClass({ -    getInitialState: function () { -        return { -            displayLarge: false, -            View: ViewAuto -        }; -    }, -    propTypes: { -        // It may seem a bit weird at the first glance: -        // Every view takes the flow and the message as props, e.g. -        // <Auto flow={flow} message={flow.request}/> -        flow: React.PropTypes.object.isRequired, -        message: React.PropTypes.object.isRequired, -    }, -    selectView: function (view) { -        this.setState({ -            View: view -        }); -    }, -    displayLarge: function () { -        this.setState({displayLarge: true}); -    }, -    componentWillReceiveProps: function (nextProps) { -        if (nextProps.message !== this.props.message) { -            this.setState(this.getInitialState()); -        } -    }, -    render: function () { -        var message = this.props.message; -        if (message.contentLength === 0) { -            return <ContentEmpty {...this.props}/>; -        } else if (message.contentLength === null) { -            return <ContentMissing {...this.props}/>; -        } else if (!this.state.displayLarge && TooLarge.isTooLarge(message)) { -            return <TooLarge {...this.props} onClick={this.displayLarge}/>; -        } - -        var downloadUrl = MessageUtils.getContentURL(this.props.flow, message); - -        return <div> -            <this.state.View {...this.props} /> -            <div className="view-options text-center"> -                <ViewSelector selectView={this.selectView} active={this.state.View} message={message}/> -              -                <a className="btn btn-default btn-xs" href={downloadUrl}> -                    <i className="fa fa-download"/> -                </a> -            </div> -        </div>; -    } -}); - -module.exports = ContentView;
\ No newline at end of file diff --git a/web/src/js/components/flowview/details.js b/web/src/js/components/flowview/details.js deleted file mode 100644 index 00e0116c..00000000 --- a/web/src/js/components/flowview/details.js +++ /dev/null @@ -1,181 +0,0 @@ -var React = require("react"); -var _ = require("lodash"); - -var utils = require("../../utils.js"); - -var TimeStamp = React.createClass({ -    render: function () { - -        if (!this.props.t) { -            //should be return null, but that triggers a React bug. -            return <tr></tr>; -        } - -        var ts = utils.formatTimeStamp(this.props.t); - -        var delta; -        if (this.props.deltaTo) { -            delta = utils.formatTimeDelta(1000 * (this.props.t - this.props.deltaTo)); -            delta = <span className="text-muted">{"(" + delta + ")"}</span>; -        } else { -            delta = null; -        } - -        return <tr> -            <td>{this.props.title + ":"}</td> -            <td>{ts} {delta}</td> -        </tr>; -    } -}); - -var ConnectionInfo = React.createClass({ - -    render: function () { -        var conn = this.props.conn; -        var address = conn.address.address.join(":"); - -        var sni = <tr key="sni"></tr>; //should be null, but that triggers a React bug. -        if (conn.sni) { -            sni = <tr key="sni"> -                <td> -                    <abbr title="TLS Server Name Indication">TLS SNI:</abbr> -                </td> -                <td>{conn.sni}</td> -            </tr>; -        } -        return ( -            <table className="connection-table"> -                <tbody> -                    <tr key="address"> -                        <td>Address:</td> -                        <td>{address}</td> -                    </tr> -                    {sni} -                </tbody> -            </table> -        ); -    } -}); - -var CertificateInfo = React.createClass({ -    render: function () { -        //TODO: We should fetch human-readable certificate representation -        // from the server -        var flow = this.props.flow; -        var client_conn = flow.client_conn; -        var server_conn = flow.server_conn; - -        var preStyle = {maxHeight: 100}; -        return ( -            <div> -            {client_conn.cert ? <h4>Client Certificate</h4> : null} -            {client_conn.cert ? <pre style={preStyle}>{client_conn.cert}</pre> : null} - -            {server_conn.cert ? <h4>Server Certificate</h4> : null} -            {server_conn.cert ? <pre style={preStyle}>{server_conn.cert}</pre> : null} -            </div> -        ); -    } -}); - -var Timing = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        var sc = flow.server_conn; -        var cc = flow.client_conn; -        var req = flow.request; -        var resp = flow.response; - -        var timestamps = [ -            { -                title: "Server conn. initiated", -                t: sc.timestamp_start, -                deltaTo: req.timestamp_start -            }, { -                title: "Server conn. TCP handshake", -                t: sc.timestamp_tcp_setup, -                deltaTo: req.timestamp_start -            }, { -                title: "Server conn. SSL handshake", -                t: sc.timestamp_ssl_setup, -                deltaTo: req.timestamp_start -            }, { -                title: "Client conn. established", -                t: cc.timestamp_start, -                deltaTo: req.timestamp_start -            }, { -                title: "Client conn. SSL handshake", -                t: cc.timestamp_ssl_setup, -                deltaTo: req.timestamp_start -            }, { -                title: "First request byte", -                t: req.timestamp_start, -            }, { -                title: "Request complete", -                t: req.timestamp_end, -                deltaTo: req.timestamp_start -            } -        ]; - -        if (flow.response) { -            timestamps.push( -                { -                    title: "First response byte", -                    t: resp.timestamp_start, -                    deltaTo: req.timestamp_start -                }, { -                    title: "Response complete", -                    t: resp.timestamp_end, -                    deltaTo: req.timestamp_start -                } -            ); -        } - -        //Add unique key for each row. -        timestamps.forEach(function (e) { -            e.key = e.title; -        }); - -        timestamps = _.sortBy(timestamps, 't'); - -        var rows = timestamps.map(function (e) { -            return <TimeStamp {...e}/>; -        }); - -        return ( -            <div> -                <h4>Timing</h4> -                <table className="timing-table"> -                    <tbody> -                    {rows} -                    </tbody> -                </table> -            </div> -        ); -    } -}); - -var Details = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        var client_conn = flow.client_conn; -        var server_conn = flow.server_conn; -        return ( -            <section> - -                <h4>Client Connection</h4> -                <ConnectionInfo conn={client_conn}/> - -                <h4>Server Connection</h4> -                <ConnectionInfo conn={server_conn}/> - -                <CertificateInfo flow={flow}/> - -                <Timing flow={flow}/> - -            </section> -        ); -    } -}); - -module.exports = Details;
\ No newline at end of file diff --git a/web/src/js/components/flowview/index.js b/web/src/js/components/flowview/index.js deleted file mode 100644 index 739a46dc..00000000 --- a/web/src/js/components/flowview/index.js +++ /dev/null @@ -1,127 +0,0 @@ -var React = require("react"); -var _ = require("lodash"); - -var common = require("../common.js"); -var Nav = require("./nav.js"); -var Messages = require("./messages.js"); -var Details = require("./details.js"); -var Prompt = require("../prompt.js"); - - -var allTabs = { -    request: Messages.Request, -    response: Messages.Response, -    error: Messages.Error, -    details: Details -}; - -var FlowView = React.createClass({ -    mixins: [common.StickyHeadMixin, common.Navigation, common.RouterState], -    getInitialState: function () { -        return { -            prompt: false -        }; -    }, -    getTabs: function (flow) { -        var tabs = []; -        ["request", "response", "error"].forEach(function (e) { -            if (flow[e]) { -                tabs.push(e); -            } -        }); -        tabs.push("details"); -        return tabs; -    }, -    nextTab: function (i) { -        var tabs = this.getTabs(this.props.flow); -        var currentIndex = tabs.indexOf(this.getActive()); -        // 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( -            "flow", -            { -                flowId: this.getParams().flowId, -                detailTab: panel -            } -        ); -    }, -    getActive: function(){ -        return this.getParams().detailTab; -    }, -    promptEdit: function () { -        var options; -        switch(this.getActive()){ -            case "request": -                options = [ -                    "method", -                    "url", -                    {text:"http version", key:"v"}, -                    "header" -                    /*, "content"*/]; -                break; -            case "response": -                options = [ -                    {text:"http version", key:"v"}, -                    "code", -                    "message", -                    "header" -                    /*, "content"*/]; -                break; -            case "details": -                return; -            default: -                throw "Unknown tab for edit: " + this.getActive(); -        } - -        this.setState({ -            prompt: { -                done: function (k) { -                    this.setState({prompt: false}); -                    if(k){ -                        this.refs.tab.edit(k); -                    } -                }.bind(this), -                options: options -            } -        }); -    }, -    render: function () { -        var flow = this.props.flow; -        var tabs = this.getTabs(flow); -        var active = this.getActive(); - -        if (!_.contains(tabs, active)) { -            if (active === "response" && flow.error) { -                active = "error"; -            } else if (active === "error" && flow.response) { -                active = "response"; -            } else { -                active = tabs[0]; -            } -            this.selectTab(active); -        } - -        var prompt = null; -        if (this.state.prompt) { -            prompt = <Prompt {...this.state.prompt}/>; -        } - -        var Tab = allTabs[active]; -        return ( -            <div className="flow-detail" onScroll={this.adjustHead}> -                <Nav ref="head" -                    flow={flow} -                    tabs={tabs} -                    active={active} -                    selectTab={this.selectTab}/> -                <Tab ref="tab" flow={flow}/> -                {prompt} -            </div> -        ); -    } -}); - -module.exports = FlowView;
\ No newline at end of file diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js deleted file mode 100644 index 7ac95d85..00000000 --- a/web/src/js/components/flowview/messages.js +++ /dev/null @@ -1,326 +0,0 @@ -var React = require("react"); -var _ = require("lodash"); - -var common = require("../common.js"); -var actions = require("../../actions.js"); -var flowutils = require("../../flow/utils.js"); -var utils = require("../../utils.js"); -var ContentView = require("./contentview.js"); -var ValueEditor = require("../editor.js").ValueEditor; - -var Headers = React.createClass({ -    propTypes: { -        onChange: React.PropTypes.func.isRequired, -        message: React.PropTypes.object.isRequired -    }, -    onChange: function (row, col, val) { -        var nextHeaders = _.cloneDeep(this.props.message.headers); -        nextHeaders[row][col] = val; -        if (!nextHeaders[row][0] && !nextHeaders[row][1]) { -            // do not delete last row -            if (nextHeaders.length === 1) { -                nextHeaders[0][0] = "Name"; -                nextHeaders[0][1] = "Value"; -            } else { -                nextHeaders.splice(row, 1); -                // manually move selection target if this has been the last row. -                if (row === nextHeaders.length) { -                    this._nextSel = (row - 1) + "-value"; -                } -            } -        } -        this.props.onChange(nextHeaders); -    }, -    edit: function () { -        this.refs["0-key"].focus(); -    }, -    onTab: function (row, col, e) { -        var headers = this.props.message.headers; -        if (row === headers.length - 1 && col === 1) { -            e.preventDefault(); - -            var nextHeaders = _.cloneDeep(this.props.message.headers); -            nextHeaders.push(["Name", "Value"]); -            this.props.onChange(nextHeaders); -            this._nextSel = (row + 1) + "-key"; -        } -    }, -    componentDidUpdate: function () { -        if (this._nextSel && this.refs[this._nextSel]) { -            this.refs[this._nextSel].focus(); -            this._nextSel = undefined; -        } -    }, -    onRemove: function (row, col, e) { -        if (col === 1) { -            e.preventDefault(); -            this.refs[row + "-key"].focus(); -        } else if (row > 0) { -            e.preventDefault(); -            this.refs[(row - 1) + "-value"].focus(); -        } -    }, -    render: function () { - -        var rows = this.props.message.headers.map(function (header, i) { - -            var kEdit = <HeaderEditor -                ref={i + "-key"} -                content={header[0]} -                onDone={this.onChange.bind(null, i, 0)} -                onRemove={this.onRemove.bind(null, i, 0)} -                onTab={this.onTab.bind(null, i, 0)}/>; -            var vEdit = <HeaderEditor -                ref={i + "-value"} -                content={header[1]} -                onDone={this.onChange.bind(null, i, 1)} -                onRemove={this.onRemove.bind(null, i, 1)} -                onTab={this.onTab.bind(null, i, 1)}/>; -            return ( -                <tr key={i}> -                    <td className="header-name">{kEdit}:</td> -                    <td className="header-value">{vEdit}</td> -                </tr> -            ); -        }.bind(this)); -        return ( -            <table className="header-table"> -                <tbody> -                    {rows} -                </tbody> -            </table> -        ); -    } -}); - -var HeaderEditor = React.createClass({ -    render: function () { -        return <ValueEditor ref="input" {...this.props} onKeyDown={this.onKeyDown} inline/>; -    }, -    focus: function () { -        this.getDOMNode().focus(); -    }, -    onKeyDown: function (e) { -        switch (e.keyCode) { -            case utils.Key.BACKSPACE: -                var s = window.getSelection().getRangeAt(0); -                if (s.startOffset === 0 && s.endOffset === 0) { -                    this.props.onRemove(e); -                } -                break; -            case utils.Key.TAB: -                if (!e.shiftKey) { -                    this.props.onTab(e); -                } -                break; -        } -    } -}); - -var RequestLine = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        var url = flowutils.RequestUtils.pretty_url(flow.request); -        var httpver = flow.request.http_version; - -        return <div className="first-line request-line"> -            <ValueEditor -                ref="method" -                content={flow.request.method} -                onDone={this.onMethodChange} -                inline/> -          -            <ValueEditor -                ref="url" -                content={url} -                onDone={this.onUrlChange} -                isValid={this.isValidUrl} -                inline/> -          -            <ValueEditor -                ref="httpVersion" -                content={httpver} -                onDone={this.onHttpVersionChange} -                isValid={flowutils.isValidHttpVersion} -                inline/> -        </div> -    }, -    isValidUrl: function (url) { -        var u = flowutils.parseUrl(url); -        return !!u.host; -    }, -    onMethodChange: function (nextMethod) { -        actions.FlowActions.update( -            this.props.flow, -            {request: {method: nextMethod}} -        ); -    }, -    onUrlChange: function (nextUrl) { -        var props = flowutils.parseUrl(nextUrl); -        props.path = props.path || ""; -        actions.FlowActions.update( -            this.props.flow, -            {request: props} -        ); -    }, -    onHttpVersionChange: function (nextVer) { -        var ver = flowutils.parseHttpVersion(nextVer); -        actions.FlowActions.update( -            this.props.flow, -            {request: {http_version: ver}} -        ); -    } -}); - -var ResponseLine = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        var httpver = flow.response.http_version; -        return <div className="first-line response-line"> -            <ValueEditor -                ref="httpVersion" -                content={httpver} -                onDone={this.onHttpVersionChange} -                isValid={flowutils.isValidHttpVersion} -                inline/> -          -            <ValueEditor -                ref="code" -                content={flow.response.status_code + ""} -                onDone={this.onCodeChange} -                isValid={this.isValidCode} -                inline/> -          -            <ValueEditor -                ref="msg" -                content={flow.response.msg} -                onDone={this.onMsgChange} -                inline/> -        </div>; -    }, -    isValidCode: function (code) { -        return /^\d+$/.test(code); -    }, -    onHttpVersionChange: function (nextVer) { -        var ver = flowutils.parseHttpVersion(nextVer); -        actions.FlowActions.update( -            this.props.flow, -            {response: {http_version: ver}} -        ); -    }, -    onMsgChange: function (nextMsg) { -        actions.FlowActions.update( -            this.props.flow, -            {response: {msg: nextMsg}} -        ); -    }, -    onCodeChange: function (nextCode) { -        nextCode = parseInt(nextCode); -        actions.FlowActions.update( -            this.props.flow, -            {response: {code: nextCode}} -        ); -    } -}); - -var Request = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        return ( -            <section className="request"> -                <RequestLine ref="requestLine" flow={flow}/> -                {/*<ResponseLine flow={flow}/>*/} -                <Headers ref="headers" message={flow.request} onChange={this.onHeaderChange}/> -                <hr/> -                <ContentView flow={flow} message={flow.request}/> -            </section> -        ); -    }, -    edit: function (k) { -        switch (k) { -            case "m": -                this.refs.requestLine.refs.method.focus(); -                break; -            case "u": -                this.refs.requestLine.refs.url.focus(); -                break; -            case "v": -                this.refs.requestLine.refs.httpVersion.focus(); -                break; -            case "h": -                this.refs.headers.edit(); -                break; -            default: -                throw "Unimplemented: " + k; -        } -    }, -    onHeaderChange: function (nextHeaders) { -        actions.FlowActions.update(this.props.flow, { -            request: { -                headers: nextHeaders -            } -        }); -    } -}); - -var Response = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        return ( -            <section className="response"> -                {/*<RequestLine flow={flow}/>*/} -                <ResponseLine ref="responseLine" flow={flow}/> -                <Headers ref="headers" message={flow.response} onChange={this.onHeaderChange}/> -                <hr/> -                <ContentView flow={flow} message={flow.response}/> -            </section> -        ); -    }, -    edit: function (k) { -        switch (k) { -            case "c": -                this.refs.responseLine.refs.status_code.focus(); -                break; -            case "m": -                this.refs.responseLine.refs.msg.focus(); -                break; -            case "v": -                this.refs.responseLine.refs.httpVersion.focus(); -                break; -            case "h": -                this.refs.headers.edit(); -                break; -            default: -                throw "Unimplemented: " + k; -        } -    }, -    onHeaderChange: function (nextHeaders) { -        actions.FlowActions.update(this.props.flow, { -            response: { -                headers: nextHeaders -            } -        }); -    } -}); - -var Error = React.createClass({ -    render: function () { -        var flow = this.props.flow; -        return ( -            <section> -                <div className="alert alert-warning"> -                {flow.error.msg} -                    <div> -                        <small>{ utils.formatTimeStamp(flow.error.timestamp) }</small> -                    </div> -                </div> -            </section> -        ); -    } -}); - -module.exports = { -    Request: Request, -    Response: Response, -    Error: Error -}; diff --git a/web/src/js/components/flowview/nav.js b/web/src/js/components/flowview/nav.js deleted file mode 100644 index 46eda707..00000000 --- a/web/src/js/components/flowview/nav.js +++ /dev/null @@ -1,61 +0,0 @@ -var React = require("react"); - -var actions = require("../../actions.js"); - -var NavAction = React.createClass({ -    onClick: function (e) { -        e.preventDefault(); -        this.props.onClick(); -    }, -    render: function () { -        return ( -            <a title={this.props.title} -                href="#" -                className="nav-action" -                onClick={this.onClick}> -                <i className={"fa fa-fw " + this.props.icon}></i> -            </a> -        ); -    } -}); - -var Nav = React.createClass({ -    render: function () { -        var flow = this.props.flow; - -        var tabs = this.props.tabs.map(function (e) { -            var str = e.charAt(0).toUpperCase() + e.slice(1); -            var className = this.props.active === e ? "active" : ""; -            var onClick = function (event) { -                this.props.selectTab(e); -                event.preventDefault(); -            }.bind(this); -            return <a key={e} -                href="#" -                className={className} -                onClick={onClick}>{str}</a>; -        }.bind(this)); - -        var acceptButton = null; -        if(flow.intercepted){ -            acceptButton = <NavAction title="[a]ccept intercepted flow" icon="fa-play" onClick={actions.FlowActions.accept.bind(null, flow)} />; -        } -        var revertButton = null; -        if(flow.modified){ -            revertButton = <NavAction title="revert changes to flow [V]" icon="fa-history" onClick={actions.FlowActions.revert.bind(null, flow)} />; -        } - -        return ( -            <nav ref="head" className="nav-tabs nav-tabs-sm"> -                {tabs} -                <NavAction title="[d]elete flow" icon="fa-trash" onClick={actions.FlowActions.delete.bind(null, flow)} /> -                <NavAction title="[D]uplicate flow" icon="fa-copy" onClick={actions.FlowActions.duplicate.bind(null, flow)} /> -                <NavAction disabled title="[r]eplay flow" icon="fa-repeat" onClick={actions.FlowActions.replay.bind(null, flow)} /> -                {acceptButton} -                {revertButton} -            </nav> -        ); -    } -}); - -module.exports = Nav;
\ No newline at end of file diff --git a/web/src/js/components/footer.js b/web/src/js/components/footer.js deleted file mode 100644 index 229d691b..00000000 --- a/web/src/js/components/footer.js +++ /dev/null @@ -1,19 +0,0 @@ -var React = require("react"); -var common = require("./common.js"); - -var Footer = React.createClass({ -    mixins: [common.SettingsState], -    render: function () { -        var mode = this.state.settings.mode; -        var intercept = this.state.settings.intercept; -        return ( -            <footer> -                {mode && mode != "regular" ? <span className="label label-success">{mode} mode</span> : null} -                  -                {intercept ? <span className="label label-success">Intercept: {intercept}</span> : null} -            </footer> -        ); -    } -}); - -module.exports = Footer;
\ No newline at end of file diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js deleted file mode 100644 index 998a41df..00000000 --- a/web/src/js/components/header.js +++ /dev/null @@ -1,399 +0,0 @@ -var React = require("react"); -var $ = require("jquery"); - -var Filt = require("../filt/filt.js"); -var utils = require("../utils.js"); -var common = require("./common.js"); -var actions = require("../actions.js"); -var Query = require("../actions.js").Query; - -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 <i className="fa fa-spinner fa-spin"></i>; -        } else { -            var commands = FilterDocs.doc.commands.map(function (c) { -                return <tr key={c[1]}> -                    <td>{c[0].replace(" ", '\u00a0')}</td> -                    <td>{c[1]}</td> -                </tr>; -            }); -            commands.push(<tr key="docs-link"> -                <td colSpan="2"> -                    <a href="https://mitmproxy.org/doc/features/filters.html" -                        target="_blank"> -                        <i className="fa fa-external-link"></i> -                      mitmproxy docs</a> -                </td> -            </tr>); -            return <table className="table table-condensed"> -                <tbody>{commands}</tbody> -            </table>; -        } -    } -}); -var FilterInput = React.createClass({ -    mixins: [common.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 -        // 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 { -            Filt.parse(filt || this.state.value); -            return true; -        } catch (e) { -            return false; -        } -    }, -    getDesc: function () { -        var desc; -        try { -            desc = Filt.parse(this.state.value).desc; -        } catch (e) { -            desc = "" + e; -        } -        if (desc !== "true") { -            return desc; -        } else { -            return ( -                <FilterDocs/> -            ); -        } -    }, -    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 === utils.Key.ESC || e.keyCode === utils.Key.ENTER) { -            this.blur(); -            // If closed using ESC/ENTER, hide the tooltip. -            this.setState({mousefocus: false}); -        } -        e.stopPropagation(); -    }, -    blur: function () { -        this.refs.input.getDOMNode().blur(); -        this.returnFocus(); -    }, -    select: function () { -        this.refs.input.getDOMNode().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 = ( -                <div className="popover bottom" onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}> -                    <div className="arrow"></div> -                    <div className="popover-content"> -                    {this.getDesc()} -                    </div> -                </div> -            ); -        } - -        return ( -            <div className={groupClassName}> -                <span className="input-group-addon"> -                    <i className={icon} style={{color: this.props.color}}></i> -                </span> -                <input type="text" placeholder={this.props.placeholder} className="form-control" -                    ref="input" -                    onChange={this.onChange} -                    onFocus={this.onFocus} -                    onBlur={this.onBlur} -                    onKeyDown={this.onKeyDown} -                    value={this.state.value}/> -                {popover} -            </div> -        ); -    } -}); - -var MainMenu = React.createClass({ -    mixins: [common.Navigation, common.RouterState, common.SettingsState], -    statics: { -        title: "Start", -        route: "flows" -    }, -    onSearchChange: function (val) { -        var d = {}; -        d[Query.SEARCH] = val; -        this.setQuery(d); -    }, -    onHighlightChange: function (val) { -        var d = {}; -        d[Query.HIGHLIGHT] = val; -        this.setQuery(d); -    }, -    onInterceptChange: function (val) { -        actions.SettingsActions.update({intercept: val}); -    }, -    render: function () { -        var search = this.getQuery()[Query.SEARCH] || ""; -        var highlight = this.getQuery()[Query.HIGHLIGHT] || ""; -        var intercept = this.state.settings.intercept || ""; - -        return ( -            <div> -                <div className="menu-row"> -                    <FilterInput -                        ref="search" -                        placeholder="Search" -                        type="search" -                        color="black" -                        value={search} -                        onChange={this.onSearchChange} /> -                    <FilterInput -                        ref="highlight" -                        placeholder="Highlight" -                        type="tag" -                        color="hsl(48, 100%, 50%)" -                        value={highlight} -                        onChange={this.onHighlightChange}/> -                    <FilterInput -                        ref="intercept" -                        placeholder="Intercept" -                        type="pause" -                        color="hsl(208, 56%, 53%)" -                        value={intercept} -                        onChange={this.onInterceptChange}/> -                </div> -                <div className="clearfix"></div> -            </div> -        ); -    } -}); - - -var ViewMenu = React.createClass({ -    statics: { -        title: "View", -        route: "flows" -    }, -    mixins: [common.Navigation, common.RouterState], -    toggleEventLog: function () { -        var d = {}; - -        if (this.getQuery()[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.setQuery(d); -    }, -    render: function () { -        var showEventLog = this.getQuery()[Query.SHOW_EVENTLOG]; -        return ( -            <div> -                <button -                    className={"btn " + (showEventLog ? "btn-primary" : "btn-default")} -                    onClick={this.toggleEventLog}> -                    <i className="fa fa-database"></i> -                 Show Eventlog -                </button> -                <span> </span> -            </div> -        ); -    } -}); - - -var ReportsMenu = React.createClass({ -    statics: { -        title: "Visualization", -        route: "reports" -    }, -    render: function () { -        return <div>Reports Menu</div>; -    } -}); - -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?")) { -            actions.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 ( -            <div className={fileMenuClass}> -                <a href="#" className="special" onClick={this.handleFileClick}> mitmproxy </a> -                <ul className="dropdown-menu" role="menu"> -                    <li> -                        <a href="#" onClick={this.handleNewClick}> -                            <i className="fa fa-fw fa-file"></i> -                            New -                        </a> -                    </li> -                    <li role="presentation" className="divider"></li> -                    <li> -                        <a href="http://mitm.it/" target="_blank"> -                            <i className="fa fa-fw fa-external-link"></i> -                            Install Certificates... -                        </a> -                    </li> -                {/* -                 <li> -                 <a href="#" onClick={this.handleOpenClick}> -                 <i className="fa fa-fw fa-folder-open"></i> -                 Open -                 </a> -                 </li> -                 <li> -                 <a href="#" onClick={this.handleSaveClick}> -                 <i className="fa fa-fw fa-save"></i> -                 Save -                 </a> -                 </li> -                 <li role="presentation" className="divider"></li> -                 <li> -                 <a href="#" onClick={this.handleShutdownClick}> -                 <i className="fa fa-fw fa-plug"></i> -                 Shutdown -                 </a> -                 </li> -                 */} -                </ul> -            </div> -        ); -    } -}); - - -var header_entries = [MainMenu, ViewMenu /*, ReportsMenu */]; - - -var Header = React.createClass({ -    mixins: [common.Navigation], -    getInitialState: function () { -        return { -            active: header_entries[0] -        }; -    }, -    handleClick: function (active, e) { -        e.preventDefault(); -        this.replaceWith(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 ( -                <a key={i} -                    href="#" -                    className={className} -                    onClick={this.handleClick.bind(this, entry)}> -                    { entry.title} -                </a> -            ); -        }.bind(this)); - -        return ( -            <header> -                <nav className="nav-tabs nav-tabs-lg"> -                    <FileMenu/> -                    {header} -                </nav> -                <div className="menu"> -                    <this.state.active ref="active"/> -                </div> -            </header> -        ); -    } -}); - - -module.exports = { -    Header: Header, -    MainMenu: MainMenu -};
\ No newline at end of file diff --git a/web/src/js/components/mainview.js b/web/src/js/components/mainview.js deleted file mode 100644 index 9ff51dfa..00000000 --- a/web/src/js/components/mainview.js +++ /dev/null @@ -1,244 +0,0 @@ -var React = require("react"); - -var actions = require("../actions.js"); -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"); -var FlowTable = require("./flowtable.js"); -var FlowView = require("./flowview/index.js"); - -var MainView = React.createClass({ -    mixins: [common.Navigation, common.RouterState], -    contextTypes: { -        flowStore: React.PropTypes.object.isRequired, -    }, -    childContextTypes: { -        view: React.PropTypes.object.isRequired, -    }, -    getChildContext: function () { -        return { -            view: this.state.view -        }; -    }, -    getInitialState: function () { -        var sortKeyFun = false; -        var view = new views.StoreView(this.context.flowStore, this.getViewFilt(), sortKeyFun); -        view.addListener("recalculate", this.onRecalculate); -        view.addListener("add", this.onUpdate); -        view.addListener("update", this.onUpdate); -        view.addListener("remove", this.onUpdate); -        view.addListener("remove", this.onRemove); - -        return { -            view: view, -            sortKeyFun: sortKeyFun -        }; -    }, -    componentWillUnmount: function () { -        this.state.view.close(); -    }, -    getViewFilt: function () { -        try { -            var filt = Filt.parse(this.getQuery()[Query.SEARCH] || ""); -            var highlightStr = this.getQuery()[Query.HIGHLIGHT]; -            var highlight = highlightStr ? Filt.parse(highlightStr) : false; -        } catch (e) { -            console.error("Error when processing filter: " + e); -        } - -        return function filter_and_highlight(flow) { -            if (!this._highlight) { -                this._highlight = {}; -            } -            this._highlight[flow.id] = highlight && highlight(flow); -            return filt(flow); -        }; -    }, -    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]); -        if (filterChanged || highlightChanged) { -            this.state.view.recalculate(this.getViewFilt(), this.state.sortKeyFun); -        } -    }, -    onRecalculate: function () { -        this.forceUpdate(); -        var selected = this.getSelected(); -        if (selected) { -            this.refs.flowTable.scrollIntoView(selected); -        } -    }, -    onUpdate: function (flow) { -        if (flow.id === this.getParams().flowId) { -            this.forceUpdate(); -        } -    }, -    onRemove: function (flow_id, index) { -        if (flow_id === this.getParams().flowId) { -            var flow_to_select = this.state.view.list[Math.min(index, this.state.view.list.length - 1)]; -            this.selectFlow(flow_to_select); -        } -    }, -    setSortKeyFun: function (sortKeyFun) { -        this.setState({ -            sortKeyFun: sortKeyFun -        }); -        this.state.view.recalculate(this.getViewFilt(), sortKeyFun); -    }, -    selectFlow: function (flow) { -        if (flow) { -            this.replaceWith( -                "flow", -                { -                    flowId: flow.id, -                    detailTab: this.getParams().detailTab || "request" -                } -            ); -            this.refs.flowTable.scrollIntoView(flow); -        } else { -            this.replaceWith("flows", {}); -        } -    }, -    selectFlowRelative: function (shift) { -        var flows = this.state.view.list; -        var index; -        if (!this.getParams().flowId) { -            if (shift < 0) { -                index = flows.length - 1; -            } else { -                index = 0; -            } -        } else { -            var currFlowId = this.getParams().flowId; -            var i = flows.length; -            while (i--) { -                if (flows[i].id === currFlowId) { -                    index = i; -                    break; -                } -            } -            index = Math.min( -                Math.max(0, index + shift), -                flows.length - 1); -        } -        this.selectFlow(flows[index]); -    }, -    onMainKeyDown: function (e) { -        var flow = this.getSelected(); -        if (e.ctrlKey) { -            return; -        } -        switch (e.keyCode) { -            case utils.Key.K: -            case utils.Key.UP: -                this.selectFlowRelative(-1); -                break; -            case utils.Key.J: -            case utils.Key.DOWN: -                this.selectFlowRelative(+1); -                break; -            case utils.Key.SPACE: -            case utils.Key.PAGE_DOWN: -                this.selectFlowRelative(+10); -                break; -            case utils.Key.PAGE_UP: -                this.selectFlowRelative(-10); -                break; -            case utils.Key.END: -                this.selectFlowRelative(+1e10); -                break; -            case utils.Key.HOME: -                this.selectFlowRelative(-1e10); -                break; -            case utils.Key.ESC: -                this.selectFlow(null); -                break; -            case utils.Key.H: -            case utils.Key.LEFT: -                if (this.refs.flowDetails) { -                    this.refs.flowDetails.nextTab(-1); -                } -                break; -            case utils.Key.L: -            case utils.Key.TAB: -            case utils.Key.RIGHT: -                if (this.refs.flowDetails) { -                    this.refs.flowDetails.nextTab(+1); -                } -                break; -            case utils.Key.C: -                if (e.shiftKey) { -                    actions.FlowActions.clear(); -                } -                break; -            case utils.Key.D: -                if (flow) { -                    if (e.shiftKey) { -                        actions.FlowActions.duplicate(flow); -                    } else { -                        actions.FlowActions.delete(flow); -                    } -                } -                break; -            case utils.Key.A: -                if (e.shiftKey) { -                    actions.FlowActions.accept_all(); -                } else if (flow && flow.intercepted) { -                    actions.FlowActions.accept(flow); -                } -                break; -            case utils.Key.R: -                if (!e.shiftKey && flow) { -                    actions.FlowActions.replay(flow); -                } -                break; -            case utils.Key.V: -                if (e.shiftKey && flow && flow.modified) { -                    actions.FlowActions.revert(flow); -                } -                break; -            case utils.Key.E: -                if (this.refs.flowDetails) { -                    this.refs.flowDetails.promptEdit(); -                } -                break; -            case utils.Key.SHIFT: -                break; -            default: -                console.debug("keydown", e.keyCode); -                return; -        } -        e.preventDefault(); -    }, -    getSelected: function () { -        return this.context.flowStore.get(this.getParams().flowId); -    }, -    render: function () { -        var selected = this.getSelected(); - -        var details; -        if (selected) { -            details = [ -                <common.Splitter key="splitter"/>, -                <FlowView key="flowDetails" ref="flowDetails" flow={selected}/> -            ]; -        } else { -            details = null; -        } - -        return ( -            <div className="main-view"> -                <FlowTable ref="flowTable" -                    selectFlow={this.selectFlow} -                    setSortKeyFun={this.setSortKeyFun} -                    selected={selected} /> -                {details} -            </div> -        ); -    } -}); - -module.exports = MainView; diff --git a/web/src/js/components/prompt.js b/web/src/js/components/prompt.js deleted file mode 100644 index 121a1170..00000000 --- a/web/src/js/components/prompt.js +++ /dev/null @@ -1,100 +0,0 @@ -var React = require("react"); -var _ = require("lodash"); - -var utils = require("../utils.js"); -var common = require("./common.js"); - -var Prompt = React.createClass({ -    mixins: [common.ChildFocus], -    propTypes: { -        options: React.PropTypes.array.isRequired, -        done: React.PropTypes.func.isRequired, -        prompt: React.PropTypes.string -    }, -    componentDidMount: function () { -        React.findDOMNode(this).focus(); -    }, -    onKeyDown: function (e) { -        e.stopPropagation(); -        e.preventDefault(); -        var opts = this.getOptions(); -        for (var i = 0; i < opts.length; i++) { -            var k = opts[i].key; -            if (utils.Key[k.toUpperCase()] === e.keyCode) { -                this.done(k); -                return; -            } -        } -        if (e.keyCode === utils.Key.ESC || e.keyCode === utils.Key.ENTER) { -            this.done(false); -        } -    }, -    onClick: function (e) { -        this.done(false); -    }, -    done: function (ret) { -        this.props.done(ret); -        this.returnFocus(); -    }, -    getOptions: function () { -        var opts = []; - -        var keyTaken = function (k) { -            return _.includes(_.pluck(opts, "key"), k); -        }; - -        for (var i = 0; i < this.props.options.length; i++) { -            var opt = this.props.options[i]; -            if (_.isString(opt)) { -                var str = opt; -                while (str.length > 0 && keyTaken(str[0])) { -                    str = str.substr(1); -                } -                opt = { -                    text: opt, -                    key: str[0] -                }; -            } -            if (!opt.text || !opt.key || keyTaken(opt.key)) { -                throw "invalid options"; -            } else { -                opts.push(opt); -            } -        } -        return opts; -    }, -    render: function () { -        var opts = this.getOptions(); -        opts = _.map(opts, function (o) { -            var prefix, suffix; -            var idx = o.text.indexOf(o.key); -            if (idx !== -1) { -                prefix = o.text.substring(0, idx); -                suffix = o.text.substring(idx + 1); - -            } else { -                prefix = o.text + " ("; -                suffix = ")"; -            } -            var onClick = function (e) { -                this.done(o.key); -                e.stopPropagation(); -            }.bind(this); -            return <span -                key={o.key} -                className="option" -                onClick={onClick}> -            {prefix} -                <strong className="text-primary">{o.key}</strong>{suffix} -            </span>; -        }.bind(this)); -        return <div tabIndex="0" onKeyDown={this.onKeyDown} onClick={this.onClick} className="prompt-dialog"> -            <div className="prompt-content"> -            {this.props.prompt || <strong>Select: </strong> } -            {opts} -            </div> -        </div>; -    } -}); - -module.exports = Prompt;
\ No newline at end of file diff --git a/web/src/js/components/proxyapp.js b/web/src/js/components/proxyapp.js deleted file mode 100644 index e766d6e6..00000000 --- a/web/src/js/components/proxyapp.js +++ /dev/null @@ -1,129 +0,0 @@ -var React = require("react"); -var ReactRouter = require("react-router"); -var _ = require("lodash"); - -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"); -var store = require("../store/store.js"); -var Query = require("../actions.js").Query; -var Key = require("../utils.js").Key; - - -//TODO: Move out of here, just a stub. -var Reports = React.createClass({ -    render: function () { -        return <div>ReportEditor</div>; -    } -}); - - -var ProxyAppMain = React.createClass({ -    mixins: [common.RouterState], -    childContextTypes: { -        settingsStore: React.PropTypes.object.isRequired, -        flowStore: React.PropTypes.object.isRequired, -        eventStore: React.PropTypes.object.isRequired, -        returnFocus: React.PropTypes.func.isRequired, -    }, -    componentDidMount: function () { -        this.focus(); -    }, -    getChildContext: function () { -        return { -            settingsStore: this.state.settingsStore, -            flowStore: this.state.flowStore, -            eventStore: this.state.eventStore, -            returnFocus: this.focus, -        }; -    }, -    getInitialState: function () { -        var eventStore = new store.EventLogStore(); -        var flowStore = new store.FlowStore(); -        var settingsStore = new store.SettingsStore(); - -        // Default Settings before fetch -        _.extend(settingsStore.dict, {}); -        return { -            settingsStore: settingsStore, -            flowStore: flowStore, -            eventStore: eventStore -        }; -    }, -    focus: function () { -        React.findDOMNode(this).focus(); -    }, -    getMainComponent: function () { -        return this.refs.view.refs.__routeHandler__; -    }, -    onKeydown: function (e) { - -        var selectFilterInput = function (name) { -            var headerComponent = this.refs.header; -            headerComponent.setState({active: header.MainMenu}, function () { -                headerComponent.refs.active.refs[name].select(); -            }); -        }.bind(this); - -        switch (e.keyCode) { -            case Key.I: -                selectFilterInput("intercept"); -                break; -            case Key.L: -                selectFilterInput("search"); -                break; -            case Key.H: -                selectFilterInput("highlight"); -                break; -            default: -                var main = this.getMainComponent(); -                if (main.onMainKeyDown) { -                    main.onMainKeyDown(e); -                } -                return; // don't prevent default then -        } -        e.preventDefault(); -    }, -    render: function () { -        var eventlog; -        if (this.getQuery()[Query.SHOW_EVENTLOG]) { -            eventlog = [ -                <common.Splitter key="splitter" axis="y"/>, -                <EventLog key="eventlog"/> -            ]; -        } else { -            eventlog = null; -        } -        return ( -            <div id="container" tabIndex="0" onKeyDown={this.onKeydown}> -                <header.Header ref="header"/> -                <RouteHandler ref="view" query={this.getQuery()}/> -                {eventlog} -                <Footer/> -            </div> -        ); -    } -}); - - -var Route = ReactRouter.Route; -var RouteHandler = ReactRouter.RouteHandler; -var Redirect = ReactRouter.Redirect; -var DefaultRoute = ReactRouter.DefaultRoute; -var NotFoundRoute = ReactRouter.NotFoundRoute; - - -var routes = ( -    <Route path="/" handler={ProxyAppMain}> -        <Route name="flows" path="flows" handler={MainView}/> -        <Route name="flow" path="flows/:flowId/:detailTab" handler={MainView}/> -        <Route name="reports" handler={Reports}/> -        <Redirect path="/" to="flows" /> -    </Route> -); - -module.exports = { -    routes: routes -};
\ No newline at end of file diff --git a/web/src/js/components/virtualscroll.js b/web/src/js/components/virtualscroll.js deleted file mode 100644 index 956e1a0b..00000000 --- a/web/src/js/components/virtualscroll.js +++ /dev/null @@ -1,85 +0,0 @@ -var React = require("react"); - -var VirtualScrollMixin = { -    getInitialState: function () { -        return { -            start: 0, -            stop: 0 -        }; -    }, -    componentWillMount: function () { -        if (!this.props.rowHeight) { -            console.warn("VirtualScrollMixin: No rowHeight specified", this); -        } -    }, -    getPlaceholderTop: function (total) { -        var Tag = this.props.placeholderTagName || "tr"; -        // When a large trunk of elements is removed from the button, start may be far off the viewport. -        // To make this issue less severe, limit the top placeholder to the total number of rows. -        var style = { -            height: Math.min(this.state.start, total) * this.props.rowHeight -        }; -        var spacer = <Tag key="placeholder-top" style={style}></Tag>; - -        if (this.state.start % 2 === 1) { -            // fix even/odd rows -            return [spacer, <Tag key="placeholder-top-2"></Tag>]; -        } else { -            return spacer; -        } -    }, -    getPlaceholderBottom: function (total) { -        var Tag = this.props.placeholderTagName || "tr"; -        var style = { -            height: Math.max(0, total - this.state.stop) * this.props.rowHeight -        }; -        return <Tag key="placeholder-bottom" style={style}></Tag>; -    }, -    componentDidMount: function () { -        this.onScroll(); -        window.addEventListener('resize', this.onScroll); -    }, -    componentWillUnmount: function(){ -        window.removeEventListener('resize', this.onScroll); -    }, -    onScroll: function () { -        var viewport = this.getDOMNode(); -        var top = viewport.scrollTop; -        var height = viewport.offsetHeight; -        var start = Math.floor(top / this.props.rowHeight); -        var stop = start + Math.ceil(height / (this.props.rowHeightMin || this.props.rowHeight)); - -        this.setState({ -            start: start, -            stop: stop -        }); -    }, -    renderRows: function (elems) { -        var rows = []; -        var max = Math.min(elems.length, this.state.stop); - -        for (var i = this.state.start; i < max; i++) { -            var elem = elems[i]; -            rows.push(this.renderRow(elem)); -        } -        return rows; -    }, -    scrollRowIntoView: function (index, head_height) { - -        var row_top = (index * this.props.rowHeight) + head_height; -        var row_bottom = row_top + this.props.rowHeight; - -        var viewport = this.getDOMNode(); -        var viewport_top = viewport.scrollTop; -        var viewport_bottom = viewport_top + viewport.offsetHeight; - -        // Account for pinned thead -        if (row_top - head_height < viewport_top) { -            viewport.scrollTop = row_top - head_height; -        } else if (row_bottom > viewport_bottom) { -            viewport.scrollTop = row_bottom - viewport.offsetHeight; -        } -    }, -}; - -module.exports  = VirtualScrollMixin;
\ No newline at end of file diff --git a/web/src/js/connection.js b/web/src/js/connection.js deleted file mode 100644 index 5e229b6e..00000000 --- a/web/src/js/connection.js +++ /dev/null @@ -1,29 +0,0 @@ - -var actions = require("./actions.js"); -var AppDispatcher = require("./dispatcher.js").AppDispatcher; - -function Connection(url) { -    if (url[0] === "/") { -        url = location.origin.replace("http", "ws") + url; -    } - -    var ws = new WebSocket(url); -    ws.onopen = function () { -        actions.ConnectionActions.open(); -    }; -    ws.onmessage = function (message) { -        var m = JSON.parse(message.data); -        AppDispatcher.dispatchServerAction(m); -    }; -    ws.onerror = function () { -        actions.ConnectionActions.error(); -        actions.EventLogActions.add_event("WebSocket connection error."); -    }; -    ws.onclose = function () { -        actions.ConnectionActions.close(); -        actions.EventLogActions.add_event("WebSocket connection closed."); -    }; -    return ws; -} - -module.exports = Connection;
\ No newline at end of file diff --git a/web/src/js/dispatcher.js b/web/src/js/dispatcher.js deleted file mode 100644 index 0c2aa202..00000000 --- a/web/src/js/dispatcher.js +++ /dev/null @@ -1,22 +0,0 @@ - -var flux = require("flux"); - -const PayloadSources = { -    VIEW: "view", -    SERVER: "server" -}; - - -var AppDispatcher = new flux.Dispatcher(); -AppDispatcher.dispatchViewAction = function (action) { -    action.source = PayloadSources.VIEW; -    this.dispatch(action); -}; -AppDispatcher.dispatchServerAction = function (action) { -    action.source = PayloadSources.SERVER; -    this.dispatch(action); -}; - -module.exports = { -    AppDispatcher: AppDispatcher -};
\ No newline at end of file diff --git a/web/src/js/filt/filt.js b/web/src/js/filt/filt.js deleted file mode 100644 index 45b42f3a..00000000 --- a/web/src/js/filt/filt.js +++ /dev/null @@ -1,1774 +0,0 @@ -module.exports = (function() { -  /* -   * Generated by PEG.js 0.8.0. -   * -   * http://pegjs.majda.cz/ -   */ - -  function peg$subclass(child, parent) { -    function ctor() { this.constructor = child; } -    ctor.prototype = parent.prototype; -    child.prototype = new ctor(); -  } - -  function SyntaxError(message, expected, found, offset, line, column) { -    this.message  = message; -    this.expected = expected; -    this.found    = found; -    this.offset   = offset; -    this.line     = line; -    this.column   = column; - -    this.name     = "SyntaxError"; -  } - -  peg$subclass(SyntaxError, Error); - -  function parse(input) { -    var options = arguments.length > 1 ? arguments[1] : {}, - -        peg$FAILED = {}, - -        peg$startRuleFunctions = { start: peg$parsestart }, -        peg$startRuleFunction  = peg$parsestart, - -        peg$c0 = { type: "other", description: "filter expression" }, -        peg$c1 = peg$FAILED, -        peg$c2 = function(orExpr) { return orExpr; }, -        peg$c3 = [], -        peg$c4 = function() {return trueFilter; }, -        peg$c5 = { type: "other", description: "whitespace" }, -        peg$c6 = /^[ \t\n\r]/, -        peg$c7 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, -        peg$c8 = { type: "other", description: "control character" }, -        peg$c9 = /^[|&!()~"]/, -        peg$c10 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, -        peg$c11 = { type: "other", description: "optional whitespace" }, -        peg$c12 = "|", -        peg$c13 = { type: "literal", value: "|", description: "\"|\"" }, -        peg$c14 = function(first, second) { return or(first, second); }, -        peg$c15 = "&", -        peg$c16 = { type: "literal", value: "&", description: "\"&\"" }, -        peg$c17 = function(first, second) { return and(first, second); }, -        peg$c18 = "!", -        peg$c19 = { type: "literal", value: "!", description: "\"!\"" }, -        peg$c20 = function(expr) { return not(expr); }, -        peg$c21 = "(", -        peg$c22 = { type: "literal", value: "(", description: "\"(\"" }, -        peg$c23 = ")", -        peg$c24 = { type: "literal", value: ")", description: "\")\"" }, -        peg$c25 = function(expr) { return binding(expr); }, -        peg$c26 = "~a", -        peg$c27 = { type: "literal", value: "~a", description: "\"~a\"" }, -        peg$c28 = function() { return assetFilter; }, -        peg$c29 = "~e", -        peg$c30 = { type: "literal", value: "~e", description: "\"~e\"" }, -        peg$c31 = function() { return errorFilter; }, -        peg$c32 = "~q", -        peg$c33 = { type: "literal", value: "~q", description: "\"~q\"" }, -        peg$c34 = function() { return noResponseFilter; }, -        peg$c35 = "~s", -        peg$c36 = { type: "literal", value: "~s", description: "\"~s\"" }, -        peg$c37 = function() { return responseFilter; }, -        peg$c38 = "true", -        peg$c39 = { type: "literal", value: "true", description: "\"true\"" }, -        peg$c40 = function() { return trueFilter; }, -        peg$c41 = "false", -        peg$c42 = { type: "literal", value: "false", description: "\"false\"" }, -        peg$c43 = function() { return falseFilter; }, -        peg$c44 = "~c", -        peg$c45 = { type: "literal", value: "~c", description: "\"~c\"" }, -        peg$c46 = function(s) { return responseCode(s); }, -        peg$c47 = "~d", -        peg$c48 = { type: "literal", value: "~d", description: "\"~d\"" }, -        peg$c49 = function(s) { return domain(s); }, -        peg$c50 = "~h", -        peg$c51 = { type: "literal", value: "~h", description: "\"~h\"" }, -        peg$c52 = function(s) { return header(s); }, -        peg$c53 = "~hq", -        peg$c54 = { type: "literal", value: "~hq", description: "\"~hq\"" }, -        peg$c55 = function(s) { return requestHeader(s); }, -        peg$c56 = "~hs", -        peg$c57 = { type: "literal", value: "~hs", description: "\"~hs\"" }, -        peg$c58 = function(s) { return responseHeader(s); }, -        peg$c59 = "~m", -        peg$c60 = { type: "literal", value: "~m", description: "\"~m\"" }, -        peg$c61 = function(s) { return method(s); }, -        peg$c62 = "~t", -        peg$c63 = { type: "literal", value: "~t", description: "\"~t\"" }, -        peg$c64 = function(s) { return contentType(s); }, -        peg$c65 = "~tq", -        peg$c66 = { type: "literal", value: "~tq", description: "\"~tq\"" }, -        peg$c67 = function(s) { return requestContentType(s); }, -        peg$c68 = "~ts", -        peg$c69 = { type: "literal", value: "~ts", description: "\"~ts\"" }, -        peg$c70 = function(s) { return responseContentType(s); }, -        peg$c71 = "~u", -        peg$c72 = { type: "literal", value: "~u", description: "\"~u\"" }, -        peg$c73 = function(s) { return url(s); }, -        peg$c74 = { type: "other", description: "integer" }, -        peg$c75 = null, -        peg$c76 = /^['"]/, -        peg$c77 = { type: "class", value: "['\"]", description: "['\"]" }, -        peg$c78 = /^[0-9]/, -        peg$c79 = { type: "class", value: "[0-9]", description: "[0-9]" }, -        peg$c80 = function(digits) { return parseInt(digits.join(""), 10); }, -        peg$c81 = { type: "other", description: "string" }, -        peg$c82 = "\"", -        peg$c83 = { type: "literal", value: "\"", description: "\"\\\"\"" }, -        peg$c84 = function(chars) { return chars.join(""); }, -        peg$c85 = "'", -        peg$c86 = { type: "literal", value: "'", description: "\"'\"" }, -        peg$c87 = void 0, -        peg$c88 = /^["\\]/, -        peg$c89 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, -        peg$c90 = { type: "any", description: "any character" }, -        peg$c91 = function(char) { return char; }, -        peg$c92 = "\\", -        peg$c93 = { type: "literal", value: "\\", description: "\"\\\\\"" }, -        peg$c94 = /^['\\]/, -        peg$c95 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, -        peg$c96 = /^['"\\]/, -        peg$c97 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, -        peg$c98 = "n", -        peg$c99 = { type: "literal", value: "n", description: "\"n\"" }, -        peg$c100 = function() { return "\n"; }, -        peg$c101 = "r", -        peg$c102 = { type: "literal", value: "r", description: "\"r\"" }, -        peg$c103 = function() { return "\r"; }, -        peg$c104 = "t", -        peg$c105 = { type: "literal", value: "t", description: "\"t\"" }, -        peg$c106 = function() { return "\t"; }, - -        peg$currPos          = 0, -        peg$reportedPos      = 0, -        peg$cachedPos        = 0, -        peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, -        peg$maxFailPos       = 0, -        peg$maxFailExpected  = [], -        peg$silentFails      = 0, - -        peg$result; - -    if ("startRule" in options) { -      if (!(options.startRule in peg$startRuleFunctions)) { -        throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); -      } - -      peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; -    } - -    function text() { -      return input.substring(peg$reportedPos, peg$currPos); -    } - -    function offset() { -      return peg$reportedPos; -    } - -    function line() { -      return peg$computePosDetails(peg$reportedPos).line; -    } - -    function column() { -      return peg$computePosDetails(peg$reportedPos).column; -    } - -    function expected(description) { -      throw peg$buildException( -        null, -        [{ type: "other", description: description }], -        peg$reportedPos -      ); -    } - -    function error(message) { -      throw peg$buildException(message, null, peg$reportedPos); -    } - -    function peg$computePosDetails(pos) { -      function advance(details, startPos, endPos) { -        var p, ch; - -        for (p = startPos; p < endPos; p++) { -          ch = input.charAt(p); -          if (ch === "\n") { -            if (!details.seenCR) { details.line++; } -            details.column = 1; -            details.seenCR = false; -          } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { -            details.line++; -            details.column = 1; -            details.seenCR = true; -          } else { -            details.column++; -            details.seenCR = false; -          } -        } -      } - -      if (peg$cachedPos !== pos) { -        if (peg$cachedPos > pos) { -          peg$cachedPos = 0; -          peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; -        } -        advance(peg$cachedPosDetails, peg$cachedPos, pos); -        peg$cachedPos = pos; -      } - -      return peg$cachedPosDetails; -    } - -    function peg$fail(expected) { -      if (peg$currPos < peg$maxFailPos) { return; } - -      if (peg$currPos > peg$maxFailPos) { -        peg$maxFailPos = peg$currPos; -        peg$maxFailExpected = []; -      } - -      peg$maxFailExpected.push(expected); -    } - -    function peg$buildException(message, expected, pos) { -      function cleanupExpected(expected) { -        var i = 1; - -        expected.sort(function(a, b) { -          if (a.description < b.description) { -            return -1; -          } else if (a.description > b.description) { -            return 1; -          } else { -            return 0; -          } -        }); - -        while (i < expected.length) { -          if (expected[i - 1] === expected[i]) { -            expected.splice(i, 1); -          } else { -            i++; -          } -        } -      } - -      function buildMessage(expected, found) { -        function stringEscape(s) { -          function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } - -          return s -            .replace(/\\/g,   '\\\\') -            .replace(/"/g,    '\\"') -            .replace(/\x08/g, '\\b') -            .replace(/\t/g,   '\\t') -            .replace(/\n/g,   '\\n') -            .replace(/\f/g,   '\\f') -            .replace(/\r/g,   '\\r') -            .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) -            .replace(/[\x10-\x1F\x80-\xFF]/g,    function(ch) { return '\\x'  + hex(ch); }) -            .replace(/[\u0180-\u0FFF]/g,         function(ch) { return '\\u0' + hex(ch); }) -            .replace(/[\u1080-\uFFFF]/g,         function(ch) { return '\\u'  + hex(ch); }); -        } - -        var expectedDescs = new Array(expected.length), -            expectedDesc, foundDesc, i; - -        for (i = 0; i < expected.length; i++) { -          expectedDescs[i] = expected[i].description; -        } - -        expectedDesc = expected.length > 1 -          ? expectedDescs.slice(0, -1).join(", ") -              + " or " -              + expectedDescs[expected.length - 1] -          : expectedDescs[0]; - -        foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; - -        return "Expected " + expectedDesc + " but " + foundDesc + " found."; -      } - -      var posDetails = peg$computePosDetails(pos), -          found      = pos < input.length ? input.charAt(pos) : null; - -      if (expected !== null) { -        cleanupExpected(expected); -      } - -      return new SyntaxError( -        message !== null ? message : buildMessage(expected, found), -        expected, -        found, -        pos, -        posDetails.line, -        posDetails.column -      ); -    } - -    function peg$parsestart() { -      var s0, s1, s2, s3; - -      peg$silentFails++; -      s0 = peg$currPos; -      s1 = peg$parse__(); -      if (s1 !== peg$FAILED) { -        s2 = peg$parseOrExpr(); -        if (s2 !== peg$FAILED) { -          s3 = peg$parse__(); -          if (s3 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c2(s2); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        s1 = []; -        if (s1 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c4(); -        } -        s0 = s1; -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c0); } -      } - -      return s0; -    } - -    function peg$parsews() { -      var s0, s1; - -      peg$silentFails++; -      if (peg$c6.test(input.charAt(peg$currPos))) { -        s0 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s0 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c7); } -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c5); } -      } - -      return s0; -    } - -    function peg$parsecc() { -      var s0, s1; - -      peg$silentFails++; -      if (peg$c9.test(input.charAt(peg$currPos))) { -        s0 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s0 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c10); } -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c8); } -      } - -      return s0; -    } - -    function peg$parse__() { -      var s0, s1; - -      peg$silentFails++; -      s0 = []; -      s1 = peg$parsews(); -      while (s1 !== peg$FAILED) { -        s0.push(s1); -        s1 = peg$parsews(); -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c11); } -      } - -      return s0; -    } - -    function peg$parseOrExpr() { -      var s0, s1, s2, s3, s4, s5; - -      s0 = peg$currPos; -      s1 = peg$parseAndExpr(); -      if (s1 !== peg$FAILED) { -        s2 = peg$parse__(); -        if (s2 !== peg$FAILED) { -          if (input.charCodeAt(peg$currPos) === 124) { -            s3 = peg$c12; -            peg$currPos++; -          } else { -            s3 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c13); } -          } -          if (s3 !== peg$FAILED) { -            s4 = peg$parse__(); -            if (s4 !== peg$FAILED) { -              s5 = peg$parseOrExpr(); -              if (s5 !== peg$FAILED) { -                peg$reportedPos = s0; -                s1 = peg$c14(s1, s5); -                s0 = s1; -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$parseAndExpr(); -      } - -      return s0; -    } - -    function peg$parseAndExpr() { -      var s0, s1, s2, s3, s4, s5; - -      s0 = peg$currPos; -      s1 = peg$parseNotExpr(); -      if (s1 !== peg$FAILED) { -        s2 = peg$parse__(); -        if (s2 !== peg$FAILED) { -          if (input.charCodeAt(peg$currPos) === 38) { -            s3 = peg$c15; -            peg$currPos++; -          } else { -            s3 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c16); } -          } -          if (s3 !== peg$FAILED) { -            s4 = peg$parse__(); -            if (s4 !== peg$FAILED) { -              s5 = peg$parseAndExpr(); -              if (s5 !== peg$FAILED) { -                peg$reportedPos = s0; -                s1 = peg$c17(s1, s5); -                s0 = s1; -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        s1 = peg$parseNotExpr(); -        if (s1 !== peg$FAILED) { -          s2 = []; -          s3 = peg$parsews(); -          if (s3 !== peg$FAILED) { -            while (s3 !== peg$FAILED) { -              s2.push(s3); -              s3 = peg$parsews(); -            } -          } else { -            s2 = peg$c1; -          } -          if (s2 !== peg$FAILED) { -            s3 = peg$parseAndExpr(); -            if (s3 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c17(s1, s3); -              s0 = s1; -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -        if (s0 === peg$FAILED) { -          s0 = peg$parseNotExpr(); -        } -      } - -      return s0; -    } - -    function peg$parseNotExpr() { -      var s0, s1, s2, s3; - -      s0 = peg$currPos; -      if (input.charCodeAt(peg$currPos) === 33) { -        s1 = peg$c18; -        peg$currPos++; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c19); } -      } -      if (s1 !== peg$FAILED) { -        s2 = peg$parse__(); -        if (s2 !== peg$FAILED) { -          s3 = peg$parseNotExpr(); -          if (s3 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c20(s3); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$parseBindingExpr(); -      } - -      return s0; -    } - -    function peg$parseBindingExpr() { -      var s0, s1, s2, s3, s4, s5; - -      s0 = peg$currPos; -      if (input.charCodeAt(peg$currPos) === 40) { -        s1 = peg$c21; -        peg$currPos++; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c22); } -      } -      if (s1 !== peg$FAILED) { -        s2 = peg$parse__(); -        if (s2 !== peg$FAILED) { -          s3 = peg$parseOrExpr(); -          if (s3 !== peg$FAILED) { -            s4 = peg$parse__(); -            if (s4 !== peg$FAILED) { -              if (input.charCodeAt(peg$currPos) === 41) { -                s5 = peg$c23; -                peg$currPos++; -              } else { -                s5 = peg$FAILED; -                if (peg$silentFails === 0) { peg$fail(peg$c24); } -              } -              if (s5 !== peg$FAILED) { -                peg$reportedPos = s0; -                s1 = peg$c25(s3); -                s0 = s1; -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$parseExpr(); -      } - -      return s0; -    } - -    function peg$parseExpr() { -      var s0; - -      s0 = peg$parseNullaryExpr(); -      if (s0 === peg$FAILED) { -        s0 = peg$parseUnaryExpr(); -      } - -      return s0; -    } - -    function peg$parseNullaryExpr() { -      var s0, s1; - -      s0 = peg$parseBooleanLiteral(); -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.substr(peg$currPos, 2) === peg$c26) { -          s1 = peg$c26; -          peg$currPos += 2; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c27); } -        } -        if (s1 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c28(); -        } -        s0 = s1; -        if (s0 === peg$FAILED) { -          s0 = peg$currPos; -          if (input.substr(peg$currPos, 2) === peg$c29) { -            s1 = peg$c29; -            peg$currPos += 2; -          } else { -            s1 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c30); } -          } -          if (s1 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c31(); -          } -          s0 = s1; -          if (s0 === peg$FAILED) { -            s0 = peg$currPos; -            if (input.substr(peg$currPos, 2) === peg$c32) { -              s1 = peg$c32; -              peg$currPos += 2; -            } else { -              s1 = peg$FAILED; -              if (peg$silentFails === 0) { peg$fail(peg$c33); } -            } -            if (s1 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c34(); -            } -            s0 = s1; -            if (s0 === peg$FAILED) { -              s0 = peg$currPos; -              if (input.substr(peg$currPos, 2) === peg$c35) { -                s1 = peg$c35; -                peg$currPos += 2; -              } else { -                s1 = peg$FAILED; -                if (peg$silentFails === 0) { peg$fail(peg$c36); } -              } -              if (s1 !== peg$FAILED) { -                peg$reportedPos = s0; -                s1 = peg$c37(); -              } -              s0 = s1; -            } -          } -        } -      } - -      return s0; -    } - -    function peg$parseBooleanLiteral() { -      var s0, s1; - -      s0 = peg$currPos; -      if (input.substr(peg$currPos, 4) === peg$c38) { -        s1 = peg$c38; -        peg$currPos += 4; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c39); } -      } -      if (s1 !== peg$FAILED) { -        peg$reportedPos = s0; -        s1 = peg$c40(); -      } -      s0 = s1; -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.substr(peg$currPos, 5) === peg$c41) { -          s1 = peg$c41; -          peg$currPos += 5; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c42); } -        } -        if (s1 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c43(); -        } -        s0 = s1; -      } - -      return s0; -    } - -    function peg$parseUnaryExpr() { -      var s0, s1, s2, s3; - -      s0 = peg$currPos; -      if (input.substr(peg$currPos, 2) === peg$c44) { -        s1 = peg$c44; -        peg$currPos += 2; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c45); } -      } -      if (s1 !== peg$FAILED) { -        s2 = []; -        s3 = peg$parsews(); -        if (s3 !== peg$FAILED) { -          while (s3 !== peg$FAILED) { -            s2.push(s3); -            s3 = peg$parsews(); -          } -        } else { -          s2 = peg$c1; -        } -        if (s2 !== peg$FAILED) { -          s3 = peg$parseIntegerLiteral(); -          if (s3 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c46(s3); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.substr(peg$currPos, 2) === peg$c47) { -          s1 = peg$c47; -          peg$currPos += 2; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c48); } -        } -        if (s1 !== peg$FAILED) { -          s2 = []; -          s3 = peg$parsews(); -          if (s3 !== peg$FAILED) { -            while (s3 !== peg$FAILED) { -              s2.push(s3); -              s3 = peg$parsews(); -            } -          } else { -            s2 = peg$c1; -          } -          if (s2 !== peg$FAILED) { -            s3 = peg$parseStringLiteral(); -            if (s3 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c49(s3); -              s0 = s1; -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -        if (s0 === peg$FAILED) { -          s0 = peg$currPos; -          if (input.substr(peg$currPos, 2) === peg$c50) { -            s1 = peg$c50; -            peg$currPos += 2; -          } else { -            s1 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c51); } -          } -          if (s1 !== peg$FAILED) { -            s2 = []; -            s3 = peg$parsews(); -            if (s3 !== peg$FAILED) { -              while (s3 !== peg$FAILED) { -                s2.push(s3); -                s3 = peg$parsews(); -              } -            } else { -              s2 = peg$c1; -            } -            if (s2 !== peg$FAILED) { -              s3 = peg$parseStringLiteral(); -              if (s3 !== peg$FAILED) { -                peg$reportedPos = s0; -                s1 = peg$c52(s3); -                s0 = s1; -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -          if (s0 === peg$FAILED) { -            s0 = peg$currPos; -            if (input.substr(peg$currPos, 3) === peg$c53) { -              s1 = peg$c53; -              peg$currPos += 3; -            } else { -              s1 = peg$FAILED; -              if (peg$silentFails === 0) { peg$fail(peg$c54); } -            } -            if (s1 !== peg$FAILED) { -              s2 = []; -              s3 = peg$parsews(); -              if (s3 !== peg$FAILED) { -                while (s3 !== peg$FAILED) { -                  s2.push(s3); -                  s3 = peg$parsews(); -                } -              } else { -                s2 = peg$c1; -              } -              if (s2 !== peg$FAILED) { -                s3 = peg$parseStringLiteral(); -                if (s3 !== peg$FAILED) { -                  peg$reportedPos = s0; -                  s1 = peg$c55(s3); -                  s0 = s1; -                } else { -                  peg$currPos = s0; -                  s0 = peg$c1; -                } -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -            if (s0 === peg$FAILED) { -              s0 = peg$currPos; -              if (input.substr(peg$currPos, 3) === peg$c56) { -                s1 = peg$c56; -                peg$currPos += 3; -              } else { -                s1 = peg$FAILED; -                if (peg$silentFails === 0) { peg$fail(peg$c57); } -              } -              if (s1 !== peg$FAILED) { -                s2 = []; -                s3 = peg$parsews(); -                if (s3 !== peg$FAILED) { -                  while (s3 !== peg$FAILED) { -                    s2.push(s3); -                    s3 = peg$parsews(); -                  } -                } else { -                  s2 = peg$c1; -                } -                if (s2 !== peg$FAILED) { -                  s3 = peg$parseStringLiteral(); -                  if (s3 !== peg$FAILED) { -                    peg$reportedPos = s0; -                    s1 = peg$c58(s3); -                    s0 = s1; -                  } else { -                    peg$currPos = s0; -                    s0 = peg$c1; -                  } -                } else { -                  peg$currPos = s0; -                  s0 = peg$c1; -                } -              } else { -                peg$currPos = s0; -                s0 = peg$c1; -              } -              if (s0 === peg$FAILED) { -                s0 = peg$currPos; -                if (input.substr(peg$currPos, 2) === peg$c59) { -                  s1 = peg$c59; -                  peg$currPos += 2; -                } else { -                  s1 = peg$FAILED; -                  if (peg$silentFails === 0) { peg$fail(peg$c60); } -                } -                if (s1 !== peg$FAILED) { -                  s2 = []; -                  s3 = peg$parsews(); -                  if (s3 !== peg$FAILED) { -                    while (s3 !== peg$FAILED) { -                      s2.push(s3); -                      s3 = peg$parsews(); -                    } -                  } else { -                    s2 = peg$c1; -                  } -                  if (s2 !== peg$FAILED) { -                    s3 = peg$parseStringLiteral(); -                    if (s3 !== peg$FAILED) { -                      peg$reportedPos = s0; -                      s1 = peg$c61(s3); -                      s0 = s1; -                    } else { -                      peg$currPos = s0; -                      s0 = peg$c1; -                    } -                  } else { -                    peg$currPos = s0; -                    s0 = peg$c1; -                  } -                } else { -                  peg$currPos = s0; -                  s0 = peg$c1; -                } -                if (s0 === peg$FAILED) { -                  s0 = peg$currPos; -                  if (input.substr(peg$currPos, 2) === peg$c62) { -                    s1 = peg$c62; -                    peg$currPos += 2; -                  } else { -                    s1 = peg$FAILED; -                    if (peg$silentFails === 0) { peg$fail(peg$c63); } -                  } -                  if (s1 !== peg$FAILED) { -                    s2 = []; -                    s3 = peg$parsews(); -                    if (s3 !== peg$FAILED) { -                      while (s3 !== peg$FAILED) { -                        s2.push(s3); -                        s3 = peg$parsews(); -                      } -                    } else { -                      s2 = peg$c1; -                    } -                    if (s2 !== peg$FAILED) { -                      s3 = peg$parseStringLiteral(); -                      if (s3 !== peg$FAILED) { -                        peg$reportedPos = s0; -                        s1 = peg$c64(s3); -                        s0 = s1; -                      } else { -                        peg$currPos = s0; -                        s0 = peg$c1; -                      } -                    } else { -                      peg$currPos = s0; -                      s0 = peg$c1; -                    } -                  } else { -                    peg$currPos = s0; -                    s0 = peg$c1; -                  } -                  if (s0 === peg$FAILED) { -                    s0 = peg$currPos; -                    if (input.substr(peg$currPos, 3) === peg$c65) { -                      s1 = peg$c65; -                      peg$currPos += 3; -                    } else { -                      s1 = peg$FAILED; -                      if (peg$silentFails === 0) { peg$fail(peg$c66); } -                    } -                    if (s1 !== peg$FAILED) { -                      s2 = []; -                      s3 = peg$parsews(); -                      if (s3 !== peg$FAILED) { -                        while (s3 !== peg$FAILED) { -                          s2.push(s3); -                          s3 = peg$parsews(); -                        } -                      } else { -                        s2 = peg$c1; -                      } -                      if (s2 !== peg$FAILED) { -                        s3 = peg$parseStringLiteral(); -                        if (s3 !== peg$FAILED) { -                          peg$reportedPos = s0; -                          s1 = peg$c67(s3); -                          s0 = s1; -                        } else { -                          peg$currPos = s0; -                          s0 = peg$c1; -                        } -                      } else { -                        peg$currPos = s0; -                        s0 = peg$c1; -                      } -                    } else { -                      peg$currPos = s0; -                      s0 = peg$c1; -                    } -                    if (s0 === peg$FAILED) { -                      s0 = peg$currPos; -                      if (input.substr(peg$currPos, 3) === peg$c68) { -                        s1 = peg$c68; -                        peg$currPos += 3; -                      } else { -                        s1 = peg$FAILED; -                        if (peg$silentFails === 0) { peg$fail(peg$c69); } -                      } -                      if (s1 !== peg$FAILED) { -                        s2 = []; -                        s3 = peg$parsews(); -                        if (s3 !== peg$FAILED) { -                          while (s3 !== peg$FAILED) { -                            s2.push(s3); -                            s3 = peg$parsews(); -                          } -                        } else { -                          s2 = peg$c1; -                        } -                        if (s2 !== peg$FAILED) { -                          s3 = peg$parseStringLiteral(); -                          if (s3 !== peg$FAILED) { -                            peg$reportedPos = s0; -                            s1 = peg$c70(s3); -                            s0 = s1; -                          } else { -                            peg$currPos = s0; -                            s0 = peg$c1; -                          } -                        } else { -                          peg$currPos = s0; -                          s0 = peg$c1; -                        } -                      } else { -                        peg$currPos = s0; -                        s0 = peg$c1; -                      } -                      if (s0 === peg$FAILED) { -                        s0 = peg$currPos; -                        if (input.substr(peg$currPos, 2) === peg$c71) { -                          s1 = peg$c71; -                          peg$currPos += 2; -                        } else { -                          s1 = peg$FAILED; -                          if (peg$silentFails === 0) { peg$fail(peg$c72); } -                        } -                        if (s1 !== peg$FAILED) { -                          s2 = []; -                          s3 = peg$parsews(); -                          if (s3 !== peg$FAILED) { -                            while (s3 !== peg$FAILED) { -                              s2.push(s3); -                              s3 = peg$parsews(); -                            } -                          } else { -                            s2 = peg$c1; -                          } -                          if (s2 !== peg$FAILED) { -                            s3 = peg$parseStringLiteral(); -                            if (s3 !== peg$FAILED) { -                              peg$reportedPos = s0; -                              s1 = peg$c73(s3); -                              s0 = s1; -                            } else { -                              peg$currPos = s0; -                              s0 = peg$c1; -                            } -                          } else { -                            peg$currPos = s0; -                            s0 = peg$c1; -                          } -                        } else { -                          peg$currPos = s0; -                          s0 = peg$c1; -                        } -                        if (s0 === peg$FAILED) { -                          s0 = peg$currPos; -                          s1 = peg$parseStringLiteral(); -                          if (s1 !== peg$FAILED) { -                            peg$reportedPos = s0; -                            s1 = peg$c73(s1); -                          } -                          s0 = s1; -                        } -                      } -                    } -                  } -                } -              } -            } -          } -        } -      } - -      return s0; -    } - -    function peg$parseIntegerLiteral() { -      var s0, s1, s2, s3; - -      peg$silentFails++; -      s0 = peg$currPos; -      if (peg$c76.test(input.charAt(peg$currPos))) { -        s1 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c77); } -      } -      if (s1 === peg$FAILED) { -        s1 = peg$c75; -      } -      if (s1 !== peg$FAILED) { -        s2 = []; -        if (peg$c78.test(input.charAt(peg$currPos))) { -          s3 = input.charAt(peg$currPos); -          peg$currPos++; -        } else { -          s3 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c79); } -        } -        if (s3 !== peg$FAILED) { -          while (s3 !== peg$FAILED) { -            s2.push(s3); -            if (peg$c78.test(input.charAt(peg$currPos))) { -              s3 = input.charAt(peg$currPos); -              peg$currPos++; -            } else { -              s3 = peg$FAILED; -              if (peg$silentFails === 0) { peg$fail(peg$c79); } -            } -          } -        } else { -          s2 = peg$c1; -        } -        if (s2 !== peg$FAILED) { -          if (peg$c76.test(input.charAt(peg$currPos))) { -            s3 = input.charAt(peg$currPos); -            peg$currPos++; -          } else { -            s3 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c77); } -          } -          if (s3 === peg$FAILED) { -            s3 = peg$c75; -          } -          if (s3 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c80(s2); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c74); } -      } - -      return s0; -    } - -    function peg$parseStringLiteral() { -      var s0, s1, s2, s3; - -      peg$silentFails++; -      s0 = peg$currPos; -      if (input.charCodeAt(peg$currPos) === 34) { -        s1 = peg$c82; -        peg$currPos++; -      } else { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c83); } -      } -      if (s1 !== peg$FAILED) { -        s2 = []; -        s3 = peg$parseDoubleStringChar(); -        while (s3 !== peg$FAILED) { -          s2.push(s3); -          s3 = peg$parseDoubleStringChar(); -        } -        if (s2 !== peg$FAILED) { -          if (input.charCodeAt(peg$currPos) === 34) { -            s3 = peg$c82; -            peg$currPos++; -          } else { -            s3 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c83); } -          } -          if (s3 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c84(s2); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.charCodeAt(peg$currPos) === 39) { -          s1 = peg$c85; -          peg$currPos++; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c86); } -        } -        if (s1 !== peg$FAILED) { -          s2 = []; -          s3 = peg$parseSingleStringChar(); -          while (s3 !== peg$FAILED) { -            s2.push(s3); -            s3 = peg$parseSingleStringChar(); -          } -          if (s2 !== peg$FAILED) { -            if (input.charCodeAt(peg$currPos) === 39) { -              s3 = peg$c85; -              peg$currPos++; -            } else { -              s3 = peg$FAILED; -              if (peg$silentFails === 0) { peg$fail(peg$c86); } -            } -            if (s3 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c84(s2); -              s0 = s1; -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -        if (s0 === peg$FAILED) { -          s0 = peg$currPos; -          s1 = peg$currPos; -          peg$silentFails++; -          s2 = peg$parsecc(); -          peg$silentFails--; -          if (s2 === peg$FAILED) { -            s1 = peg$c87; -          } else { -            peg$currPos = s1; -            s1 = peg$c1; -          } -          if (s1 !== peg$FAILED) { -            s2 = []; -            s3 = peg$parseUnquotedStringChar(); -            if (s3 !== peg$FAILED) { -              while (s3 !== peg$FAILED) { -                s2.push(s3); -                s3 = peg$parseUnquotedStringChar(); -              } -            } else { -              s2 = peg$c1; -            } -            if (s2 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c84(s2); -              s0 = s1; -            } else { -              peg$currPos = s0; -              s0 = peg$c1; -            } -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } -      } -      peg$silentFails--; -      if (s0 === peg$FAILED) { -        s1 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c81); } -      } - -      return s0; -    } - -    function peg$parseDoubleStringChar() { -      var s0, s1, s2; - -      s0 = peg$currPos; -      s1 = peg$currPos; -      peg$silentFails++; -      if (peg$c88.test(input.charAt(peg$currPos))) { -        s2 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s2 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c89); } -      } -      peg$silentFails--; -      if (s2 === peg$FAILED) { -        s1 = peg$c87; -      } else { -        peg$currPos = s1; -        s1 = peg$c1; -      } -      if (s1 !== peg$FAILED) { -        if (input.length > peg$currPos) { -          s2 = input.charAt(peg$currPos); -          peg$currPos++; -        } else { -          s2 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c90); } -        } -        if (s2 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c91(s2); -          s0 = s1; -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.charCodeAt(peg$currPos) === 92) { -          s1 = peg$c92; -          peg$currPos++; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c93); } -        } -        if (s1 !== peg$FAILED) { -          s2 = peg$parseEscapeSequence(); -          if (s2 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c91(s2); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } - -      return s0; -    } - -    function peg$parseSingleStringChar() { -      var s0, s1, s2; - -      s0 = peg$currPos; -      s1 = peg$currPos; -      peg$silentFails++; -      if (peg$c94.test(input.charAt(peg$currPos))) { -        s2 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s2 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c95); } -      } -      peg$silentFails--; -      if (s2 === peg$FAILED) { -        s1 = peg$c87; -      } else { -        peg$currPos = s1; -        s1 = peg$c1; -      } -      if (s1 !== peg$FAILED) { -        if (input.length > peg$currPos) { -          s2 = input.charAt(peg$currPos); -          peg$currPos++; -        } else { -          s2 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c90); } -        } -        if (s2 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c91(s2); -          s0 = s1; -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.charCodeAt(peg$currPos) === 92) { -          s1 = peg$c92; -          peg$currPos++; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c93); } -        } -        if (s1 !== peg$FAILED) { -          s2 = peg$parseEscapeSequence(); -          if (s2 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c91(s2); -            s0 = s1; -          } else { -            peg$currPos = s0; -            s0 = peg$c1; -          } -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } - -      return s0; -    } - -    function peg$parseUnquotedStringChar() { -      var s0, s1, s2; - -      s0 = peg$currPos; -      s1 = peg$currPos; -      peg$silentFails++; -      s2 = peg$parsews(); -      peg$silentFails--; -      if (s2 === peg$FAILED) { -        s1 = peg$c87; -      } else { -        peg$currPos = s1; -        s1 = peg$c1; -      } -      if (s1 !== peg$FAILED) { -        if (input.length > peg$currPos) { -          s2 = input.charAt(peg$currPos); -          peg$currPos++; -        } else { -          s2 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c90); } -        } -        if (s2 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c91(s2); -          s0 = s1; -        } else { -          peg$currPos = s0; -          s0 = peg$c1; -        } -      } else { -        peg$currPos = s0; -        s0 = peg$c1; -      } - -      return s0; -    } - -    function peg$parseEscapeSequence() { -      var s0, s1; - -      if (peg$c96.test(input.charAt(peg$currPos))) { -        s0 = input.charAt(peg$currPos); -        peg$currPos++; -      } else { -        s0 = peg$FAILED; -        if (peg$silentFails === 0) { peg$fail(peg$c97); } -      } -      if (s0 === peg$FAILED) { -        s0 = peg$currPos; -        if (input.charCodeAt(peg$currPos) === 110) { -          s1 = peg$c98; -          peg$currPos++; -        } else { -          s1 = peg$FAILED; -          if (peg$silentFails === 0) { peg$fail(peg$c99); } -        } -        if (s1 !== peg$FAILED) { -          peg$reportedPos = s0; -          s1 = peg$c100(); -        } -        s0 = s1; -        if (s0 === peg$FAILED) { -          s0 = peg$currPos; -          if (input.charCodeAt(peg$currPos) === 114) { -            s1 = peg$c101; -            peg$currPos++; -          } else { -            s1 = peg$FAILED; -            if (peg$silentFails === 0) { peg$fail(peg$c102); } -          } -          if (s1 !== peg$FAILED) { -            peg$reportedPos = s0; -            s1 = peg$c103(); -          } -          s0 = s1; -          if (s0 === peg$FAILED) { -            s0 = peg$currPos; -            if (input.charCodeAt(peg$currPos) === 116) { -              s1 = peg$c104; -              peg$currPos++; -            } else { -              s1 = peg$FAILED; -              if (peg$silentFails === 0) { peg$fail(peg$c105); } -            } -            if (s1 !== peg$FAILED) { -              peg$reportedPos = s0; -              s1 = peg$c106(); -            } -            s0 = s1; -          } -        } -      } - -      return s0; -    } - - -    var flowutils = require("../flow/utils.js"); - -    function or(first, second) { -        // Add explicit function names to ease debugging. -        function orFilter() { -            return first.apply(this, arguments) || second.apply(this, arguments); -        } -        orFilter.desc = first.desc + " or " + second.desc; -        return orFilter; -    } -    function and(first, second) { -        function andFilter() { -            return first.apply(this, arguments) && second.apply(this, arguments); -        } -        andFilter.desc = first.desc + " and " + second.desc; -        return andFilter; -    } -    function not(expr) { -        function notFilter() { -            return !expr.apply(this, arguments); -        } -        notFilter.desc = "not " + expr.desc; -        return notFilter; -    } -    function binding(expr) { -        function bindingFilter() { -            return expr.apply(this, arguments); -        } -        bindingFilter.desc = "(" + expr.desc + ")"; -        return bindingFilter; -    } -    function trueFilter(flow) { -        return true; -    } -    trueFilter.desc = "true"; -    function falseFilter(flow) { -        return false; -    } -    falseFilter.desc = "false"; - -    var ASSET_TYPES = [ -        new RegExp("text/javascript"), -        new RegExp("application/x-javascript"), -        new RegExp("application/javascript"), -        new RegExp("text/css"), -        new RegExp("image/.*"), -        new RegExp("application/x-shockwave-flash") -    ]; -    function assetFilter(flow) { -        if (flow.response) { -            var ct = flowutils.ResponseUtils.getContentType(flow.response); -            var i = ASSET_TYPES.length; -            while (i--) { -                if (ASSET_TYPES[i].test(ct)) { -                    return true; -                } -            } -        } -        return false; -    } -    assetFilter.desc = "is asset"; -    function responseCode(code){ -        function responseCodeFilter(flow){ -            return flow.response && flow.response.status_code === code; -        } -        responseCodeFilter.desc = "resp. code is " + code; -        return responseCodeFilter; -    } -    function domain(regex){ -        regex = new RegExp(regex, "i"); -        function domainFilter(flow){ -            return flow.request && regex.test(flow.request.host); -        } -        domainFilter.desc = "domain matches " + regex; -        return domainFilter; -    } -    function errorFilter(flow){ -        return !!flow.error; -    } -    errorFilter.desc = "has error"; -    function header(regex){ -        regex = new RegExp(regex, "i"); -        function headerFilter(flow){ -            return ( -                (flow.request && flowutils.RequestUtils.match_header(flow.request, regex)) -                || -                (flow.response && flowutils.ResponseUtils.match_header(flow.response, regex)) -            ); -        } -        headerFilter.desc = "header matches " + regex; -        return headerFilter; -    } -    function requestHeader(regex){ -        regex = new RegExp(regex, "i"); -        function requestHeaderFilter(flow){ -            return (flow.request && flowutils.RequestUtils.match_header(flow.request, regex)); -        } -        requestHeaderFilter.desc = "req. header matches " + regex; -        return requestHeaderFilter; -    } -    function responseHeader(regex){ -        regex = new RegExp(regex, "i"); -        function responseHeaderFilter(flow){ -            return (flow.response && flowutils.ResponseUtils.match_header(flow.response, regex)); -        } -        responseHeaderFilter.desc = "resp. header matches " + regex; -        return responseHeaderFilter; -    } -    function method(regex){ -        regex = new RegExp(regex, "i"); -        function methodFilter(flow){ -            return flow.request && regex.test(flow.request.method); -        } -        methodFilter.desc = "method matches " + regex; -        return methodFilter; -    } -    function noResponseFilter(flow){ -        return flow.request && !flow.response; -    } -    noResponseFilter.desc = "has no response"; -    function responseFilter(flow){ -        return !!flow.response; -    } -    responseFilter.desc = "has response"; - -    function contentType(regex){ -        regex = new RegExp(regex, "i"); -        function contentTypeFilter(flow){ -            return ( -                (flow.request && regex.test(flowutils.RequestUtils.getContentType(flow.request))) -                || -                (flow.response && regex.test(flowutils.ResponseUtils.getContentType(flow.response))) -            ); -        } -        contentTypeFilter.desc = "content type matches " + regex; -        return contentTypeFilter; -    } -    function requestContentType(regex){ -        regex = new RegExp(regex, "i"); -        function requestContentTypeFilter(flow){ -            return flow.request && regex.test(flowutils.RequestUtils.getContentType(flow.request)); -        } -        requestContentTypeFilter.desc = "req. content type matches " + regex; -        return requestContentTypeFilter; -    } -    function responseContentType(regex){ -        regex = new RegExp(regex, "i"); -        function responseContentTypeFilter(flow){ -            return flow.response && regex.test(flowutils.ResponseUtils.getContentType(flow.response)); -        } -        responseContentTypeFilter.desc = "resp. content type matches " + regex; -        return responseContentTypeFilter; -    } -    function url(regex){ -        regex = new RegExp(regex, "i"); -        function urlFilter(flow){ -            return flow.request && regex.test(flowutils.RequestUtils.pretty_url(flow.request)); -        } -        urlFilter.desc = "url matches " + regex; -        return urlFilter; -    } - - -    peg$result = peg$startRuleFunction(); - -    if (peg$result !== peg$FAILED && peg$currPos === input.length) { -      return peg$result; -    } else { -      if (peg$result !== peg$FAILED && peg$currPos < input.length) { -        peg$fail({ type: "end", description: "end of input" }); -      } - -      throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); -    } -  } - -  return { -    SyntaxError: SyntaxError, -    parse:       parse -  }; -})();
\ No newline at end of file diff --git a/web/src/js/filt/filt.peg b/web/src/js/filt/filt.peg deleted file mode 100644 index 6f9bdac6..00000000 --- a/web/src/js/filt/filt.peg +++ /dev/null @@ -1,249 +0,0 @@ -// PEG.js filter rules - see http://pegjs.majda.cz/online - -{ -var flowutils = require("../flow/utils.js"); - -function or(first, second) { -    // Add explicit function names to ease debugging. -    function orFilter() { -        return first.apply(this, arguments) || second.apply(this, arguments); -    } -    orFilter.desc = first.desc + " or " + second.desc; -    return orFilter; -} -function and(first, second) { -    function andFilter() { -        return first.apply(this, arguments) && second.apply(this, arguments); -    } -    andFilter.desc = first.desc + " and " + second.desc; -    return andFilter; -} -function not(expr) { -    function notFilter() { -        return !expr.apply(this, arguments); -    } -    notFilter.desc = "not " + expr.desc; -    return notFilter; -} -function binding(expr) { -    function bindingFilter() { -        return expr.apply(this, arguments); -    } -    bindingFilter.desc = "(" + expr.desc + ")"; -    return bindingFilter; -} -function trueFilter(flow) { -    return true; -} -trueFilter.desc = "true"; -function falseFilter(flow) { -    return false; -} -falseFilter.desc = "false"; - -var ASSET_TYPES = [ -    new RegExp("text/javascript"), -    new RegExp("application/x-javascript"), -    new RegExp("application/javascript"), -    new RegExp("text/css"), -    new RegExp("image/.*"), -    new RegExp("application/x-shockwave-flash") -]; -function assetFilter(flow) { -    if (flow.response) { -        var ct = flowutils.ResponseUtils.getContentType(flow.response); -        var i = ASSET_TYPES.length; -        while (i--) { -            if (ASSET_TYPES[i].test(ct)) { -                return true; -            } -        } -    } -    return false; -} -assetFilter.desc = "is asset"; -function responseCode(code){ -    function responseCodeFilter(flow){ -        return flow.response && flow.response.status_code === code; -    } -    responseCodeFilter.desc = "resp. code is " + code; -    return responseCodeFilter; -} -function domain(regex){ -    regex = new RegExp(regex, "i"); -    function domainFilter(flow){ -        return flow.request && regex.test(flow.request.host); -    } -    domainFilter.desc = "domain matches " + regex; -    return domainFilter; -} -function errorFilter(flow){ -    return !!flow.error; -} -errorFilter.desc = "has error"; -function header(regex){ -    regex = new RegExp(regex, "i"); -    function headerFilter(flow){ -        return ( -            (flow.request && flowutils.RequestUtils.match_header(flow.request, regex)) -            || -            (flow.response && flowutils.ResponseUtils.match_header(flow.response, regex)) -        ); -    } -    headerFilter.desc = "header matches " + regex; -    return headerFilter; -} -function requestHeader(regex){ -    regex = new RegExp(regex, "i"); -    function requestHeaderFilter(flow){ -        return (flow.request && flowutils.RequestUtils.match_header(flow.request, regex)); -    } -    requestHeaderFilter.desc = "req. header matches " + regex; -    return requestHeaderFilter; -} -function responseHeader(regex){ -    regex = new RegExp(regex, "i"); -    function responseHeaderFilter(flow){ -        return (flow.response && flowutils.ResponseUtils.match_header(flow.response, regex)); -    } -    responseHeaderFilter.desc = "resp. header matches " + regex; -    return responseHeaderFilter; -} -function method(regex){ -    regex = new RegExp(regex, "i"); -    function methodFilter(flow){ -        return flow.request && regex.test(flow.request.method); -    } -    methodFilter.desc = "method matches " + regex; -    return methodFilter; -} -function noResponseFilter(flow){ -    return flow.request && !flow.response; -} -noResponseFilter.desc = "has no response"; -function responseFilter(flow){ -    return !!flow.response; -} -responseFilter.desc = "has response"; - -function contentType(regex){ -    regex = new RegExp(regex, "i"); -    function contentTypeFilter(flow){ -        return ( -            (flow.request && regex.test(flowutils.RequestUtils.getContentType(flow.request))) -            || -            (flow.response && regex.test(flowutils.ResponseUtils.getContentType(flow.response))) -        ); -    } -    contentTypeFilter.desc = "content type matches " + regex; -    return contentTypeFilter; -} -function requestContentType(regex){ -    regex = new RegExp(regex, "i"); -    function requestContentTypeFilter(flow){ -        return flow.request && regex.test(flowutils.RequestUtils.getContentType(flow.request)); -    } -    requestContentTypeFilter.desc = "req. content type matches " + regex; -    return requestContentTypeFilter; -} -function responseContentType(regex){ -    regex = new RegExp(regex, "i"); -    function responseContentTypeFilter(flow){ -        return flow.response && regex.test(flowutils.ResponseUtils.getContentType(flow.response)); -    } -    responseContentTypeFilter.desc = "resp. content type matches " + regex; -    return responseContentTypeFilter; -} -function url(regex){ -    regex = new RegExp(regex, "i"); -    function urlFilter(flow){ -        return flow.request && regex.test(flowutils.RequestUtils.pretty_url(flow.request)); -    } -    urlFilter.desc = "url matches " + regex; -    return urlFilter; -} -} - -start "filter expression" -  = __ orExpr:OrExpr __ { return orExpr; } -  / {return trueFilter; } - -ws "whitespace" = [ \t\n\r] -cc "control character" = [|&!()~"] -__ "optional whitespace" = ws* - -OrExpr -  = first:AndExpr __ "|" __ second:OrExpr  -    { return or(first, second); } -  / AndExpr - -AndExpr -  = first:NotExpr __ "&" __ second:AndExpr  -    { return and(first, second); } -  / first:NotExpr ws+ second:AndExpr  -    { return and(first, second); } -  / NotExpr - -NotExpr -  = "!" __ expr:NotExpr  -    { return not(expr); } -  / BindingExpr - -BindingExpr -  = "(" __ expr:OrExpr __ ")"  -    { return binding(expr); } -  / Expr - -Expr -  = NullaryExpr -  / UnaryExpr - -NullaryExpr -  = BooleanLiteral -  / "~a" { return assetFilter; } -  / "~e" { return errorFilter; } -  / "~q" { return noResponseFilter; } -  / "~s" { return responseFilter; } - - -BooleanLiteral -  = "true" { return trueFilter; } -  / "false" { return falseFilter; } - -UnaryExpr -  = "~c"  ws+ s:IntegerLiteral { return responseCode(s); } -  / "~d"  ws+ s:StringLiteral { return domain(s); } -  / "~h"  ws+ s:StringLiteral { return header(s); } -  / "~hq" ws+ s:StringLiteral { return requestHeader(s); } -  / "~hs" ws+ s:StringLiteral { return responseHeader(s); } -  / "~m"  ws+ s:StringLiteral { return method(s); } -  / "~t"  ws+ s:StringLiteral { return contentType(s); } -  / "~tq" ws+ s:StringLiteral { return requestContentType(s); } -  / "~ts" ws+ s:StringLiteral { return responseContentType(s); } -  / "~u"  ws+ s:StringLiteral { return url(s); } -  / s:StringLiteral { return url(s); } - -IntegerLiteral "integer" -  = ['"]? digits:[0-9]+ ['"]? { return parseInt(digits.join(""), 10); } - -StringLiteral "string" -  = '"' chars:DoubleStringChar* '"' { return chars.join(""); } -  / "'" chars:SingleStringChar* "'" { return chars.join(""); } -  / !cc chars:UnquotedStringChar+ { return chars.join(""); } - -DoubleStringChar -  = !["\\] char:. { return char; } -  / "\\" char:EscapeSequence { return char; } - -SingleStringChar -  = !['\\] char:. { return char; } -  / "\\" char:EscapeSequence { return char; } - -UnquotedStringChar -  = !ws char:. { return char; } - -EscapeSequence -  = ['"\\] -  / "n" { return "\n"; } -  / "r" { return "\r"; } -  / "t" { return "\t"; } diff --git a/web/src/js/flow/utils.js b/web/src/js/flow/utils.js deleted file mode 100644 index d72febaa..00000000 --- a/web/src/js/flow/utils.js +++ /dev/null @@ -1,130 +0,0 @@ -var _ = require("lodash"); -var $ = require("jquery"); - -var defaultPorts = { -    "http": 80, -    "https": 443 -}; - -var MessageUtils = { -    getContentType: function (message) { -        var ct = this.get_first_header(message, /^Content-Type$/i); -        if(ct){ -            return ct.split(";")[0].trim(); -        } -    }, -    get_first_header: function (message, regex) { -        //FIXME: Cache Invalidation. -        if (!message._headerLookups) -            Object.defineProperty(message, "_headerLookups", { -                value: {}, -                configurable: false, -                enumerable: false, -                writable: false -            }); -        if (!(regex in message._headerLookups)) { -            var header; -            for (var i = 0; i < message.headers.length; i++) { -                if (!!message.headers[i][0].match(regex)) { -                    header = message.headers[i]; -                    break; -                } -            } -            message._headerLookups[regex] = header ? header[1] : undefined; -        } -        return message._headerLookups[regex]; -    }, -    match_header: function (message, regex) { -        var headers = message.headers; -        var i = headers.length; -        while (i--) { -            if (regex.test(headers[i].join(" "))) { -                return headers[i]; -            } -        } -        return false; -    }, -    getContentURL: function (flow, message) { -        if (message === flow.request) { -            message = "request"; -        } else if (message === flow.response) { -            message = "response"; -        } -        return "/flows/" + flow.id + "/" + message + "/content"; -    }, -    getContent: function (flow, message) { -        var url = MessageUtils.getContentURL(flow, message); -        return $.get(url); -    } -}; - -var RequestUtils = _.extend(MessageUtils, { -    pretty_host: function (request) { -        //FIXME: Add hostheader -        return request.host; -    }, -    pretty_url: function (request) { -        var port = ""; -        if (defaultPorts[request.scheme] !== request.port) { -            port = ":" + request.port; -        } -        return request.scheme + "://" + this.pretty_host(request) + port + request.path; -    } -}); - -var ResponseUtils = _.extend(MessageUtils, {}); - - -var parseUrl_regex = /^(?:(https?):\/\/)?([^\/:]+)?(?::(\d+))?(\/.*)?$/i; -var parseUrl = function (url) { -    //there are many correct ways to parse a URL, -    //however, a mitmproxy user may also wish to generate a not-so-correct URL. ;-) -    var parts = parseUrl_regex.exec(url); -    if(!parts){ -        return false; -    } - -    var scheme = parts[1], -        host = parts[2], -        port = parseInt(parts[3]), -        path = parts[4]; -    if (scheme) { -        port = port || defaultPorts[scheme]; -    } -    var ret = {}; -    if (scheme) { -        ret.scheme = scheme; -    } -    if (host) { -        ret.host = host; -    } -    if (port) { -        ret.port = port; -    } -    if (path) { -        ret.path = path; -    } -    return ret; -}; - - -var isValidHttpVersion_regex = /^HTTP\/\d+(\.\d+)*$/i; -var isValidHttpVersion = function (httpVersion) { -    return isValidHttpVersion_regex.test(httpVersion); -}; - -var parseHttpVersion = function (httpVersion) { -    httpVersion = httpVersion.replace("HTTP/", "").split("."); -    return _.map(httpVersion, function (x) { -        return parseInt(x); -    }); -}; - -module.exports = { -    ResponseUtils: ResponseUtils, -    RequestUtils: RequestUtils, -    MessageUtils: MessageUtils, -    parseUrl: parseUrl, -    parseHttpVersion: parseHttpVersion, -    isValidHttpVersion: isValidHttpVersion -};
\ No newline at end of file diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js deleted file mode 100644 index 5024049f..00000000 --- a/web/src/js/store/store.js +++ /dev/null @@ -1,181 +0,0 @@ - -var _ = require("lodash"); -var $ = require("jquery"); -var EventEmitter = require('events').EventEmitter; - -var utils = require("../utils.js"); -var actions = require("../actions.js"); -var dispatcher = require("../dispatcher.js"); - - -function ListStore() { -    EventEmitter.call(this); -    this.reset(); -} -_.extend(ListStore.prototype, EventEmitter.prototype, { -    add: function (elem) { -        if (elem.id in this._pos_map) { -            return; -        } -        this._pos_map[elem.id] = this.list.length; -        this.list.push(elem); -        this.emit("add", elem); -    }, -    update: function (elem) { -        if (!(elem.id in this._pos_map)) { -            return; -        } -        this.list[this._pos_map[elem.id]] = elem; -        this.emit("update", elem); -    }, -    remove: function (elem_id) { -        if (!(elem_id in this._pos_map)) { -            return; -        } -        this.list.splice(this._pos_map[elem_id], 1); -        this._build_map(); -        this.emit("remove", elem_id); -    }, -    reset: function (elems) { -        this.list = elems || []; -        this._build_map(); -        this.emit("recalculate"); -    }, -    _build_map: function () { -        this._pos_map = {}; -        for (var i = 0; i < this.list.length; i++) { -            var elem = this.list[i]; -            this._pos_map[elem.id] = i; -        } -    }, -    get: function (elem_id) { -        return this.list[this._pos_map[elem_id]]; -    }, -    index: function (elem_id) { -        return this._pos_map[elem_id]; -    } -}); - - -function DictStore() { -    EventEmitter.call(this); -    this.reset(); -} -_.extend(DictStore.prototype, EventEmitter.prototype, { -    update: function (dict) { -        _.merge(this.dict, dict); -        this.emit("recalculate"); -    }, -    reset: function (dict) { -        this.dict = dict || {}; -        this.emit("recalculate"); -    } -}); - -function LiveStoreMixin(type) { -    this.type = type; - -    this._updates_before_fetch = undefined; -    this._fetchxhr = false; - -    this.handle = this.handle.bind(this); -    dispatcher.AppDispatcher.register(this.handle); - -    // Avoid double-fetch on startup. -    if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { -        this.fetch(); -    } -} -_.extend(LiveStoreMixin.prototype, { -    handle: function (event) { -        if (event.type === actions.ActionTypes.CONNECTION_OPEN) { -            return this.fetch(); -        } -        if (event.type === this.type) { -            if (event.cmd === actions.StoreCmds.RESET) { -                this.fetch(event.data); -            } else if (this._updates_before_fetch) { -                console.log("defer update", event); -                this._updates_before_fetch.push(event); -            } else { -                this[event.cmd](event.data); -            } -        } -    }, -    close: function () { -        dispatcher.AppDispatcher.unregister(this.handle); -    }, -    fetch: function (data) { -        console.log("fetch " + this.type); -        if (this._fetchxhr) { -            this._fetchxhr.abort(); -        } -        this._updates_before_fetch = []; // (JS: empty array is true) -        if (data) { -            this.handle_fetch(data); -        } else { -            this._fetchxhr = $.getJSON("/" + this.type) -                .done(function (message) { -                    this.handle_fetch(message.data); -                }.bind(this)) -                .fail(function () { -                    EventLogActions.add_event("Could not fetch " + this.type); -                }.bind(this)); -        } -    }, -    handle_fetch: function (data) { -        this._fetchxhr = false; -        console.log(this.type + " fetched.", this._updates_before_fetch); -        this.reset(data); -        var updates = this._updates_before_fetch; -        this._updates_before_fetch = false; -        for (var i = 0; i < updates.length; i++) { -            this.handle(updates[i]); -        } -    }, -}); - -function LiveListStore(type) { -    ListStore.call(this); -    LiveStoreMixin.call(this, type); -} -_.extend(LiveListStore.prototype, ListStore.prototype, LiveStoreMixin.prototype); - -function LiveDictStore(type) { -    DictStore.call(this); -    LiveStoreMixin.call(this, type); -} -_.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype); - - -function FlowStore() { -    return new LiveListStore(actions.ActionTypes.FLOW_STORE); -} - -function SettingsStore() { -    return new LiveDictStore(actions.ActionTypes.SETTINGS_STORE); -} - -function EventLogStore() { -    LiveListStore.call(this, actions.ActionTypes.EVENT_STORE); -} -_.extend(EventLogStore.prototype, LiveListStore.prototype, { -    fetch: function(){ -        LiveListStore.prototype.fetch.apply(this, arguments); - -        // Make sure to display updates even if fetching all events failed. -        // This way, we can send "fetch failed" log messages to the log. -        if(this._fetchxhr){ -            this._fetchxhr.fail(function(){ -                this.handle_fetch(null); -            }.bind(this)); -        } -    } -}); - - -module.exports = { -    EventLogStore: EventLogStore, -    SettingsStore: SettingsStore, -    FlowStore: FlowStore -};
\ No newline at end of file diff --git a/web/src/js/store/view.js b/web/src/js/store/view.js deleted file mode 100644 index d628d46b..00000000 --- a/web/src/js/store/view.js +++ /dev/null @@ -1,115 +0,0 @@ -var EventEmitter = require('events').EventEmitter; -var _ = require("lodash"); - -var utils = require("../utils.js"); - -function SortByStoreOrder(elem) { -    return this.store.index(elem.id); -} - -var default_sort = SortByStoreOrder; -var default_filt = function (elem) { -    return true; -}; - -function StoreView(store, filt, sortfun) { -    EventEmitter.call(this); - -    this.store = store; - -    this.add = this.add.bind(this); -    this.update = this.update.bind(this); -    this.remove = this.remove.bind(this); -    this.recalculate = this.recalculate.bind(this); -    this.store.addListener("add", this.add); -    this.store.addListener("update", this.update); -    this.store.addListener("remove", this.remove); -    this.store.addListener("recalculate", this.recalculate); - -    this.recalculate(filt, sortfun); -} - -_.extend(StoreView.prototype, EventEmitter.prototype, { -    close: function () { -        this.store.removeListener("add", this.add); -        this.store.removeListener("update", this.update); -        this.store.removeListener("remove", this.remove); -        this.store.removeListener("recalculate", this.recalculate); -        this.removeAllListeners(); -    }, -    recalculate: function (filt, sortfun) { -        filt = filt || this.filt || default_filt; -        sortfun = sortfun || this.sortfun || default_sort; -        filt = filt.bind(this); -        sortfun = sortfun.bind(this); -        this.filt = filt; -        this.sortfun = sortfun; - -        this.list = this.store.list.filter(filt); -        this.list.sort(function (a, b) { -            var akey = sortfun(a); -            var bkey = sortfun(b); -            if(akey < bkey){ -                return -1; -            } else if(akey > bkey){ -                return 1; -            } else { -                return 0; -            } -        }); -        this.emit("recalculate"); -    }, -    index: function (elem) { -        return _.sortedIndex(this.list, elem, this.sortfun); -    }, -    add: function (elem) { -        if (this.filt(elem)) { -            var idx = this.index(elem); -            if (idx === this.list.length) { //happens often, .push is way faster. -                this.list.push(elem); -            } else { -                this.list.splice(idx, 0, elem); -            } -            this.emit("add", elem, idx); -        } -    }, -    update: function (elem) { -        var idx; -        var i = this.list.length; -        // Search from the back, we usually update the latest entries. -        while (i--) { -            if (this.list[i].id === elem.id) { -                idx = i; -                break; -            } -        } - -        if (idx === -1) { //not contained in list -            this.add(elem); -        } else if (!this.filt(elem)) { -            this.remove(elem.id); -        } else { -            if (this.sortfun(this.list[idx]) !== this.sortfun(elem)) { //sortpos has changed -                this.remove(this.list[idx]); -                this.add(elem); -            } else { -                this.list[idx] = elem; -                this.emit("update", elem, idx); -            } -        } -    }, -    remove: function (elem_id) { -        var idx = this.list.length; -        while (idx--) { -            if (this.list[idx].id === elem_id) { -                this.list.splice(idx, 1); -                this.emit("remove", elem_id, idx); -                break; -            } -        } -    } -}); - -module.exports = { -    StoreView: StoreView -};
\ No newline at end of file diff --git a/web/src/js/tests/utils.js b/web/src/js/tests/utils.js deleted file mode 100644 index dfbb9ba6..00000000 --- a/web/src/js/tests/utils.js +++ /dev/null @@ -1,15 +0,0 @@ -jest.dontMock("jquery"); -jest.dontMock("../utils"); - -describe("utils", function () { -    var utils = require("../utils"); -    it("formatSize", function(){ -        expect(utils.formatSize(1024)).toEqual("1kb"); -        expect(utils.formatSize(0)).toEqual("0"); -        expect(utils.formatSize(10)).toEqual("10b"); -        expect(utils.formatSize(1025)).toEqual("1.0kb"); -        expect(utils.formatSize(1024*1024)).toEqual("1mb"); -        expect(utils.formatSize(1024*1024+1)).toEqual("1.0mb"); -    }); -}); - diff --git a/web/src/js/utils.js b/web/src/js/utils.js deleted file mode 100644 index 40575692..00000000 --- a/web/src/js/utils.js +++ /dev/null @@ -1,112 +0,0 @@ -var $ = require("jquery"); -var _ = require("lodash"); -var actions = require("./actions.js"); - -window.$ = $; -window._ = _; -window.React = require("react"); - -var Key = { -    UP: 38, -    DOWN: 40, -    PAGE_UP: 33, -    PAGE_DOWN: 34, -    HOME: 36, -    END: 35, -    LEFT: 37, -    RIGHT: 39, -    ENTER: 13, -    ESC: 27, -    TAB: 9, -    SPACE: 32, -    BACKSPACE: 8, -    SHIFT: 16 -}; -// Add A-Z -for (var i = 65; i <= 90; i++) { -    Key[String.fromCharCode(i)] = i; -} - - -var formatSize = function (bytes) { -    if (bytes === 0) -        return "0"; -    var prefix = ["b", "kb", "mb", "gb", "tb"]; -    for (var i = 0; i < prefix.length; i++) { -        if (Math.pow(1024, i + 1) > bytes) { -            break; -        } -    } -    var precision; -    if (bytes % Math.pow(1024, i) === 0) -        precision = 0; -    else -        precision = 1; -    return (bytes / Math.pow(1024, i)).toFixed(precision) + prefix[i]; -}; - - -var formatTimeDelta = function (milliseconds) { -    var time = milliseconds; -    var prefix = ["ms", "s", "min", "h"]; -    var div = [1000, 60, 60]; -    var i = 0; -    while (Math.abs(time) >= div[i] && i < div.length) { -        time = time / div[i]; -        i++; -    } -    return Math.round(time) + prefix[i]; -}; - - -var formatTimeStamp = function (seconds) { -    var ts = (new Date(seconds * 1000)).toISOString(); -    return ts.replace("T", " ").replace("Z", ""); -}; - -// At some places, we need to sort strings alphabetically descending, -// but we can only provide a key function. -// This beauty "reverses" a JS string. -var end = String.fromCharCode(0xffff); -function reverseString(s) { -    return String.fromCharCode.apply(String, -            _.map(s.split(""), function (c) { -                return 0xffff - c.charCodeAt(0); -            }) -        ) + end; -} - -function getCookie(name) { -    var r = document.cookie.match(new RegExp("\\b" + name + "=([^;]*)\\b")); -    return r ? r[1] : undefined; -} -var xsrf = $.param({_xsrf: getCookie("_xsrf")}); - -//Tornado XSRF Protection. -$.ajaxPrefilter(function (options) { -    if (["post", "put", "delete"].indexOf(options.type.toLowerCase()) >= 0 && options.url[0] === "/") { -        if(options.url.indexOf("?") === -1){ -            options.url += "?" + xsrf; -        } else { -            options.url += "&" + xsrf; -        } -    } -}); -// Log AJAX Errors -$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { -    if (thrownError === "abort") { -        return; -    } -    var message = jqXHR.responseText; -    console.error(thrownError, message, arguments); -    actions.EventLogActions.add_event(thrownError + ": " + message); -    alert(message); -}); - -module.exports = { -    formatSize: formatSize, -    formatTimeDelta: formatTimeDelta, -    formatTimeStamp: formatTimeStamp, -    reverseString: reverseString, -    Key: Key, -};
\ No newline at end of file  | 
