Skip to content

Commit 805c4ea

Browse files
committed
refactor, add tests, fix some issues
1 parent 131a576 commit 805c4ea

28 files changed

Lines changed: 673 additions & 61 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ The `dist` folder should be committed to the repo for now.
6767
#### Linting
6868
`npm run lint` - please lint before committing any code
6969

70+
#### Testing
71+
`npm test`
72+
7073
## Known Issues
7174
- Typing a decimal as the last character in a number field doesn't work because of the way we coerce the type - if the field is a number type, we try to `parseFloat()` it, which parses a value like `1.` to `1`. Adding the decimal anywhere but the last character will work, so a workaround to trying to type `1.1` would be to type `11`, then insert the decimal between the `1`s.
7275

dist/components/Editor.js

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ var _lodash7 = require('lodash.set');
2626

2727
var _lodash8 = _interopRequireDefault(_lodash7);
2828

29+
var _lib = require('../lib');
30+
2931
var _Field = require('./Field');
3032

3133
var _Field2 = _interopRequireDefault(_Field);
@@ -99,52 +101,57 @@ var JSONEditor = function (_Component) {
99101
}, {
100102
key: 'onFieldValueChange',
101103
value: function onFieldValueChange(path, value) {
102-
var json = (0, _lodash4.default)(this.parseJson());
104+
var _changeFieldValue = (0, _lib.changeFieldValue)(this.parseJson(), path, value);
105+
106+
var json = _changeFieldValue.json;
107+
var previous = _changeFieldValue.previous;
108+
103109

104110
this.undoStack.push({
105111
path: path,
106-
value: (0, _lodash6.default)(json, path)
112+
value: previous
107113
});
108114

109-
(0, _lodash8.default)(json, path, value);
110115
this.redoStack = [];
111116
this.props.onChange(json);
112117
}
113118
}, {
114119
key: 'addArrayElement',
115120
value: function addArrayElement(path, value) {
116-
var json = (0, _lodash4.default)(this.parseJson());
117-
var currentVal = (0, _lodash6.default)(json, path);
121+
var _addArrayElement2 = (0, _lib.addArrayElement)(this.parseJson(), path, value);
122+
123+
var json = _addArrayElement2.json;
124+
var previous = _addArrayElement2.previous;
125+
118126

119127
this.undoStack.push({
120128
path: path,
121-
value: currentVal
129+
value: previous
122130
});
123131

124-
(0, _lodash8.default)(json, path, currentVal.concat(value));
125132
this.redoStack = [];
126133
this.props.onChange(json);
127134
}
128135
}, {
129136
key: 'addMapElement',
130137
value: function addMapElement(path, name, value) {
131-
var json = (0, _lodash4.default)(this.parseJson());
132-
var currentVal = (0, _lodash6.default)(json, path) || json;
138+
var _addMapElement2 = (0, _lib.addMapElement)(this.parseJson(), path, name, value);
133139

134-
if (typeof currentVal[name] !== 'undefined') {
140+
var json = _addMapElement2.json;
141+
var previous = _addMapElement2.previous;
142+
143+
144+
if (!json) {
135145
return false;
136146
}
137147

138-
// quick hack to fix an issue where adding an element to the root level
139-
// messes up undo/redo since there's no path
140-
if (path) {
148+
if (path && path.length) {
141149
this.undoStack.push({
142150
path: path,
143-
value: (0, _lodash4.default)(currentVal)
151+
value: previous
144152
});
145153
}
146154

147-
currentVal[name] = value;
148155
this.redoStack = [];
149156
this.props.onChange(json);
150157

@@ -153,23 +160,17 @@ var JSONEditor = function (_Component) {
153160
}, {
154161
key: 'removeElement',
155162
value: function removeElement(path, isArrayElement) {
156-
var json = (0, _lodash4.default)(this.parseJson());
163+
var _removeElement2 = (0, _lib.removeElement)(this.parseJson(), path, isArrayElement);
164+
165+
var json = _removeElement2.json;
166+
var previous = _removeElement2.previous;
157167

158-
var beforePath = path.slice(0, path.length - 1);
159-
var elementKey = path[path.length - 1];
160-
var beforePathValue = (0, _lodash6.default)(json, beforePath);
161168

162169
this.undoStack.push({
163-
path: beforePath,
164-
value: (0, _lodash4.default)(beforePathValue)
170+
path: path,
171+
value: previous
165172
});
166173

167-
if (isArrayElement) {
168-
beforePathValue.splice(elementKey, 1);
169-
} else {
170-
delete beforePathValue[elementKey];
171-
}
172-
173174
this.redoStack = [];
174175
this.props.onChange(json);
175176
}
@@ -252,7 +253,7 @@ var JSONEditor = function (_Component) {
252253
React.createElement(
253254
'div',
254255
{ className: 'editor-actions' },
255-
React.createElement(_AddElementButton2.default, { path: '' }),
256+
React.createElement(_AddElementButton2.default, { path: [] }),
256257
this.undoStack.length > 0 && React.createElement(
257258
'button',
258259
{ className: 'btn default btn-xs', type: 'button', onClick: this.undo },

dist/components/Field.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ var JSONField = function (_Component) {
7171
}
7272

7373
_createClass(JSONField, [{
74+
key: 'shouldComponentUpdate',
75+
value: function shouldComponentUpdate(nextProps, nextState) {
76+
if (nextState.expanded !== this.state.expanded) {
77+
return true;
78+
}
79+
80+
if (JSON.stringify(nextProps.fieldValue) !== JSON.stringify(this.props.fieldValue)) {
81+
return true;
82+
}
83+
84+
return false;
85+
}
86+
}, {
7487
key: 'toggleExpanded',
7588
value: function toggleExpanded() {
7689
this.setState({ expanded: !this.state.expanded });

dist/lib/addArrayElement.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = addArrayElement;
7+
8+
var _lodash = require('lodash.get');
9+
10+
var _lodash2 = _interopRequireDefault(_lodash);
11+
12+
var _changeFieldValue = require('./changeFieldValue');
13+
14+
var _changeFieldValue2 = _interopRequireDefault(_changeFieldValue);
15+
16+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17+
18+
function addArrayElement(json, path, value) {
19+
var previous = (0, _lodash2.default)(json, path);
20+
21+
return {
22+
json: (0, _changeFieldValue2.default)(json, path, previous.concat(value)).json,
23+
previous: previous
24+
};
25+
}

dist/lib/addMapElement.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = addMapElement;
7+
8+
var _lodash = require('lodash.clonedeep');
9+
10+
var _lodash2 = _interopRequireDefault(_lodash);
11+
12+
var _lodash3 = require('lodash.get');
13+
14+
var _lodash4 = _interopRequireDefault(_lodash3);
15+
16+
var _changeFieldValue = require('./changeFieldValue');
17+
18+
var _changeFieldValue2 = _interopRequireDefault(_changeFieldValue);
19+
20+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21+
22+
function addMapElement(json, path, name, value) {
23+
if (path && path.length) {
24+
// adding element to sub map - not root json object
25+
var cloned = (0, _lodash2.default)(json);
26+
var previous = (0, _lodash4.default)(cloned, path);
27+
28+
if (typeof previous[name] !== 'undefined') {
29+
return false;
30+
}
31+
32+
// get a snapshot of the previous value before we modify it
33+
var clonedPrevious = (0, _lodash2.default)(previous);
34+
35+
previous[name] = value;
36+
37+
return {
38+
json: (0, _changeFieldValue2.default)(json, path, previous).json,
39+
previous: clonedPrevious
40+
};
41+
} else {
42+
// adding element to root json object
43+
if (typeof json[name] !== 'undefined') {
44+
return false;
45+
}
46+
47+
return {
48+
json: (0, _changeFieldValue2.default)(json, name, value).json,
49+
previous: json
50+
};
51+
}
52+
}

dist/lib/changeFieldValue.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = changeFieldValue;
7+
8+
var _lodash = require('lodash.clonedeep');
9+
10+
var _lodash2 = _interopRequireDefault(_lodash);
11+
12+
var _lodash3 = require('lodash.set');
13+
14+
var _lodash4 = _interopRequireDefault(_lodash3);
15+
16+
var _lodash5 = require('lodash.get');
17+
18+
var _lodash6 = _interopRequireDefault(_lodash5);
19+
20+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21+
22+
function changeFieldValue(json, path, value) {
23+
var previous = (0, _lodash6.default)(json, path);
24+
var cloned = (0, _lodash2.default)(json);
25+
26+
(0, _lodash4.default)(cloned, path, value);
27+
28+
return {
29+
previous: previous,
30+
json: cloned
31+
};
32+
}

dist/lib/index.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Object.defineProperty(exports, "__esModule", {
44
value: true
55
});
6-
exports.coerceToType = exports.getValueType = exports.isPlainValue = undefined;
6+
exports.removeElement = exports.addMapElement = exports.addArrayElement = exports.changeFieldValue = exports.coerceToType = exports.getValueType = exports.isPlainValue = undefined;
77

88
var _isPlainValue2 = require('./isPlainValue');
99

@@ -17,8 +17,28 @@ var _coerceToType2 = require('./coerceToType');
1717

1818
var _coerceToType3 = _interopRequireDefault(_coerceToType2);
1919

20+
var _changeFieldValue2 = require('./changeFieldValue');
21+
22+
var _changeFieldValue3 = _interopRequireDefault(_changeFieldValue2);
23+
24+
var _addArrayElement2 = require('./addArrayElement');
25+
26+
var _addArrayElement3 = _interopRequireDefault(_addArrayElement2);
27+
28+
var _addMapElement2 = require('./addMapElement');
29+
30+
var _addMapElement3 = _interopRequireDefault(_addMapElement2);
31+
32+
var _removeElement2 = require('./removeElement');
33+
34+
var _removeElement3 = _interopRequireDefault(_removeElement2);
35+
2036
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2137

2238
exports.isPlainValue = _isPlainValue3.default;
2339
exports.getValueType = _getValueType3.default;
24-
exports.coerceToType = _coerceToType3.default;
40+
exports.coerceToType = _coerceToType3.default;
41+
exports.changeFieldValue = _changeFieldValue3.default;
42+
exports.addArrayElement = _addArrayElement3.default;
43+
exports.addMapElement = _addMapElement3.default;
44+
exports.removeElement = _removeElement3.default;

dist/lib/removeElement.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.default = removeElement;
7+
8+
var _lodash = require('lodash.clonedeep');
9+
10+
var _lodash2 = _interopRequireDefault(_lodash);
11+
12+
var _lodash3 = require('lodash.get');
13+
14+
var _lodash4 = _interopRequireDefault(_lodash3);
15+
16+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17+
18+
function removeElement(json, path, isArrayElement) {
19+
var cloned = (0, _lodash2.default)(json);
20+
21+
if (path.length === 1) {
22+
// removing from the root json object
23+
var previous = (0, _lodash2.default)(json[path[0]]);
24+
delete cloned[path[0]];
25+
26+
return {
27+
json: cloned,
28+
previous: previous
29+
};
30+
} else {
31+
// removing from a sub object or array
32+
var beforePath = path.slice(0, path.length - 1);
33+
var elementKey = path[path.length - 1];
34+
var beforePathValue = (0, _lodash4.default)(cloned, beforePath);
35+
var clonedBeforePathValue = (0, _lodash2.default)(beforePathValue);
36+
37+
if (isArrayElement) {
38+
beforePathValue.splice(elementKey, 1);
39+
} else {
40+
delete beforePathValue[elementKey];
41+
}
42+
43+
return {
44+
json: cloned,
45+
previous: clonedBeforePathValue
46+
};
47+
}
48+
}

karma.conf.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const webpackConfig = require('./tests/webpack.config');
2+
3+
module.exports = config => {
4+
config.set({
5+
browsers: ['Chrome'],
6+
frameworks: ['mocha'],
7+
reporters: ['mocha'],
8+
9+
files: ['tests/index.js'],
10+
11+
preprocessors: {
12+
'tests/index.js': ['webpack'],
13+
'**/*.js': ['sourcemap'],
14+
},
15+
16+
webpack: webpackConfig,
17+
18+
webpackServer: {
19+
noInfo: true,
20+
},
21+
22+
autoWatch: true,
23+
singleRun: false,
24+
colors: true,
25+
});
26+
};

0 commit comments

Comments
 (0)