diff --git a/dist/client/ui/foldable.js b/dist/client/ui/foldable.js
index febf2cc58d7..ce8ff5ccdb8 100644
--- a/dist/client/ui/foldable.js
+++ b/dist/client/ui/foldable.js
@@ -36,6 +36,10 @@ var _jsonStringifySafe = require('json-stringify-safe');
var _jsonStringifySafe2 = _interopRequireDefault(_jsonStringifySafe);
+var _highlight = require('./highlight');
+
+var _highlight2 = _interopRequireDefault(_highlight);
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var folderStyle = {
@@ -124,11 +128,9 @@ var Foldable = function (_React$Component) {
this.state.collapsed ? '►' : '▼'
)
),
- _react2.default.createElement(
- 'div',
- { ref: 'foldable-content', style: folderContentStyle },
- content
- )
+ _react2.default.createElement('div', { ref: 'foldable-content', style: folderContentStyle,
+ dangerouslySetInnerHTML: { __html: (0, _highlight2.default)(content) }
+ })
);
}
}]);
diff --git a/dist/client/ui/highlight.js b/dist/client/ui/highlight.js
new file mode 100644
index 00000000000..233b59b71b5
--- /dev/null
+++ b/dist/client/ui/highlight.js
@@ -0,0 +1,40 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = highlight;
+/**
+ * Parses the JSON string and adds styling and class based on whether
+ * a part is string, number, undefined, null or key. Also removes quotes
+ * from keys.
+ *
+ * @param data A stringified JSON
+ * @returns {string} String with styling
+ */
+function highlight(data) {
+ var json = data.replace(/&/g, '&').replace(//g, '>');
+ var regex = /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g; // eslint-disable-line
+ return json.replace(regex, function (match) {
+ var className = 'number';
+ var style = void 0;
+ var result = match;
+ if (/^"/.test(result)) {
+ if (/:$/.test(result)) {
+ className = 'key';
+ style = 'color:#800080';
+ result = match.replace(/"/g, '');
+ } else {
+ className = 'string';
+ style = 'color:#a31515';
+ }
+ } else if (/true|false/.test(result)) {
+ className = 'boolean';
+ style = 'color:#066066';
+ } else if (/null|undefined/.test(result)) {
+ className = 'null';
+ style = 'color:#a31515';
+ }
+ return '' + result + '';
+ });
+}
\ No newline at end of file
diff --git a/src/client/ui/__tests__/foldable.js b/src/client/ui/__tests__/foldable.js
index 63910ee7197..69b67e94747 100644
--- a/src/client/ui/__tests__/foldable.js
+++ b/src/client/ui/__tests__/foldable.js
@@ -12,7 +12,7 @@ describe('', function () {
args: 'things',
};
- const compactString = '{"name":"test action","args":"things"}';
+ const compactString = '{name:"test action",args:"things"}';
const wrap = mount();
const content = wrap.ref('foldable-content');
@@ -25,7 +25,7 @@ describe('', function () {
args: 'things',
};
- const fullString = '{\n "name": "test action",\n "args": "things"\n}';
+ const fullString = '{\n name: "test action",\n args: "things"\n}';
const wrap = mount();
const toggle = wrap.ref('foldable-toggle');
diff --git a/src/client/ui/__tests__/highlight.js b/src/client/ui/__tests__/highlight.js
new file mode 100644
index 00000000000..c7ed3e24d96
--- /dev/null
+++ b/src/client/ui/__tests__/highlight.js
@@ -0,0 +1,21 @@
+const { describe, it } = global;
+import { expect } from 'chai';
+import highlight from '../highlight';
+
+describe('highlight', function () {
+ it('should remove quotes from keys and add correct colour', function () {
+ const data = '{ "name": "react-storybook" }';
+ const expected = '{ name: "react-storybook" }'; // eslint-disable-line
+ expect(highlight(data)).to.equal(expected);
+ });
+
+ it('should preserve new lines also', function () {
+ const data = '{\n "name": "test action",\n "args": "things"\n}';
+ const expected = '{\n ' +
+ 'name: ' +
+ '"test action",\n ' +
+ 'args: ' +
+ '"things"\n}';
+ expect(highlight(data)).to.equal(expected);
+ });
+});
diff --git a/src/client/ui/foldable.js b/src/client/ui/foldable.js
index 291ed4bb22e..49b10d3bd45 100644
--- a/src/client/ui/foldable.js
+++ b/src/client/ui/foldable.js
@@ -1,5 +1,6 @@
import React from 'react';
import stringify from 'json-stringify-safe';
+import highlight from './highlight';
const folderStyle = {
display: 'block',
@@ -70,9 +71,9 @@ class Foldable extends React.Component {
{ this.state.collapsed ? '►' : '▼' }
-
-
);
diff --git a/src/client/ui/highlight.js b/src/client/ui/highlight.js
new file mode 100644
index 00000000000..bba93bd35aa
--- /dev/null
+++ b/src/client/ui/highlight.js
@@ -0,0 +1,34 @@
+/**
+ * Parses the JSON string and adds styling and class based on whether
+ * a part is string, number, undefined, null or key. Also removes quotes
+ * from keys.
+ *
+ * @param data A stringified JSON
+ * @returns {string} String with styling
+ */
+export default function highlight(data) {
+ const json = data.replace(/&/g, '&').replace(//g, '>');
+ const regex = /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g; // eslint-disable-line
+ return json.replace(regex, (match) => {
+ let className = 'number';
+ let style;
+ let result = match;
+ if (/^"/.test(result)) {
+ if (/:$/.test(result)) {
+ className = 'key';
+ style = 'color:#800080';
+ result = match.replace(/"/g, '');
+ } else {
+ className = 'string';
+ style = 'color:#a31515';
+ }
+ } else if (/true|false/.test(result)) {
+ className = 'boolean';
+ style = 'color:#066066';
+ } else if (/null|undefined/.test(result)) {
+ className = 'null';
+ style = 'color:#a31515';
+ }
+ return `${result}`;
+ });
+}