Fix a bug in `append` and a bit of refactoring
This commit is contained in:
parent
ce8cf93170
commit
401a6e19fd
|
@ -17,7 +17,7 @@
|
||||||
import Icon from 'svelte-awesome'
|
import Icon from 'svelte-awesome'
|
||||||
import { faCut, faCopy, faPaste, faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons'
|
import { faCut, faCopy, faPaste, faSearch, faUndo, faRedo } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { createHistory } from './history.js'
|
import { createHistory } from './history.js'
|
||||||
import Node from './JSONNode.svelte'
|
import JSONNode from './JSONNode.svelte'
|
||||||
import { expandSelection } from './selection.js'
|
import { expandSelection } from './selection.js'
|
||||||
import { isContentEditableDiv } from './utils/domUtils.js'
|
import { isContentEditableDiv } from './utils/domUtils.js'
|
||||||
import {
|
import {
|
||||||
|
@ -342,24 +342,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Selection} newSelection
|
* @param {SelectionSchema} selectionSchema
|
||||||
*/
|
*/
|
||||||
function handleSelect (newSelection) {
|
function handleSelect (selectionSchema) {
|
||||||
// TODO: refactor handleSelect: should be redundant except for the functionality to expand the selection and generate pathsMap
|
if (selectionSchema) {
|
||||||
|
const { anchorPath, focusPath, beforePath, appendPath } = selectionSchema
|
||||||
if (newSelection) {
|
|
||||||
const { paths, anchorPath, focusPath, beforePath, appendPath } = newSelection
|
|
||||||
|
|
||||||
if (beforePath) {
|
if (beforePath) {
|
||||||
selection = {
|
selection = { beforePath }
|
||||||
beforePath
|
|
||||||
}
|
|
||||||
} else if (appendPath) {
|
} else if (appendPath) {
|
||||||
selection = {
|
selection = { appendPath }
|
||||||
appendPath
|
|
||||||
}
|
|
||||||
} else if (anchorPath && focusPath) {
|
} else if (anchorPath && focusPath) {
|
||||||
// TODO: move expandSelection to JSONNode? (must change expandSelection to support relative path)
|
|
||||||
const paths = expandSelection(doc, state, anchorPath, focusPath)
|
const paths = expandSelection(doc, state, anchorPath, focusPath)
|
||||||
|
|
||||||
selection = {
|
selection = {
|
||||||
|
@ -367,7 +360,7 @@
|
||||||
pathsMap: createPathsMap(paths)
|
pathsMap: createPathsMap(paths)
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// set focus to the hidden input, so we can capture quick keys like Ctrl+X, Ctrl+C, Ctrl+V
|
||||||
|
@ -552,7 +545,7 @@
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<div class="contents" bind:this={divContents}>
|
<div class="contents" bind:this={divContents}>
|
||||||
<Node
|
<JSONNode
|
||||||
value={doc}
|
value={doc}
|
||||||
path={[]}
|
path={[]}
|
||||||
state={state}
|
state={state}
|
||||||
|
|
|
@ -23,10 +23,10 @@ export function insertBefore (json, path, values, nextKeys) { // TODO: find a b
|
||||||
const parent = getIn(json, parentPath)
|
const parent = getIn(json, parentPath)
|
||||||
|
|
||||||
if (Array.isArray(parent)) {
|
if (Array.isArray(parent)) {
|
||||||
const startIndex = parseInt(last(path), 10)
|
const offset = parseInt(last(path), 10)
|
||||||
return values.map((entry, offset) => ({
|
return values.map((entry, index) => ({
|
||||||
op: 'add',
|
op: 'add',
|
||||||
path: compileJSONPointer(parentPath.concat(startIndex + offset)),
|
path: compileJSONPointer(parentPath.concat(offset + index)),
|
||||||
value: entry.value
|
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)
|
const parent = getIn(json, path)
|
||||||
|
|
||||||
if (Array.isArray(parent)) {
|
if (Array.isArray(parent)) {
|
||||||
const index = parent.length
|
const offset = parent.length
|
||||||
return values.map((entry, offset) => ({
|
return values.map((entry, index) => ({
|
||||||
op: 'add',
|
op: 'add',
|
||||||
path: compileJSONPointer(path.concat(index)),
|
path: compileJSONPointer(path.concat(offset + index)),
|
||||||
value: entry.value
|
value: entry.value
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { STATE_PROPS } from './constants.js'
|
||||||
import { getIn } from './utils/immutabilityHelpers.js'
|
import { getIn } from './utils/immutabilityHelpers.js'
|
||||||
import { isObject } from './utils/typeUtils.js'
|
import { isObject } from './utils/typeUtils.js'
|
||||||
|
@ -11,7 +11,7 @@ import { isObject } from './utils/typeUtils.js'
|
||||||
* @param {JSON} state
|
* @param {JSON} state
|
||||||
* @param {Path} anchorPath
|
* @param {Path} anchorPath
|
||||||
* @param {Path} focusPath
|
* @param {Path} focusPath
|
||||||
* @return {Path[]} selection
|
* @return {Path[]} paths
|
||||||
*/
|
*/
|
||||||
export function expandSelection (doc, state, anchorPath, focusPath) {
|
export function expandSelection (doc, state, anchorPath, focusPath) {
|
||||||
if (isEqual(anchorPath, focusPath)) {
|
if (isEqual(anchorPath, focusPath)) {
|
||||||
|
@ -26,14 +26,14 @@ export function expandSelection (doc, state, anchorPath, focusPath) {
|
||||||
return [ sharedPath ]
|
return [ sharedPath ]
|
||||||
}
|
}
|
||||||
|
|
||||||
const anchorProp = anchorPath[sharedPath.length]
|
const anchorKey = anchorPath[sharedPath.length]
|
||||||
const focusProp = focusPath[sharedPath.length]
|
const focusKey = focusPath[sharedPath.length]
|
||||||
const value = getIn(doc, sharedPath)
|
const value = getIn(doc, sharedPath)
|
||||||
|
|
||||||
if (isObject(value)) {
|
if (isObject(value)) {
|
||||||
const props = getIn(state, sharedPath.concat(STATE_PROPS))
|
const props = getIn(state, sharedPath.concat(STATE_PROPS))
|
||||||
const anchorIndex = props.findIndex(prop => prop.key === anchorProp)
|
const anchorIndex = props.findIndex(prop => prop.key === anchorKey)
|
||||||
const focusIndex = props.findIndex(prop => prop.key === focusProp)
|
const focusIndex = props.findIndex(prop => prop.key === focusKey)
|
||||||
|
|
||||||
if (anchorIndex !== -1 && focusIndex !== -1) {
|
if (anchorIndex !== -1 && focusIndex !== -1) {
|
||||||
const startIndex = Math.min(anchorIndex, focusIndex)
|
const startIndex = Math.min(anchorIndex, focusIndex)
|
||||||
|
@ -49,8 +49,8 @@ export function expandSelection (doc, state, anchorPath, focusPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
const startIndex = Math.min(anchorProp, focusProp)
|
const startIndex = Math.min(anchorKey, focusKey)
|
||||||
const endIndex = Math.max(anchorProp, focusProp)
|
const endIndex = Math.max(anchorKey, focusKey)
|
||||||
const paths = []
|
const paths = []
|
||||||
|
|
||||||
for (let i = startIndex; i <= endIndex; i++) {
|
for (let i = startIndex; i <= endIndex; i++) {
|
||||||
|
@ -61,8 +61,7 @@ export function expandSelection (doc, state, anchorPath, focusPath) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// should never happen
|
throw new Error('Failed to create selection')
|
||||||
return []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
19
src/types.js
19
src/types.js
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue