diff --git a/src/JSONEditor.svelte b/src/JSONEditor.svelte index d1f2e97..1fae384 100644 --- a/src/JSONEditor.svelte +++ b/src/JSONEditor.svelte @@ -17,7 +17,7 @@ import Icon from 'svelte-awesome' import { faCut, faCopy, faPaste, faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons' import { createHistory } from './history.js' - import Node from './JSONNode.svelte' + import JSONNode from './JSONNode.svelte' import { expandSelection } from './selection.js' import { isContentEditableDiv } from './utils/domUtils.js' import { @@ -342,24 +342,17 @@ } /** - * @param {Selection} newSelection + * @param {SelectionSchema} selectionSchema */ - function handleSelect (newSelection) { - // TODO: refactor handleSelect: should be redundant except for the functionality to expand the selection and generate pathsMap - - if (newSelection) { - const { paths, anchorPath, focusPath, beforePath, appendPath } = newSelection + function handleSelect (selectionSchema) { + if (selectionSchema) { + const { anchorPath, focusPath, beforePath, appendPath } = selectionSchema if (beforePath) { - selection = { - beforePath - } + selection = { beforePath } } else if (appendPath) { - selection = { - appendPath - } + selection = { appendPath } } else if (anchorPath && focusPath) { - // TODO: move expandSelection to JSONNode? (must change expandSelection to support relative path) const paths = expandSelection(doc, state, anchorPath, focusPath) selection = { @@ -367,7 +360,7 @@ pathsMap: createPathsMap(paths) } } else { - console.error('Unknown type of selection', newSelection) + console.error('Unknown type of selection', selectionSchema) } // set focus to the hidden input, so we can capture quick keys like Ctrl+X, Ctrl+C, Ctrl+V @@ -552,7 +545,7 @@ />
- ({ + const offset = parseInt(last(path), 10) + return values.map((entry, index) => ({ op: 'add', - path: compileJSONPointer(parentPath.concat(startIndex + offset)), + path: compileJSONPointer(parentPath.concat(offset + index)), value: entry.value })) } @@ -65,10 +65,10 @@ export function append (json, path, values) { // TODO: find a better name and d const parent = getIn(json, path) if (Array.isArray(parent)) { - const index = parent.length - return values.map((entry, offset) => ({ + const offset = parent.length + return values.map((entry, index) => ({ op: 'add', - path: compileJSONPointer(path.concat(index)), + path: compileJSONPointer(path.concat(offset + index)), value: entry.value })) } diff --git a/src/selection.js b/src/selection.js index 71f03c6..7a3a489 100644 --- a/src/selection.js +++ b/src/selection.js @@ -1,4 +1,4 @@ -import { isEqual } from 'lodash-es' +import { first, initial, isEmpty, isEqual, last } from 'lodash-es' import { STATE_PROPS } from './constants.js' import { getIn } from './utils/immutabilityHelpers.js' import { isObject } from './utils/typeUtils.js' @@ -11,7 +11,7 @@ import { isObject } from './utils/typeUtils.js' * @param {JSON} state * @param {Path} anchorPath * @param {Path} focusPath - * @return {Path[]} selection + * @return {Path[]} paths */ export function expandSelection (doc, state, anchorPath, focusPath) { if (isEqual(anchorPath, focusPath)) { @@ -26,14 +26,14 @@ export function expandSelection (doc, state, anchorPath, focusPath) { return [ sharedPath ] } - const anchorProp = anchorPath[sharedPath.length] - const focusProp = focusPath[sharedPath.length] + const anchorKey = anchorPath[sharedPath.length] + const focusKey = focusPath[sharedPath.length] const value = getIn(doc, sharedPath) if (isObject(value)) { const props = getIn(state, sharedPath.concat(STATE_PROPS)) - const anchorIndex = props.findIndex(prop => prop.key === anchorProp) - const focusIndex = props.findIndex(prop => prop.key === focusProp) + const anchorIndex = props.findIndex(prop => prop.key === anchorKey) + const focusIndex = props.findIndex(prop => prop.key === focusKey) if (anchorIndex !== -1 && focusIndex !== -1) { const startIndex = Math.min(anchorIndex, focusIndex) @@ -49,8 +49,8 @@ export function expandSelection (doc, state, anchorPath, focusPath) { } if (Array.isArray(value)) { - const startIndex = Math.min(anchorProp, focusProp) - const endIndex = Math.max(anchorProp, focusProp) + const startIndex = Math.min(anchorKey, focusKey) + const endIndex = Math.max(anchorKey, focusKey) const paths = [] for (let i = startIndex; i <= endIndex; i++) { @@ -61,8 +61,7 @@ export function expandSelection (doc, state, anchorPath, focusPath) { } } - // should never happen - return [] + throw new Error('Failed to create selection') } /** diff --git a/src/types.js b/src/types.js index 9530b3f..5ed3693 100644 --- a/src/types.js +++ b/src/types.js @@ -25,7 +25,7 @@ */ /** - * @typedef {[]} Path + * @typedef {Array} Path */ /** @@ -50,5 +50,20 @@ */ /** - * @typedef {{paths: Path[], pathsMap: Object}} | {beforePath: Path} | {appendPath: Path}} Selection + * @typedef {{ + * paths: Path[], + * pathsMap: Object + * }} MultiSelection + * + * @typedef {{beforePath: Path}} BeforeSelection + * + * @typedef {{appendPath: Path}} AppendSelection + + * @typedef {MultiSelection | BeforeSelection | AppendSelection} Selection + */ + +/** + * @typedef {{anchorPath: Path, focusPath: Path}} MultiSelectionSchema + * + * @typedef {MultiSelectionSchema | BeforeSelection | AppendSelection} SelectionSchema */