aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/.babelrc4
-rw-r--r--web/.bowerrc3
-rw-r--r--web/.eslintrc8
-rw-r--r--web/.eslintrc.yml3
-rw-r--r--web/gulpfile.js14
-rw-r--r--web/package.json54
-rw-r--r--web/src/css/flowtable.less3
-rw-r--r--web/src/css/footer.less4
-rw-r--r--web/src/css/layout.less2
-rw-r--r--web/src/js/actions.js32
-rw-r--r--web/src/js/app.js16
-rw-r--r--web/src/js/components/common.js135
-rw-r--r--web/src/js/components/editor.js38
-rw-r--r--web/src/js/components/eventlog.js244
-rw-r--r--web/src/js/components/flowtable-columns.js13
-rw-r--r--web/src/js/components/flowtable.js349
-rw-r--r--web/src/js/components/flowview/contentview.js12
-rw-r--r--web/src/js/components/flowview/details.js12
-rw-r--r--web/src/js/components/flowview/index.js58
-rw-r--r--web/src/js/components/flowview/messages.js68
-rw-r--r--web/src/js/components/flowview/nav.js16
-rw-r--r--web/src/js/components/footer.js35
-rw-r--r--web/src/js/components/header.js89
-rw-r--r--web/src/js/components/helpers/AutoScroll.js25
-rw-r--r--web/src/js/components/helpers/VirtualScroll.js70
-rw-r--r--web/src/js/components/mainview.js128
-rw-r--r--web/src/js/components/prompt.js22
-rw-r--r--web/src/js/components/proxyapp.js93
-rw-r--r--web/src/js/components/virtualscroll.js85
-rw-r--r--web/src/js/connection.js16
-rw-r--r--web/src/js/dispatcher.js8
-rw-r--r--web/src/js/filt/filt.js886
-rw-r--r--web/src/js/filt/filt.peg1
-rw-r--r--web/src/js/flow/utils.js25
-rw-r--r--web/src/js/store/store.js38
-rw-r--r--web/src/js/store/view.js18
-rw-r--r--web/src/js/tests/utils.js15
-rw-r--r--web/src/js/utils.js26
-rw-r--r--web/src/templates/index.html1
39 files changed, 1313 insertions, 1356 deletions
diff --git a/web/.babelrc b/web/.babelrc
new file mode 100644
index 00000000..5dd7708c
--- /dev/null
+++ b/web/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["es2015", "react"],
+ "plugins": ["transform-class-properties"]
+} \ No newline at end of file
diff --git a/web/.bowerrc b/web/.bowerrc
deleted file mode 100644
index 5e6701af..00000000
--- a/web/.bowerrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "directory" : "bower_components"
-} \ No newline at end of file
diff --git a/web/.eslintrc b/web/.eslintrc
deleted file mode 100644
index df187739..00000000
--- a/web/.eslintrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "ecmaFeatures": {
- "jsx": true
- },
- "env": {
- "es6": true
- }
-} \ No newline at end of file
diff --git a/web/.eslintrc.yml b/web/.eslintrc.yml
new file mode 100644
index 00000000..60028c97
--- /dev/null
+++ b/web/.eslintrc.yml
@@ -0,0 +1,3 @@
+{
+ "parser": "babel-eslint"
+} \ No newline at end of file
diff --git a/web/gulpfile.js b/web/gulpfile.js
index 83893c91..3c2e3f15 100644
--- a/web/gulpfile.js
+++ b/web/gulpfile.js
@@ -7,8 +7,6 @@ var conf = require('./conf.js');
var babelify = require('babelify');
var browserify = require('browserify');
var gulp = require("gulp");
-var concat = require('gulp-concat');
-var connect = require('gulp-connect');
var eslint = require('gulp-eslint');
var less = require("gulp-less");
var livereload = require("gulp-livereload");
@@ -16,18 +14,13 @@ var minifyCSS = require('gulp-minify-css');
var notify = require("gulp-notify");
var peg = require("gulp-peg");
var plumber = require("gulp-plumber");
-var react = require("gulp-react");
var rename = require("gulp-rename");
-var replace = require('gulp-replace');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require("gulp-util");
var _ = require('lodash');
-var map = require("map-stream");
-var reactify = require('reactify');
var uglifyify = require('uglifyify');
var buffer = require('vinyl-buffer');
var source = require('vinyl-source-stream');
-var transform = require('vinyl-transform');
var watchify = require('watchify');
var vendor_packages = _.difference(
@@ -103,6 +96,10 @@ function buildScript(bundler, filename, dev) {
function rebundle() {
return bundler.bundle()
+ .on('error', function(error) {
+ gutil.log(error + '\n' + error.codeFrame);
+ this.emit('end');
+ })
.pipe(dev ? plumber(handleError) : gutil.noop())
.pipe(source('bundle.js'))
.pipe(buffer())
@@ -116,6 +113,7 @@ function buildScript(bundler, filename, dev) {
// listen for an update and run rebundle
bundler.on('update', rebundle);
bundler.on('log', gutil.log);
+ bundler.on('error', gutil.log);
// run it once the first time buildScript is called
return rebundle();
@@ -150,7 +148,7 @@ function app_stream(dev) {
for (var vp of vendor_packages) {
bundler.external(vp);
}
- bundler = bundler.transform(babelify).transform(reactify);
+ bundler = bundler.transform(babelify);
return buildScript(bundler, "app.js", dev);
}
gulp.task('scripts-app-dev', function () {
diff --git a/web/package.json b/web/package.json
index 5bcbdd87..e489a0b1 100644
--- a/web/package.json
+++ b/web/package.json
@@ -5,6 +5,7 @@
"test": "jest ./src/js"
},
"jest": {
+ "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"testPathDirs": [
"./src/js"
],
@@ -15,41 +16,42 @@
"testDirectoryName": "tests"
},
"dependencies": {
- "bootstrap": "^3.3.4",
+ "bootstrap": "^3.3.6",
+ "classnames": "^2.2.3",
"flux": "^2.1.1",
- "jquery": "^2.1.4",
- "lodash": "^3.10.1",
- "react": "^0.13.3",
- "react-router": "^0.13.2"
+ "jquery": "^2.2.1",
+ "lodash": "^4.5.1",
+ "react": "^0.14.7",
+ "react-dom": "^0.14.7",
+ "react-router": "^2.0.0",
+ "shallowequal": "^0.2.2"
},
"devDependencies": {
- "babelify": "^6.3.0",
- "browserify": "^11.2.0",
- "eslint": "^1.5.1",
- "gulp": "^3.9.0",
- "gulp-concat": "^2.6.0",
- "gulp-connect": "^2.2.0",
- "gulp-eslint": "^1.0.0",
- "gulp-jshint": "^1.11.2",
- "gulp-less": "^3.0.3",
+ "babel-core": "^6.5.2",
+ "babel-eslint": "^5.0.0",
+ "babel-jest": "^6.0.1",
+ "babel-plugin-transform-class-properties": "^6.6.0",
+ "babel-preset-es2015": "^6.5.0",
+ "babel-preset-react": "^6.5.0",
+ "babelify": "^7.2.0",
+ "browserify": "^13.0.0",
+ "eslint": "^2.2.0",
+ "gulp": "^3.9.1",
+ "gulp-eslint": "^2.0.0",
+ "gulp-less": "^3.0.5",
"gulp-livereload": "^3.8.1",
- "gulp-minify-css": "^1.2.1",
+ "gulp-minify-css": "^1.2.4",
"gulp-notify": "^2.2.0",
- "gulp-peg": "^0.1.2",
- "gulp-plumber": "^1.0.1",
- "gulp-react": "^3.0.1",
+ "gulp-peg": "^0.2.0",
+ "gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
- "gulp-replace": "^0.5.4",
"gulp-sourcemaps": "^1.6.0",
- "gulp-uglify": "^1.4.1",
- "gulp-util": "^3.0.6",
- "lodash": "^3.10.1",
- "map-stream": "0.0.6",
- "reactify": "^1.1.1",
+ "gulp-util": "^3.0.7",
+ "jest": "^0.1.40",
+ "lodash": "^4.5.1",
"uglifyify": "^3.0.1",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
- "vinyl-transform": "^1.0.0",
- "watchify": "^3.4.0"
+ "watchify": "^3.7.0"
}
}
diff --git a/web/src/css/flowtable.less b/web/src/css/flowtable.less
index 3533983c..1b560eba 100644
--- a/web/src/css/flowtable.less
+++ b/web/src/css/flowtable.less
@@ -10,7 +10,8 @@
.flow-table {
width: 100%;
- overflow: auto;
+ overflow-y: scroll;
+ overflow-x: hidden;
table {
width: 100%;
diff --git a/web/src/css/footer.less b/web/src/css/footer.less
index c041a022..34691207 100644
--- a/web/src/css/footer.less
+++ b/web/src/css/footer.less
@@ -1,4 +1,8 @@
footer {
box-shadow: 0 -1px 3px lightgray;
padding: 0px 10px 3px;
+
+ .label {
+ margin-right: 3px;
+ }
} \ No newline at end of file
diff --git a/web/src/css/layout.less b/web/src/css/layout.less
index 1075d6c9..ed4adb69 100644
--- a/web/src/css/layout.less
+++ b/web/src/css/layout.less
@@ -1,4 +1,4 @@
-html, body, #container {
+html, body, #container, #mitmproxy {
height: 100%;
margin: 0;
overflow: hidden;
diff --git a/web/src/js/actions.js b/web/src/js/actions.js
index 2455a52e..6ded4c44 100644
--- a/web/src/js/actions.js
+++ b/web/src/js/actions.js
@@ -1,8 +1,8 @@
-var $ = require("jquery");
-var _ = require("lodash");
-var AppDispatcher = require("./dispatcher.js").AppDispatcher;
+import $ from "jquery";
+import _ from "lodash";
+import {AppDispatcher} from "./dispatcher.js";
-var ActionTypes = {
+export var ActionTypes = {
// Connection
CONNECTION_OPEN: "connection_open",
CONNECTION_CLOSE: "connection_close",
@@ -11,17 +11,17 @@ var ActionTypes = {
// Stores
SETTINGS_STORE: "settings",
EVENT_STORE: "events",
- FLOW_STORE: "flows",
+ FLOW_STORE: "flows"
};
-var StoreCmds = {
+export var StoreCmds = {
ADD: "add",
UPDATE: "update",
REMOVE: "remove",
RESET: "reset"
};
-var ConnectionActions = {
+export var ConnectionActions = {
open: function () {
AppDispatcher.dispatchViewAction({
type: ActionTypes.CONNECTION_OPEN
@@ -39,7 +39,7 @@ var ConnectionActions = {
}
};
-var SettingsActions = {
+export var SettingsActions = {
update: function (settings) {
$.ajax({
@@ -61,7 +61,7 @@ var SettingsActions = {
};
var EventLogActions_event_id = 0;
-var EventLogActions = {
+export var EventLogActions = {
add_event: function (message) {
AppDispatcher.dispatchViewAction({
type: ActionTypes.EVENT_STORE,
@@ -75,7 +75,7 @@ var EventLogActions = {
}
};
-var FlowActions = {
+export var FlowActions = {
accept: function (flow) {
$.post("/flows/" + flow.id + "/accept");
},
@@ -120,18 +120,8 @@ var FlowActions = {
}
};
-var Query = {
+export 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
index 9fb868b8..e21fa499 100644
--- a/web/src/js/app.js
+++ b/web/src/js/app.js
@@ -1,9 +1,9 @@
-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;
+import React from "react"
+import { render } from 'react-dom'
+import $ from "jquery"
+import Connection from "./connection"
+import {app} from "./components/proxyapp.js"
+import { EventLogActions } from "./actions.js"
$(function () {
window.ws = new Connection("/updates");
@@ -12,8 +12,6 @@ $(function () {
EventLogActions.add_event(msg);
};
- ReactRouter.run(proxyapp.routes, function (Handler, state) {
- React.render(<Handler/>, document.body);
- });
+ render(app, document.getElementById("mitmproxy"));
});
diff --git a/web/src/js/components/common.js b/web/src/js/components/common.js
index 965ae9a7..ad97ab38 100644
--- a/web/src/js/components/common.js
+++ b/web/src/js/components/common.js
@@ -1,109 +1,34 @@
-var React = require("react");
-var ReactRouter = require("react-router");
-var _ = require("lodash");
+import React from "react"
+import ReactDOM from "react-dom"
+import _ from "lodash"
-// http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example)
-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 = {
+export var Router = {
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
- });
+ location: React.PropTypes.object,
+ router: React.PropTypes.object.isRequired
},
-};
-
-
-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.
+ updateLocation: function (pathname, queryUpdate) {
+ if (pathname === undefined) {
+ pathname = this.context.location.pathname;
+ }
+ var query = this.context.location.query;
+ if (queryUpdate !== undefined) {
+ for (var i in queryUpdate) {
+ if (queryUpdate.hasOwnProperty(i)) {
+ query[i] = queryUpdate[i] || undefined; //falsey values shall be removed.
+ }
}
}
- this.replaceWith(this.context.router.getCurrentPath(), this.context.router.getCurrentParams(), q);
+ this.context.router.replace({pathname, query});
},
- 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());
+ return _.clone(this.context.location.query);
}
-});
+};
-var Splitter = React.createClass({
+export var Splitter = React.createClass({
getDefaultProps: function () {
return {
axis: "x"
@@ -127,7 +52,7 @@ var Splitter = React.createClass({
window.addEventListener("dragend", this.onDragEnd);
},
onDragEnd: function () {
- this.getDOMNode().style.transform = "";
+ ReactDOM.findDOMNode(this).style.transform = "";
window.removeEventListener("dragend", this.onDragEnd);
window.removeEventListener("mouseup", this.onMouseUp);
window.removeEventListener("mousemove", this.onMouseMove);
@@ -135,7 +60,7 @@ var Splitter = React.createClass({
onMouseUp: function (e) {
this.onDragEnd();
- var node = this.getDOMNode();
+ var node = ReactDOM.findDOMNode(this);
var prev = node.previousElementSibling;
var next = node.nextElementSibling;
@@ -163,7 +88,7 @@ var Splitter = React.createClass({
} else {
dY = e.pageY - this.state.startY;
}
- this.getDOMNode().style.transform = "translate(" + dX + "px," + dY + "px)";
+ ReactDOM.findDOMNode(this).style.transform = "translate(" + dX + "px," + dY + "px)";
},
onResize: function () {
// Trigger a global resize event. This notifies components that employ virtual scrolling
@@ -176,7 +101,7 @@ var Splitter = React.createClass({
if (!this.state.applied) {
return;
}
- var node = this.getDOMNode();
+ var node = ReactDOM.findDOMNode(this);
var prev = node.previousElementSibling;
var next = node.nextElementSibling;
@@ -206,14 +131,4 @@ var Splitter = React.createClass({
</div>
);
}
-});
-
-module.exports = {
- ChildFocus: ChildFocus,
- RouterState: RouterState,
- Navigation: Navigation,
- StickyHeadMixin: StickyHeadMixin,
- AutoScrollMixin: AutoScrollMixin,
- Splitter: Splitter,
- SettingsState: SettingsState
-}; \ No newline at end of file
+}); \ No newline at end of file
diff --git a/web/src/js/components/editor.js b/web/src/js/components/editor.js
index f2d44566..eed2f7c6 100644
--- a/web/src/js/components/editor.js
+++ b/web/src/js/components/editor.js
@@ -1,6 +1,6 @@
-var React = require("react");
-var common = require("./common.js");
-var utils = require("../utils.js");
+import React from "react";
+import ReactDOM from 'react-dom';
+import {Key} from "../utils.js";
var contentToHtml = function (content) {
return _.escape(content);
@@ -98,12 +98,12 @@ var EditorBase = React.createClass({
range = document.caretRangeFromPoint(e.clientX, e.clientY);
} else {
range = document.createRange();
- range.selectNodeContents(React.findDOMNode(this));
+ range.selectNodeContents(ReactDOM.findDOMNode(this));
}
this._ignore_events = true;
this.setState({editable: true}, function () {
- var node = React.findDOMNode(this);
+ var node = ReactDOM.findDOMNode(this);
node.blur();
node.focus();
this._ignore_events = false;
@@ -117,7 +117,7 @@ var EditorBase = React.createClass({
// 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();
+ ReactDOM.findDOMNode(this).blur();
this.props.onStop && this.props.onStop();
},
_stop: function (e) {
@@ -126,24 +126,24 @@ var EditorBase = React.createClass({
}
console.log("_stop", _.extend({}, e));
window.getSelection().removeAllRanges(); //make sure that selection is cleared on blur
- var node = React.findDOMNode(this);
+ var node = ReactDOM.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);
+ ReactDOM.findDOMNode(this).innerHTML = this.props.contentToHtml(this.props.content);
},
onKeyDown: function (e) {
e.stopPropagation();
switch (e.keyCode) {
- case utils.Key.ESC:
+ case Key.ESC:
e.preventDefault();
this.reset();
this.stop();
break;
- case utils.Key.ENTER:
+ case Key.ENTER:
if (this.props.submitOnEnter && !e.shiftKey) {
e.preventDefault();
this.stop();
@@ -154,7 +154,7 @@ var EditorBase = React.createClass({
}
},
onInput: function () {
- var node = React.findDOMNode(this);
+ var node = ReactDOM.findDOMNode(this);
var content = this.props.nodeToContent(node);
this.props.onInput && this.props.onInput(content);
}
@@ -212,8 +212,10 @@ var ValidateEditor = React.createClass({
/*
Text Editor with mitmweb-specific convenience features
*/
-var ValueEditor = React.createClass({
- mixins: [common.ChildFocus],
+export var ValueEditor = React.createClass({
+ contextTypes: {
+ returnFocus: React.PropTypes.func
+ },
propTypes: {
content: React.PropTypes.string.isRequired,
onDone: React.PropTypes.func.isRequired,
@@ -228,13 +230,9 @@ var ValueEditor = React.createClass({
/>;
},
focus: function () {
- React.findDOMNode(this).focus();
+ ReactDOM.findDOMNode(this).focus();
},
onStop: function () {
- this.returnFocus();
+ this.context.returnFocus();
}
-});
-
-module.exports = {
- ValueEditor: ValueEditor
-}; \ No newline at end of file
+}); \ No newline at end of file
diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js
index fea7b247..d1b23ace 100644
--- a/web/src/js/components/eventlog.js
+++ b/web/src/js/components/eventlog.js
@@ -1,115 +1,151 @@
-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>
+import React from "react"
+import ReactDOM from "react-dom"
+import shallowEqual from "shallowequal"
+import {Router} from "./common.js"
+import {Query} from "../actions.js"
+import AutoScroll from "./helpers/AutoScroll";
+import {calcVScroll} from "./helpers/VirtualScroll"
+import {StoreView} from "../store/view.js"
+import _ from "lodash"
+
+class EventLogContents extends React.Component {
+
+ static contextTypes = {
+ eventStore: React.PropTypes.object.isRequired,
+ };
+
+ static defaultProps = {
+ rowHeight: 18,
+ };
+
+ constructor(props, context) {
+ super(props, context);
+
+ this.view = new StoreView(
+ this.context.eventStore,
+ entry => this.props.filter[entry.level]
);
- },
- shouldComponentUpdate: function () {
- return false; // log entries are immutable.
+
+ this.heights = {};
+ this.state = { entries: this.view.list, vScroll: calcVScroll() };
+
+ this.onChange = this.onChange.bind(this);
+ this.onViewportUpdate = this.onViewportUpdate.bind(this);
}
-});
-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);
+ componentDidMount() {
+ window.addEventListener("resize", this.onViewportUpdate);
+ this.view.addListener("add", this.onChange);
+ this.view.addListener("recalculate", this.onChange);
+ this.onViewportUpdate();
+ }
- 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) {
+ componentWillUnmount() {
+ window.removeEventListener("resize", this.onViewportUpdate);
+ this.view.removeListener("add", this.onChange);
+ this.view.removeListener("recalculate", this.onChange);
+ this.view.close();
+ }
+
+ componentDidUpdate() {
+ this.onViewportUpdate();
+ }
+
+ componentWillReceiveProps(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();
+ this.view.recalculate(
+ entry => nextProps.filter[entry.level]
+ );
}
- },
- 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";
+ onViewportUpdate() {
+ const viewport = ReactDOM.findDOMNode(this);
+
+ const vScroll = calcVScroll({
+ itemCount: this.state.entries.length,
+ rowHeight: this.props.rowHeight,
+ viewportTop: viewport.scrollTop,
+ viewportHeight: viewport.offsetHeight,
+ itemHeights: this.state.entries.map(entry => this.heights[entry.id]),
+ });
+
+ if (!shallowEqual(this.state.vScroll, vScroll)) {
+ this.setState({ vScroll });
}
+ }
+
+ onChange() {
+ this.setState({ entries: this.view.list });
+ }
+
+ setHeight(id, ref) {
+ if (ref && !this.heights[id]) {
+ const height = ReactDOM.findDOMNode(ref).offsetHeight;
+ if (this.heights[id] !== height) {
+ this.heights[id] = height;
+ this.onViewportUpdate();
+ }
+ }
+ }
+
+ getIcon(level) {
+ return { web: "html5", debug: "bug" }[level] || "info";
+ }
+
+ render() {
+ const vScroll = this.state.vScroll;
+ const entries = this.state.entries.slice(vScroll.start, vScroll.end);
+
return (
- <a
- href="#"
- className={className}
- onClick={this.toggle}>
- {this.props.name}
- </a>
+ <pre onScroll={this.onViewportUpdate}>
+ <div style={{ height: vScroll.paddingTop }}></div>
+ {entries.map((entry, index) => (
+ <div key={entry.id} ref={this.setHeight.bind(this, entry.id)}>
+ <i className={`fa fa-fw fa-${this.getIcon(entry.level)}`}></i>
+ {entry.message}
+ </div>
+ ))}
+ <div style={{ height: vScroll.paddingBottom }}></div>
+ </pre>
);
}
-});
+}
+
+ToggleFilter.propTypes = {
+ name: React.PropTypes.string.isRequired,
+ toggleLevel: React.PropTypes.func.isRequired,
+ active: React.PropTypes.bool,
+};
+
+function ToggleFilter ({ name, active, toggleLevel }) {
+ let className = "label ";
+ if (active) {
+ className += "label-primary";
+ } else {
+ className += "label-default";
+ }
+
+ function onClick(event) {
+ event.preventDefault();
+ toggleLevel(name);
+ }
+
+ return (
+ <a
+ href="#"
+ className={className}
+ onClick={onClick}>
+ {name}
+ </a>
+ );
+}
+
+const AutoScrollEventLog = AutoScroll(EventLogContents);
var EventLog = React.createClass({
- mixins: [common.Navigation],
- getInitialState: function () {
+ mixins: [Router],
+ getInitialState() {
return {
filter: {
"debug": false,
@@ -118,17 +154,17 @@ var EventLog = React.createClass({
}
};
},
- close: function () {
+ close() {
var d = {};
d[Query.SHOW_EVENTLOG] = undefined;
- this.setQuery(d);
+ this.updateLocation(undefined, d);
},
- toggleLevel: function (level) {
+ toggleLevel(level) {
var filter = _.extend({}, this.state.filter);
filter[level] = !filter[level];
this.setState({filter: filter});
},
- render: function () {
+ render() {
return (
<div className="eventlog">
<div>
@@ -141,10 +177,10 @@ var EventLog = React.createClass({
</div>
</div>
- <EventLogContents filter={this.state.filter}/>
+ <AutoScrollEventLog filter={this.state.filter}/>
</div>
);
}
});
-module.exports = EventLog; \ No newline at end of file
+export default EventLog;
diff --git a/web/src/js/components/flowtable-columns.js b/web/src/js/components/flowtable-columns.js
index 74d96216..dbbe8847 100644
--- a/web/src/js/components/flowtable-columns.js
+++ b/web/src/js/components/flowtable-columns.js
@@ -1,7 +1,6 @@
-var React = require("react");
-var RequestUtils = require("../flow/utils.js").RequestUtils;
-var ResponseUtils = require("../flow/utils.js").ResponseUtils;
-var utils = require("../utils.js");
+import React from "react";
+import {RequestUtils, ResponseUtils} from "../flow/utils.js";
+import {formatSize, formatTimeDelta} from "../utils.js";
var TLSColumn = React.createClass({
statics: {
@@ -156,7 +155,7 @@ var SizeColumn = React.createClass({
if (flow.response) {
total += flow.response.contentLength || 0;
}
- var size = utils.formatSize(total);
+ var size = formatSize(total);
return <td className="col-size">{size}</td>;
}
});
@@ -179,7 +178,7 @@ var TimeColumn = React.createClass({
var flow = this.props.flow;
var time;
if (flow.response) {
- time = utils.formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start));
+ time = formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start));
} else {
time = "...";
}
@@ -198,4 +197,4 @@ var all_columns = [
TimeColumn
];
-module.exports = all_columns;
+export default all_columns;
diff --git a/web/src/js/components/flowtable.js b/web/src/js/components/flowtable.js
index 609034f6..f03b8ec0 100644
--- a/web/src/js/components/flowtable.js
+++ b/web/src/js/components/flowtable.js
@@ -1,187 +1,216 @@
-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";
- }
+import React from "react";
+import ReactDOM from "react-dom";
+import classNames from "classnames";
+import {reverseString} from "../utils.js";
+import _ from "lodash";
+import shallowEqual from "shallowequal";
+import AutoScroll from "./helpers/AutoScroll";
+import {calcVScroll} from "./helpers/VirtualScroll";
+import flowtable_columns from "./flowtable-columns.js";
- 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)
- //);
+FlowRow.propTypes = {
+ selectFlow: React.PropTypes.func.isRequired,
+ columns: React.PropTypes.array.isRequired,
+ flow: React.PropTypes.object.isRequired,
+ highlighted: React.PropTypes.bool,
+ selected: React.PropTypes.bool,
+};
+
+function FlowRow(props) {
+ const flow = props.flow;
+
+ const className = classNames({
+ "selected": props.selected,
+ "highlighted": props.highlighted,
+ "intercepted": flow.intercepted,
+ "has-request": flow.request,
+ "has-response": flow.response,
+ });
+
+ return (
+ <tr className={className} onClick={() => props.selectFlow(flow)}>
+ {props.columns.map(Column => (
+ <Column key={Column.displayName} flow={flow}/>
+ ))}
+ </tr>
+ );
+}
+
+class FlowTableHead extends React.Component {
+
+ static propTypes = {
+ setSortKeyFun: React.PropTypes.func.isRequired,
+ columns: React.PropTypes.array.isRequired,
+ };
+
+ constructor(props, context) {
+ super(props, context);
+ this.state = { sortColumn: undefined, sortDesc: false };
}
-});
-
-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){
+
+ onClick(Column) {
+ const hasSort = Column.sortKeyFun;
+
+ let sortDesc = this.state.sortDesc;
+
+ if (Column === this.state.sortColumn) {
sortDesc = !sortDesc;
- this.setState({
- sortDesc: sortDesc
- });
+ this.setState({ sortDesc });
} else {
- this.setState({
- sortColumn: hasSort && Column,
- sortDesc: false
- })
+ 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;
+
+ let sortKeyFun = Column.sortKeyFun;
+ if (sortDesc) {
+ sortKeyFun = hasSort && function() {
+ const k = Column.sortKeyFun.apply(this, arguments);
+ if (_.isString(k)) {
+ return reverseString("" + k);
}
- }
+ 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
+ }
+
+ render() {
+ const sortColumn = this.state.sortColumn;
+ const sortType = this.state.sortDesc ? "sort-desc" : "sort-asc";
+ return (
+ <tr>
+ {this.props.columns.map(Column => (
+ <Column.Title
key={Column.displayName}
- onClick={onClick}
- className={className} />;
- }.bind(this));
- return <thead>
- <tr>{columns}</tr>
- </thead>;
+ onClick={() => this.onClick(Column)}
+ className={sortColumn === Column && sortType}
+ />
+ ))}
+ </tr>
+ );
+ }
+}
+
+class FlowTable extends React.Component {
+
+ static contextTypes = {
+ view: React.PropTypes.object.isRequired,
+ };
+
+ static propTypes = {
+ rowHeight: React.PropTypes.number,
+ };
+
+ static defaultProps = {
+ rowHeight: 32,
+ };
+
+ constructor(props, context) {
+ super(props, context);
+
+ this.state = { flows: [], vScroll: calcVScroll() };
+
+ this.onChange = this.onChange.bind(this);
+ this.onViewportUpdate = this.onViewportUpdate.bind(this);
}
-});
-
-
-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 () {
+
+ componentWillMount() {
+ window.addEventListener("resize", this.onViewportUpdate);
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(){
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener("resize", this.onViewportUpdate);
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);
+ }
+
+ componentDidUpdate() {
+ this.onViewportUpdate();
+ }
+
+ onViewportUpdate() {
+ const viewport = ReactDOM.findDOMNode(this);
+ const viewportTop = viewport.scrollTop;
+
+ const vScroll = calcVScroll({
+ viewportTop,
+ viewportHeight: viewport.offsetHeight,
+ itemCount: this.state.flows.length,
+ rowHeight: this.props.rowHeight,
+ });
+
+ if (!shallowEqual(this.state.vScroll, vScroll) ||
+ this.state.viewportTop !== viewportTop) {
+ this.setState({ vScroll, viewportTop });
+ }
+ }
+
+ onChange() {
+ this.setState({ flows: this.context.view.list });
+ }
+
+ scrollIntoView(flow) {
+ const viewport = ReactDOM.findDOMNode(this);
+ const index = this.context.view.indexOf(flow);
+ const rowHeight = this.props.rowHeight;
+ const head = ReactDOM.findDOMNode(this.refs.head);
+
+ const headHeight = head ? head.offsetHeight : 0;
+
+ const rowTop = (index * rowHeight) + headHeight;
+ const rowBottom = rowTop + rowHeight;
+
+ const viewportTop = viewport.scrollTop;
+ const viewportHeight = viewport.offsetHeight;
+
+ // Account for pinned thead
+ if (rowTop - headHeight < viewportTop) {
+ viewport.scrollTop = rowTop - headHeight;
+ } else if (rowBottom > viewportTop + viewportHeight) {
+ viewport.scrollTop = rowBottom - viewportHeight;
+ }
+ }
+
+ render() {
+ const vScroll = this.state.vScroll;
+ const highlight = this.context.view._highlight;
+ const flows = this.state.flows.slice(vScroll.start, vScroll.end);
+
+ const transform = `translate(0,${this.state.viewportTop}px)`;
return (
- <div className="flow-table" onScroll={this.onScrollFlowTable}>
+ <div className="flow-table" onScroll={this.onViewportUpdate}>
<table>
- <FlowTableHead ref="head"
- columns={this.state.columns}
- setSortKeyFun={this.props.setSortKeyFun}/>
- <tbody ref="body">
- { this.getPlaceholderTop(flows.length) }
- {rows}
- { this.getPlaceholderBottom(flows.length) }
+ <thead ref="head" style={{ transform }}>
+ <FlowTableHead
+ columns={flowtable_columns}
+ setSortKeyFun={this.props.setSortKeyFun}
+ />
+ </thead>
+ <tbody>
+ <tr style={{ height: vScroll.paddingTop }}></tr>
+ {flows.map(flow => (
+ <FlowRow
+ key={flow.id}
+ flow={flow}
+ columns={flowtable_columns}
+ selected={flow === this.props.selected}
+ highlighted={highlight && highlight[flow.id]}
+ selectFlow={this.props.selectFlow}
+ />
+ ))}
+ <tr style={{ height: vScroll.paddingBottom }}></tr>
</tbody>
</table>
</div>
);
}
-});
+}
-module.exports = FlowTable;
+export default AutoScroll(FlowTable);
diff --git a/web/src/js/components/flowview/contentview.js b/web/src/js/components/flowview/contentview.js
index 63d22c1c..2743eec3 100644
--- a/web/src/js/components/flowview/contentview.js
+++ b/web/src/js/components/flowview/contentview.js
@@ -1,8 +1,8 @@
-var React = require("react");
-var _ = require("lodash");
+import React from "react";
+import _ from "lodash";
-var MessageUtils = require("../../flow/utils.js").MessageUtils;
-var utils = require("../../utils.js");
+import {MessageUtils} from "../../flow/utils.js";
+import {formatSize} from "../../utils.js";
var image_regex = /^image\/(png|jpe?g|gif|vnc.microsoft.icon|x-icon)$/i;
var ViewImage = React.createClass({
@@ -145,7 +145,7 @@ var TooLarge = React.createClass({
}
},
render: function () {
- var size = utils.formatSize(this.props.message.contentLength);
+ var size = 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.
@@ -234,4 +234,4 @@ var ContentView = React.createClass({
}
});
-module.exports = ContentView; \ No newline at end of file
+export default 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
index 00e0116c..45fe1292 100644
--- a/web/src/js/components/flowview/details.js
+++ b/web/src/js/components/flowview/details.js
@@ -1,7 +1,7 @@
-var React = require("react");
-var _ = require("lodash");
+import React from "react";
+import _ from "lodash";
-var utils = require("../../utils.js");
+import {formatTimeStamp, formatTimeDelta} from "../../utils.js";
var TimeStamp = React.createClass({
render: function () {
@@ -11,11 +11,11 @@ var TimeStamp = React.createClass({
return <tr></tr>;
}
- var ts = utils.formatTimeStamp(this.props.t);
+ var ts = formatTimeStamp(this.props.t);
var delta;
if (this.props.deltaTo) {
- delta = utils.formatTimeDelta(1000 * (this.props.t - this.props.deltaTo));
+ delta = formatTimeDelta(1000 * (this.props.t - this.props.deltaTo));
delta = <span className="text-muted">{"(" + delta + ")"}</span>;
} else {
delta = null;
@@ -178,4 +178,4 @@ var Details = React.createClass({
}
});
-module.exports = Details; \ No newline at end of file
+export default 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
index 739a46dc..47531f58 100644
--- a/web/src/js/components/flowview/index.js
+++ b/web/src/js/components/flowview/index.js
@@ -1,22 +1,21 @@
-var React = require("react");
-var _ = require("lodash");
+import React from "react";
-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");
+import {Router, StickyHeadMixin} from "../common.js"
+import Nav from "./nav.js";
+import {Request, Response, Error} from "./messages.js";
+import Details from "./details.js";
+import Prompt from "../prompt.js";
var allTabs = {
- request: Messages.Request,
- response: Messages.Response,
- error: Messages.Error,
+ request: Request,
+ response: Response,
+ error: Error,
details: Details
};
var FlowView = React.createClass({
- mixins: [common.StickyHeadMixin, common.Navigation, common.RouterState],
+ mixins: [StickyHeadMixin, Router],
getInitialState: function () {
return {
prompt: false
@@ -34,37 +33,28 @@ var FlowView = React.createClass({
},
nextTab: function (i) {
var tabs = this.getTabs(this.props.flow);
- var currentIndex = tabs.indexOf(this.getActive());
+ var currentIndex = tabs.indexOf(this.props.tab);
// JS modulo operator doesn't correct negative numbers, make sure that we are positive.
var nextIndex = (currentIndex + i + tabs.length) % tabs.length;
this.selectTab(tabs[nextIndex]);
},
selectTab: function (panel) {
- this.replaceWith(
- "flow",
- {
- flowId: this.getParams().flowId,
- detailTab: panel
- }
- );
- },
- getActive: function(){
- return this.getParams().detailTab;
+ this.updateLocation(`/flows/${this.props.flow.id}/${panel}`);
},
promptEdit: function () {
var options;
- switch(this.getActive()){
+ switch (this.props.tab) {
case "request":
options = [
"method",
"url",
- {text:"http version", key:"v"},
+ {text: "http version", key: "v"},
"header"
/*, "content"*/];
break;
case "response":
options = [
- {text:"http version", key:"v"},
+ {text: "http version", key: "v"},
"code",
"message",
"header"
@@ -73,14 +63,14 @@ var FlowView = React.createClass({
case "details":
return;
default:
- throw "Unknown tab for edit: " + this.getActive();
+ throw "Unknown tab for edit: " + this.props.tab;
}
this.setState({
prompt: {
done: function (k) {
this.setState({prompt: false});
- if(k){
+ if (k) {
this.refs.tab.edit(k);
}
}.bind(this),
@@ -91,9 +81,9 @@ var FlowView = React.createClass({
render: function () {
var flow = this.props.flow;
var tabs = this.getTabs(flow);
- var active = this.getActive();
+ var active = this.props.tab;
- if (!_.contains(tabs, active)) {
+ if (tabs.indexOf(active) < 0) {
if (active === "response" && flow.error) {
active = "error";
} else if (active === "error" && flow.response) {
@@ -113,10 +103,10 @@ var FlowView = React.createClass({
return (
<div className="flow-detail" onScroll={this.adjustHead}>
<Nav ref="head"
- flow={flow}
- tabs={tabs}
- active={active}
- selectTab={this.selectTab}/>
+ flow={flow}
+ tabs={tabs}
+ active={active}
+ selectTab={this.selectTab}/>
<Tab ref="tab" flow={flow}/>
{prompt}
</div>
@@ -124,4 +114,4 @@ var FlowView = React.createClass({
}
});
-module.exports = FlowView; \ No newline at end of file
+export default 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
index 7ac95d85..2885b3b1 100644
--- a/web/src/js/components/flowview/messages.js
+++ b/web/src/js/components/flowview/messages.js
@@ -1,12 +1,12 @@
-var React = require("react");
-var _ = require("lodash");
+import React from "react";
+import ReactDOM from 'react-dom';
+import _ from "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;
+import {FlowActions} from "../../actions.js";
+import {RequestUtils, isValidHttpVersion, parseUrl, parseHttpVersion} from "../../flow/utils.js";
+import {Key, formatTimeStamp} from "../../utils.js";
+import ContentView from "./contentview.js";
+import {ValueEditor} from "../editor.js";
var Headers = React.createClass({
propTypes: {
@@ -98,17 +98,17 @@ var HeaderEditor = React.createClass({
return <ValueEditor ref="input" {...this.props} onKeyDown={this.onKeyDown} inline/>;
},
focus: function () {
- this.getDOMNode().focus();
+ ReactDOM.findDOMNode(this).focus();
},
onKeyDown: function (e) {
switch (e.keyCode) {
- case utils.Key.BACKSPACE:
+ case Key.BACKSPACE:
var s = window.getSelection().getRangeAt(0);
if (s.startOffset === 0 && s.endOffset === 0) {
this.props.onRemove(e);
}
break;
- case utils.Key.TAB:
+ case Key.TAB:
if (!e.shiftKey) {
this.props.onTab(e);
}
@@ -120,7 +120,7 @@ var HeaderEditor = React.createClass({
var RequestLine = React.createClass({
render: function () {
var flow = this.props.flow;
- var url = flowutils.RequestUtils.pretty_url(flow.request);
+ var url = RequestUtils.pretty_url(flow.request);
var httpver = flow.request.http_version;
return <div className="first-line request-line">
@@ -141,31 +141,31 @@ var RequestLine = React.createClass({
ref="httpVersion"
content={httpver}
onDone={this.onHttpVersionChange}
- isValid={flowutils.isValidHttpVersion}
+ isValid={isValidHttpVersion}
inline/>
</div>
},
isValidUrl: function (url) {
- var u = flowutils.parseUrl(url);
+ var u = parseUrl(url);
return !!u.host;
},
onMethodChange: function (nextMethod) {
- actions.FlowActions.update(
+ FlowActions.update(
this.props.flow,
{request: {method: nextMethod}}
);
},
onUrlChange: function (nextUrl) {
- var props = flowutils.parseUrl(nextUrl);
+ var props = parseUrl(nextUrl);
props.path = props.path || "";
- actions.FlowActions.update(
+ FlowActions.update(
this.props.flow,
{request: props}
);
},
onHttpVersionChange: function (nextVer) {
- var ver = flowutils.parseHttpVersion(nextVer);
- actions.FlowActions.update(
+ var ver = parseHttpVersion(nextVer);
+ FlowActions.update(
this.props.flow,
{request: {http_version: ver}}
);
@@ -181,7 +181,7 @@ var ResponseLine = React.createClass({
ref="httpVersion"
content={httpver}
onDone={this.onHttpVersionChange}
- isValid={flowutils.isValidHttpVersion}
+ isValid={isValidHttpVersion}
inline/>
&nbsp;
<ValueEditor
@@ -193,7 +193,7 @@ var ResponseLine = React.createClass({
&nbsp;
<ValueEditor
ref="msg"
- content={flow.response.msg}
+ content={flow.response.reason}
onDone={this.onMsgChange}
inline/>
</div>;
@@ -202,28 +202,28 @@ var ResponseLine = React.createClass({
return /^\d+$/.test(code);
},
onHttpVersionChange: function (nextVer) {
- var ver = flowutils.parseHttpVersion(nextVer);
- actions.FlowActions.update(
+ var ver = parseHttpVersion(nextVer);
+ FlowActions.update(
this.props.flow,
{response: {http_version: ver}}
);
},
onMsgChange: function (nextMsg) {
- actions.FlowActions.update(
+ FlowActions.update(
this.props.flow,
{response: {msg: nextMsg}}
);
},
onCodeChange: function (nextCode) {
nextCode = parseInt(nextCode);
- actions.FlowActions.update(
+ FlowActions.update(
this.props.flow,
{response: {code: nextCode}}
);
}
});
-var Request = React.createClass({
+export var Request = React.createClass({
render: function () {
var flow = this.props.flow;
return (
@@ -255,7 +255,7 @@ var Request = React.createClass({
}
},
onHeaderChange: function (nextHeaders) {
- actions.FlowActions.update(this.props.flow, {
+ FlowActions.update(this.props.flow, {
request: {
headers: nextHeaders
}
@@ -263,7 +263,7 @@ var Request = React.createClass({
}
});
-var Response = React.createClass({
+export var Response = React.createClass({
render: function () {
var flow = this.props.flow;
return (
@@ -295,7 +295,7 @@ var Response = React.createClass({
}
},
onHeaderChange: function (nextHeaders) {
- actions.FlowActions.update(this.props.flow, {
+ FlowActions.update(this.props.flow, {
response: {
headers: nextHeaders
}
@@ -303,7 +303,7 @@ var Response = React.createClass({
}
});
-var Error = React.createClass({
+export var Error = React.createClass({
render: function () {
var flow = this.props.flow;
return (
@@ -311,16 +311,10 @@ var Error = React.createClass({
<div className="alert alert-warning">
{flow.error.msg}
<div>
- <small>{ utils.formatTimeStamp(flow.error.timestamp) }</small>
+ <small>{ 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
index 46eda707..a12fd1fd 100644
--- a/web/src/js/components/flowview/nav.js
+++ b/web/src/js/components/flowview/nav.js
@@ -1,6 +1,6 @@
-var React = require("react");
+import React from "react";
-var actions = require("../../actions.js");
+import {FlowActions} from "../../actions.js";
var NavAction = React.createClass({
onClick: function (e) {
@@ -38,19 +38,19 @@ var Nav = React.createClass({
var acceptButton = null;
if(flow.intercepted){
- acceptButton = <NavAction title="[a]ccept intercepted flow" icon="fa-play" onClick={actions.FlowActions.accept.bind(null, flow)} />;
+ acceptButton = <NavAction title="[a]ccept intercepted flow" icon="fa-play" onClick={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)} />;
+ revertButton = <NavAction title="revert changes to flow [V]" icon="fa-history" onClick={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)} />
+ <NavAction title="[d]elete flow" icon="fa-trash" onClick={FlowActions.delete.bind(null, flow)} />
+ <NavAction title="[D]uplicate flow" icon="fa-copy" onClick={FlowActions.duplicate.bind(null, flow)} />
+ <NavAction disabled title="[r]eplay flow" icon="fa-repeat" onClick={FlowActions.replay.bind(null, flow)} />
{acceptButton}
{revertButton}
</nav>
@@ -58,4 +58,4 @@ var Nav = React.createClass({
}
});
-module.exports = Nav; \ No newline at end of file
+export default Nav; \ No newline at end of file
diff --git a/web/src/js/components/footer.js b/web/src/js/components/footer.js
index 229d691b..e2d96288 100644
--- a/web/src/js/components/footer.js
+++ b/web/src/js/components/footer.js
@@ -1,19 +1,20 @@
-var React = require("react");
-var common = require("./common.js");
+import React from "react";
+import {SettingsState} from "./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}
- &nbsp;
- {intercept ? <span className="label label-success">Intercept: {intercept}</span> : null}
- </footer>
- );
- }
-});
+Footer.propTypes = {
+ settings: React.PropTypes.object.isRequired,
+};
-module.exports = Footer; \ No newline at end of file
+export default function Footer({ settings }) {
+ const {mode, intercept} = settings;
+ return (
+ <footer>
+ {mode && mode != "regular" && (
+ <span className="label label-success">{mode} mode</span>
+ )}
+ {intercept && (
+ <span className="label label-success">Intercept: {intercept}</span>
+ )}
+ </footer>
+ );
+}
diff --git a/web/src/js/components/header.js b/web/src/js/components/header.js
index 998a41df..1af928a3 100644
--- a/web/src/js/components/header.js
+++ b/web/src/js/components/header.js
@@ -1,11 +1,12 @@
-var React = require("react");
-var $ = require("jquery");
+import React from "react";
+import ReactDOM from 'react-dom';
+import $ from "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;
+import Filt from "../filt/filt.js";
+import {Key} from "../utils.js";
+import {Router} from "./common.js";
+import {SettingsActions, FlowActions} from "../actions.js";
+import {Query} from "../actions.js";
var FilterDocs = React.createClass({
statics: {
@@ -50,7 +51,9 @@ var FilterDocs = React.createClass({
}
});
var FilterInput = React.createClass({
- mixins: [common.ChildFocus],
+ contextTypes: {
+ returnFocus: React.PropTypes.func
+ },
getInitialState: function () {
// Consider both focus and mouseover for showing/hiding the tooltip,
// because onBlur of the input is triggered before the click on the tooltip
@@ -76,26 +79,24 @@ var FilterInput = React.createClass({
},
isValid: function (filt) {
try {
- Filt.parse(filt || this.state.value);
+ var str = filt || this.state.value;
+ if(str){
+ 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/>
- );
+ if(this.state.value) {
+ try {
+ return Filt.parse(this.state.value).desc;
+ } catch (e) {
+ return "" + e;
+ }
}
+ return <FilterDocs/>;
},
onFocus: function () {
this.setState({focus: true});
@@ -110,7 +111,7 @@ var FilterInput = React.createClass({
this.setState({mousefocus: false});
},
onKeyDown: function (e) {
- if (e.keyCode === utils.Key.ESC || e.keyCode === utils.Key.ENTER) {
+ if (e.keyCode === Key.ESC || e.keyCode === Key.ENTER) {
this.blur();
// If closed using ESC/ENTER, hide the tooltip.
this.setState({mousefocus: false});
@@ -118,11 +119,11 @@ var FilterInput = React.createClass({
e.stopPropagation();
},
blur: function () {
- this.refs.input.getDOMNode().blur();
- this.returnFocus();
+ ReactDOM.findDOMNode(this.refs.input).blur();
+ this.context.returnFocus();
},
select: function () {
- this.refs.input.getDOMNode().select();
+ ReactDOM.findDOMNode(this.refs.input).select();
},
render: function () {
var isValid = this.isValid();
@@ -159,8 +160,11 @@ var FilterInput = React.createClass({
}
});
-var MainMenu = React.createClass({
- mixins: [common.Navigation, common.RouterState, common.SettingsState],
+export var MainMenu = React.createClass({
+ mixins: [Router],
+ propTypes: {
+ settings: React.PropTypes.object.isRequired,
+ },
statics: {
title: "Start",
route: "flows"
@@ -168,20 +172,20 @@ var MainMenu = React.createClass({
onSearchChange: function (val) {
var d = {};
d[Query.SEARCH] = val;
- this.setQuery(d);
+ this.updateLocation(undefined, d);
},
onHighlightChange: function (val) {
var d = {};
d[Query.HIGHLIGHT] = val;
- this.setQuery(d);
+ this.updateLocation(undefined, d);
},
onInterceptChange: function (val) {
- actions.SettingsActions.update({intercept: val});
+ SettingsActions.update({intercept: val});
},
render: function () {
var search = this.getQuery()[Query.SEARCH] || "";
var highlight = this.getQuery()[Query.HIGHLIGHT] || "";
- var intercept = this.state.settings.intercept || "";
+ var intercept = this.props.settings.intercept || "";
return (
<div>
@@ -220,7 +224,7 @@ var ViewMenu = React.createClass({
title: "View",
route: "flows"
},
- mixins: [common.Navigation, common.RouterState],
+ mixins: [Router],
toggleEventLog: function () {
var d = {};
@@ -230,7 +234,7 @@ var ViewMenu = React.createClass({
d[Query.SHOW_EVENTLOG] = "t"; // any non-false value will do it, keep it short
}
- this.setQuery(d);
+ this.updateLocation(undefined, d);
},
render: function () {
var showEventLog = this.getQuery()[Query.SHOW_EVENTLOG];
@@ -282,7 +286,7 @@ var FileMenu = React.createClass({
handleNewClick: function (e) {
e.preventDefault();
if (confirm("Delete all flows?")) {
- actions.FlowActions.clear();
+ FlowActions.clear();
}
},
handleOpenClick: function (e) {
@@ -348,8 +352,11 @@ var FileMenu = React.createClass({
var header_entries = [MainMenu, ViewMenu /*, ReportsMenu */];
-var Header = React.createClass({
- mixins: [common.Navigation],
+export var Header = React.createClass({
+ mixins: [Router],
+ propTypes: {
+ settings: React.PropTypes.object.isRequired,
+ },
getInitialState: function () {
return {
active: header_entries[0]
@@ -357,7 +364,7 @@ var Header = React.createClass({
},
handleClick: function (active, e) {
e.preventDefault();
- this.replaceWith(active.route);
+ this.updateLocation(active.route);
this.setState({active: active});
},
render: function () {
@@ -385,15 +392,9 @@ var Header = React.createClass({
{header}
</nav>
<div className="menu">
- <this.state.active ref="active"/>
+ <this.state.active ref="active" settings={this.props.settings}/>
</div>
</header>
);
}
});
-
-
-module.exports = {
- Header: Header,
- MainMenu: MainMenu
-}; \ No newline at end of file
diff --git a/web/src/js/components/helpers/AutoScroll.js b/web/src/js/components/helpers/AutoScroll.js
new file mode 100644
index 00000000..d37b9f37
--- /dev/null
+++ b/web/src/js/components/helpers/AutoScroll.js
@@ -0,0 +1,25 @@
+import React from "react";
+import ReactDOM from "react-dom";
+
+const symShouldStick = Symbol("shouldStick");
+const isAtBottom = v => v.scrollTop + v.clientHeight === v.scrollHeight;
+
+export default Component => Object.assign(class AutoScrollWrapper extends Component {
+
+ static displayName = Component.name;
+
+ componentWillUpdate() {
+ const viewport = ReactDOM.findDOMNode(this);
+ this[symShouldStick] = viewport.scrollTop && isAtBottom(viewport);
+ super.componentWillUpdate && super.componentWillUpdate();
+ }
+
+ componentDidUpdate() {
+ const viewport = ReactDOM.findDOMNode(this);
+ if (this[symShouldStick] && !isAtBottom(viewport)) {
+ viewport.scrollTop = viewport.scrollHeight;
+ }
+ super.componentDidUpdate && super.componentDidUpdate();
+ }
+
+}, Component);
diff --git a/web/src/js/components/helpers/VirtualScroll.js b/web/src/js/components/helpers/VirtualScroll.js
new file mode 100644
index 00000000..d9b31003
--- /dev/null
+++ b/web/src/js/components/helpers/VirtualScroll.js
@@ -0,0 +1,70 @@
+/**
+ * Calculate virtual scroll stuffs
+ *
+ * @param {?Object} opts Options for calculation
+ *
+ * @returns {Object} result
+ *
+ * __opts__ should have following properties:
+ * - {number} itemCount
+ * - {number} rowHeight
+ * - {number} viewportTop
+ * - {number} viewportHeight
+ * - {Array<?number>} [itemHeights]
+ *
+ * __result__ have following properties:
+ * - {number} start
+ * - {number} end
+ * - {number} paddingTop
+ * - {number} paddingBottom
+ */
+export function calcVScroll(opts) {
+ if (!opts) {
+ return { start: 0, end: 0, paddingTop: 0, paddingBottom: 0 };
+ }
+
+ const { itemCount, rowHeight, viewportTop, viewportHeight, itemHeights } = opts;
+ const viewportBottom = viewportTop + viewportHeight;
+
+ let start = 0;
+ let end = 0;
+
+ let paddingTop = 0;
+ let paddingBottom = 0;
+
+ if (itemHeights) {
+
+ for (let i = 0, pos = 0; i < itemCount; i++) {
+ const height = itemHeights[i] || rowHeight;
+
+ if (pos <= viewportTop && i % 2 === 0) {
+ paddingTop = pos;
+ start = i;
+ }
+
+ if (pos <= viewportBottom) {
+ end = i + 1;
+ } else {
+ paddingBottom += height;
+ }
+
+ pos += height;
+ }
+
+ } else {
+
+ // Make sure that we start at an even row so that CSS `:nth-child(even)` is preserved
+ start = Math.max(0, Math.floor(viewportTop / rowHeight) - 1) & ~1;
+ end = Math.min(
+ itemCount,
+ start + Math.ceil(viewportHeight / rowHeight) + 2
+ );
+
+ // 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.
+ paddingTop = Math.min(start, itemCount) * rowHeight;
+ paddingBottom = Math.max(0, itemCount - end) * rowHeight;
+ }
+
+ return { start, end, paddingTop, paddingBottom };
+}
diff --git a/web/src/js/components/mainview.js b/web/src/js/components/mainview.js
index 9ff51dfa..87c0c4bd 100644
--- a/web/src/js/components/mainview.js
+++ b/web/src/js/components/mainview.js
@@ -1,17 +1,16 @@
-var React = require("react");
+import React from "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");
+import {FlowActions} from "../actions.js";
+import {Query} from "../actions.js";
+import {Key} from "../utils.js";
+import {StoreView} from "../store/view.js";
+import Filt from "../filt/filt.js";
+import { Router, Splitter} from "./common.js"
+import FlowTable from "./flowtable.js";
+import FlowView from "./flowview/index.js";
var MainView = React.createClass({
- mixins: [common.Navigation, common.RouterState],
+ mixins: [Router],
contextTypes: {
flowStore: React.PropTypes.object.isRequired,
},
@@ -25,7 +24,7 @@ var MainView = React.createClass({
},
getInitialState: function () {
var sortKeyFun = false;
- var view = new views.StoreView(this.context.flowStore, this.getViewFilt(), sortKeyFun);
+ var view = new StoreView(this.context.flowStore, this.getViewFilt(), sortKeyFun);
view.addListener("recalculate", this.onRecalculate);
view.addListener("add", this.onUpdate);
view.addListener("update", this.onUpdate);
@@ -42,24 +41,28 @@ var MainView = React.createClass({
},
getViewFilt: function () {
try {
- var filt = Filt.parse(this.getQuery()[Query.SEARCH] || "");
+ var filtStr = this.getQuery()[Query.SEARCH];
+ var filt = filtStr ? Filt.parse(filtStr) : () => true;
var highlightStr = this.getQuery()[Query.HIGHLIGHT];
- var highlight = highlightStr ? Filt.parse(highlightStr) : false;
+ var highlight = highlightStr ? Filt.parse(highlightStr) : () => false;
} catch (e) {
console.error("Error when processing filter: " + e);
}
- return function filter_and_highlight(flow) {
+ var fun = function filter_and_highlight(flow) {
if (!this._highlight) {
this._highlight = {};
}
- this._highlight[flow.id] = highlight && highlight(flow);
+ this._highlight[flow.id] = highlight(flow);
return filt(flow);
};
+ fun.highlightStr = highlightStr;
+ fun.filtStr = filtStr;
+ return fun;
},
componentWillReceiveProps: function (nextProps) {
- var filterChanged = (this.props.query[Query.SEARCH] !== nextProps.query[Query.SEARCH]);
- var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]);
+ var filterChanged = this.state.view.filt.filtStr !== nextProps.location.query[Query.SEARCH];
+ var highlightChanged = this.state.view.filt.highlightStr !== nextProps.location.query[Query.HIGHLIGHT];
if (filterChanged || highlightChanged) {
this.state.view.recalculate(this.getViewFilt(), this.state.sortKeyFun);
}
@@ -72,12 +75,12 @@ var MainView = React.createClass({
}
},
onUpdate: function (flow) {
- if (flow.id === this.getParams().flowId) {
+ if (flow.id === this.props.routeParams.flowId) {
this.forceUpdate();
}
},
onRemove: function (flow_id, index) {
- if (flow_id === this.getParams().flowId) {
+ if (flow_id === this.props.routeParams.flowId) {
var flow_to_select = this.state.view.list[Math.min(index, this.state.view.list.length - 1)];
this.selectFlow(flow_to_select);
}
@@ -90,29 +93,24 @@ var MainView = React.createClass({
},
selectFlow: function (flow) {
if (flow) {
- this.replaceWith(
- "flow",
- {
- flowId: flow.id,
- detailTab: this.getParams().detailTab || "request"
- }
- );
+ var tab = this.props.routeParams.detailTab || "request";
+ this.updateLocation(`/flows/${flow.id}/${tab}`);
this.refs.flowTable.scrollIntoView(flow);
} else {
- this.replaceWith("flows", {});
+ this.updateLocation("/flows");
}
},
selectFlowRelative: function (shift) {
var flows = this.state.view.list;
var index;
- if (!this.getParams().flowId) {
+ if (!this.props.routeParams.flowId) {
if (shift < 0) {
index = flows.length - 1;
} else {
index = 0;
}
} else {
- var currFlowId = this.getParams().flowId;
+ var currFlowId = this.props.routeParams.flowId;
var i = flows.length;
while (i--) {
if (flows[i].id === currFlowId) {
@@ -132,80 +130,80 @@ var MainView = React.createClass({
return;
}
switch (e.keyCode) {
- case utils.Key.K:
- case utils.Key.UP:
+ case Key.K:
+ case Key.UP:
this.selectFlowRelative(-1);
break;
- case utils.Key.J:
- case utils.Key.DOWN:
+ case Key.J:
+ case Key.DOWN:
this.selectFlowRelative(+1);
break;
- case utils.Key.SPACE:
- case utils.Key.PAGE_DOWN:
+ case Key.SPACE:
+ case Key.PAGE_DOWN:
this.selectFlowRelative(+10);
break;
- case utils.Key.PAGE_UP:
+ case Key.PAGE_UP:
this.selectFlowRelative(-10);
break;
- case utils.Key.END:
+ case Key.END:
this.selectFlowRelative(+1e10);
break;
- case utils.Key.HOME:
+ case Key.HOME:
this.selectFlowRelative(-1e10);
break;
- case utils.Key.ESC:
+ case Key.ESC:
this.selectFlow(null);
break;
- case utils.Key.H:
- case utils.Key.LEFT:
+ case Key.H:
+ case Key.LEFT:
if (this.refs.flowDetails) {
this.refs.flowDetails.nextTab(-1);
}
break;
- case utils.Key.L:
- case utils.Key.TAB:
- case utils.Key.RIGHT:
+ case Key.L:
+ case Key.TAB:
+ case Key.RIGHT:
if (this.refs.flowDetails) {
this.refs.flowDetails.nextTab(+1);
}
break;
- case utils.Key.C:
+ case Key.C:
if (e.shiftKey) {
- actions.FlowActions.clear();
+ FlowActions.clear();
}
break;
- case utils.Key.D:
+ case Key.D:
if (flow) {
if (e.shiftKey) {
- actions.FlowActions.duplicate(flow);
+ FlowActions.duplicate(flow);
} else {
- actions.FlowActions.delete(flow);
+ FlowActions.delete(flow);
}
}
break;
- case utils.Key.A:
+ case Key.A:
if (e.shiftKey) {
- actions.FlowActions.accept_all();
+ FlowActions.accept_all();
} else if (flow && flow.intercepted) {
- actions.FlowActions.accept(flow);
+ FlowActions.accept(flow);
}
break;
- case utils.Key.R:
+ case Key.R:
if (!e.shiftKey && flow) {
- actions.FlowActions.replay(flow);
+ FlowActions.replay(flow);
}
break;
- case utils.Key.V:
+ case Key.V:
if (e.shiftKey && flow && flow.modified) {
- actions.FlowActions.revert(flow);
+ FlowActions.revert(flow);
}
break;
- case utils.Key.E:
+ case Key.E:
if (this.refs.flowDetails) {
this.refs.flowDetails.promptEdit();
}
break;
- case utils.Key.SHIFT:
+ case Key.SHIFT:
break;
default:
console.debug("keydown", e.keyCode);
@@ -214,7 +212,7 @@ var MainView = React.createClass({
e.preventDefault();
},
getSelected: function () {
- return this.context.flowStore.get(this.getParams().flowId);
+ return this.context.flowStore.get(this.props.routeParams.flowId);
},
render: function () {
var selected = this.getSelected();
@@ -222,8 +220,12 @@ var MainView = React.createClass({
var details;
if (selected) {
details = [
- <common.Splitter key="splitter"/>,
- <FlowView key="flowDetails" ref="flowDetails" flow={selected}/>
+ <Splitter key="splitter"/>,
+ <FlowView
+ key="flowDetails"
+ ref="flowDetails"
+ tab={this.props.routeParams.detailTab}
+ flow={selected}/>
];
} else {
details = null;
@@ -241,4 +243,4 @@ var MainView = React.createClass({
}
});
-module.exports = MainView;
+export default MainView;
diff --git a/web/src/js/components/prompt.js b/web/src/js/components/prompt.js
index 121a1170..e324f7d4 100644
--- a/web/src/js/components/prompt.js
+++ b/web/src/js/components/prompt.js
@@ -1,18 +1,20 @@
-var React = require("react");
-var _ = require("lodash");
+import React from "react";
+import ReactDOM from 'react-dom';
+import _ from "lodash";
-var utils = require("../utils.js");
-var common = require("./common.js");
+import {Key} from "../utils.js";
var Prompt = React.createClass({
- mixins: [common.ChildFocus],
+ contextTypes: {
+ returnFocus: React.PropTypes.func
+ },
propTypes: {
options: React.PropTypes.array.isRequired,
done: React.PropTypes.func.isRequired,
prompt: React.PropTypes.string
},
componentDidMount: function () {
- React.findDOMNode(this).focus();
+ ReactDOM.findDOMNode(this).focus();
},
onKeyDown: function (e) {
e.stopPropagation();
@@ -20,12 +22,12 @@ var Prompt = React.createClass({
var opts = this.getOptions();
for (var i = 0; i < opts.length; i++) {
var k = opts[i].key;
- if (utils.Key[k.toUpperCase()] === e.keyCode) {
+ if (Key[k.toUpperCase()] === e.keyCode) {
this.done(k);
return;
}
}
- if (e.keyCode === utils.Key.ESC || e.keyCode === utils.Key.ENTER) {
+ if (e.keyCode === Key.ESC || e.keyCode === Key.ENTER) {
this.done(false);
}
},
@@ -34,7 +36,7 @@ var Prompt = React.createClass({
},
done: function (ret) {
this.props.done(ret);
- this.returnFocus();
+ this.context.returnFocus();
},
getOptions: function () {
var opts = [];
@@ -97,4 +99,4 @@ var Prompt = React.createClass({
}
});
-module.exports = Prompt; \ No newline at end of file
+export default Prompt; \ No newline at end of file
diff --git a/web/src/js/components/proxyapp.js b/web/src/js/components/proxyapp.js
index e766d6e6..d17a1522 100644
--- a/web/src/js/components/proxyapp.js
+++ b/web/src/js/components/proxyapp.js
@@ -1,15 +1,15 @@
-var React = require("react");
-var ReactRouter = require("react-router");
-var _ = require("lodash");
+import React from "react";
+import ReactDOM from "react-dom";
+import _ from "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;
+import {Router, Splitter} from "./common.js"
+import MainView from "./mainview.js";
+import Footer from "./footer.js";
+import {Header, MainMenu} from "./header.js";
+import EventLog from "./eventlog.js"
+import {EventLogStore, FlowStore, SettingsStore} from "../store/store.js";
+import {Query} from "../actions.js";
+import {Key} from "../utils.js";
//TODO: Move out of here, just a stub.
@@ -21,48 +21,58 @@ var Reports = React.createClass({
var ProxyAppMain = React.createClass({
- mixins: [common.RouterState],
+ mixins: [Router],
childContextTypes: {
- settingsStore: React.PropTypes.object.isRequired,
flowStore: React.PropTypes.object.isRequired,
eventStore: React.PropTypes.object.isRequired,
returnFocus: React.PropTypes.func.isRequired,
+ location: React.PropTypes.object.isRequired,
},
componentDidMount: function () {
this.focus();
+ this.settingsStore.addListener("recalculate", this.onSettingsChange);
+ },
+ componentWillUnmount: function () {
+ this.settingsStore.removeListener("recalculate", this.onSettingsChange);
+ },
+ onSettingsChange: function () {
+ this.setState({ settings: this.settingsStore.dict });
},
getChildContext: function () {
return {
- settingsStore: this.state.settingsStore,
flowStore: this.state.flowStore,
eventStore: this.state.eventStore,
returnFocus: this.focus,
+ location: this.props.location
};
},
getInitialState: function () {
- var eventStore = new store.EventLogStore();
- var flowStore = new store.FlowStore();
- var settingsStore = new store.SettingsStore();
+ var eventStore = new EventLogStore();
+ var flowStore = new FlowStore();
+ var settingsStore = new SettingsStore();
+ this.settingsStore = settingsStore;
// Default Settings before fetch
_.extend(settingsStore.dict, {});
return {
- settingsStore: settingsStore,
+ settings: settingsStore.dict,
flowStore: flowStore,
eventStore: eventStore
};
},
focus: function () {
- React.findDOMNode(this).focus();
+ document.activeElement.blur();
+ window.getSelection().removeAllRanges();
+ ReactDOM.findDOMNode(this).focus();
},
getMainComponent: function () {
- return this.refs.view.refs.__routeHandler__;
+ return this.refs.view;
},
onKeydown: function (e) {
var selectFilterInput = function (name) {
var headerComponent = this.refs.header;
- headerComponent.setState({active: header.MainMenu}, function () {
+ headerComponent.setState({active: MainMenu}, function () {
headerComponent.refs.active.refs[name].select();
});
}.bind(this);
@@ -88,42 +98,39 @@ var ProxyAppMain = React.createClass({
},
render: function () {
var eventlog;
- if (this.getQuery()[Query.SHOW_EVENTLOG]) {
+ if (this.props.location.query[Query.SHOW_EVENTLOG]) {
eventlog = [
- <common.Splitter key="splitter" axis="y"/>,
+ <Splitter key="splitter" axis="y"/>,
<EventLog key="eventlog"/>
];
} else {
eventlog = null;
}
+ var children = React.cloneElement(
+ this.props.children,
+ { ref: "view", location: this.props.location }
+ );
return (
<div id="container" tabIndex="0" onKeyDown={this.onKeydown}>
- <header.Header ref="header"/>
- <RouteHandler ref="view" query={this.getQuery()}/>
+ <Header ref="header" settings={this.state.settings}/>
+ {children}
{eventlog}
- <Footer/>
+ <Footer settings={this.state.settings}/>
</div>
);
}
});
-var Route = ReactRouter.Route;
-var RouteHandler = ReactRouter.RouteHandler;
-var Redirect = ReactRouter.Redirect;
-var DefaultRoute = ReactRouter.DefaultRoute;
-var NotFoundRoute = ReactRouter.NotFoundRoute;
+import { Route, Router as ReactRouter, hashHistory, Redirect} from "react-router";
-
-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" />
+export var app = (
+<ReactRouter history={hashHistory}>
+ <Redirect from="/" to="/flows" />
+ <Route path="/" component={ProxyAppMain}>
+ <Route path="flows" component={MainView}/>
+ <Route path="flows/:flowId/:detailTab" component={MainView}/>
+ <Route path="reports" component={Reports}/>
</Route>
-);
-
-module.exports = {
- routes: routes
-}; \ No newline at end of file
+</ReactRouter>
+); \ 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
index 5e229b6e..6177938e 100644
--- a/web/src/js/connection.js
+++ b/web/src/js/connection.js
@@ -1,6 +1,6 @@
-var actions = require("./actions.js");
-var AppDispatcher = require("./dispatcher.js").AppDispatcher;
+import {ConnectionActions, EventLogActions} from "./actions.js";
+import {AppDispatcher} from "./dispatcher.js";
function Connection(url) {
if (url[0] === "/") {
@@ -9,21 +9,21 @@ function Connection(url) {
var ws = new WebSocket(url);
ws.onopen = function () {
- actions.ConnectionActions.open();
+ 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.");
+ ConnectionActions.error();
+ EventLogActions.add_event("WebSocket connection error.");
};
ws.onclose = function () {
- actions.ConnectionActions.close();
- actions.EventLogActions.add_event("WebSocket connection closed.");
+ ConnectionActions.close();
+ EventLogActions.add_event("WebSocket connection closed.");
};
return ws;
}
-module.exports = Connection; \ No newline at end of file
+export default Connection; \ No newline at end of file
diff --git a/web/src/js/dispatcher.js b/web/src/js/dispatcher.js
index 0c2aa202..b4e22ed9 100644
--- a/web/src/js/dispatcher.js
+++ b/web/src/js/dispatcher.js
@@ -1,5 +1,5 @@
-var flux = require("flux");
+import flux from "flux";
const PayloadSources = {
VIEW: "view",
@@ -7,7 +7,7 @@ const PayloadSources = {
};
-var AppDispatcher = new flux.Dispatcher();
+export var AppDispatcher = new flux.Dispatcher();
AppDispatcher.dispatchViewAction = function (action) {
action.source = PayloadSources.VIEW;
this.dispatch(action);
@@ -15,8 +15,4 @@ AppDispatcher.dispatchViewAction = function (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
index 45b42f3a..6a0bbab7 100644
--- a/web/src/js/filt/filt.js
+++ b/web/src/js/filt/filt.js
@@ -1,8 +1,10 @@
module.exports = (function() {
+ "use strict";
+
/*
- * Generated by PEG.js 0.8.0.
+ * Generated by PEG.js 0.9.0.
*
- * http://pegjs.majda.cz/
+ * http://pegjs.org/
*/
function peg$subclass(child, parent) {
@@ -11,21 +13,23 @@ module.exports = (function() {
child.prototype = new ctor();
}
- function SyntaxError(message, expected, found, offset, line, column) {
+ function peg$SyntaxError(message, expected, found, location) {
this.message = message;
this.expected = expected;
this.found = found;
- this.offset = offset;
- this.line = line;
- this.column = column;
-
+ this.location = location;
this.name = "SyntaxError";
+
+ if (typeof Error.captureStackTrace === "function") {
+ Error.captureStackTrace(this, peg$SyntaxError);
+ }
}
- peg$subclass(SyntaxError, Error);
+ peg$subclass(peg$SyntaxError, Error);
- function parse(input) {
+ function peg$parse(input) {
var options = arguments.length > 1 ? arguments[1] : {},
+ parser = this,
peg$FAILED = {},
@@ -33,117 +37,111 @@ module.exports = (function() {
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$c1 = function(orExpr) { return orExpr; },
+ peg$c2 = { type: "other", description: "whitespace" },
+ peg$c3 = /^[ \t\n\r]/,
+ peg$c4 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" },
+ peg$c5 = { type: "other", description: "control character" },
+ peg$c6 = /^[|&!()~"]/,
+ peg$c7 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" },
+ peg$c8 = { type: "other", description: "optional whitespace" },
+ peg$c9 = "|",
+ peg$c10 = { type: "literal", value: "|", description: "\"|\"" },
+ peg$c11 = function(first, second) { return or(first, second); },
+ peg$c12 = "&",
+ peg$c13 = { type: "literal", value: "&", description: "\"&\"" },
+ peg$c14 = function(first, second) { return and(first, second); },
+ peg$c15 = "!",
+ peg$c16 = { type: "literal", value: "!", description: "\"!\"" },
+ peg$c17 = function(expr) { return not(expr); },
+ peg$c18 = "(",
+ peg$c19 = { type: "literal", value: "(", description: "\"(\"" },
+ peg$c20 = ")",
+ peg$c21 = { type: "literal", value: ")", description: "\")\"" },
+ peg$c22 = function(expr) { return binding(expr); },
+ peg$c23 = "~a",
+ peg$c24 = { type: "literal", value: "~a", description: "\"~a\"" },
+ peg$c25 = function() { return assetFilter; },
+ peg$c26 = "~e",
+ peg$c27 = { type: "literal", value: "~e", description: "\"~e\"" },
+ peg$c28 = function() { return errorFilter; },
+ peg$c29 = "~q",
+ peg$c30 = { type: "literal", value: "~q", description: "\"~q\"" },
+ peg$c31 = function() { return noResponseFilter; },
+ peg$c32 = "~s",
+ peg$c33 = { type: "literal", value: "~s", description: "\"~s\"" },
+ peg$c34 = function() { return responseFilter; },
+ peg$c35 = "true",
+ peg$c36 = { type: "literal", value: "true", description: "\"true\"" },
+ peg$c37 = function() { return trueFilter; },
+ peg$c38 = "false",
+ peg$c39 = { type: "literal", value: "false", description: "\"false\"" },
+ peg$c40 = function() { return falseFilter; },
+ peg$c41 = "~c",
+ peg$c42 = { type: "literal", value: "~c", description: "\"~c\"" },
+ peg$c43 = function(s) { return responseCode(s); },
+ peg$c44 = "~d",
+ peg$c45 = { type: "literal", value: "~d", description: "\"~d\"" },
+ peg$c46 = function(s) { return domain(s); },
+ peg$c47 = "~h",
+ peg$c48 = { type: "literal", value: "~h", description: "\"~h\"" },
+ peg$c49 = function(s) { return header(s); },
+ peg$c50 = "~hq",
+ peg$c51 = { type: "literal", value: "~hq", description: "\"~hq\"" },
+ peg$c52 = function(s) { return requestHeader(s); },
+ peg$c53 = "~hs",
+ peg$c54 = { type: "literal", value: "~hs", description: "\"~hs\"" },
+ peg$c55 = function(s) { return responseHeader(s); },
+ peg$c56 = "~m",
+ peg$c57 = { type: "literal", value: "~m", description: "\"~m\"" },
+ peg$c58 = function(s) { return method(s); },
+ peg$c59 = "~t",
+ peg$c60 = { type: "literal", value: "~t", description: "\"~t\"" },
+ peg$c61 = function(s) { return contentType(s); },
+ peg$c62 = "~tq",
+ peg$c63 = { type: "literal", value: "~tq", description: "\"~tq\"" },
+ peg$c64 = function(s) { return requestContentType(s); },
+ peg$c65 = "~ts",
+ peg$c66 = { type: "literal", value: "~ts", description: "\"~ts\"" },
+ peg$c67 = function(s) { return responseContentType(s); },
+ peg$c68 = "~u",
+ peg$c69 = { type: "literal", value: "~u", description: "\"~u\"" },
+ peg$c70 = function(s) { return url(s); },
+ peg$c71 = { type: "other", description: "integer" },
+ peg$c72 = /^['"]/,
+ peg$c73 = { type: "class", value: "['\"]", description: "['\"]" },
+ peg$c74 = /^[0-9]/,
+ peg$c75 = { type: "class", value: "[0-9]", description: "[0-9]" },
+ peg$c76 = function(digits) { return parseInt(digits.join(""), 10); },
+ peg$c77 = { type: "other", description: "string" },
+ peg$c78 = "\"",
+ peg$c79 = { type: "literal", value: "\"", description: "\"\\\"\"" },
+ peg$c80 = function(chars) { return chars.join(""); },
+ peg$c81 = "'",
+ peg$c82 = { type: "literal", value: "'", description: "\"'\"" },
+ peg$c83 = /^["\\]/,
+ peg$c84 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" },
+ peg$c85 = { type: "any", description: "any character" },
+ peg$c86 = function(char) { return char; },
+ peg$c87 = "\\",
+ peg$c88 = { type: "literal", value: "\\", description: "\"\\\\\"" },
+ peg$c89 = /^['\\]/,
+ peg$c90 = { type: "class", value: "['\\\\]", description: "['\\\\]" },
+ peg$c91 = /^['"\\]/,
+ peg$c92 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" },
+ peg$c93 = "n",
+ peg$c94 = { type: "literal", value: "n", description: "\"n\"" },
+ peg$c95 = function() { return "\n"; },
+ peg$c96 = "r",
+ peg$c97 = { type: "literal", value: "r", description: "\"r\"" },
+ peg$c98 = function() { return "\r"; },
+ peg$c99 = "t",
+ peg$c100 = { type: "literal", value: "t", description: "\"t\"" },
+ peg$c101 = function() { return "\t"; },
peg$currPos = 0,
- peg$reportedPos = 0,
- peg$cachedPos = 0,
- peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
+ peg$savedPos = 0,
+ peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }],
peg$maxFailPos = 0,
peg$maxFailExpected = [],
peg$silentFails = 0,
@@ -159,38 +157,51 @@ module.exports = (function() {
}
function text() {
- return input.substring(peg$reportedPos, peg$currPos);
+ return input.substring(peg$savedPos, peg$currPos);
}
- function offset() {
- return peg$reportedPos;
- }
-
- function line() {
- return peg$computePosDetails(peg$reportedPos).line;
- }
-
- function column() {
- return peg$computePosDetails(peg$reportedPos).column;
+ function location() {
+ return peg$computeLocation(peg$savedPos, peg$currPos);
}
function expected(description) {
throw peg$buildException(
null,
[{ type: "other", description: description }],
- peg$reportedPos
+ input.substring(peg$savedPos, peg$currPos),
+ peg$computeLocation(peg$savedPos, peg$currPos)
);
}
function error(message) {
- throw peg$buildException(message, null, peg$reportedPos);
+ throw peg$buildException(
+ message,
+ null,
+ input.substring(peg$savedPos, peg$currPos),
+ peg$computeLocation(peg$savedPos, peg$currPos)
+ );
}
function peg$computePosDetails(pos) {
- function advance(details, startPos, endPos) {
- var p, ch;
+ var details = peg$posDetailsCache[pos],
+ p, ch;
+
+ if (details) {
+ return details;
+ } else {
+ p = pos - 1;
+ while (!peg$posDetailsCache[p]) {
+ p--;
+ }
- for (p = startPos; p < endPos; p++) {
+ details = peg$posDetailsCache[p];
+ details = {
+ line: details.line,
+ column: details.column,
+ seenCR: details.seenCR
+ };
+
+ while (p < pos) {
ch = input.charAt(p);
if (ch === "\n") {
if (!details.seenCR) { details.line++; }
@@ -204,19 +215,31 @@ module.exports = (function() {
details.column++;
details.seenCR = false;
}
- }
- }
- if (peg$cachedPos !== pos) {
- if (peg$cachedPos > pos) {
- peg$cachedPos = 0;
- peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
+ p++;
}
- advance(peg$cachedPosDetails, peg$cachedPos, pos);
- peg$cachedPos = pos;
+
+ peg$posDetailsCache[pos] = details;
+ return details;
}
+ }
- return peg$cachedPosDetails;
+ function peg$computeLocation(startPos, endPos) {
+ var startPosDetails = peg$computePosDetails(startPos),
+ endPosDetails = peg$computePosDetails(endPos);
+
+ return {
+ start: {
+ offset: startPos,
+ line: startPosDetails.line,
+ column: startPosDetails.column
+ },
+ end: {
+ offset: endPos,
+ line: endPosDetails.line,
+ column: endPosDetails.column
+ }
+ };
}
function peg$fail(expected) {
@@ -230,7 +253,7 @@ module.exports = (function() {
peg$maxFailExpected.push(expected);
}
- function peg$buildException(message, expected, pos) {
+ function peg$buildException(message, expected, found, location) {
function cleanupExpected(expected) {
var i = 1;
@@ -267,8 +290,8 @@ module.exports = (function() {
.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); });
+ .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
+ .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
}
var expectedDescs = new Array(expected.length),
@@ -289,20 +312,15 @@ module.exports = (function() {
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(
+ return new peg$SyntaxError(
message !== null ? message : buildMessage(expected, found),
expected,
found,
- pos,
- posDetails.line,
- posDetails.column
+ location
);
}
@@ -317,29 +335,20 @@ module.exports = (function() {
if (s2 !== peg$FAILED) {
s3 = peg$parse__();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c2(s2);
+ peg$savedPos = s0;
+ s1 = peg$c1(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} 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;
+ s0 = peg$FAILED;
}
peg$silentFails--;
if (s0 === peg$FAILED) {
@@ -354,17 +363,17 @@ module.exports = (function() {
var s0, s1;
peg$silentFails++;
- if (peg$c6.test(input.charAt(peg$currPos))) {
+ if (peg$c3.test(input.charAt(peg$currPos))) {
s0 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s0 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c7); }
+ if (peg$silentFails === 0) { peg$fail(peg$c4); }
}
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c5); }
+ if (peg$silentFails === 0) { peg$fail(peg$c2); }
}
return s0;
@@ -374,17 +383,17 @@ module.exports = (function() {
var s0, s1;
peg$silentFails++;
- if (peg$c9.test(input.charAt(peg$currPos))) {
+ 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$c10); }
+ if (peg$silentFails === 0) { peg$fail(peg$c7); }
}
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c8); }
+ if (peg$silentFails === 0) { peg$fail(peg$c5); }
}
return s0;
@@ -403,7 +412,7 @@ module.exports = (function() {
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c11); }
+ if (peg$silentFails === 0) { peg$fail(peg$c8); }
}
return s0;
@@ -418,39 +427,39 @@ module.exports = (function() {
s2 = peg$parse__();
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 124) {
- s3 = peg$c12;
+ s3 = peg$c9;
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c13); }
+ if (peg$silentFails === 0) { peg$fail(peg$c10); }
}
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);
+ peg$savedPos = s0;
+ s1 = peg$c11(s1, s5);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$parseAndExpr();
@@ -468,39 +477,39 @@ module.exports = (function() {
s2 = peg$parse__();
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 38) {
- s3 = peg$c15;
+ s3 = peg$c12;
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c16); }
+ if (peg$silentFails === 0) { peg$fail(peg$c13); }
}
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);
+ peg$savedPos = s0;
+ s1 = peg$c14(s1, s5);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
@@ -514,25 +523,25 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseAndExpr();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c17(s1, s3);
+ peg$savedPos = s0;
+ s1 = peg$c14(s1, s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$parseNotExpr();
@@ -547,31 +556,31 @@ module.exports = (function() {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 33) {
- s1 = peg$c18;
+ s1 = peg$c15;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c19); }
+ if (peg$silentFails === 0) { peg$fail(peg$c16); }
}
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);
+ peg$savedPos = s0;
+ s1 = peg$c17(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$parseBindingExpr();
@@ -585,11 +594,11 @@ module.exports = (function() {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 40) {
- s1 = peg$c21;
+ s1 = peg$c18;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c22); }
+ if (peg$silentFails === 0) { peg$fail(peg$c19); }
}
if (s1 !== peg$FAILED) {
s2 = peg$parse__();
@@ -599,35 +608,35 @@ module.exports = (function() {
s4 = peg$parse__();
if (s4 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 41) {
- s5 = peg$c23;
+ s5 = peg$c20;
peg$currPos++;
} else {
s5 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c24); }
+ if (peg$silentFails === 0) { peg$fail(peg$c21); }
}
if (s5 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c25(s3);
+ peg$savedPos = s0;
+ s1 = peg$c22(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$parseExpr();
@@ -653,58 +662,58 @@ module.exports = (function() {
s0 = peg$parseBooleanLiteral();
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c26) {
- s1 = peg$c26;
+ if (input.substr(peg$currPos, 2) === peg$c23) {
+ s1 = peg$c23;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c27); }
+ if (peg$silentFails === 0) { peg$fail(peg$c24); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c28();
+ peg$savedPos = s0;
+ s1 = peg$c25();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c29) {
- s1 = peg$c29;
+ 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$c30); }
+ if (peg$silentFails === 0) { peg$fail(peg$c27); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c31();
+ peg$savedPos = s0;
+ s1 = peg$c28();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c32) {
- s1 = peg$c32;
+ 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$c33); }
+ if (peg$silentFails === 0) { peg$fail(peg$c30); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c34();
+ peg$savedPos = s0;
+ s1 = peg$c31();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c35) {
- s1 = peg$c35;
+ 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$c36); }
+ if (peg$silentFails === 0) { peg$fail(peg$c33); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c37();
+ peg$savedPos = s0;
+ s1 = peg$c34();
}
s0 = s1;
}
@@ -719,30 +728,30 @@ module.exports = (function() {
var s0, s1;
s0 = peg$currPos;
- if (input.substr(peg$currPos, 4) === peg$c38) {
- s1 = peg$c38;
+ if (input.substr(peg$currPos, 4) === peg$c35) {
+ s1 = peg$c35;
peg$currPos += 4;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c39); }
+ if (peg$silentFails === 0) { peg$fail(peg$c36); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c40();
+ peg$savedPos = s0;
+ s1 = peg$c37();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 5) === peg$c41) {
- s1 = peg$c41;
+ if (input.substr(peg$currPos, 5) === peg$c38) {
+ s1 = peg$c38;
peg$currPos += 5;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c42); }
+ if (peg$silentFails === 0) { peg$fail(peg$c39); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c43();
+ peg$savedPos = s0;
+ s1 = peg$c40();
}
s0 = s1;
}
@@ -754,12 +763,12 @@ module.exports = (function() {
var s0, s1, s2, s3;
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c44) {
- s1 = peg$c44;
+ if (input.substr(peg$currPos, 2) === peg$c41) {
+ s1 = peg$c41;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c45); }
+ if (peg$silentFails === 0) { peg$fail(peg$c42); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -770,34 +779,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseIntegerLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c46(s3);
+ peg$savedPos = s0;
+ s1 = peg$c43(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c47) {
- s1 = peg$c47;
+ 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$c48); }
+ if (peg$silentFails === 0) { peg$fail(peg$c45); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -808,34 +817,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c49(s3);
+ peg$savedPos = s0;
+ s1 = peg$c46(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c50) {
- s1 = peg$c50;
+ 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$c51); }
+ if (peg$silentFails === 0) { peg$fail(peg$c48); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -846,34 +855,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c52(s3);
+ peg$savedPos = s0;
+ s1 = peg$c49(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 3) === peg$c53) {
- s1 = peg$c53;
+ if (input.substr(peg$currPos, 3) === peg$c50) {
+ s1 = peg$c50;
peg$currPos += 3;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c54); }
+ if (peg$silentFails === 0) { peg$fail(peg$c51); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -884,34 +893,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c55(s3);
+ peg$savedPos = s0;
+ s1 = peg$c52(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 3) === peg$c56) {
- s1 = peg$c56;
+ 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$c57); }
+ if (peg$silentFails === 0) { peg$fail(peg$c54); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -922,34 +931,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c58(s3);
+ peg$savedPos = s0;
+ s1 = peg$c55(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c59) {
- s1 = peg$c59;
+ if (input.substr(peg$currPos, 2) === peg$c56) {
+ s1 = peg$c56;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c60); }
+ if (peg$silentFails === 0) { peg$fail(peg$c57); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -960,34 +969,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c61(s3);
+ peg$savedPos = s0;
+ s1 = peg$c58(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c62) {
- s1 = peg$c62;
+ 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$c63); }
+ if (peg$silentFails === 0) { peg$fail(peg$c60); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -998,34 +1007,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c64(s3);
+ peg$savedPos = s0;
+ s1 = peg$c61(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 3) === peg$c65) {
- s1 = peg$c65;
+ if (input.substr(peg$currPos, 3) === peg$c62) {
+ s1 = peg$c62;
peg$currPos += 3;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c66); }
+ if (peg$silentFails === 0) { peg$fail(peg$c63); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1036,34 +1045,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c67(s3);
+ peg$savedPos = s0;
+ s1 = peg$c64(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 3) === peg$c68) {
- s1 = peg$c68;
+ 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$c69); }
+ if (peg$silentFails === 0) { peg$fail(peg$c66); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1074,34 +1083,34 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c70(s3);
+ peg$savedPos = s0;
+ s1 = peg$c67(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
- if (input.substr(peg$currPos, 2) === peg$c71) {
- s1 = peg$c71;
+ if (input.substr(peg$currPos, 2) === peg$c68) {
+ s1 = peg$c68;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c72); }
+ if (peg$silentFails === 0) { peg$fail(peg$c69); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1112,32 +1121,32 @@ module.exports = (function() {
s3 = peg$parsews();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
s3 = peg$parseStringLiteral();
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c73(s3);
+ peg$savedPos = s0;
+ s1 = peg$c70(s3);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
s1 = peg$parseStringLiteral();
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c73(s1);
+ peg$savedPos = s0;
+ s1 = peg$c70(s1);
}
s0 = s1;
}
@@ -1159,70 +1168,70 @@ module.exports = (function() {
peg$silentFails++;
s0 = peg$currPos;
- if (peg$c76.test(input.charAt(peg$currPos))) {
+ if (peg$c72.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 (peg$silentFails === 0) { peg$fail(peg$c73); }
}
if (s1 === peg$FAILED) {
- s1 = peg$c75;
+ s1 = null;
}
if (s1 !== peg$FAILED) {
s2 = [];
- if (peg$c78.test(input.charAt(peg$currPos))) {
+ if (peg$c74.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 (peg$silentFails === 0) { peg$fail(peg$c75); }
}
if (s3 !== peg$FAILED) {
while (s3 !== peg$FAILED) {
s2.push(s3);
- if (peg$c78.test(input.charAt(peg$currPos))) {
+ if (peg$c74.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 (peg$silentFails === 0) { peg$fail(peg$c75); }
}
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
- if (peg$c76.test(input.charAt(peg$currPos))) {
+ if (peg$c72.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 (peg$silentFails === 0) { peg$fail(peg$c73); }
}
if (s3 === peg$FAILED) {
- s3 = peg$c75;
+ s3 = null;
}
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c80(s2);
+ peg$savedPos = s0;
+ s1 = peg$c76(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c74); }
+ if (peg$silentFails === 0) { peg$fail(peg$c71); }
}
return s0;
@@ -1234,11 +1243,11 @@ module.exports = (function() {
peg$silentFails++;
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 34) {
- s1 = peg$c82;
+ s1 = peg$c78;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c83); }
+ if (peg$silentFails === 0) { peg$fail(peg$c79); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1249,36 +1258,36 @@ module.exports = (function() {
}
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 34) {
- s3 = peg$c82;
+ s3 = peg$c78;
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c83); }
+ if (peg$silentFails === 0) { peg$fail(peg$c79); }
}
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c84(s2);
+ peg$savedPos = s0;
+ s1 = peg$c80(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 39) {
- s1 = peg$c85;
+ s1 = peg$c81;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c86); }
+ if (peg$silentFails === 0) { peg$fail(peg$c82); }
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1289,27 +1298,27 @@ module.exports = (function() {
}
if (s2 !== peg$FAILED) {
if (input.charCodeAt(peg$currPos) === 39) {
- s3 = peg$c85;
+ s3 = peg$c81;
peg$currPos++;
} else {
s3 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c86); }
+ if (peg$silentFails === 0) { peg$fail(peg$c82); }
}
if (s3 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c84(s2);
+ peg$savedPos = s0;
+ s1 = peg$c80(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
@@ -1318,10 +1327,10 @@ module.exports = (function() {
s2 = peg$parsecc();
peg$silentFails--;
if (s2 === peg$FAILED) {
- s1 = peg$c87;
+ s1 = void 0;
} else {
peg$currPos = s1;
- s1 = peg$c1;
+ s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
s2 = [];
@@ -1332,26 +1341,26 @@ module.exports = (function() {
s3 = peg$parseUnquotedStringChar();
}
} else {
- s2 = peg$c1;
+ s2 = peg$FAILED;
}
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c84(s2);
+ peg$savedPos = s0;
+ s1 = peg$c80(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
}
}
peg$silentFails--;
if (s0 === peg$FAILED) {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c81); }
+ if (peg$silentFails === 0) { peg$fail(peg$c77); }
}
return s0;
@@ -1363,19 +1372,19 @@ module.exports = (function() {
s0 = peg$currPos;
s1 = peg$currPos;
peg$silentFails++;
- if (peg$c88.test(input.charAt(peg$currPos))) {
+ if (peg$c83.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c89); }
+ if (peg$silentFails === 0) { peg$fail(peg$c84); }
}
peg$silentFails--;
if (s2 === peg$FAILED) {
- s1 = peg$c87;
+ s1 = void 0;
} else {
peg$currPos = s1;
- s1 = peg$c1;
+ s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
if (input.length > peg$currPos) {
@@ -1383,42 +1392,42 @@ module.exports = (function() {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c90); }
+ if (peg$silentFails === 0) { peg$fail(peg$c85); }
}
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c91(s2);
+ peg$savedPos = s0;
+ s1 = peg$c86(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 92) {
- s1 = peg$c92;
+ s1 = peg$c87;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c93); }
+ if (peg$silentFails === 0) { peg$fail(peg$c88); }
}
if (s1 !== peg$FAILED) {
s2 = peg$parseEscapeSequence();
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c91(s2);
+ peg$savedPos = s0;
+ s1 = peg$c86(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
}
@@ -1431,19 +1440,19 @@ module.exports = (function() {
s0 = peg$currPos;
s1 = peg$currPos;
peg$silentFails++;
- if (peg$c94.test(input.charAt(peg$currPos))) {
+ if (peg$c89.test(input.charAt(peg$currPos))) {
s2 = input.charAt(peg$currPos);
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c95); }
+ if (peg$silentFails === 0) { peg$fail(peg$c90); }
}
peg$silentFails--;
if (s2 === peg$FAILED) {
- s1 = peg$c87;
+ s1 = void 0;
} else {
peg$currPos = s1;
- s1 = peg$c1;
+ s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
if (input.length > peg$currPos) {
@@ -1451,42 +1460,42 @@ module.exports = (function() {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c90); }
+ if (peg$silentFails === 0) { peg$fail(peg$c85); }
}
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c91(s2);
+ peg$savedPos = s0;
+ s1 = peg$c86(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 92) {
- s1 = peg$c92;
+ s1 = peg$c87;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c93); }
+ if (peg$silentFails === 0) { peg$fail(peg$c88); }
}
if (s1 !== peg$FAILED) {
s2 = peg$parseEscapeSequence();
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c91(s2);
+ peg$savedPos = s0;
+ s1 = peg$c86(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
}
@@ -1502,10 +1511,10 @@ module.exports = (function() {
s2 = peg$parsews();
peg$silentFails--;
if (s2 === peg$FAILED) {
- s1 = peg$c87;
+ s1 = void 0;
} else {
peg$currPos = s1;
- s1 = peg$c1;
+ s1 = peg$FAILED;
}
if (s1 !== peg$FAILED) {
if (input.length > peg$currPos) {
@@ -1513,19 +1522,19 @@ module.exports = (function() {
peg$currPos++;
} else {
s2 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c90); }
+ if (peg$silentFails === 0) { peg$fail(peg$c85); }
}
if (s2 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c91(s2);
+ peg$savedPos = s0;
+ s1 = peg$c86(s2);
s0 = s1;
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
- s0 = peg$c1;
+ s0 = peg$FAILED;
}
return s0;
@@ -1534,53 +1543,53 @@ module.exports = (function() {
function peg$parseEscapeSequence() {
var s0, s1;
- if (peg$c96.test(input.charAt(peg$currPos))) {
+ if (peg$c91.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 (peg$silentFails === 0) { peg$fail(peg$c92); }
}
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 110) {
- s1 = peg$c98;
+ s1 = peg$c93;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c99); }
+ if (peg$silentFails === 0) { peg$fail(peg$c94); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c100();
+ peg$savedPos = s0;
+ s1 = peg$c95();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 114) {
- s1 = peg$c101;
+ s1 = peg$c96;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c102); }
+ if (peg$silentFails === 0) { peg$fail(peg$c97); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c103();
+ peg$savedPos = s0;
+ s1 = peg$c98();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 116) {
- s1 = peg$c104;
+ s1 = peg$c99;
peg$currPos++;
} else {
s1 = peg$FAILED;
- if (peg$silentFails === 0) { peg$fail(peg$c105); }
+ if (peg$silentFails === 0) { peg$fail(peg$c100); }
}
if (s1 !== peg$FAILED) {
- peg$reportedPos = s0;
- s1 = peg$c106();
+ peg$savedPos = s0;
+ s1 = peg$c101();
}
s0 = s1;
}
@@ -1763,12 +1772,19 @@ module.exports = (function() {
peg$fail({ type: "end", description: "end of input" });
}
- throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
+ throw peg$buildException(
+ null,
+ peg$maxFailExpected,
+ peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
+ peg$maxFailPos < input.length
+ ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
+ : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
+ );
}
}
return {
- SyntaxError: SyntaxError,
- parse: parse
+ SyntaxError: peg$SyntaxError,
+ parse: peg$parse
};
})(); \ No newline at end of file
diff --git a/web/src/js/filt/filt.peg b/web/src/js/filt/filt.peg
index 6f9bdac6..ccaaa072 100644
--- a/web/src/js/filt/filt.peg
+++ b/web/src/js/filt/filt.peg
@@ -166,7 +166,6 @@ function url(regex){
start "filter expression"
= __ orExpr:OrExpr __ { return orExpr; }
- / {return trueFilter; }
ws "whitespace" = [ \t\n\r]
cc "control character" = [|&!()~"]
diff --git a/web/src/js/flow/utils.js b/web/src/js/flow/utils.js
index d72febaa..d64e2d55 100644
--- a/web/src/js/flow/utils.js
+++ b/web/src/js/flow/utils.js
@@ -1,12 +1,12 @@
-var _ = require("lodash");
-var $ = require("jquery");
+import _ from "lodash";
+import $ from "jquery";
var defaultPorts = {
"http": 80,
"https": 443
};
-var MessageUtils = {
+export var MessageUtils = {
getContentType: function (message) {
var ct = this.get_first_header(message, /^Content-Type$/i);
if(ct){
@@ -58,7 +58,7 @@ var MessageUtils = {
}
};
-var RequestUtils = _.extend(MessageUtils, {
+export var RequestUtils = _.extend(MessageUtils, {
pretty_host: function (request) {
//FIXME: Add hostheader
return request.host;
@@ -72,11 +72,11 @@ var RequestUtils = _.extend(MessageUtils, {
}
});
-var ResponseUtils = _.extend(MessageUtils, {});
+export var ResponseUtils = _.extend(MessageUtils, {});
var parseUrl_regex = /^(?:(https?):\/\/)?([^\/:]+)?(?::(\d+))?(\/.*)?$/i;
-var parseUrl = function (url) {
+export 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);
@@ -109,22 +109,13 @@ var parseUrl = function (url) {
var isValidHttpVersion_regex = /^HTTP\/\d+(\.\d+)*$/i;
-var isValidHttpVersion = function (httpVersion) {
+export var isValidHttpVersion = function (httpVersion) {
return isValidHttpVersion_regex.test(httpVersion);
};
-var parseHttpVersion = function (httpVersion) {
+export 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
index 5024049f..e41b2eef 100644
--- a/web/src/js/store/store.js
+++ b/web/src/js/store/store.js
@@ -1,11 +1,10 @@
-var _ = require("lodash");
-var $ = require("jquery");
-var EventEmitter = require('events').EventEmitter;
+import _ from "lodash";
+import $ from "jquery";
+import {EventEmitter} from 'events';
-var utils = require("../utils.js");
-var actions = require("../actions.js");
-var dispatcher = require("../dispatcher.js");
+import {ActionTypes, StoreCmds} from "../actions.js";
+import {AppDispatcher} from "../dispatcher.js";
function ListStore() {
@@ -79,7 +78,7 @@ function LiveStoreMixin(type) {
this._fetchxhr = false;
this.handle = this.handle.bind(this);
- dispatcher.AppDispatcher.register(this.handle);
+ AppDispatcher.register(this.handle);
// Avoid double-fetch on startup.
if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) {
@@ -88,11 +87,11 @@ function LiveStoreMixin(type) {
}
_.extend(LiveStoreMixin.prototype, {
handle: function (event) {
- if (event.type === actions.ActionTypes.CONNECTION_OPEN) {
+ if (event.type === ActionTypes.CONNECTION_OPEN) {
return this.fetch();
}
if (event.type === this.type) {
- if (event.cmd === actions.StoreCmds.RESET) {
+ if (event.cmd === StoreCmds.RESET) {
this.fetch(event.data);
} else if (this._updates_before_fetch) {
console.log("defer update", event);
@@ -103,7 +102,7 @@ _.extend(LiveStoreMixin.prototype, {
}
},
close: function () {
- dispatcher.AppDispatcher.unregister(this.handle);
+ AppDispatcher.unregister(this.handle);
},
fetch: function (data) {
console.log("fetch " + this.type);
@@ -148,16 +147,16 @@ function LiveDictStore(type) {
_.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype);
-function FlowStore() {
- return new LiveListStore(actions.ActionTypes.FLOW_STORE);
+export function FlowStore() {
+ return new LiveListStore(ActionTypes.FLOW_STORE);
}
-function SettingsStore() {
- return new LiveDictStore(actions.ActionTypes.SETTINGS_STORE);
+export function SettingsStore() {
+ return new LiveDictStore(ActionTypes.SETTINGS_STORE);
}
-function EventLogStore() {
- LiveListStore.call(this, actions.ActionTypes.EVENT_STORE);
+export function EventLogStore() {
+ LiveListStore.call(this, ActionTypes.EVENT_STORE);
}
_.extend(EventLogStore.prototype, LiveListStore.prototype, {
fetch: function(){
@@ -172,10 +171,3 @@ _.extend(EventLogStore.prototype, LiveListStore.prototype, {
}
}
});
-
-
-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
index d628d46b..d8aeba60 100644
--- a/web/src/js/store/view.js
+++ b/web/src/js/store/view.js
@@ -1,7 +1,7 @@
-var EventEmitter = require('events').EventEmitter;
-var _ = require("lodash");
+import {EventEmitter} from 'events';
+import _ from "lodash";
-var utils = require("../utils.js");
+import utils from "../utils.js";
function SortByStoreOrder(elem) {
return this.store.index(elem.id);
@@ -12,7 +12,7 @@ var default_filt = function (elem) {
return true;
};
-function StoreView(store, filt, sortfun) {
+export function StoreView(store, filt, sortfun) {
EventEmitter.call(this);
this.store = store;
@@ -59,12 +59,12 @@ _.extend(StoreView.prototype, EventEmitter.prototype, {
});
this.emit("recalculate");
},
- index: function (elem) {
- return _.sortedIndex(this.list, elem, this.sortfun);
+ indexOf: function (elem) {
+ return this.list.indexOf(elem, _.sortedIndexBy(this.list, elem, this.sortfun));
},
add: function (elem) {
if (this.filt(elem)) {
- var idx = this.index(elem);
+ var idx = _.sortedIndexBy(this.list, elem, this.sortfun);
if (idx === this.list.length) { //happens often, .push is way faster.
this.list.push(elem);
} else {
@@ -109,7 +109,3 @@ _.extend(StoreView.prototype, EventEmitter.prototype, {
}
}
});
-
-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
index dfbb9ba6..acbadc92 100644
--- a/web/src/js/tests/utils.js
+++ b/web/src/js/tests/utils.js
@@ -1,15 +1,16 @@
jest.dontMock("jquery");
jest.dontMock("../utils");
+import {formatSize} from "../utils.js"
+
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");
+ expect(formatSize(1024)).toEqual("1kb");
+ expect(formatSize(0)).toEqual("0");
+ expect(formatSize(10)).toEqual("10b");
+ expect(formatSize(1025)).toEqual("1.0kb");
+ expect(formatSize(1024*1024)).toEqual("1mb");
+ expect(formatSize(1024*1024+1)).toEqual("1.0mb");
});
});
diff --git a/web/src/js/utils.js b/web/src/js/utils.js
index 40575692..2627cf58 100644
--- a/web/src/js/utils.js
+++ b/web/src/js/utils.js
@@ -1,12 +1,12 @@
-var $ = require("jquery");
-var _ = require("lodash");
-var actions = require("./actions.js");
+import $ from "jquery";
+import _ from "lodash";
+import actions from "./actions.js";
window.$ = $;
window._ = _;
window.React = require("react");
-var Key = {
+export var Key = {
UP: 38,
DOWN: 40,
PAGE_UP: 33,
@@ -28,7 +28,7 @@ for (var i = 65; i <= 90; i++) {
}
-var formatSize = function (bytes) {
+export var formatSize = function (bytes) {
if (bytes === 0)
return "0";
var prefix = ["b", "kb", "mb", "gb", "tb"];
@@ -46,7 +46,7 @@ var formatSize = function (bytes) {
};
-var formatTimeDelta = function (milliseconds) {
+export var formatTimeDelta = function (milliseconds) {
var time = milliseconds;
var prefix = ["ms", "s", "min", "h"];
var div = [1000, 60, 60];
@@ -59,7 +59,7 @@ var formatTimeDelta = function (milliseconds) {
};
-var formatTimeStamp = function (seconds) {
+export var formatTimeStamp = function (seconds) {
var ts = (new Date(seconds * 1000)).toISOString();
return ts.replace("T", " ").replace("Z", "");
};
@@ -68,7 +68,7 @@ var formatTimeStamp = function (seconds) {
// but we can only provide a key function.
// This beauty "reverses" a JS string.
var end = String.fromCharCode(0xffff);
-function reverseString(s) {
+export function reverseString(s) {
return String.fromCharCode.apply(String,
_.map(s.split(""), function (c) {
return 0xffff - c.charCodeAt(0);
@@ -101,12 +101,4 @@ $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
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
+}); \ No newline at end of file
diff --git a/web/src/templates/index.html b/web/src/templates/index.html
index 5f2c6d5e..165d7d3d 100644
--- a/web/src/templates/index.html
+++ b/web/src/templates/index.html
@@ -10,5 +10,6 @@
<script src="/static/app.js"></script>
</head>
<body>
+<div id="mitmproxy"></div>
</body>
</html> \ No newline at end of file