Some refactoring in `applySelection`
This commit is contained in:
parent
52ec02e3e1
commit
375ea56316
51
src/eson.js
51
src/eson.js
|
@ -324,42 +324,43 @@ export function applySelection (eson: ESON, selection: ESONSelection) {
|
|||
const rootEsonPath = toEsonPath(eson, rootPath)
|
||||
|
||||
if (rootPath.length === selection.start.path.length || rootPath.length === selection.end.path.length) {
|
||||
// select the root itself
|
||||
// select a single node
|
||||
return setIn(eson, rootEsonPath.concat(['selected']), true)
|
||||
}
|
||||
else {
|
||||
// select multiple childs of an object or array
|
||||
return updateIn(eson, rootEsonPath, (root) => {
|
||||
if (root.type === 'Object') {
|
||||
const startIndex = findPropertyIndex(root, selection.start.path[rootPath.length])
|
||||
const endIndex = findPropertyIndex(root, selection.end.path[rootPath.length])
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
const start = selection.start.path[rootPath.length]
|
||||
const end = selection.end.path[rootPath.length]
|
||||
const { minIndex, maxIndex } = findSelectionIndices(root, start, end)
|
||||
|
||||
const propsBefore = root.props.slice(0, minIndex)
|
||||
const propsUpdated = root.props.slice(minIndex, maxIndex)
|
||||
.map((prop, index) => setIn(prop, ['value', 'selected'], true))
|
||||
const propsAfter = root.props.slice(maxIndex)
|
||||
const childsKey = (root.type === 'Object') ? 'props' : 'items' // property name of the array with props/items
|
||||
const childsBefore = root[childsKey].slice(0, minIndex)
|
||||
const childsUpdated = root[childsKey].slice(minIndex, maxIndex)
|
||||
.map((child, index) => setIn(child, ['value', 'selected'], true))
|
||||
const childsAfter = root[childsKey].slice(maxIndex)
|
||||
|
||||
return setIn(root, ['props'], propsBefore.concat(propsUpdated, propsAfter))
|
||||
}
|
||||
else if (root.type === 'Array') {
|
||||
const startIndex = parseInt(selection.start.path[rootPath.length])
|
||||
const endIndex = parseInt(selection.end.path[rootPath.length])
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
|
||||
const itemsBefore = root.items.slice(0, minIndex)
|
||||
const itemsUpdated = root.items.slice(minIndex, maxIndex)
|
||||
.map((item, index) => setIn(item, ['value', 'selected'], true))
|
||||
const itemsAfter = root.items.slice(maxIndex)
|
||||
|
||||
return setIn(root, ['items'], itemsBefore.concat(itemsUpdated, itemsAfter))
|
||||
}
|
||||
return setIn(root, [childsKey], childsBefore.concat(childsUpdated, childsAfter))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the min and max index of a start and end child.
|
||||
* Start and end can be a property name in case of an Object,
|
||||
* or a matrix index (string with a number) in case of an Array.
|
||||
*/
|
||||
export function findSelectionIndices (root: ESON, start: string, end: string) : { minIndex: number, maxIndex: number } {
|
||||
// if no object we assume it's an Array
|
||||
const startIndex = root.type === 'Object' ? findPropertyIndex(root, start) : parseInt(start)
|
||||
const endIndex = root.type === 'Object' ? findPropertyIndex(root, end) : parseInt(end)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
|
||||
return { minIndex, maxIndex }
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the common path of two paths.
|
||||
* For example findCommonRoot(['arr', '1', 'name'], ['arr', '1', 'address', 'contact']) returns ['arr', '1']
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { readFileSync } from 'fs'
|
||||
import test from 'ava';
|
||||
import { setIn } from '../src/utils/immutabilityHelpers'
|
||||
import { setIn, getIn } from '../src/utils/immutabilityHelpers'
|
||||
import {
|
||||
jsonToEson, esonToJson, toEsonPath, pathExists, transform, traverse,
|
||||
parseJSONPointer, compileJSONPointer,
|
||||
expand, addErrors, search, applySearchResults, nextSearchResult, previousSearchResult,
|
||||
applySelection
|
||||
applySelection, getSelection
|
||||
} from '../src/eson'
|
||||
|
||||
const JSON1 = loadJSON('./resources/json1.json')
|
||||
|
@ -288,22 +288,18 @@ test('selection (value)', t => {
|
|||
}
|
||||
|
||||
const actual = applySelection(ESON1, selection)
|
||||
|
||||
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr', '2', 'first']).concat(['selected']), true)
|
||||
|
||||
t.deepEqual(actual, expected)
|
||||
})
|
||||
|
||||
test('selection (single parent)', t => {
|
||||
test('selection (node)', t => {
|
||||
const selection = {
|
||||
start: {path: ['obj', 'arr']},
|
||||
end: {path: ['obj', 'arr']}
|
||||
}
|
||||
|
||||
const actual = applySelection(ESON1, selection)
|
||||
|
||||
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr']).concat(['selected']), true)
|
||||
|
||||
t.deepEqual(actual, expected)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue