Fixed losing focus when editing property

This commit is contained in:
jos 2017-01-06 20:17:31 +01:00
parent ab8d4b4be6
commit 1cce254e9c
2 changed files with 50 additions and 46 deletions

View File

@ -352,10 +352,11 @@ export function simplifyPatch(patch: JSONPatch) {
* @param {string} path * @param {string} path
* @param {JSONData} value * @param {JSONData} value
* @param {{before?: string}} [options] * @param {{before?: string}} [options]
* @param {number} [id] Optional id for the new item
* @return {{data: JSONData, revert: JSONPatch}} * @return {{data: JSONData, revert: JSONPatch}}
* @private * @private
*/ */
export function add (data: JSONData, path: string, value: JSONData, options) { export function add (data: JSONData, path: string, value: JSONData, options, id = getId()) {
const pathArray = parseJSONPointer(path) const pathArray = parseJSONPointer(path)
const parentPath = pathArray.slice(0, pathArray.length - 1) const parentPath = pathArray.slice(0, pathArray.length - 1)
const dataPath = toDataPath(data, parentPath) const dataPath = toDataPath(data, parentPath)
@ -366,7 +367,7 @@ export function add (data: JSONData, path: string, value: JSONData, options) {
let updatedData let updatedData
if (parent.type === 'Array') { if (parent.type === 'Array') {
const newItem = { const newItem = {
id: getId(), // TODO: create a unique id within current id's instead of using a global, ever incrementing id id, // TODO: create a unique id within current id's instead of using a global, ever incrementing id
value value
} }
updatedData = insertAt(data, dataPath.concat('items', prop), newItem) updatedData = insertAt(data, dataPath.concat('items', prop), newItem)
@ -380,8 +381,7 @@ export function add (data: JSONData, path: string, value: JSONData, options) {
} }
else { else {
// insert new item // insert new item
const newId = getId() const newProp = { id, name: prop, value }
const newProp = { id: newId, name: prop, value }
const index = (options && typeof options.before === 'string') const index = (options && typeof options.before === 'string')
? findPropertyIndex(object, options.before) // insert before ? findPropertyIndex(object, options.before) // insert before
: object.props.length // append : object.props.length // append
@ -441,13 +441,17 @@ export function copy (data: JSONData, path: string, from: string, options) {
*/ */
export function move (data: JSONData, path: string, from: string, options) { export function move (data: JSONData, path: string, from: string, options) {
const fromArray = parseJSONPointer(from) const fromArray = parseJSONPointer(from)
const dataValue = getIn(data, toDataPath(data, fromArray)) const prop = getIn(data, allButLast(toDataPath(data, fromArray)))
const dataValue = prop.value
const id = prop.id // we want to use the existing id in case the move is a renaming a property
// FIXME: only reuse the existing id when move is renaming a property in the same object
const parentPath = fromArray.slice(0, fromArray.length - 1) const parentPathFrom = allButLast(fromArray)
const parent = getIn(data, toDataPath(data, parentPath)) const parent = getIn(data, toDataPath(data, parentPathFrom))
const result1 = remove(data, from) const result1 = remove(data, from)
const result2 = add(result1.data, path, dataValue, options) const result2 = add(result1.data, path, dataValue, options, id)
// FIXME: passing id as parameter is ugly, make that redundant (use replace instead of remove/add? (that would give less predictive output :( ))
const before = result1.revert[0].jsoneditor.before const before = result1.revert[0].jsoneditor.before
const beforeNeeded = (parent.type === 'Object' && before) const beforeNeeded = (parent.type === 'Object' && before)
@ -706,11 +710,11 @@ export function transform (data: JSONData, callback: RecurseCallback) {
* Recursively transform JSONData * Recursively transform JSONData
* @param {JSONData} value * @param {JSONData} value
* @param {Path} path * @param {Path} path
* @param {JSONData | null} root The root object, object at path=[] * @param {JSONData} root The root object, object at path=[]
* @param {function(value: JSONData, path: Path, root: JSONData)} callback * @param {function(value: JSONData, path: Path, root: JSONData)} callback
* @return {JSONData} Returns the transformed data * @return {JSONData} Returns the transformed data
*/ */
function recurseTransform (value: JSONData, path: Path, root?: JSONData, callback: RecurseCallback) : JSONData{ function recurseTransform (value: JSONData, path: Path, root: JSONData, callback: RecurseCallback) : JSONData{
let updatedValue = callback(value, path, root) let updatedValue = callback(value, path, root)
if (value.type === 'Array') { if (value.type === 'Array') {

View File

@ -766,34 +766,35 @@ test('jsonpatch copy', t => {
]) ])
}) })
// test('jsonpatch copy (create new ids)', t => { test('jsonpatch copy (keeps the same ids)', t => {
// const json = { foo: { bar: 42 } } const json = { foo: { bar: 42 } }
// const patch = [ const patch = [
// {op: 'copy', from: '/foo', path: '/copied'} {op: 'copy', from: '/foo', path: '/copied'}
// ] ]
//
// const data = jsonToData(json) const data = jsonToData(json)
// const objectId = data.id const fooId = data.props[0].id
// const fooId = data.props[0].value.id const barId = data.props[0].value.props[0].id
// const barId = data.props[0].value.props[0].value.id
// const patchedData = patchData(data, patch).data
// const patchedData = patchData(data, patch).data const patchedFooId = patchedData.props[0].id
// const patchedObjectId = patchedData.id const patchedBarId = patchedData.props[0].value.props[0].id
// const patchedFooId = patchedData.props[0].value.id const copiedId = patchedData.props[1].id
// const patchedBarId = patchedData.props[0].value.props[0].value.id const patchedCopiedBarId = patchedData.props[1].value.props[0].id
// const patchedCopiedId = patchedData.props[1].value.id
// const patchedCopiedBarId = patchedData.props[1].value.props[0].value.id t.is(patchedData.props[0].name, 'foo')
// t.is(patchedData.props[1].name, 'copied')
// t.is(patchedData.props[0].name, 'foo')
// t.is(patchedData.props[1].name, 'copied') t.is(patchedFooId, fooId, 'same foo id')
// t.is(patchedBarId, barId, 'same bar id')
// t.is(patchedObjectId, objectId, 'same object id')
// t.is(patchedFooId, fooId, 'same foo id') t.not(copiedId, fooId, 'different id of property copied')
// t.is(patchedBarId, barId, 'same bar id')
// t.not(patchedCopiedId, patchedFooId, 'different copied foo id') // The id's of the copied childs are the same, that's okish, they will not bite each other
// t.not(patchedCopiedBarId, patchedBarId, 'different copied bar id') // FIXME: better solution for id's either always unique, or unique per object/array
// }) t.is(patchedCopiedBarId, patchedBarId, 'same copied bar id')
// })
test('jsonpatch move', t => { test('jsonpatch move', t => {
const json = { const json = {
arr: [1,2,3], arr: [1,2,3],
@ -874,11 +875,15 @@ test('jsonpatch move and replace', t => {
] ]
const data = jsonToData(json) const data = jsonToData(json)
const result = patchData(data, patch) const result = patchData(data, patch)
const patchedData = result.data const patchedData = result.data
const revert = result.revert const revert = result.revert
const patchedJson = dataToJson(patchedData) const patchedJson = dataToJson(patchedData)
// id of the replaced B must be kept intact
t.is(patchedData.props[0].id, data.props[1].id)
replaceIds(patchedData) replaceIds(patchedData)
t.deepEqual(patchedData, { t.deepEqual(patchedData, {
"type": "Object", "type": "Object",
@ -958,15 +963,11 @@ test('jsonpatch move (keep id intact)', t => {
] ]
const data = jsonToData(json) const data = jsonToData(json)
const objectId = data.id const valueId = data.props[0].id
const valueId = data.props[0].value.id
const patchedData = patchData(data, patch).data const patchedData = patchData(data, patch).data
const patchedValueId = patchedData.props[0].id
const patchedObjectId = patchedData.id
const patchedValueId = patchedData.props[0].value.id
t.is(patchedObjectId, objectId)
t.is(patchedValueId, valueId) t.is(patchedValueId, valueId)
}) })
@ -983,10 +984,9 @@ test('jsonpatch move and replace (keep ids intact)', t => {
t.is(data.props[1].name, 'b') t.is(data.props[1].name, 'b')
const patchedData = patchData(data, patch).data const patchedData = patchData(data, patch).data
const patchedBId = patchedData.props[0].id
t.is(patchedData.props[0].name, 'b') t.is(patchedData.props[0].name, 'b')
t.is(patchedBId, bId) t.is(patchedData.props[0].id, bId)
}) })
test('jsonpatch test (ok)', t => { test('jsonpatch test (ok)', t => {