diff --git a/src/jsonData.js b/src/jsonData.js index 2e0e9b3..2c6c905 100644 --- a/src/jsonData.js +++ b/src/jsonData.js @@ -339,20 +339,18 @@ export function add (data, path, value, options) { updatedData = insertAt(data, dataPath.concat('items', prop), value) } else { // parent.type === 'Object' - // TODO: create an immutable helper function to update a property in an Object - updatedData = updateIn(data, dataPath.concat('props'), (props) => { - const newProp = { name: prop, value } + const newProp = { name: prop, value } + const insertBefore = options && typeof options.before === 'string' - if (!options || typeof options.before !== 'string') { - // append - return props.concat(newProp) + updatedData = updateIn(data, dataPath.concat('props'), (props) => { + if (insertBefore) { + // insert after prop + const index = props.findIndex(p => p.name === options.before) + return insertAt(props, [index], newProp) } else { - // insert after prop - const updatedProps = props.slice(0) - const index = props.findIndex(p => p.name === options.before) - updatedProps.splice(index, 0, newProp) - return updatedProps + // append + return props.concat(newProp) } }) } @@ -419,24 +417,15 @@ export function move (data, path, from, options) { const beforeNeeded = (parent.type === 'Object' && before) if (result2.revert[0].op === 'replace') { + const value = result2.revert[0].value const type = result2.revert[0].jsoneditor.type + const options = beforeNeeded ? { type, before } : { type } return { data: result2.data, revert: [ - { - op: 'move', - from: path, - path: from - }, - { - op: 'add', - path, - value: result2.revert[0].value, - jsoneditor: beforeNeeded - ? { type, before } - : { type } - } + { op: 'move', from: path, path: from }, + { op: 'add', path, value, jsoneditor: options} ] } } @@ -616,6 +605,16 @@ export function findNextProp (parent, prop) { return next && next.name || null } +/** + * Find the index of a property + * @param {ObjectData} parent + * @param {string} prop + * @return {number} Returns the index when found, -1 when not found + */ +export function findPropertyIndex (parent, prop) { + return parent.props.findIndex(p => p.name === prop) || -1 +} + /** * Parse a JSON Pointer * WARNING: this is not a complete string implementation diff --git a/src/utils/immutabilityHelpers.js b/src/utils/immutabilityHelpers.js index 06707ef..fa06a13 100644 --- a/src/utils/immutabilityHelpers.js +++ b/src/utils/immutabilityHelpers.js @@ -152,17 +152,21 @@ export function deleteIn (object, path) { } /** - * Insert a new item in an array - * @param {Array} array + * Insert a new item in an array at a specific index. + * Example usage: + * + * insertAt({arr: [1,2,3]}, ['arr', '2'], 'inserted') // [1,2,'inserted',3] + * + * @param {Object | Array} object * @param {Path} path * @param {*} value * @return {Array} */ -export function insertAt (array, path, value) { +export function insertAt (object, path, value) { const parentPath = path.slice(0, path.length - 1) const index = path[path.length - 1] - return updateIn(array, parentPath, (items) => { + return updateIn(object, parentPath, (items) => { if (!Array.isArray(items)) { throw new TypeError('Array expected at path ' + JSON.stringify(parentPath)) } diff --git a/test/immutabilityHelpers.test.js b/test/immutabilityHelpers.test.js index 937b53e..7770c3e 100644 --- a/test/immutabilityHelpers.test.js +++ b/test/immutabilityHelpers.test.js @@ -273,6 +273,6 @@ test('deleteIn non existing path', t => { test('insertAt', t => { const obj = { a: [1,2,3]} - const updated = insertAt(obj, ['ab', '2'], 8) + const updated = insertAt(obj, ['a', '2'], 8) t.deepEqual(updated, {a: [1,2,8,3]}) })