Refactored `findSelectionIndices`
This commit is contained in:
parent
9b2b8233af
commit
80f45f39ec
|
@ -1,7 +1,8 @@
|
|||
import last from 'lodash/last'
|
||||
import initial from 'lodash/initial'
|
||||
import isEmpty from 'lodash/isEmpty'
|
||||
import { findRootPath, findSelectionIndices, pathsFromSelection } from './eson'
|
||||
import first from 'lodash/first'
|
||||
import { findRootPath, pathsFromSelection } from './eson'
|
||||
import { getIn } from './utils/immutabilityHelpers'
|
||||
import { findUniqueName } from './utils/stringUtils'
|
||||
import { isObject, stringConvert } from './utils/typeUtils'
|
||||
|
@ -86,14 +87,16 @@ export function duplicate (json, selection) {
|
|||
|
||||
const rootPath = findRootPath(selection)
|
||||
const root = getIn(json, rootPath)
|
||||
const { maxIndex } = findSelectionIndices(root, rootPath, selection)
|
||||
const paths = pathsFromSelection(json, selection)
|
||||
|
||||
if (Array.isArray(root)) {
|
||||
return paths.map((path, offset) => ({
|
||||
const lastPath = last(paths)
|
||||
const offset = lastPath ? (parseInt(last(lastPath), 10) + 1) : 0
|
||||
|
||||
return paths.map((path, index) => ({
|
||||
op: 'copy',
|
||||
from: compileJSONPointer(path),
|
||||
path: compileJSONPointer(rootPath.concat(maxIndex + offset))
|
||||
path: compileJSONPointer(rootPath.concat(index + offset))
|
||||
}))
|
||||
}
|
||||
else { // 'object'
|
||||
|
@ -221,13 +224,16 @@ export function insertInside (json, parentPath, values) {
|
|||
export function replace (json, selection, values) { // TODO: find a better name and define datastructure for values
|
||||
const rootPath = findRootPath(selection)
|
||||
const root = getIn(json, rootPath)
|
||||
const { minIndex, maxIndex } = findSelectionIndices(root, rootPath, selection)
|
||||
|
||||
if (Array.isArray(root)) {
|
||||
const removeActions = removeAll(pathsFromSelection(json, selection))
|
||||
const insertActions = values.map((entry, offset) => ({
|
||||
const paths = pathsFromSelection(json, selection)
|
||||
const firstPath = first(paths)
|
||||
const offset = firstPath ? parseInt(last(firstPath), 10) : 0
|
||||
|
||||
const removeActions = removeAll(paths)
|
||||
const insertActions = values.map((entry, index) => ({
|
||||
op: 'add',
|
||||
path: compileJSONPointer(rootPath.concat(minIndex + offset)),
|
||||
path: compileJSONPointer(rootPath.concat(index + offset)),
|
||||
value: entry.value
|
||||
}))
|
||||
|
||||
|
|
|
@ -413,33 +413,6 @@ export function applySelection (eson, selection) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param {ESON} root
|
||||
* @param {Path} rootPath
|
||||
* @param {Selection} selection
|
||||
* @return {{minIndex: number, maxIndex: number}}
|
||||
*/
|
||||
export function findSelectionIndices (root, rootPath, selection) {
|
||||
const start = (selection.after || selection.inside || selection.start)[rootPath.length]
|
||||
const end = (selection.after || selection.inside || selection.end)[rootPath.length]
|
||||
|
||||
// if no object we assume it's an Array
|
||||
// TODO: create a util function getSortedProps, cache results?
|
||||
const rootIsObject = getType(root) === 'object'
|
||||
const props = rootIsObject ? Object.keys(root).sort(naturalSort) : undefined
|
||||
const startIndex = rootIsObject ? props.indexOf(start) : parseInt(start, 10)
|
||||
const endIndex = rootIsObject ? props.indexOf(end) : parseInt(end, 10)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + ((selection.after || selection.inside) ? 0 : 1) // include max index itself
|
||||
|
||||
return { minIndex, maxIndex }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of a list with paths
|
||||
* @param {ESON} eson
|
||||
|
@ -518,14 +491,27 @@ export function pathsFromSelection (eson, selection) {
|
|||
const rootPath = findRootPath(selection)
|
||||
const root = getIn(eson, rootPath)
|
||||
|
||||
const { minIndex, maxIndex } = findSelectionIndices(root, rootPath, selection)
|
||||
const start = (selection.after || selection.inside || selection.start)[rootPath.length]
|
||||
const end = (selection.after || selection.inside || selection.end)[rootPath.length]
|
||||
|
||||
if (getType(root) === 'object') {
|
||||
const props = Object.keys(root).sort(naturalSort) // TODO: create a util function getSortedProps
|
||||
// TODO: create a util function getSortedProps, cache results?
|
||||
const props = Object.keys(root).sort(naturalSort)
|
||||
const startIndex = props.indexOf(start)
|
||||
const endIndex = props.indexOf(end)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + ((selection.after || selection.inside) ? 0 : 1) // include max index itself
|
||||
|
||||
return times(maxIndex - minIndex, i => rootPath.concat(props[i + minIndex]))
|
||||
}
|
||||
else { // root[TYPE] === 'array'
|
||||
const startIndex = parseInt(start, 10)
|
||||
const endIndex = parseInt(end, 10)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + ((selection.after || selection.inside) ? 0 : 1) // include max index itself
|
||||
|
||||
return times(maxIndex - minIndex, i => rootPath.concat(String(i + minIndex)))
|
||||
}
|
||||
}
|
||||
|
@ -541,7 +527,7 @@ export function pathsFromSelection (eson, selection) {
|
|||
export function immutableESONPatch (eson, operations) {
|
||||
return immutableJSONPatch(eson, operations, {
|
||||
fromJSON: (value, previousEson) => syncEson(value, previousEson),
|
||||
toJSON: (eson) => eson[VALUE],
|
||||
toJSON: (eson) => eson.valueOf(),
|
||||
clone: (value) => setIn(value, [ID], createId())
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue