From 02a61ea45dc1ca6d0c88b44adf83f68b791130e7 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 21 Mar 2015 22:49:51 +0100 Subject: structure components --- web/src/js/components/flowview/messages.js | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 web/src/js/components/flowview/messages.js (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js new file mode 100644 index 00000000..ffbfff43 --- /dev/null +++ b/web/src/js/components/flowview/messages.js @@ -0,0 +1,102 @@ +var React = require("react"); + +var flowutils = require("../../flow/utils.js"); +var utils = require("../../utils.js"); + +var Headers = React.createClass({ + render: function () { + var rows = this.props.message.headers.map(function (header, i) { + return ( + + {header[0] + ":"} + {header[1]} + + ); + }); + return ( + + + {rows} + +
+ ); + } +}); + +var Request = React.createClass({ + render: function () { + var flow = this.props.flow; + var first_line = [ + flow.request.method, + flowutils.RequestUtils.pretty_url(flow.request), + "HTTP/" + flow.request.httpversion.join(".") + ].join(" "); + var content = null; + if (flow.request.contentLength > 0) { + content = "Request Content Size: " + utils.formatSize(flow.request.contentLength); + } else { + content =
No Content
; + } + + //TODO: Styling + + return ( +
+
{ first_line }
+ +
+ {content} +
+ ); + } +}); + +var Response = React.createClass({ + render: function () { + var flow = this.props.flow; + var first_line = [ + "HTTP/" + flow.response.httpversion.join("."), + flow.response.code, + flow.response.msg + ].join(" "); + var content = null; + if (flow.response.contentLength > 0) { + content = "Response Content Size: " + utils.formatSize(flow.response.contentLength); + } else { + content =
No Content
; + } + + //TODO: Styling + + return ( +
+
{ first_line }
+ +
+ {content} +
+ ); + } +}); + +var Error = React.createClass({ + render: function () { + var flow = this.props.flow; + return ( +
+
+ {flow.error.msg} +
+ { utils.formatTimeStamp(flow.error.timestamp) } +
+
+
+ ); + } +}); + +module.exports = { + Request: Request, + Response: Response, + Error: Error +}; \ No newline at end of file -- cgit v1.2.3 From 1143552e1690f8b96b3d95381f7f06cbb46ead59 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 22 Mar 2015 00:21:38 +0100 Subject: web: add content views --- web/src/js/components/flowview/messages.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index ffbfff43..fe8fa200 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -2,6 +2,7 @@ var React = require("react"); var flowutils = require("../../flow/utils.js"); var utils = require("../../utils.js"); +var ContentView = require("./contentview.js"); var Headers = React.createClass({ render: function () { @@ -31,12 +32,6 @@ var Request = React.createClass({ flowutils.RequestUtils.pretty_url(flow.request), "HTTP/" + flow.request.httpversion.join(".") ].join(" "); - var content = null; - if (flow.request.contentLength > 0) { - content = "Request Content Size: " + utils.formatSize(flow.request.contentLength); - } else { - content =
No Content
; - } //TODO: Styling @@ -45,7 +40,7 @@ var Request = React.createClass({
{ first_line }

- {content} + ); } @@ -59,12 +54,6 @@ var Response = React.createClass({ flow.response.code, flow.response.msg ].join(" "); - var content = null; - if (flow.response.contentLength > 0) { - content = "Response Content Size: " + utils.formatSize(flow.response.contentLength); - } else { - content =
No Content
; - } //TODO: Styling @@ -73,7 +62,7 @@ var Response = React.createClass({
{ first_line }

- {content} + ); } -- cgit v1.2.3 From 968c7021dfef00c459899520921faf7367e923d9 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 23 Mar 2015 00:24:56 +0100 Subject: web: add basic edit capability for first line --- web/src/js/components/flowview/messages.js | 231 ++++++++++++++++++++++++++--- 1 file changed, 212 insertions(+), 19 deletions(-) (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index fe8fa200..cb8516fc 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -1,5 +1,8 @@ var React = require("react"); +var _ = require("lodash"); +var common = require("../common.js"); +var actions = require("../../actions.js"); var flowutils = require("../../flow/utils.js"); var utils = require("../../utils.js"); var ContentView = require("./contentview.js"); @@ -24,20 +27,217 @@ var Headers = React.createClass({ } }); -var Request = React.createClass({ +var InlineInput = React.createClass({ + mixins: [common.ChildFocus], + getInitialState: function () { + return { + editable: false + }; + }, + render: function () { + var Tag = this.props.tag || "span"; + var className = "inline-input " + (this.props.className || ""); + var html = {__html: _.escape(this.props.content)}; + return ; + }, + onKeyDown: function (e) { + e.stopPropagation(); + switch (e.keyCode) { + case utils.Key.ESC: + this.blur(); + break; + case utils.Key.ENTER: + e.preventDefault(); + if (!e.ctrlKey) { + this.blur(); + } else { + this.props.onDone && this.props.onDone(); + } + break; + default: + break; + } + }, + blur: function(){ + this.getDOMNode().blur(); + this.context.returnFocus && this.context.returnFocus(); + }, + selectContents: function () { + var range = document.createRange(); + range.selectNodeContents(this.getDOMNode()); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + }, + onFocus: function () { + this.setState({editable: true}, this.selectContents); + }, + onBlur: function (e) { + this.setState({editable: false}); + this.handleChange(); + this.props.onDone && this.props.onDone(); + }, + onInput: function () { + this.handleChange(); + }, + handleChange: function () { + var content = this.getDOMNode().textContent; + if (content !== this.props.content) { + this.props.onChange(content); + } + } +}); + +var ValidateInlineInput = React.createClass({ + getInitialState: function () { + return { + content: ""+this.props.content, + originalContent: ""+this.props.content + }; + }, + onChange: function (val) { + this.setState({ + content: val + }); + }, + onDone: function () { + if (this.state.content === this.state.originalContent) { + return true; + } + if (this.props.isValid(this.state.content)) { + this.props.onChange(this.state.content); + } else { + this.setState({ + content: this.state.originalContent + }); + } + }, + componentWillReceiveProps: function (nextProps) { + if (nextProps.content !== this.state.content) { + this.setState({ + content: ""+nextProps.content, + originalContent: ""+nextProps.content + }) + } + }, + render: function () { + var className = this.props.className || ""; + if (this.props.isValid(this.state.content)) { + className += " has-success"; + } else { + className += " has-warning" + } + return ; + } +}); + +var RequestLine = React.createClass({ render: function () { var flow = this.props.flow; - var first_line = [ - flow.request.method, - flowutils.RequestUtils.pretty_url(flow.request), - "HTTP/" + flow.request.httpversion.join(".") - ].join(" "); + var url = flowutils.RequestUtils.pretty_url(flow.request); + var httpver = "HTTP/" + flow.request.httpversion.join("."); - //TODO: Styling + return
+ +   + +   + +
+ }, + isValidMethod: function (method) { + return true; + }, + isValidUrl: function (url) { + var u = flowutils.parseUrl(url); + return !!u.host; + }, + onMethodChange: function (nextMethod) { + actions.FlowActions.update( + this.props.flow, + {request: {method: nextMethod}} + ); + }, + onUrlChange: function (nextUrl) { + var props = flowutils.parseUrl(nextUrl); + props.path = props.path || ""; + actions.FlowActions.update( + this.props.flow, + {request: props} + ); + }, + onHttpVersionChange: function (nextVer) { + var ver = flowutils.parseHttpVersion(nextVer); + actions.FlowActions.update( + this.props.flow, + {request: {httpversion: ver}} + ); + } +}); +var ResponseLine = React.createClass({ + render: function () { + var flow = this.props.flow; + var httpver = "HTTP/" + flow.response.httpversion.join("."); + return
+ +   + +   + + +
; + }, + isValidCode: function (code) { + return /^\d+$/.test(code); + }, + isValidMsg: function () { + return true; + }, + onHttpVersionChange: function (nextVer) { + var ver = flowutils.parseHttpVersion(nextVer); + actions.FlowActions.update( + this.props.flow, + {response: {httpversion: ver}} + ); + }, + onMsgChange: function(nextMsg){ + actions.FlowActions.update( + this.props.flow, + {response: {msg: nextMsg}} + ); + }, + onCodeChange: function(nextCode){ + nextCode = parseInt(nextCode); + actions.FlowActions.update( + this.props.flow, + {response: {code: nextCode}} + ); + } +}); + +var Request = React.createClass({ + render: function () { + var flow = this.props.flow; return ( -
-
{ first_line }
+
+ + {/**/}
@@ -49,17 +249,10 @@ var Request = React.createClass({ var Response = React.createClass({ render: function () { var flow = this.props.flow; - var first_line = [ - "HTTP/" + flow.response.httpversion.join("."), - flow.response.code, - flow.response.msg - ].join(" "); - - //TODO: Styling - return ( -
-
{ first_line }
+
+ {/**/} +
-- cgit v1.2.3 From 42cd942b64e53db9feb5f6c8b2a95669e97b1230 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 27 Mar 2015 15:30:19 +0100 Subject: web: initial attempt at header editor --- web/src/js/components/flowview/messages.js | 154 ++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 23 deletions(-) (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index cb8516fc..7feaa634 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -8,15 +8,77 @@ var utils = require("../../utils.js"); var ContentView = require("./contentview.js"); var Headers = React.createClass({ + propTypes: { + onChange: React.PropTypes.func.isRequired, + message: React.PropTypes.object.isRequired + }, + onChange: function (row, col, val) { + var nextHeaders = _.cloneDeep(this.props.message.headers); + nextHeaders[row][col] = val; + if (!nextHeaders[row][0] && !nextHeaders[row][1]) { + // do not delete last row + if (nextHeaders.length === 1) { + nextHeaders[0][0] = "Name"; + nextHeaders[0][1] = "Value"; + } else { + nextHeaders.splice(row, 1); + // manually move selection target if this has been the last row. + if(row === nextHeaders.length){ + this._nextSel = (row-1)+"-value"; + } + } + } + this.props.onChange(nextHeaders); + }, + onTab: function (row, col, e) { + var headers = this.props.message.headers; + if (row === headers.length - 1 && col === 1) { + e.preventDefault(); + + var nextHeaders = _.cloneDeep(this.props.message.headers); + nextHeaders.push(["Name", "Value"]); + this.props.onChange(nextHeaders); + this._nextSel = (row + 1) + "-key"; + } + }, + componentDidUpdate: function () { + if (this._nextSel && this.refs[this._nextSel]) { + this.refs[this._nextSel].focus(); + this._nextSel = undefined; + } + }, + onRemove: function (row, col, e) { + if (col === 1) { + e.preventDefault(); + this.refs[row + "-key"].focus(); + } else if (row > 0) { + e.preventDefault(); + this.refs[(row - 1) + "-value"].focus(); + } + }, render: function () { + var rows = this.props.message.headers.map(function (header, i) { + + var kEdit = ; + var vEdit = ; return ( - {header[0] + ":"} - {header[1]} + {kEdit}: + {vEdit} ); - }); + }.bind(this)); return ( @@ -27,8 +89,13 @@ var Headers = React.createClass({ } }); + var InlineInput = React.createClass({ mixins: [common.ChildFocus], + propTypes: { + content: React.PropTypes.string.isRequired, //must be string to match strict equality. + onChange: React.PropTypes.func.isRequired, + }, getInitialState: function () { return { editable: false @@ -65,10 +132,11 @@ var InlineInput = React.createClass({ } break; default: + this.props.onKeyDown && this.props.onKeyDown(e); break; } }, - blur: function(){ + blur: function () { this.getDOMNode().blur(); this.context.returnFocus && this.context.returnFocus(); }, @@ -98,17 +166,49 @@ var InlineInput = React.createClass({ } }); +var HeaderInlineInput = React.createClass({ + render: function () { + return ; + }, + focus: function () { + this.getDOMNode().focus(); + }, + onKeyDown: function (e) { + switch (e.keyCode) { + case utils.Key.BACKSPACE: + var s = window.getSelection().getRangeAt(0); + if (s.startOffset === 0 && s.endOffset === 0) { + this.props.onRemove(e); + } + break; + case utils.Key.TAB: + if(!e.shiftKey){ + this.props.onTab(e); + } + break; + } + } +}); + var ValidateInlineInput = React.createClass({ + propTypes: { + onChange: React.PropTypes.func.isRequired, + isValid: React.PropTypes.func.isRequired, + immediate: React.PropTypes.bool + }, getInitialState: function () { return { - content: ""+this.props.content, - originalContent: ""+this.props.content + content: this.props.content, + originalContent: this.props.content }; }, onChange: function (val) { this.setState({ content: val }); + if (this.props.immediate && val !== this.state.originalContent && this.props.isValid(val)) { + this.props.onChange(val); + } }, onDone: function () { if (this.state.content === this.state.originalContent) { @@ -125,8 +225,8 @@ var ValidateInlineInput = React.createClass({ componentWillReceiveProps: function (nextProps) { if (nextProps.content !== this.state.content) { this.setState({ - content: ""+nextProps.content, - originalContent: ""+nextProps.content + content: nextProps.content, + originalContent: nextProps.content }) } }, @@ -153,16 +253,13 @@ var RequestLine = React.createClass({ var httpver = "HTTP/" + flow.request.httpversion.join("."); return
- +     - +
}, - isValidMethod: function (method) { - return true; - }, isValidUrl: function (url) { var u = flowutils.parseUrl(url); return !!u.host; @@ -195,20 +292,17 @@ var ResponseLine = React.createClass({ var flow = this.props.flow; var httpver = "HTTP/" + flow.response.httpversion.join("."); return
- +   - +   - +
; }, isValidCode: function (code) { return /^\d+$/.test(code); }, - isValidMsg: function () { - return true; - }, onHttpVersionChange: function (nextVer) { var ver = flowutils.parseHttpVersion(nextVer); actions.FlowActions.update( @@ -216,13 +310,13 @@ var ResponseLine = React.createClass({ {response: {httpversion: ver}} ); }, - onMsgChange: function(nextMsg){ + onMsgChange: function (nextMsg) { actions.FlowActions.update( this.props.flow, {response: {msg: nextMsg}} ); }, - onCodeChange: function(nextCode){ + onCodeChange: function (nextCode) { nextCode = parseInt(nextCode); actions.FlowActions.update( this.props.flow, @@ -238,11 +332,18 @@ var Request = React.createClass({
{/**/} - +
); + }, + onHeaderChange: function (nextHeaders) { + actions.FlowActions.update(this.props.flow, { + request: { + headers: nextHeaders + } + }); } }); @@ -253,11 +354,18 @@ var Response = React.createClass({
{/**/} - +
); + }, + onHeaderChange: function (nextHeaders) { + actions.FlowActions.update(this.props.flow, { + response: { + headers: nextHeaders + } + }); } }); -- cgit v1.2.3 From 6d29f93e9eaaabe20c0d46887048f2367bfbb3cf Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 30 Mar 2015 03:49:50 +0200 Subject: web: add prompt for keyboard navigation --- web/src/js/components/flowview/messages.js | 74 ++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 15 deletions(-) (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index 7feaa634..cb166026 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -23,13 +23,16 @@ var Headers = React.createClass({ } else { nextHeaders.splice(row, 1); // manually move selection target if this has been the last row. - if(row === nextHeaders.length){ - this._nextSel = (row-1)+"-value"; + if (row === nextHeaders.length) { + this._nextSel = (row - 1) + "-value"; } } } this.props.onChange(nextHeaders); }, + edit: function () { + this.refs["0-key"].focus(); + }, onTab: function (row, col, e) { var headers = this.props.message.headers; if (row === headers.length - 1 && col === 1) { @@ -138,9 +141,11 @@ var InlineInput = React.createClass({ }, blur: function () { this.getDOMNode().blur(); + window.getSelection().removeAllRanges(); this.context.returnFocus && this.context.returnFocus(); }, - selectContents: function () { + focus: function () { + React.findDOMNode(this).focus(); var range = document.createRange(); range.selectNodeContents(this.getDOMNode()); var sel = window.getSelection(); @@ -148,7 +153,7 @@ var InlineInput = React.createClass({ sel.addRange(range); }, onFocus: function () { - this.setState({editable: true}, this.selectContents); + this.setState({editable: true}, this.focus); }, onBlur: function (e) { this.setState({editable: false}); @@ -182,7 +187,7 @@ var HeaderInlineInput = React.createClass({ } break; case utils.Key.TAB: - if(!e.shiftKey){ + if (!e.shiftKey) { this.props.onTab(e); } break; @@ -202,6 +207,9 @@ var ValidateInlineInput = React.createClass({ originalContent: this.props.content }; }, + focus: function () { + this.getDOMNode().focus(); + }, onChange: function (val) { this.setState({ content: val @@ -253,11 +261,11 @@ var RequestLine = React.createClass({ var httpver = "HTTP/" + flow.request.httpversion.join("."); return
- +   - +   - +
}, isValidUrl: function (url) { @@ -292,11 +300,11 @@ var ResponseLine = React.createClass({ var flow = this.props.flow; var httpver = "HTTP/" + flow.response.httpversion.join("."); return
- +   - +   - +
; }, @@ -330,14 +338,32 @@ var Request = React.createClass({ var flow = this.props.flow; return (
- + {/**/} - +
); }, + edit: function (k) { + switch (k) { + case "m": + this.refs.requestLine.refs.method.focus(); + break; + case "u": + this.refs.requestLine.refs.url.focus(); + break; + case "v": + this.refs.requestLine.refs.httpVersion.focus(); + break; + case "h": + this.refs.headers.edit(); + break; + default: + throw "Unimplemented: "+ k; + } + }, onHeaderChange: function (nextHeaders) { actions.FlowActions.update(this.props.flow, { request: { @@ -353,13 +379,31 @@ var Response = React.createClass({ return (
{/**/} - - + +
); }, + edit: function (k) { + switch (k) { + case "c": + this.refs.responseLine.refs.code.focus(); + break; + case "m": + this.refs.responseLine.refs.msg.focus(); + break; + case "v": + this.refs.responseLine.refs.httpVersion.focus(); + break; + case "h": + this.refs.headers.edit(); + break; + default: + throw "Unimplemented: "+ k; + } + }, onHeaderChange: function (nextHeaders) { actions.FlowActions.update(this.props.flow, { response: { -- cgit v1.2.3 From 3f5ca10c39a9f7d55e0f6943caf8f6ff762a0222 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 1 May 2015 17:24:44 +0200 Subject: mitmweb: add editor --- web/src/js/components/flowview/messages.js | 196 +++++++---------------------- 1 file changed, 43 insertions(+), 153 deletions(-) (limited to 'web/src/js/components/flowview/messages.js') diff --git a/web/src/js/components/flowview/messages.js b/web/src/js/components/flowview/messages.js index cb166026..fa75efbe 100644 --- a/web/src/js/components/flowview/messages.js +++ b/web/src/js/components/flowview/messages.js @@ -6,6 +6,7 @@ var actions = require("../../actions.js"); var flowutils = require("../../flow/utils.js"); var utils = require("../../utils.js"); var ContentView = require("./contentview.js"); +var ValueEditor = require("../editor.js").ValueEditor; var Headers = React.createClass({ propTypes: { @@ -63,16 +64,16 @@ var Headers = React.createClass({ var rows = this.props.message.headers.map(function (header, i) { - var kEdit = ; - var vEdit = ; return ( @@ -92,88 +93,9 @@ var Headers = React.createClass({ } }); - -var InlineInput = React.createClass({ - mixins: [common.ChildFocus], - propTypes: { - content: React.PropTypes.string.isRequired, //must be string to match strict equality. - onChange: React.PropTypes.func.isRequired, - }, - getInitialState: function () { - return { - editable: false - }; - }, +var HeaderEditor = React.createClass({ render: function () { - var Tag = this.props.tag || "span"; - var className = "inline-input " + (this.props.className || ""); - var html = {__html: _.escape(this.props.content)}; - return ; - }, - onKeyDown: function (e) { - e.stopPropagation(); - switch (e.keyCode) { - case utils.Key.ESC: - this.blur(); - break; - case utils.Key.ENTER: - e.preventDefault(); - if (!e.ctrlKey) { - this.blur(); - } else { - this.props.onDone && this.props.onDone(); - } - break; - default: - this.props.onKeyDown && this.props.onKeyDown(e); - break; - } - }, - blur: function () { - this.getDOMNode().blur(); - window.getSelection().removeAllRanges(); - this.context.returnFocus && this.context.returnFocus(); - }, - focus: function () { - React.findDOMNode(this).focus(); - var range = document.createRange(); - range.selectNodeContents(this.getDOMNode()); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - }, - onFocus: function () { - this.setState({editable: true}, this.focus); - }, - onBlur: function (e) { - this.setState({editable: false}); - this.handleChange(); - this.props.onDone && this.props.onDone(); - }, - onInput: function () { - this.handleChange(); - }, - handleChange: function () { - var content = this.getDOMNode().textContent; - if (content !== this.props.content) { - this.props.onChange(content); - } - } -}); - -var HeaderInlineInput = React.createClass({ - render: function () { - return ; + return ; }, focus: function () { this.getDOMNode().focus(); @@ -195,65 +117,6 @@ var HeaderInlineInput = React.createClass({ } }); -var ValidateInlineInput = React.createClass({ - propTypes: { - onChange: React.PropTypes.func.isRequired, - isValid: React.PropTypes.func.isRequired, - immediate: React.PropTypes.bool - }, - getInitialState: function () { - return { - content: this.props.content, - originalContent: this.props.content - }; - }, - focus: function () { - this.getDOMNode().focus(); - }, - onChange: function (val) { - this.setState({ - content: val - }); - if (this.props.immediate && val !== this.state.originalContent && this.props.isValid(val)) { - this.props.onChange(val); - } - }, - onDone: function () { - if (this.state.content === this.state.originalContent) { - return true; - } - if (this.props.isValid(this.state.content)) { - this.props.onChange(this.state.content); - } else { - this.setState({ - content: this.state.originalContent - }); - } - }, - componentWillReceiveProps: function (nextProps) { - if (nextProps.content !== this.state.content) { - this.setState({ - content: nextProps.content, - originalContent: nextProps.content - }) - } - }, - render: function () { - var className = this.props.className || ""; - if (this.props.isValid(this.state.content)) { - className += " has-success"; - } else { - className += " has-warning" - } - return ; - } -}); - var RequestLine = React.createClass({ render: function () { var flow = this.props.flow; @@ -261,11 +124,25 @@ var RequestLine = React.createClass({ var httpver = "HTTP/" + flow.request.httpversion.join("."); return
- +   - +   - +
}, isValidUrl: function (url) { @@ -300,12 +177,25 @@ var ResponseLine = React.createClass({ var flow = this.props.flow; var httpver = "HTTP/" + flow.response.httpversion.join("."); return
- +   - +   - - +
; }, isValidCode: function (code) { @@ -361,7 +251,7 @@ var Request = React.createClass({ this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { @@ -401,7 +291,7 @@ var Response = React.createClass({ this.refs.headers.edit(); break; default: - throw "Unimplemented: "+ k; + throw "Unimplemented: " + k; } }, onHeaderChange: function (nextHeaders) { -- cgit v1.2.3