diff --git a/dev-server/src/index.js b/dev-server/src/index.js
index 58e2699..9158e1f 100644
--- a/dev-server/src/index.js
+++ b/dev-server/src/index.js
@@ -180,6 +180,13 @@ ReactDom.render(
}
src={getExampleJson2()}
/>
+
+ {/* String with special escape sequences */}
+
,
document.getElementById('app-container')
)
@@ -294,3 +301,7 @@ function getExampleArray () {
}
]
}
+
+function getExampleWithStringEscapeSequences () {
+ return { '\\\n\t\r\f\\n': '\\\n\t\r\f\\n' }
+}
diff --git a/src/js/components/DataTypes/String.js b/src/js/components/DataTypes/String.js
index 29454e5..4faa1d8 100644
--- a/src/js/components/DataTypes/String.js
+++ b/src/js/components/DataTypes/String.js
@@ -1,6 +1,6 @@
import React from 'react'
import DataTypeLabel from './DataTypeLabel'
-import { toType } from './../../helpers/util'
+import { toType, escapeString } from './../../helpers/util'
// theme
import Theme from './../../themes/getStyle'
@@ -46,6 +46,8 @@ export default class extends React.PureComponent {
const collapsible = toType(collapseStringsAfterLength) === 'integer'
const style = { style: { cursor: 'default' } }
+ value = escapeString(value)
+
if (collapsible && value.length > collapseStringsAfterLength) {
style.style.cursor = 'pointer'
if (this.state.collapsed) {
diff --git a/src/js/components/VariableEditor.js b/src/js/components/VariableEditor.js
index 56cbb84..01b7cde 100644
--- a/src/js/components/VariableEditor.js
+++ b/src/js/components/VariableEditor.js
@@ -1,7 +1,7 @@
import React from 'react'
import AutosizeTextarea from 'react-textarea-autosize'
-import { toType } from './../helpers/util'
+import { escapeString } from './../helpers/util'
import dispatcher from './../helpers/dispatcher'
import parseInput from './../helpers/parseInput'
import stringifyVariable from './../helpers/stringifyVariable'
@@ -93,7 +93,7 @@ class VariableEditor extends React.PureComponent {
{!!quotesOnKeys && (
"
)}
- {variable.name}
+ {escapeString(variable.name)}
{!!quotesOnKeys && (
"
)}
diff --git a/src/js/helpers/util.js b/src/js/helpers/util.js
index a11ea83..6654f8a 100644
--- a/src/js/helpers/util.js
+++ b/src/js/helpers/util.js
@@ -23,6 +23,15 @@ function getType (obj) {
.toLowerCase()
}
+export function escapeString (value) {
+ return value
+ .replace(/\\/g, '\\\\')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ .replace(/\r/g, '\\r')
+ .replace(/\f/g, '\\f')
+}
+
// validation for base-16 themes
export function isTheme (theme) {
const theme_keys = [
diff --git a/test/tests/js/components/DataTypes/String-test.js b/test/tests/js/components/DataTypes/String-test.js
index 1ef0a47..26e851d 100644
--- a/test/tests/js/components/DataTypes/String-test.js
+++ b/test/tests/js/components/DataTypes/String-test.js
@@ -6,11 +6,9 @@ import JsonString from './../../../../../src/js/components/DataTypes/String'
describe('', function () {
it('string component should have a data type label', function () {
- const rjvId = 1
const wrapper = mount(
@@ -19,10 +17,8 @@ describe('', function () {
})
it('string with hidden data type', function () {
- const rjvId = 1
const props = {
value: 'test',
- rjvId: 1,
theme: 'rjv-default',
displayDataTypes: false
}
@@ -32,10 +28,8 @@ describe('', function () {
// test collapsed string and expand click
it('string displaying data type', function () {
- const rjvId = 1
const props = {
value: 'test',
- rjvId: 1,
displayDataTypes: false,
theme: 'rjv-default'
}
@@ -44,11 +38,9 @@ describe('', function () {
})
it('collapsed string content', function () {
- const rjvId = 1
const props = {
value: '123456789',
collapseStringsAfterLength: 3,
- rjvId: 1,
displayDataTypes: false,
theme: 'rjv-default'
}
@@ -61,4 +53,16 @@ describe('', function () {
'"123456789"'
)
})
+
+ it('string with special escape sequences', function () {
+ const props = {
+ value: '\\\n\t\r\f\\n',
+ displayDataTypes: false,
+ theme: 'rjv-default'
+ }
+ const component = mount().render()
+ expect(component.find('.string-value').text()).to.equal(
+ '"\\\\\\n\\t\\r\\f\\\\n"'
+ )
+ })
})
diff --git a/test/tests/js/components/VariableEditor-test.js b/test/tests/js/components/VariableEditor-test.js
index fe5c100..9d1f57c 100644
--- a/test/tests/js/components/VariableEditor-test.js
+++ b/test/tests/js/components/VariableEditor-test.js
@@ -13,7 +13,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
singleIndent={1}
variable={{
@@ -48,7 +48,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -66,7 +66,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -172,7 +172,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -192,7 +192,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -212,7 +212,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -232,7 +232,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -252,7 +252,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -274,7 +274,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -294,7 +294,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -314,7 +314,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -334,7 +334,7 @@ describe('', function () {
{}}
+ onEdit={edit => { }}
rjvId={rjvId}
variable={{
name: 'test',
@@ -348,4 +348,28 @@ describe('', function () {
expect(wrapper.state('editMode')).to.equal(true)
expect(wrapper.find('.variable-editor').props().value).to.equal('5')
})
+
+ it('VariableEditor renders escaped characters', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ variable={{
+ name: '\\\n\t\r\f\\n',
+ value: '\\\n\t\r\f\\n',
+ type: 'string'
+ }}
+ />
+ )
+ console.log(wrapper.debug())
+ expect(wrapper.find('.object-key').text()).to.equal('\\\\\\n\\t\\r\\f\\\\n')
+ expect(wrapper.find('.click-to-edit-icon').length).to.equal(1)
+ wrapper.find('.click-to-edit-icon').simulate('click')
+ expect(wrapper.state('editMode')).to.equal(true)
+ expect(wrapper.find('.variable-editor').props().value).to.equal(
+ '\\\n\t\r\f\\n'
+ )
+ })
})
diff --git a/test/tests/js/helpers/Util-test.js b/test/tests/js/helpers/Util-test.js
index fce258d..19d51ba 100644
--- a/test/tests/js/helpers/Util-test.js
+++ b/test/tests/js/helpers/Util-test.js
@@ -1,7 +1,7 @@
import React from 'react'
import { expect } from 'chai'
-import { toType, isTheme } from './../../../../src/js/helpers/util'
+import { toType, isTheme, escapeString } from './../../../../src/js/helpers/util'
describe('toType', function () {
it('toType object', function () {
@@ -30,7 +30,7 @@ describe('toType', function () {
})
it('toType function', function () {
- const test = () => {}
+ const test = () => { }
expect(toType(test)).to.equal('function')
})
@@ -60,6 +60,33 @@ describe('toType', function () {
})
})
+describe('escapeString', function () {
+ it('escape \\\\', function () {
+ const test = '\\'
+ expect(escapeString(test)).to.equal('\\\\')
+ })
+ it('escape \\n', function () {
+ const test = '\n'
+ expect(escapeString(test)).to.equal('\\n')
+ })
+ it('escape \\t', function () {
+ const test = '\t'
+ expect(escapeString(test)).to.equal('\\t')
+ })
+ it('escape \\r', function () {
+ const test = '\r'
+ expect(escapeString(test)).to.equal('\\r')
+ })
+ it('escape \\f', function () {
+ const test = '\f'
+ expect(escapeString(test)).to.equal('\\f')
+ })
+ it('escape \\\\n', function () {
+ const test = '\\n'
+ expect(escapeString(test)).to.equal('\\\\n')
+ })
+})
+
describe('isTheme', function () {
it('isTheme valid theme', function () {
const test = {