Skip to content

Commit d6f784b

Browse files
committed
escape line breaks in value input
1 parent 011a843 commit d6f784b

File tree

8 files changed

+170
-109
lines changed

8 files changed

+170
-109
lines changed

src/formatCommand.js

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,56 @@
2020
var declaredVars = {};
2121

2222
function xlateArgument(value) {
23-
value = value.replace(/^\s+/, '');
24-
value = value.replace(/\s+$/, '');
25-
var r;
26-
var r2;
27-
var parts = [];
28-
if ((r = /\$\{/.exec(value))) {
29-
var regexp = /\$\{(.*?)\}/g;
30-
var lastIndex = 0;
31-
while ( (r2 = regexp.exec(value)) ) {
32-
if (declaredVars[r2[1]]) {
33-
if (r2.index - lastIndex > 0) {
34-
parts.push(string(value.substring(lastIndex, r2.index)));
35-
}
36-
parts.push(declaredVars[r2[1]]);
37-
lastIndex = regexp.lastIndex;
38-
} else if (r2[1] == "nbsp") {
39-
if (r2.index - lastIndex > 0) {
40-
parts.push(declaredVars[string(value.substring(lastIndex, r2.index))]);
41-
}
42-
parts.push(nonBreakingSpace());
43-
lastIndex = regexp.lastIndex;
44-
}
23+
value = value.replace(/^\s+/, "");
24+
value = value.replace(/\s+$/, "");
25+
var r;
26+
var r2;
27+
var parts = [];
28+
if ((r = /\$\{/.exec(value))) {
29+
var regexp = /\$\{(.*?)\}/g;
30+
var lastIndex = 0;
31+
while ((r2 = regexp.exec(value))) {
32+
if (declaredVars[r2[1]]) {
33+
if (r2.index - lastIndex > 0) {
34+
parts.push(string(value.substring(lastIndex, r2.index)));
4535
}
46-
if (lastIndex < value.length) {
47-
parts.push(string(value.substring(lastIndex, value.length)));
36+
parts.push(declaredVars[r2[1]]);
37+
lastIndex = regexp.lastIndex;
38+
} else if (r2[1] == "nbsp") {
39+
if (r2.index - lastIndex > 0) {
40+
parts.push(declaredVars[string(value.substring(lastIndex, r2.index))]);
4841
}
49-
return parts.join("");
50-
} else {
51-
return string(value);
42+
parts.push(nonBreakingSpace());
43+
lastIndex = regexp.lastIndex;
44+
}
5245
}
46+
if (lastIndex < value.length) {
47+
parts.push(string(value.substring(lastIndex, value.length)));
48+
}
49+
return parts.join("");
50+
} else {
51+
return string(value);
52+
}
5353
}
5454

5555
function string(value) {
56-
if (value != null) {
57-
value = value.replace(/\\/g, '\\\\');
58-
value = value.replace(/\"/g, '\\"');
59-
value = value.replace(/\r/g, '\\r');
60-
value = value.replace(/\n/g, '\\n');
61-
return value;
62-
} else {
63-
return '';
64-
}
56+
if (value != null) {
57+
value = value.replace(/\\\\/g, "\\");
58+
value = value.replace(/\\r/g, "\r");
59+
value = value.replace(/\\n/g, "\n");
60+
return value;
61+
} else {
62+
return "";
63+
}
6564
}
6665

67-
function handleFormatCommand(message, sender, response) {
68-
if (message.storeStr) {
69-
declaredVars[message.storeVar] = message.storeStr;
70-
} else if (message.echoStr) {
71-
window.addLog("echo: " + message.echoStr);
72-
}
66+
function handleFormatCommand(message) {
67+
if (message.storeStr) {
68+
declaredVars[message.storeVar] = message.storeStr;
69+
} else if (message.echoStr) {
70+
window.addLog("echo: " + message.echoStr);
71+
}
7372
}
7473

7574
browser.runtime.onMessage.addListener(handleFormatCommand);
75+

src/neo/__test__/models/Command.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ describe("Command", () => {
4747
command.setValue("123456");
4848
expect(command.value).toBe("123456");
4949
});
50+
it("should escape new lines when value is set", () => {
51+
const command = new Command();
52+
command.setValue("Hello\nWorld!");
53+
expect(command.value).toBe("Hello\\nWorld!");
54+
});
5055
it("should initialize the primitives with empty strings", () => {
5156
const command = new Command();
5257
expect(command.command).toBe("");

src/neo/components/CommandForm/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { observer } from "mobx-react";
2121
import classNames from "classnames";
2222
import { Commands } from "../../models/Command";
2323
import Input from "../FormInput";
24+
import TextArea from "../FormTextArea";
2425
import CommandInput from "../CommandInput";
2526
import FlatButton from "../FlatButton";
2627
import { find, select } from "../../IO/SideeX/find-select";
@@ -57,7 +58,7 @@ import "./style.css";
5758
<FlatButton data-tip="<p>Select target in page</p>" className={classNames("icon", "si-select", {"active": this.props.isSelecting})} onClick={select} />
5859
<FlatButton data-tip="<p>Find target in page</p>" className="icon si-search" onClick={() => {find(this.props.command.target);}} />
5960
</div>
60-
<Input
61+
<TextArea
6162
id="value"
6263
name="value"
6364
label="Value"
Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,56 @@
11
.command-form {
2-
margin: 15px 8px;
2+
margin: 15px 8px;
33
}
44

5-
.command-form form > * {
6-
max-width: 480px;
5+
.command-form form> * {
6+
max-width: 480px;
77
}
88

9-
.command-form .form-input:first-child > div {
10-
display: flex!important;
9+
.command-form .form-input:first-child> div {
10+
display: flex!important;
1111
}
1212

13-
.command-form .form-input:first-child > div span {
14-
flex-grow: 1;
13+
.command-form .form-input:first-child> div span {
14+
flex-grow: 1;
1515
}
1616

17-
.command-form input {
18-
font-size: 13px;
19-
padding: 4px 5px;
20-
width: 100px;
17+
.command-form input,
18+
.command-form textarea {
19+
font-size: 13px;
20+
padding: 4px 5px;
21+
width: 100px;
22+
}
23+
24+
.command-form textarea {
25+
text-overflow: ellipsis;
26+
overflow: hidden;
27+
white-space: pre;
2128
}
2229

2330
.command-form .target {
24-
display: flex;
25-
align-items: center;
31+
display: flex;
32+
align-items: center;
2633
}
2734

28-
.command-form .target > *:first-child {
29-
flex-grow: 1;
35+
.command-form .target> *:first-child {
36+
flex-grow: 1;
3037
}
3138

3239
.command-form .target button {
33-
margin: 0;
34-
padding: 2px 4px;
35-
margin-left: 5px;
40+
margin: 0;
41+
padding: 2px 4px;
42+
margin-left: 5px;
3643
}
3744

3845
.command-form .target button img {
39-
height: 19px;
46+
height: 19px;
4047
}
4148

4249
.command-form input[type="submit"] {
43-
position: absolute;
44-
width: 0;
45-
height: 0;
46-
padding: 0;
47-
border: none;
50+
position: absolute;
51+
width: 0;
52+
height: 0;
53+
padding: 0;
54+
border: none;
4855
}
56+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
import React from "react";
19+
import PropTypes from "prop-types";
20+
import Input from "../FormInput";
21+
22+
export default class FormTextArea extends React.Component {
23+
static propTypes = {
24+
onChange: PropTypes.func
25+
};
26+
render() {
27+
const props = Object.assign({ rows: "1" }, this.props, { onChange: (e) => {if (this.props.onChange) this.props.onChange(e.target.value);}});
28+
return (
29+
<Input {...props}><textarea {...props}></textarea></Input>
30+
);
31+
}
32+
}

src/neo/containers/Editor/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import "./style.css";
6666
modifier(e);
6767
const noModifiers = (!e.primaryKey && !e.secondaryKey);
6868

69-
if (e.target.localName !== "input" && noModifiers && e.key === "ArrowLeft") {
69+
if (e.target.localName !== "input" && e.target.localName !== "textarea" && noModifiers && e.key === "ArrowLeft") {
7070
event.preventDefault();
7171
event.stopPropagation();
7272
UiState.focusNavigation();

src/neo/models/Command.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default class Command {
5353
}
5454

5555
@action.bound setValue(value) {
56-
this.value = value;
56+
this.value = value.replace(/\n/g, "\\n");
5757
}
5858

5959
static fromJS = function(jsRep) {

0 commit comments

Comments
 (0)