Some refactoring: created `getInEson`, `setInEson`, `updateInEson`, `deleteInEson`

This commit is contained in:
jos 2017-11-22 10:45:00 +01:00
parent 56528dc054
commit e69868da85
4 changed files with 63 additions and 55 deletions

View File

@ -1,11 +1,10 @@
import last from 'lodash/last'
import initial from 'lodash/initial'
import {
compileJSONPointer, toEsonPath, esonToJson, findNextProp,
compileJSONPointer, getInEson, esonToJson, findNextProp,
pathsFromSelection, findRootPath, findSelectionIndices
} from './eson'
import { findUniqueName } from './utils/stringUtils'
import { getIn } from './utils/immutabilityHelpers'
import { isObject, stringConvert } from './utils/typeUtils'
import { compareAsc, compareDesc, strictShallowEqual } from './utils/arrayUtils'
@ -19,9 +18,7 @@ import { compareAsc, compareDesc, strictShallowEqual } from './utils/arrayUtils'
*/
export function changeValue (data, path, value) {
// console.log('changeValue', data, value)
const esonPath = toEsonPath(data, path)
const oldDataValue = getIn(data, esonPath)
const oldDataValue = getInEson(data, path)
return [{
op: 'replace',
@ -43,9 +40,7 @@ export function changeValue (data, path, value) {
*/
export function changeProperty (data, parentPath, oldProp, newProp) {
// console.log('changeProperty', parentPath, oldProp, newProp)
const esonPath = toEsonPath(data, parentPath)
const parent = getIn(data, esonPath)
const parent = getInEson(data, parentPath)
// prevent duplicate property names
const uniqueNewProp = findUniqueName(newProp, parent.props.map(p => p.name))
@ -68,8 +63,7 @@ export function changeProperty (data, parentPath, oldProp, newProp) {
* @return {Array}
*/
export function changeType (data, path, type) {
const esonPath = toEsonPath(data, path)
const oldValue = esonToJson(getIn(data, esonPath))
const oldValue = esonToJson(getInEson(data, path))
const newValue = convertType(oldValue, type)
// console.log('changeType', path, type, oldValue, newValue)
@ -102,7 +96,7 @@ export function duplicate (data, selection) {
}
const rootPath = findRootPath(selection)
const root = getIn(data, toEsonPath(data, rootPath))
const root = getInEson(data, rootPath)
const { maxIndex } = findSelectionIndices(root, rootPath, selection)
const paths = pathsFromSelection(data, selection)
@ -147,8 +141,7 @@ export function duplicate (data, selection) {
*/
export function insertBefore (data, path, values) { // TODO: find a better name and define datastructure for values
const parentPath = initial(path)
const esonPath = toEsonPath(data, parentPath)
const parent = getIn(data, esonPath)
const parent = getInEson(data, parentPath)
if (parent.type === 'Array') {
const startIndex = parseInt(last(path))
@ -192,7 +185,7 @@ export function insertBefore (data, path, values) { // TODO: find a better name
*/
export function replace (data, selection, values) { // TODO: find a better name and define datastructure for values
const rootPath = findRootPath(selection)
const root = getIn(data, toEsonPath(data, rootPath))
const root = getInEson(data, rootPath)
const { minIndex, maxIndex } = findSelectionIndices(root, rootPath, selection)
if (root.type === 'Array') {
@ -245,8 +238,7 @@ export function replace (data, selection, values) { // TODO: find a better name
export function append (data, parentPath, type) {
// console.log('append', parentPath, value)
const esonPath = toEsonPath(data, parentPath)
const parent = getIn(data, esonPath)
const parent = getInEson(data, parentPath)
const value = createEntry(type)
if (parent.type === 'Array') {
@ -310,8 +302,7 @@ export function sort (data, path, order = null) {
// console.log('sort', path, order)
const compare = order === 'desc' ? compareDesc : compareAsc
const esonPath = toEsonPath(data, path)
const object = getIn(data, esonPath)
const object = getInEson(data, path)
if (object.type === 'Array') {
const orderedItems = object.items.slice(0)

View File

@ -4,17 +4,15 @@ import { createElement as h, Component } from 'react'
import isEqual from 'lodash/isEqual'
import reverse from 'lodash/reverse'
import initial from 'lodash/initial'
import last from 'lodash/last'
import Hammer from 'react-hammerjs'
import jump from '../assets/jump.js/src/jump'
import Ajv from 'ajv'
import { updateIn, getIn, setIn } from '../utils/immutabilityHelpers'
import { setIn } from '../utils/immutabilityHelpers'
import { parseJSON } from '../utils/jsonUtils'
import { findUniqueName } from '../utils/stringUtils'
import { enrichSchemaError } from '../utils/schemaUtils'
import {
jsonToEson, esonToJson, toEsonPath, pathExists,
jsonToEson, esonToJson, getInEson, updateInEson, pathExists,
expand, expandPath, addErrors,
search, applySearchResults, nextSearchResult, previousSearchResult,
applySelection, pathsFromSelection, contentsFromPaths,
@ -548,10 +546,8 @@ export default class TreeMode extends Component {
handleExpand = (path, expanded, recurse) => {
if (recurse) {
const esonPath = toEsonPath(this.state.data, path)
this.setState({
data: updateIn(this.state.data, esonPath, function (child) {
data: updateInEson(this.state.data, path, function (child) {
return expand(child, (path) => true, expanded)
})
})
@ -986,7 +982,7 @@ export default class TreeMode extends Component {
* @return {boolean} Returns true when expanded, false otherwise
*/
isExpanded (path) {
return getIn(this.state.data, toEsonPath(this.state.data, path)).expanded
return getInEson(this.state.data, path).expanded
}
/**

View File

@ -5,7 +5,7 @@
* All functions are pure and don't mutate the ESON.
*/
import { setIn, getIn, updateIn } from './utils/immutabilityHelpers'
import { setIn, getIn, updateIn, deleteIn } from './utils/immutabilityHelpers'
import { isObject } from './utils/typeUtils'
import isEqual from 'lodash/isEqual'
import times from 'lodash/times'
@ -174,7 +174,35 @@ export function toJsonPath (eson: ESON, esonPath: ESONPath) : JSONPath {
}
}
type ExpandCallback = (Path) => boolean
/**
* Get a nested property from an ESON object using a JSON path
*/
export function getInEson (eson: ESON, jsonPath: JSONPath) {
return getIn(eson, toEsonPath(eson, jsonPath))
}
/**
* Set the value of a nested property in an ESON object using a JSON path
*/
export function setInEson (eson: ESON, jsonPath: JSONPath, value: JSONType) {
return setIn(eson, toEsonPath(eson, jsonPath), value)
}
/**
* Set the value of a nested property in an ESON object using a JSON path
*/
export function updateInEson (eson: ESON, jsonPath: JSONPath, callback) {
return updateIn(eson, toEsonPath(eson, jsonPath), callback)
}
/**
* Set the value of a nested property in an ESON object using a JSON path
*/
export function deleteInEson (eson: ESON, jsonPath: JSONPath) : JSONType {
// with initial we remove the 'value' property,
// we want to remove the whole item from the items array
return deleteIn(eson, initial(toEsonPath(eson, jsonPath)))
}
/**
* Expand or collapse one or multiple items or properties
@ -263,7 +291,7 @@ export function search (eson: ESON, text: string): ESONPointer[] {
// only add search result when this is an object property name,
// don't add search result for array indices
const parentPath = initial(path)
const parent = getIn(eson, toEsonPath(eson, parentPath))
const parent = getInEson(eson, parentPath)
if (parent.type === 'Object') {
results.push({path, area: 'property'})
}
@ -374,7 +402,7 @@ export function applySelection (eson: ESON, selection: Selection) {
// find the parent node shared by both start and end of the selection
const rootPath = findRootPath(selection)
return updateIn(eson, toEsonPath(eson, rootPath), (root) => {
return updateInEson(eson, rootPath, (root) => {
const { minIndex, maxIndex } = findSelectionIndices(root, rootPath, selection)
const childsKey = (root.type === 'Object') ? 'props' : 'items' // property name of the array with props/items
@ -415,7 +443,7 @@ export function findSelectionIndices (root: ESON, rootPath: JSONPath, selection:
export function pathsFromSelection (eson: ESON, selection: Selection): JSONPath[] {
// find the parent node shared by both start and end of the selection
const rootPath = findRootPath(selection)
const root = getIn(eson, toEsonPath(eson, rootPath))
const root = getInEson(eson, rootPath)
const { minIndex, maxIndex } = findSelectionIndices(root, rootPath, selection)
@ -613,7 +641,7 @@ export function pathExists (eson: ESON, path: JSONPath) {
export function resolvePathIndex (eson, path) {
if (path[path.length - 1] === '-') {
const parentPath = path.slice(0, path.length - 1)
const parent = getIn(eson, toEsonPath(eson, parentPath))
const parent = getInEson(eson, parentPath)
if (parent.type === 'Array') {
const index = parent.items.length

View File

@ -1,10 +1,12 @@
import isEqual from 'lodash/isEqual'
import initial from 'lodash/initial'
import last from 'lodash/last'
import type { ESON, Path, ESONPatch } from './types'
import { setIn, updateIn, getIn, deleteIn, insertAt } from './utils/immutabilityHelpers'
import { setIn, updateIn, getIn, insertAt } from './utils/immutabilityHelpers'
import {
jsonToEson, esonToJson, toEsonPath,
getInEson, setInEson, deleteInEson,
parseJSONPointer, compileJSONPointer,
expandAll, pathExists, resolvePathIndex, findPropertyIndex, findNextProp, getId
} from './eson'
@ -126,11 +128,10 @@ export function patchEson (eson: ESON, patch: ESONPatch, expand = expandAll) {
* @return {{data: ESON, revert: ESONPatch}}
*/
export function replace (data: ESON, path: Path, value: ESON) {
const esonPath = toEsonPath(data, path)
const oldValue = getIn(data, esonPath)
const oldValue = getInEson(data, path)
return {
data: setIn(data, esonPath, value),
data: setInEson(data, path, value),
revert: [{
op: 'replace',
path: compileJSONPointer(path),
@ -148,23 +149,19 @@ export function replace (data: ESON, path: Path, value: ESON) {
* @param {string} path
* @return {{data: ESON, revert: ESONPatch}}
*/
// FIXME: path should be a path instead of a string? (all functions in patchEson)
export function remove (data: ESON, path: string) {
// console.log('remove', path)
const pathArray = parseJSONPointer(path)
const parentPath = pathArray.slice(0, pathArray.length - 1)
const parent = getIn(data, toEsonPath(data, parentPath))
const dataValue = getIn(data, toEsonPath(data, pathArray))
const parentPath = initial(pathArray)
const parent = getInEson(data, parentPath)
const dataValue = getInEson(data, pathArray)
const value = esonToJson(dataValue)
if (parent.type === 'Array') {
const esonPath = toEsonPath(data, pathArray)
// remove the 'value' property, we want to remove the whole item from the items array
esonPath.pop()
return {
data: deleteIn(data, esonPath),
data: deleteInEson(data, pathArray),
revert: [{
op: 'add',
path,
@ -176,14 +173,10 @@ export function remove (data: ESON, path: string) {
}
}
else { // object.type === 'Object'
const esonPath = toEsonPath(data, pathArray)
const prop = pathArray[pathArray.length - 1]
// remove the 'value' property, we want to remove the whole object property from props
esonPath.pop()
const prop = last(pathArray)
return {
data: deleteIn(data, esonPath),
data: deleteInEson(data, pathArray),
revert: [{
op: 'add',
path,
@ -274,7 +267,7 @@ export function add (data: ESON, path: string, value: ESON, options, id = getId(
}
if (parent.type === 'Object' && pathExists(data, resolvedPath)) {
const oldValue = getIn(data, toEsonPath(data, resolvedPath))
const oldValue = getInEson(data, resolvedPath)
return {
data: updatedEson,
@ -307,7 +300,7 @@ export function add (data: ESON, path: string, value: ESON, options, id = getId(
* @private
*/
export function copy (data: ESON, path: string, from: string, options) {
const value = getIn(data, toEsonPath(data, parseJSONPointer(from)))
const value = getInEson(data, parseJSONPointer(from))
return add(data, path, value, options)
}
@ -329,7 +322,7 @@ export function move (data: ESON, path: string, from: string, options) {
// FIXME: only reuse the existing id when move is renaming a property in the same object
const parentPathFrom = initial(fromArray)
const parent = getIn(data, toEsonPath(data, parentPathFrom))
const parent = getInEson(data, parentPathFrom)
const result1 = remove(data, from)
const result2 = add(result1.data, path, dataValue, options, id)
@ -379,7 +372,7 @@ export function test (data: ESON, path: string, value: any) {
return new Error('Test failed, path not found')
}
const actualValue = getIn(data, toEsonPath(data, pathArray))
const actualValue = getInEson(data, pathArray)
if (!isEqual(esonToJson(actualValue), value)) {
return new Error('Test failed, value differs')
}