Fix a bug in `append` and a bit of refactoring

This commit is contained in:
Jos de Jong 2020-07-22 11:09:33 +02:00
parent ce8cf93170
commit 401a6e19fd
4 changed files with 41 additions and 34 deletions

View File

@ -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 @@
/>
</label>
<div class="contents" bind:this={divContents}>
<Node
<JSONNode
value={doc}
path={[]}
state={state}

View File

@ -23,10 +23,10 @@ export function insertBefore (json, path, values, nextKeys) { // TODO: find a b
const parent = getIn(json, parentPath)
if (Array.isArray(parent)) {
const startIndex = parseInt(last(path), 10)
return values.map((entry, offset) => ({
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
}))
}

View File

@ -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')
}
/**

View File

@ -25,7 +25,7 @@
*/
/**
* @typedef {<string | number>[]} Path
* @typedef {Array<string | number>} Path
*/
/**
@ -50,5 +50,20 @@
*/
/**
* @typedef {{paths: Path[], pathsMap: Object<string, boolean>}} | {beforePath: Path} | {appendPath: Path}} Selection
* @typedef {{
* paths: Path[],
* pathsMap: Object<string, boolean>
* }} 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
*/