mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-01-30 23:09:44 +00:00
add table sort
This commit is contained in:
parent
4a92c42517
commit
40c242c3f6
@ -175,6 +175,33 @@ header .menu {
|
|||||||
.flow-table th {
|
.flow-table th {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
box-shadow: 0 1px 0 #a6a6a6;
|
box-shadow: 0 1px 0 #a6a6a6;
|
||||||
|
position: relative !important;
|
||||||
|
padding-left: 1px;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.flow-table th.sort-asc,
|
||||||
|
.flow-table th.sort-desc {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
.flow-table th.sort-asc:after,
|
||||||
|
.flow-table th.sort-desc:after {
|
||||||
|
font: normal normal normal 14px/1 FontAwesome;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: 3px;
|
||||||
|
padding: 2px;
|
||||||
|
background-color: rgba(250, 250, 250, 0.8);
|
||||||
|
}
|
||||||
|
.flow-table th.sort-asc:after {
|
||||||
|
content: "\f0de";
|
||||||
|
}
|
||||||
|
.flow-table th.sort-desc:after {
|
||||||
|
content: "\f0dd";
|
||||||
}
|
}
|
||||||
.flow-table tr {
|
.flow-table tr {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -1178,13 +1178,19 @@ module.exports = {
|
|||||||
|
|
||||||
},{"../actions.js":2,"../flow/utils.js":17,"../utils.js":20,"./common.js":4,"lodash":"lodash","react":"react"}],7:[function(require,module,exports){
|
},{"../actions.js":2,"../flow/utils.js":17,"../utils.js":20,"./common.js":4,"lodash":"lodash","react":"react"}],7:[function(require,module,exports){
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var flowutils = require("../flow/utils.js");
|
var RequestUtils = require("../flow/utils.js").RequestUtils;
|
||||||
|
var ResponseUtils = require("../flow/utils.js").ResponseUtils;
|
||||||
var utils = require("../utils.js");
|
var utils = require("../utils.js");
|
||||||
|
|
||||||
var TLSColumn = React.createClass({displayName: "TLSColumn",
|
var TLSColumn = React.createClass({displayName: "TLSColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "tls", className: "col-tls"});
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-tls " + (this.props.className || "") }));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.request.scheme;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1203,16 +1209,18 @@ var TLSColumn = React.createClass({displayName: "TLSColumn",
|
|||||||
|
|
||||||
var IconColumn = React.createClass({displayName: "IconColumn",
|
var IconColumn = React.createClass({displayName: "IconColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "icon", className: "col-icon"});
|
render: function(){
|
||||||
}
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-icon " + (this.props.className || "") }));
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var flow = this.props.flow;
|
var flow = this.props.flow;
|
||||||
|
|
||||||
var icon;
|
var icon;
|
||||||
if (flow.response) {
|
if (flow.response) {
|
||||||
var contentType = flowutils.ResponseUtils.getContentType(flow.response);
|
var contentType = ResponseUtils.getContentType(flow.response);
|
||||||
|
|
||||||
//TODO: We should assign a type to the flow somewhere else.
|
//TODO: We should assign a type to the flow somewhere else.
|
||||||
if (flow.response.code == 304) {
|
if (flow.response.code == 304) {
|
||||||
@ -1243,8 +1251,13 @@ var IconColumn = React.createClass({displayName: "IconColumn",
|
|||||||
|
|
||||||
var PathColumn = React.createClass({displayName: "PathColumn",
|
var PathColumn = React.createClass({displayName: "PathColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "path", className: "col-path"}, "Path");
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-path " + (this.props.className || "") }), "Path");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return RequestUtils.pretty_url(flow.request);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1252,7 +1265,7 @@ var PathColumn = React.createClass({displayName: "PathColumn",
|
|||||||
return React.createElement("td", {className: "col-path"},
|
return React.createElement("td", {className: "col-path"},
|
||||||
flow.request.is_replay ? React.createElement("i", {className: "fa fa-fw fa-repeat pull-right"}) : null,
|
flow.request.is_replay ? React.createElement("i", {className: "fa fa-fw fa-repeat pull-right"}) : null,
|
||||||
flow.intercepted ? React.createElement("i", {className: "fa fa-fw fa-pause pull-right"}) : null,
|
flow.intercepted ? React.createElement("i", {className: "fa fa-fw fa-pause pull-right"}) : null,
|
||||||
flow.request.scheme + "://" + flow.request.host + flow.request.path
|
RequestUtils.pretty_url(flow.request)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1260,8 +1273,13 @@ var PathColumn = React.createClass({displayName: "PathColumn",
|
|||||||
|
|
||||||
var MethodColumn = React.createClass({displayName: "MethodColumn",
|
var MethodColumn = React.createClass({displayName: "MethodColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "method", className: "col-method"}, "Method");
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-method " + (this.props.className || "") }), "Method");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.request.method;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1273,8 +1291,13 @@ var MethodColumn = React.createClass({displayName: "MethodColumn",
|
|||||||
|
|
||||||
var StatusColumn = React.createClass({displayName: "StatusColumn",
|
var StatusColumn = React.createClass({displayName: "StatusColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "status", className: "col-status"}, "Status");
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-status " + (this.props.className || "") }), "Status");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.response ? flow.response.code : undefined;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1292,8 +1315,17 @@ var StatusColumn = React.createClass({displayName: "StatusColumn",
|
|||||||
|
|
||||||
var SizeColumn = React.createClass({displayName: "SizeColumn",
|
var SizeColumn = React.createClass({displayName: "SizeColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "size", className: "col-size"}, "Size");
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-size " + (this.props.className || "") }), "Size");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
var total = flow.request.contentLength;
|
||||||
|
if (flow.response) {
|
||||||
|
total += flow.response.contentLength || 0;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1311,8 +1343,15 @@ var SizeColumn = React.createClass({displayName: "SizeColumn",
|
|||||||
|
|
||||||
var TimeColumn = React.createClass({displayName: "TimeColumn",
|
var TimeColumn = React.createClass({displayName: "TimeColumn",
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({displayName: "Title",
|
||||||
return React.createElement("th", {key: "time", className: "col-time"}, "Time");
|
render: function(){
|
||||||
|
return React.createElement("th", React.__spread({}, this.props, {className: "col-time " + (this.props.className || "") }), "Time");
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
if(flow.response) {
|
||||||
|
return flow.response.timestamp_end - flow.request.timestamp_start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -1335,17 +1374,17 @@ var all_columns = [
|
|||||||
MethodColumn,
|
MethodColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
SizeColumn,
|
SizeColumn,
|
||||||
TimeColumn];
|
TimeColumn
|
||||||
|
];
|
||||||
|
|
||||||
module.exports = all_columns;
|
module.exports = all_columns;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},{"../flow/utils.js":17,"../utils.js":20,"react":"react"}],8:[function(require,module,exports){
|
},{"../flow/utils.js":17,"../utils.js":20,"react":"react"}],8:[function(require,module,exports){
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var common = require("./common.js");
|
var common = require("./common.js");
|
||||||
|
var utils = require("../utils.js");
|
||||||
|
var _ = require("lodash");
|
||||||
|
|
||||||
var VirtualScrollMixin = require("./virtualscroll.js");
|
var VirtualScrollMixin = require("./virtualscroll.js");
|
||||||
var flowtable_columns = require("./flowtable-columns.js");
|
var flowtable_columns = require("./flowtable-columns.js");
|
||||||
|
|
||||||
@ -1389,9 +1428,56 @@ var FlowRow = React.createClass({displayName: "FlowRow",
|
|||||||
});
|
});
|
||||||
|
|
||||||
var FlowTableHead = React.createClass({displayName: "FlowTableHead",
|
var FlowTableHead = React.createClass({displayName: "FlowTableHead",
|
||||||
|
getInitialState: function(){
|
||||||
|
return {
|
||||||
|
sortColumn: undefined,
|
||||||
|
sortDesc: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onClick: function(Column){
|
||||||
|
var sortDesc = this.state.sortDesc;
|
||||||
|
var hasSort = Column.sortKeyFun;
|
||||||
|
if(Column === this.state.sortColumn){
|
||||||
|
sortDesc = !sortDesc;
|
||||||
|
this.setState({
|
||||||
|
sortDesc: sortDesc
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
sortColumn: hasSort && Column,
|
||||||
|
sortDesc: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var sortKeyFun;
|
||||||
|
if(!sortDesc){
|
||||||
|
sortKeyFun = Column.sortKeyFun;
|
||||||
|
} else {
|
||||||
|
sortKeyFun = hasSort && function(){
|
||||||
|
var k = Column.sortKeyFun.apply(this, arguments);
|
||||||
|
if(_.isString(k)){
|
||||||
|
return utils.reverseString(""+k);
|
||||||
|
} else {
|
||||||
|
return -k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.props.setSortKeyFun(sortKeyFun);
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var columns = this.props.columns.map(function (column) {
|
var columns = this.props.columns.map(function (Column) {
|
||||||
return column.renderTitle();
|
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 React.createElement(Column.Title, {
|
||||||
|
key: Column.displayName,
|
||||||
|
onClick: onClick,
|
||||||
|
className: className});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
return React.createElement("thead", null,
|
return React.createElement("thead", null,
|
||||||
React.createElement("tr", null, columns)
|
React.createElement("tr", null, columns)
|
||||||
@ -1409,13 +1495,17 @@ var FlowTable = React.createClass({displayName: "FlowTable",
|
|||||||
columns: flowtable_columns
|
columns: flowtable_columns
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function () {
|
_listen: function(view){
|
||||||
if (this.props.view) {
|
if(!view){
|
||||||
this.props.view.addListener("add", this.onChange);
|
return;
|
||||||
this.props.view.addListener("update", this.onChange);
|
|
||||||
this.props.view.addListener("remove", this.onChange);
|
|
||||||
this.props.view.addListener("recalculate", this.onChange);
|
|
||||||
}
|
}
|
||||||
|
view.addListener("add", this.onChange);
|
||||||
|
view.addListener("update", this.onChange);
|
||||||
|
view.addListener("remove", this.onChange);
|
||||||
|
view.addListener("recalculate", this.onChange);
|
||||||
|
},
|
||||||
|
componentWillMount: function () {
|
||||||
|
this._listen(this.props.view);
|
||||||
},
|
},
|
||||||
componentWillReceiveProps: function (nextProps) {
|
componentWillReceiveProps: function (nextProps) {
|
||||||
if (nextProps.view !== this.props.view) {
|
if (nextProps.view !== this.props.view) {
|
||||||
@ -1425,10 +1515,7 @@ var FlowTable = React.createClass({displayName: "FlowTable",
|
|||||||
this.props.view.removeListener("remove");
|
this.props.view.removeListener("remove");
|
||||||
this.props.view.removeListener("recalculate");
|
this.props.view.removeListener("recalculate");
|
||||||
}
|
}
|
||||||
nextProps.view.addListener("add", this.onChange);
|
this._listen(nextProps.view);
|
||||||
nextProps.view.addListener("update", this.onChange);
|
|
||||||
nextProps.view.addListener("remove", this.onChange);
|
|
||||||
nextProps.view.addListener("recalculate", this.onChange);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
@ -1476,7 +1563,8 @@ var FlowTable = React.createClass({displayName: "FlowTable",
|
|||||||
React.createElement("div", {className: "flow-table", onScroll: this.onScrollFlowTable},
|
React.createElement("div", {className: "flow-table", onScroll: this.onScrollFlowTable},
|
||||||
React.createElement("table", null,
|
React.createElement("table", null,
|
||||||
React.createElement(FlowTableHead, {ref: "head",
|
React.createElement(FlowTableHead, {ref: "head",
|
||||||
columns: this.state.columns}),
|
columns: this.state.columns,
|
||||||
|
setSortKeyFun: this.props.setSortKeyFun}),
|
||||||
React.createElement("tbody", {ref: "body"},
|
React.createElement("tbody", {ref: "body"},
|
||||||
this.getPlaceholderTop(flows.length),
|
this.getPlaceholderTop(flows.length),
|
||||||
rows,
|
rows,
|
||||||
@ -1491,7 +1579,7 @@ var FlowTable = React.createClass({displayName: "FlowTable",
|
|||||||
module.exports = FlowTable;
|
module.exports = FlowTable;
|
||||||
|
|
||||||
|
|
||||||
},{"./common.js":4,"./flowtable-columns.js":7,"./virtualscroll.js":13,"react":"react"}],9:[function(require,module,exports){
|
},{"../utils.js":20,"./common.js":4,"./flowtable-columns.js":7,"./virtualscroll.js":13,"lodash":"lodash","react":"react"}],9:[function(require,module,exports){
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
|
|
||||||
var Footer = React.createClass({displayName: "Footer",
|
var Footer = React.createClass({displayName: "Footer",
|
||||||
@ -1914,12 +2002,12 @@ var Filt = require("../filt/filt.js");
|
|||||||
FlowTable = require("./flowtable.js");
|
FlowTable = require("./flowtable.js");
|
||||||
var flowdetail = require("./flowdetail.js");
|
var flowdetail = require("./flowdetail.js");
|
||||||
|
|
||||||
|
|
||||||
var MainView = React.createClass({displayName: "MainView",
|
var MainView = React.createClass({displayName: "MainView",
|
||||||
mixins: [common.Navigation, common.State],
|
mixins: [common.Navigation, common.State],
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
flows: []
|
flows: [],
|
||||||
|
sortKeyFun: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getViewFilt: function () {
|
getViewFilt: function () {
|
||||||
@ -1939,8 +2027,6 @@ var MainView = React.createClass({displayName: "MainView",
|
|||||||
return filt(flow);
|
return filt(flow);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getViewSort: function () {
|
|
||||||
},
|
|
||||||
componentWillReceiveProps: function (nextProps) {
|
componentWillReceiveProps: function (nextProps) {
|
||||||
if (nextProps.flowStore !== this.props.flowStore) {
|
if (nextProps.flowStore !== this.props.flowStore) {
|
||||||
this.closeView();
|
this.closeView();
|
||||||
@ -1950,11 +2036,11 @@ var MainView = React.createClass({displayName: "MainView",
|
|||||||
var filterChanged = (this.props.query[Query.FILTER] !== nextProps.query[Query.FILTER]);
|
var filterChanged = (this.props.query[Query.FILTER] !== nextProps.query[Query.FILTER]);
|
||||||
var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]);
|
var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]);
|
||||||
if (filterChanged || highlightChanged) {
|
if (filterChanged || highlightChanged) {
|
||||||
this.state.view.recalculate(this.getViewFilt(), this.getViewSort());
|
this.state.view.recalculate(this.getViewFilt(), this.state.sortKeyFun);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openView: function (store) {
|
openView: function (store) {
|
||||||
var view = new views.StoreView(store, this.getViewFilt(), this.getViewSort());
|
var view = new views.StoreView(store, this.getViewFilt(), this.state.sortKeyFun);
|
||||||
this.setState({
|
this.setState({
|
||||||
view: view
|
view: view
|
||||||
});
|
});
|
||||||
@ -1992,6 +2078,12 @@ var MainView = React.createClass({displayName: "MainView",
|
|||||||
componentWillUnmount: function () {
|
componentWillUnmount: function () {
|
||||||
this.closeView();
|
this.closeView();
|
||||||
},
|
},
|
||||||
|
setSortKeyFun: function(sortKeyFun){
|
||||||
|
this.setState({
|
||||||
|
sortKeyFun: sortKeyFun
|
||||||
|
});
|
||||||
|
this.state.view.recalculate(this.getViewFilt(), sortKeyFun);
|
||||||
|
},
|
||||||
selectFlow: function (flow) {
|
selectFlow: function (flow) {
|
||||||
if (flow) {
|
if (flow) {
|
||||||
this.replaceWith(
|
this.replaceWith(
|
||||||
@ -2131,6 +2223,7 @@ var MainView = React.createClass({displayName: "MainView",
|
|||||||
React.createElement(FlowTable, {ref: "flowTable",
|
React.createElement(FlowTable, {ref: "flowTable",
|
||||||
view: this.state.view,
|
view: this.state.view,
|
||||||
selectFlow: this.selectFlow,
|
selectFlow: this.selectFlow,
|
||||||
|
setSortKeyFun: this.setSortKeyFun,
|
||||||
selected: selected}),
|
selected: selected}),
|
||||||
details
|
details
|
||||||
)
|
)
|
||||||
@ -4408,7 +4501,6 @@ module.exports = {
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
|
|
||||||
var utils = require("../utils.js");
|
var utils = require("../utils.js");
|
||||||
|
|
||||||
function SortByStoreOrder(elem) {
|
function SortByStoreOrder(elem) {
|
||||||
@ -4447,17 +4539,25 @@ _.extend(StoreView.prototype, EventEmitter.prototype, {
|
|||||||
this.store.removeListener("recalculate", this.recalculate);
|
this.store.removeListener("recalculate", this.recalculate);
|
||||||
},
|
},
|
||||||
recalculate: function (filt, sortfun) {
|
recalculate: function (filt, sortfun) {
|
||||||
if (filt) {
|
filt = filt || default_filt;
|
||||||
this.filt = filt.bind(this);
|
sortfun = sortfun || default_sort;
|
||||||
}
|
filt = filt.bind(this);
|
||||||
if (sortfun) {
|
sortfun = sortfun.bind(this)
|
||||||
this.sortfun = sortfun.bind(this);
|
this.filt = filt;
|
||||||
}
|
this.sortfun = sortfun;
|
||||||
|
|
||||||
this.list = this.store.list.filter(this.filt);
|
this.list = this.store.list.filter(filt);
|
||||||
this.list.sort(function (a, b) {
|
this.list.sort(function (a, b) {
|
||||||
return this.sortfun(a) - this.sortfun(b);
|
var akey = sortfun(a);
|
||||||
}.bind(this));
|
var bkey = sortfun(b);
|
||||||
|
if(akey < bkey){
|
||||||
|
return -1;
|
||||||
|
} else if(akey > bkey){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
this.emit("recalculate");
|
this.emit("recalculate");
|
||||||
},
|
},
|
||||||
index: function (elem) {
|
index: function (elem) {
|
||||||
@ -4517,7 +4617,7 @@ module.exports = {
|
|||||||
|
|
||||||
},{"../utils.js":20,"events":1,"lodash":"lodash"}],20:[function(require,module,exports){
|
},{"../utils.js":20,"events":1,"lodash":"lodash"}],20:[function(require,module,exports){
|
||||||
var $ = require("jquery");
|
var $ = require("jquery");
|
||||||
|
var _ = require("lodash");
|
||||||
|
|
||||||
var Key = {
|
var Key = {
|
||||||
UP: 38,
|
UP: 38,
|
||||||
@ -4577,6 +4677,18 @@ var formatTimeStamp = function (seconds) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// At some places, we need to sort strings alphabetically descending,
|
||||||
|
// but we can only provide a key function.
|
||||||
|
// This beauty "reverses" a JS string.
|
||||||
|
var end = String.fromCharCode(0xffff);
|
||||||
|
function reverseString(s){
|
||||||
|
return String.fromCharCode.apply(String,
|
||||||
|
_.map(s.split(""), function (c) {
|
||||||
|
return 0xffff - c.charCodeAt();
|
||||||
|
})
|
||||||
|
) + end;
|
||||||
|
}
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
|
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
|
||||||
return r ? r[1] : undefined;
|
return r ? r[1] : undefined;
|
||||||
@ -4605,10 +4717,11 @@ module.exports = {
|
|||||||
formatSize: formatSize,
|
formatSize: formatSize,
|
||||||
formatTimeDelta: formatTimeDelta,
|
formatTimeDelta: formatTimeDelta,
|
||||||
formatTimeStamp: formatTimeStamp,
|
formatTimeStamp: formatTimeStamp,
|
||||||
|
reverseString: reverseString,
|
||||||
Key: Key
|
Key: Key
|
||||||
};
|
};
|
||||||
|
|
||||||
},{"jquery":"jquery"}]},{},[3])
|
},{"jquery":"jquery","lodash":"lodash"}]},{},[3])
|
||||||
|
|
||||||
|
|
||||||
//# sourceMappingURL=app.js.map
|
//# sourceMappingURL=app.js.map
|
@ -1,3 +1,13 @@
|
|||||||
|
//TODO: move into utils
|
||||||
|
.user-select (@val) {
|
||||||
|
-webkit-touch-callout: @val;
|
||||||
|
-webkit-user-select: @val;
|
||||||
|
-khtml-user-select: @val;
|
||||||
|
-moz-user-select: @val;
|
||||||
|
-ms-user-select: @val;
|
||||||
|
user-select: @val;
|
||||||
|
}
|
||||||
|
|
||||||
.flow-table {
|
.flow-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -15,6 +25,28 @@
|
|||||||
th {
|
th {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
box-shadow: 0 1px 0 #a6a6a6;
|
box-shadow: 0 1px 0 #a6a6a6;
|
||||||
|
position: relative !important;
|
||||||
|
padding-left: 1px;
|
||||||
|
.user-select(none);
|
||||||
|
|
||||||
|
&.sort-asc, &.sort-desc {
|
||||||
|
background-color: lighten(#F2F2F2, 3%);
|
||||||
|
}
|
||||||
|
&.sort-asc:after, &.sort-desc:after {
|
||||||
|
font: normal normal normal 14px/1 FontAwesome;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: 3px;
|
||||||
|
padding: 2px;
|
||||||
|
background-color: fadeout(lighten(#F2F2F2, 3%), 20%);
|
||||||
|
}
|
||||||
|
&.sort-asc:after {
|
||||||
|
content: "\f0de";
|
||||||
|
}
|
||||||
|
&.sort-desc:after {
|
||||||
|
content: "\f0dd";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
var React = require("react");
|
var React = require("react");
|
||||||
var flowutils = require("../flow/utils.js");
|
var RequestUtils = require("../flow/utils.js").RequestUtils;
|
||||||
|
var ResponseUtils = require("../flow/utils.js").ResponseUtils;
|
||||||
var utils = require("../utils.js");
|
var utils = require("../utils.js");
|
||||||
|
|
||||||
var TLSColumn = React.createClass({
|
var TLSColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="tls" className="col-tls"></th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-tls " + (this.props.className || "") }></th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.request.scheme;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -24,16 +30,18 @@ var TLSColumn = React.createClass({
|
|||||||
|
|
||||||
var IconColumn = React.createClass({
|
var IconColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="icon" className="col-icon"></th>;
|
render: function(){
|
||||||
}
|
return <th {...this.props} className={"col-icon " + (this.props.className || "") }></th>;
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var flow = this.props.flow;
|
var flow = this.props.flow;
|
||||||
|
|
||||||
var icon;
|
var icon;
|
||||||
if (flow.response) {
|
if (flow.response) {
|
||||||
var contentType = flowutils.ResponseUtils.getContentType(flow.response);
|
var contentType = ResponseUtils.getContentType(flow.response);
|
||||||
|
|
||||||
//TODO: We should assign a type to the flow somewhere else.
|
//TODO: We should assign a type to the flow somewhere else.
|
||||||
if (flow.response.code == 304) {
|
if (flow.response.code == 304) {
|
||||||
@ -64,8 +72,13 @@ var IconColumn = React.createClass({
|
|||||||
|
|
||||||
var PathColumn = React.createClass({
|
var PathColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="path" className="col-path">Path</th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-path " + (this.props.className || "") }>Path</th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return RequestUtils.pretty_url(flow.request);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -73,7 +86,7 @@ var PathColumn = React.createClass({
|
|||||||
return <td className="col-path">
|
return <td className="col-path">
|
||||||
{flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null}
|
{flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null}
|
||||||
{flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null}
|
{flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null}
|
||||||
{flow.request.scheme + "://" + flow.request.host + flow.request.path}
|
{ RequestUtils.pretty_url(flow.request) }
|
||||||
</td>;
|
</td>;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -81,8 +94,13 @@ var PathColumn = React.createClass({
|
|||||||
|
|
||||||
var MethodColumn = React.createClass({
|
var MethodColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="method" className="col-method">Method</th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-method " + (this.props.className || "") }>Method</th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.request.method;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -94,8 +112,13 @@ var MethodColumn = React.createClass({
|
|||||||
|
|
||||||
var StatusColumn = React.createClass({
|
var StatusColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="status" className="col-status">Status</th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-status " + (this.props.className || "") }>Status</th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
return flow.response ? flow.response.code : undefined;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -113,8 +136,17 @@ var StatusColumn = React.createClass({
|
|||||||
|
|
||||||
var SizeColumn = React.createClass({
|
var SizeColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="size" className="col-size">Size</th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-size " + (this.props.className || "") }>Size</th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
var total = flow.request.contentLength;
|
||||||
|
if (flow.response) {
|
||||||
|
total += flow.response.contentLength || 0;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -132,8 +164,15 @@ var SizeColumn = React.createClass({
|
|||||||
|
|
||||||
var TimeColumn = React.createClass({
|
var TimeColumn = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
renderTitle: function () {
|
Title: React.createClass({
|
||||||
return <th key="time" className="col-time">Time</th>;
|
render: function(){
|
||||||
|
return <th {...this.props} className={"col-time " + (this.props.className || "") }>Time</th>;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
sortKeyFun: function(flow){
|
||||||
|
if(flow.response) {
|
||||||
|
return flow.response.timestamp_end - flow.request.timestamp_start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
@ -156,9 +195,7 @@ var all_columns = [
|
|||||||
MethodColumn,
|
MethodColumn,
|
||||||
StatusColumn,
|
StatusColumn,
|
||||||
SizeColumn,
|
SizeColumn,
|
||||||
TimeColumn];
|
TimeColumn
|
||||||
|
];
|
||||||
|
|
||||||
module.exports = all_columns;
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = all_columns;
|
@ -1,5 +1,8 @@
|
|||||||
var React = require("react");
|
var React = require("react");
|
||||||
var common = require("./common.js");
|
var common = require("./common.js");
|
||||||
|
var utils = require("../utils.js");
|
||||||
|
var _ = require("lodash");
|
||||||
|
|
||||||
var VirtualScrollMixin = require("./virtualscroll.js");
|
var VirtualScrollMixin = require("./virtualscroll.js");
|
||||||
var flowtable_columns = require("./flowtable-columns.js");
|
var flowtable_columns = require("./flowtable-columns.js");
|
||||||
|
|
||||||
@ -43,9 +46,56 @@ var FlowRow = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
var FlowTableHead = React.createClass({
|
var FlowTableHead = React.createClass({
|
||||||
|
getInitialState: function(){
|
||||||
|
return {
|
||||||
|
sortColumn: undefined,
|
||||||
|
sortDesc: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onClick: function(Column){
|
||||||
|
var sortDesc = this.state.sortDesc;
|
||||||
|
var hasSort = Column.sortKeyFun;
|
||||||
|
if(Column === this.state.sortColumn){
|
||||||
|
sortDesc = !sortDesc;
|
||||||
|
this.setState({
|
||||||
|
sortDesc: sortDesc
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
sortColumn: hasSort && Column,
|
||||||
|
sortDesc: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var sortKeyFun;
|
||||||
|
if(!sortDesc){
|
||||||
|
sortKeyFun = Column.sortKeyFun;
|
||||||
|
} else {
|
||||||
|
sortKeyFun = hasSort && function(){
|
||||||
|
var k = Column.sortKeyFun.apply(this, arguments);
|
||||||
|
if(_.isString(k)){
|
||||||
|
return utils.reverseString(""+k);
|
||||||
|
} else {
|
||||||
|
return -k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.props.setSortKeyFun(sortKeyFun);
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var columns = this.props.columns.map(function (column) {
|
var columns = this.props.columns.map(function (Column) {
|
||||||
return column.renderTitle();
|
var onClick = this.onClick.bind(this, Column);
|
||||||
|
var className;
|
||||||
|
if(this.state.sortColumn === Column) {
|
||||||
|
if(this.state.sortDesc){
|
||||||
|
className = "sort-desc";
|
||||||
|
} else {
|
||||||
|
className = "sort-asc";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return <Column.Title
|
||||||
|
key={Column.displayName}
|
||||||
|
onClick={onClick}
|
||||||
|
className={className} />;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
return <thead>
|
return <thead>
|
||||||
<tr>{columns}</tr>
|
<tr>{columns}</tr>
|
||||||
@ -63,13 +113,17 @@ var FlowTable = React.createClass({
|
|||||||
columns: flowtable_columns
|
columns: flowtable_columns
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentWillMount: function () {
|
_listen: function(view){
|
||||||
if (this.props.view) {
|
if(!view){
|
||||||
this.props.view.addListener("add", this.onChange);
|
return;
|
||||||
this.props.view.addListener("update", this.onChange);
|
|
||||||
this.props.view.addListener("remove", this.onChange);
|
|
||||||
this.props.view.addListener("recalculate", this.onChange);
|
|
||||||
}
|
}
|
||||||
|
view.addListener("add", this.onChange);
|
||||||
|
view.addListener("update", this.onChange);
|
||||||
|
view.addListener("remove", this.onChange);
|
||||||
|
view.addListener("recalculate", this.onChange);
|
||||||
|
},
|
||||||
|
componentWillMount: function () {
|
||||||
|
this._listen(this.props.view);
|
||||||
},
|
},
|
||||||
componentWillReceiveProps: function (nextProps) {
|
componentWillReceiveProps: function (nextProps) {
|
||||||
if (nextProps.view !== this.props.view) {
|
if (nextProps.view !== this.props.view) {
|
||||||
@ -79,10 +133,7 @@ var FlowTable = React.createClass({
|
|||||||
this.props.view.removeListener("remove");
|
this.props.view.removeListener("remove");
|
||||||
this.props.view.removeListener("recalculate");
|
this.props.view.removeListener("recalculate");
|
||||||
}
|
}
|
||||||
nextProps.view.addListener("add", this.onChange);
|
this._listen(nextProps.view);
|
||||||
nextProps.view.addListener("update", this.onChange);
|
|
||||||
nextProps.view.addListener("remove", this.onChange);
|
|
||||||
nextProps.view.addListener("recalculate", this.onChange);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
@ -130,7 +181,8 @@ var FlowTable = React.createClass({
|
|||||||
<div className="flow-table" onScroll={this.onScrollFlowTable}>
|
<div className="flow-table" onScroll={this.onScrollFlowTable}>
|
||||||
<table>
|
<table>
|
||||||
<FlowTableHead ref="head"
|
<FlowTableHead ref="head"
|
||||||
columns={this.state.columns}/>
|
columns={this.state.columns}
|
||||||
|
setSortKeyFun={this.props.setSortKeyFun}/>
|
||||||
<tbody ref="body">
|
<tbody ref="body">
|
||||||
{ this.getPlaceholderTop(flows.length) }
|
{ this.getPlaceholderTop(flows.length) }
|
||||||
{rows}
|
{rows}
|
||||||
|
@ -9,12 +9,12 @@ var Filt = require("../filt/filt.js");
|
|||||||
FlowTable = require("./flowtable.js");
|
FlowTable = require("./flowtable.js");
|
||||||
var flowdetail = require("./flowdetail.js");
|
var flowdetail = require("./flowdetail.js");
|
||||||
|
|
||||||
|
|
||||||
var MainView = React.createClass({
|
var MainView = React.createClass({
|
||||||
mixins: [common.Navigation, common.State],
|
mixins: [common.Navigation, common.State],
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
flows: []
|
flows: [],
|
||||||
|
sortKeyFun: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getViewFilt: function () {
|
getViewFilt: function () {
|
||||||
@ -34,8 +34,6 @@ var MainView = React.createClass({
|
|||||||
return filt(flow);
|
return filt(flow);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getViewSort: function () {
|
|
||||||
},
|
|
||||||
componentWillReceiveProps: function (nextProps) {
|
componentWillReceiveProps: function (nextProps) {
|
||||||
if (nextProps.flowStore !== this.props.flowStore) {
|
if (nextProps.flowStore !== this.props.flowStore) {
|
||||||
this.closeView();
|
this.closeView();
|
||||||
@ -45,11 +43,11 @@ var MainView = React.createClass({
|
|||||||
var filterChanged = (this.props.query[Query.FILTER] !== nextProps.query[Query.FILTER]);
|
var filterChanged = (this.props.query[Query.FILTER] !== nextProps.query[Query.FILTER]);
|
||||||
var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]);
|
var highlightChanged = (this.props.query[Query.HIGHLIGHT] !== nextProps.query[Query.HIGHLIGHT]);
|
||||||
if (filterChanged || highlightChanged) {
|
if (filterChanged || highlightChanged) {
|
||||||
this.state.view.recalculate(this.getViewFilt(), this.getViewSort());
|
this.state.view.recalculate(this.getViewFilt(), this.state.sortKeyFun);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openView: function (store) {
|
openView: function (store) {
|
||||||
var view = new views.StoreView(store, this.getViewFilt(), this.getViewSort());
|
var view = new views.StoreView(store, this.getViewFilt(), this.state.sortKeyFun);
|
||||||
this.setState({
|
this.setState({
|
||||||
view: view
|
view: view
|
||||||
});
|
});
|
||||||
@ -87,6 +85,12 @@ var MainView = React.createClass({
|
|||||||
componentWillUnmount: function () {
|
componentWillUnmount: function () {
|
||||||
this.closeView();
|
this.closeView();
|
||||||
},
|
},
|
||||||
|
setSortKeyFun: function(sortKeyFun){
|
||||||
|
this.setState({
|
||||||
|
sortKeyFun: sortKeyFun
|
||||||
|
});
|
||||||
|
this.state.view.recalculate(this.getViewFilt(), sortKeyFun);
|
||||||
|
},
|
||||||
selectFlow: function (flow) {
|
selectFlow: function (flow) {
|
||||||
if (flow) {
|
if (flow) {
|
||||||
this.replaceWith(
|
this.replaceWith(
|
||||||
@ -226,6 +230,7 @@ var MainView = React.createClass({
|
|||||||
<FlowTable ref="flowTable"
|
<FlowTable ref="flowTable"
|
||||||
view={this.state.view}
|
view={this.state.view}
|
||||||
selectFlow={this.selectFlow}
|
selectFlow={this.selectFlow}
|
||||||
|
setSortKeyFun={this.setSortKeyFun}
|
||||||
selected={selected} />
|
selected={selected} />
|
||||||
{details}
|
{details}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
|
|
||||||
var utils = require("../utils.js");
|
var utils = require("../utils.js");
|
||||||
|
|
||||||
function SortByStoreOrder(elem) {
|
function SortByStoreOrder(elem) {
|
||||||
@ -40,17 +39,25 @@ _.extend(StoreView.prototype, EventEmitter.prototype, {
|
|||||||
this.store.removeListener("recalculate", this.recalculate);
|
this.store.removeListener("recalculate", this.recalculate);
|
||||||
},
|
},
|
||||||
recalculate: function (filt, sortfun) {
|
recalculate: function (filt, sortfun) {
|
||||||
if (filt) {
|
filt = filt || default_filt;
|
||||||
this.filt = filt.bind(this);
|
sortfun = sortfun || default_sort;
|
||||||
}
|
filt = filt.bind(this);
|
||||||
if (sortfun) {
|
sortfun = sortfun.bind(this)
|
||||||
this.sortfun = sortfun.bind(this);
|
this.filt = filt;
|
||||||
}
|
this.sortfun = sortfun;
|
||||||
|
|
||||||
this.list = this.store.list.filter(this.filt);
|
this.list = this.store.list.filter(filt);
|
||||||
this.list.sort(function (a, b) {
|
this.list.sort(function (a, b) {
|
||||||
return this.sortfun(a) - this.sortfun(b);
|
var akey = sortfun(a);
|
||||||
}.bind(this));
|
var bkey = sortfun(b);
|
||||||
|
if(akey < bkey){
|
||||||
|
return -1;
|
||||||
|
} else if(akey > bkey){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
this.emit("recalculate");
|
this.emit("recalculate");
|
||||||
},
|
},
|
||||||
index: function (elem) {
|
index: function (elem) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
var $ = require("jquery");
|
var $ = require("jquery");
|
||||||
|
var _ = require("lodash");
|
||||||
|
|
||||||
var Key = {
|
var Key = {
|
||||||
UP: 38,
|
UP: 38,
|
||||||
@ -59,6 +59,18 @@ var formatTimeStamp = function (seconds) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// At some places, we need to sort strings alphabetically descending,
|
||||||
|
// but we can only provide a key function.
|
||||||
|
// This beauty "reverses" a JS string.
|
||||||
|
var end = String.fromCharCode(0xffff);
|
||||||
|
function reverseString(s){
|
||||||
|
return String.fromCharCode.apply(String,
|
||||||
|
_.map(s.split(""), function (c) {
|
||||||
|
return 0xffff - c.charCodeAt();
|
||||||
|
})
|
||||||
|
) + end;
|
||||||
|
}
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
|
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
|
||||||
return r ? r[1] : undefined;
|
return r ? r[1] : undefined;
|
||||||
@ -87,5 +99,6 @@ module.exports = {
|
|||||||
formatSize: formatSize,
|
formatSize: formatSize,
|
||||||
formatTimeDelta: formatTimeDelta,
|
formatTimeDelta: formatTimeDelta,
|
||||||
formatTimeStamp: formatTimeStamp,
|
formatTimeStamp: formatTimeStamp,
|
||||||
|
reverseString: reverseString,
|
||||||
Key: Key
|
Key: Key
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user