Handle changes via JSONPatch

This commit is contained in:
josdejong 2020-05-06 13:57:55 +02:00
parent e66ff70ac4
commit 4d2eb28eb3
3 changed files with 49 additions and 46 deletions

View File

@ -1,6 +1,5 @@
<script>
import JSONEditor from './JSONEditor.svelte'
import { beforeUpdate, afterUpdate } from 'svelte'
let json = {
'array': [1, 2, 3, {
@ -47,9 +46,6 @@
console.time('load editor')
beforeUpdate(() => console.time('render app'))
afterUpdate(() => console.timeEnd('render app'))
function handleChangeFiles (event) {
console.log('handleChangeFiles', event.target.files)

View File

@ -3,7 +3,7 @@
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import Node from './JSONNode.svelte'
import { search } from './search'
import { beforeUpdate, afterUpdate } from 'svelte'
import { immutableJSONPatch } from './utils/immutableJSONPatch'
export let json = {}
export let onChange = () => {}
@ -17,8 +17,9 @@
json = newJson
}
beforeUpdate(() => console.time('render JSONEditor'))
afterUpdate(() => console.timeEnd('render JSONEditor'))
function getPath () {
return []
}
function doSearch (json, searchText) {
console.time('search')
@ -38,16 +39,17 @@
function handleChangeValue (value, key) {
// console.log('handleChangeValue', value, key)
json = value
// json = value
}
function handleInputTextArea (event) {
console.log('on:input')
try {
json = JSON.parse(event.target.value)
} catch (err) {
console.error(err)
}
/**
* @param {JSONPatchDocument} operations
*/
function handleChange (operations) {
console.log('handleChange', operations)
// TODO: store changes in history
json = immutableJSONPatch(json, operations).json
}
</script>
@ -62,6 +64,8 @@
expanded={true}
onChangeKey={handleChangeKey}
onChangeValue={handleChangeValue}
onChange={handleChange}
getParentPath={getPath}
/>
</div>
</div>

View File

@ -8,14 +8,24 @@
import { updateProps } from './utils/updateProps.js'
import { unescapeHTML } from './utils/stringUtils'
import { getInnerText } from './utils/domUtils'
import { compileJSONPointer } from './utils/jsonPointer'
export let key = undefined
export let key = undefined // only applicable for object properties
export let index = undefined // only applicable for array items
export let value
export let searchResult
export let onChange
export let onChangeKey
export let onChangeValue
export let expanded = false
export let getParentPath
function getPath () {
return key !== undefined
? getParentPath().concat(key)
: []
}
const DEFAULT_LIMIT = 100
const escapeUnicode = false // TODO: pass via options
@ -90,7 +100,17 @@
function handleKeyInput (event) {
const newKey = unescapeHTML(getInnerText(event.target))
// TODO: replace the onChangeKey callback with gobally managed JSONNode id's,
// which are kept in sync with the json itself using JSONPatch
onChangeKey(newKey, key)
const parentPath = getParentPath()
onChange([{
op: 'move',
from: compileJSONPointer(parentPath.concat(key)),
path: compileJSONPointer(parentPath.concat(newKey))
}])
}
function handleKeyBlur () {
@ -101,7 +121,12 @@
function handleValueInput (event) {
const valueText = unescapeHTML(getInnerText(event.target))
const newValue = stringConvert(valueText) // TODO: implement support for type "string"
onChangeValue(newValue, key)
onChange([{
op: 'replace',
path: compileJSONPointer(getPath()),
value: newValue
}])
}
function handleValueBlur () {
@ -129,15 +154,6 @@
function handleChangeKey (newChildKey, oldChildKey) {
if (type === 'object') {
const updatedValue = {}
Object.keys(value).forEach(childKey => {
if (childKey === oldChildKey) {
updatedValue[newChildKey] = value[childKey]
} else {
updatedValue[childKey] = value[childKey]
}
})
const index = props.findIndex(item => item.key === oldChildKey)
if (index !== -1) {
// we use splice here to replace the old key with the new new one
@ -150,21 +166,6 @@
key: newChildKey
})
}
onChangeValue(updatedValue, key)
}
}
function handleChangeValue (childValue, childKey) {
// FIXME: use an immutability setIn function here
if (type === 'array') {
const updatedValue = [...value]
updatedValue[childKey] = childValue
onChangeValue(updatedValue, key)
} else if (type === 'object') {
const updatedValue = { ...value }
updatedValue[childKey] = childValue
onChangeValue(updatedValue, key)
}
}
@ -210,7 +211,8 @@
value={item}
searchResult={searchResult ? searchResult[index] : undefined}
onChangeKey={handleChangeKey}
onChangeValue={handleChangeValue}
onChange={onChange}
getParentPath={getPath}
/>
{/each}
{#if limited}
@ -259,7 +261,8 @@
value={value[prop.key]}
searchResult={searchResult ? searchResult[prop.key] : undefined}
onChangeKey={handleChangeKey}
onChangeValue={handleChangeValue}
onChange={onChange}
getParentPath={getPath}
/>
{/each}
</div>