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)
|
const rootEsonPath = toEsonPath(eson, rootPath)
|
||||||
|
|
||||||
if (rootPath.length === selection.start.path.length || rootPath.length === selection.end.path.length) {
|
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)
|
return setIn(eson, rootEsonPath.concat(['selected']), true)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// select multiple childs of an object or array
|
// select multiple childs of an object or array
|
||||||
return updateIn(eson, rootEsonPath, (root) => {
|
return updateIn(eson, rootEsonPath, (root) => {
|
||||||
if (root.type === 'Object') {
|
const start = selection.start.path[rootPath.length]
|
||||||
const startIndex = findPropertyIndex(root, selection.start.path[rootPath.length])
|
const end = selection.end.path[rootPath.length]
|
||||||
const endIndex = findPropertyIndex(root, selection.end.path[rootPath.length])
|
const { minIndex, maxIndex } = findSelectionIndices(root, start, end)
|
||||||
const minIndex = Math.min(startIndex, endIndex)
|
|
||||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
|
||||||
|
|
||||||
const propsBefore = root.props.slice(0, minIndex)
|
const childsKey = (root.type === 'Object') ? 'props' : 'items' // property name of the array with props/items
|
||||||
const propsUpdated = root.props.slice(minIndex, maxIndex)
|
const childsBefore = root[childsKey].slice(0, minIndex)
|
||||||
.map((prop, index) => setIn(prop, ['value', 'selected'], true))
|
const childsUpdated = root[childsKey].slice(minIndex, maxIndex)
|
||||||
const propsAfter = root.props.slice(maxIndex)
|
.map((child, index) => setIn(child, ['value', 'selected'], true))
|
||||||
|
const childsAfter = root[childsKey].slice(maxIndex)
|
||||||
|
|
||||||
return setIn(root, ['props'], propsBefore.concat(propsUpdated, propsAfter))
|
return setIn(root, [childsKey], childsBefore.concat(childsUpdated, childsAfter))
|
||||||
}
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Find the common path of two paths.
|
||||||
* For example findCommonRoot(['arr', '1', 'name'], ['arr', '1', 'address', 'contact']) returns ['arr', '1']
|
* For example findCommonRoot(['arr', '1', 'name'], ['arr', '1', 'address', 'contact']) returns ['arr', '1']
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import { setIn } from '../src/utils/immutabilityHelpers'
|
import { setIn, getIn } from '../src/utils/immutabilityHelpers'
|
||||||
import {
|
import {
|
||||||
jsonToEson, esonToJson, toEsonPath, pathExists, transform, traverse,
|
jsonToEson, esonToJson, toEsonPath, pathExists, transform, traverse,
|
||||||
parseJSONPointer, compileJSONPointer,
|
parseJSONPointer, compileJSONPointer,
|
||||||
expand, addErrors, search, applySearchResults, nextSearchResult, previousSearchResult,
|
expand, addErrors, search, applySearchResults, nextSearchResult, previousSearchResult,
|
||||||
applySelection
|
applySelection, getSelection
|
||||||
} from '../src/eson'
|
} from '../src/eson'
|
||||||
|
|
||||||
const JSON1 = loadJSON('./resources/json1.json')
|
const JSON1 = loadJSON('./resources/json1.json')
|
||||||
|
@ -288,22 +288,18 @@ test('selection (value)', t => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const actual = applySelection(ESON1, selection)
|
const actual = applySelection(ESON1, selection)
|
||||||
|
|
||||||
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr', '2', 'first']).concat(['selected']), true)
|
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr', '2', 'first']).concat(['selected']), true)
|
||||||
|
|
||||||
t.deepEqual(actual, expected)
|
t.deepEqual(actual, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('selection (single parent)', t => {
|
test('selection (node)', t => {
|
||||||
const selection = {
|
const selection = {
|
||||||
start: {path: ['obj', 'arr']},
|
start: {path: ['obj', 'arr']},
|
||||||
end: {path: ['obj', 'arr']}
|
end: {path: ['obj', 'arr']}
|
||||||
}
|
}
|
||||||
|
|
||||||
const actual = applySelection(ESON1, selection)
|
const actual = applySelection(ESON1, selection)
|
||||||
|
|
||||||
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr']).concat(['selected']), true)
|
const expected = setIn(ESON1, toEsonPath(ESON1, ['obj', 'arr']).concat(['selected']), true)
|
||||||
|
|
||||||
t.deepEqual(actual, expected)
|
t.deepEqual(actual, expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue