diff --git a/src/components/DropdownMenu.svelte b/src/components/DropdownMenu.svelte
index c2c64e8..b0ff7cb 100644
--- a/src/components/DropdownMenu.svelte
+++ b/src/components/DropdownMenu.svelte
@@ -10,7 +10,6 @@
export let title = null
export let width = '120px'
export let visible = false
- export let disabled = false
function toggleShow (event) {
event.stopPropagation()
@@ -51,7 +50,11 @@
{#each items as item}
-
-
diff --git a/src/components/JSONEditor.svelte b/src/components/JSONEditor.svelte
index 464e1a4..4b53ef8 100644
--- a/src/components/JSONEditor.svelte
+++ b/src/components/JSONEditor.svelte
@@ -1,11 +1,10 @@
@@ -107,13 +115,12 @@
diff --git a/src/logic/operations.js b/src/logic/operations.js
index 2c55f4a..2d829e5 100644
--- a/src/logic/operations.js
+++ b/src/logic/operations.js
@@ -1,7 +1,11 @@
-import { first, initial, last, pickBy } from 'lodash-es'
-import { getIn } from '../utils/immutabilityHelpers'
-import { compileJSONPointer } from '../utils/jsonPointer'
-import { findUniqueName } from '../utils/stringUtils'
+import { first, initial, isEmpty, last, pickBy, cloneDeepWith } from 'lodash-es'
+import { STATE_PROPS } from '../constants.js'
+import { getNextKeys } from '../logic/documentState.js'
+import { getParentPath } from '../logic/selection.js'
+import { getIn } from '../utils/immutabilityHelpers.js'
+import { compileJSONPointer } from '../utils/jsonPointer.js'
+import { findUniqueName } from '../utils/stringUtils.js'
+import { isObjectOrArray } from '../utils/typeUtils.js'
/**
* Create a JSONPatch for an insert operation.
@@ -229,6 +233,66 @@ export function duplicate (json, paths, nextKeys) {
}
}
+export function insert (doc, state, selection, values) {
+ if (selection.beforePath) {
+ const parentPath = initial(selection.beforePath)
+ const beforeKey = last(selection.beforePath)
+ const props = getIn(state, parentPath.concat(STATE_PROPS))
+ const nextKeys = getNextKeys(props, beforeKey, true)
+ const operations = insertBefore(doc, selection.beforePath, values, nextKeys)
+
+ return operations
+ } else if (selection.appendPath) {
+ const operations = append(doc, selection.appendPath, values)
+
+ return operations
+ } else if (selection.paths) {
+ const lastPath = last(selection.paths) // FIXME: here we assume selection.paths is sorted correctly, that's a dangerous assumption
+ const parentPath = initial(lastPath)
+ const beforeKey = last(lastPath)
+ const props = getIn(state, parentPath.concat(STATE_PROPS))
+ const nextKeys = getNextKeys(props, beforeKey, true)
+ const operations = replace(doc, selection.paths, values, nextKeys)
+
+ return operations
+ }
+}
+
+export function createNewValue (doc, selection, type) {
+ switch (type) {
+ case 'value':
+ return ''
+
+ case 'object':
+ return {}
+
+ case 'array':
+ return []
+
+ case 'structure':
+ const parentPath = getParentPath(selection)
+ const parent = getIn(doc, parentPath)
+
+ if (Array.isArray(parent) && !isEmpty(parent)) {
+ const jsonExample = first(parent)
+ const structure = cloneDeepWith(jsonExample, (value) => {
+ return isObjectOrArray(value)
+ ? undefined // leave as is
+ : ''
+ })
+
+ console.log('structure', jsonExample, structure)
+
+ return structure
+ } else {
+ // no example structure
+ return ''
+ }
+
+ default: ''
+ }
+}
+
/**
* Create a JSONPatch for a remove operation
* @param {Path} path
diff --git a/src/logic/selection.js b/src/logic/selection.js
index 38d26c3..b87f749 100644
--- a/src/logic/selection.js
+++ b/src/logic/selection.js
@@ -1,4 +1,4 @@
-import { isEqual } from 'lodash-es'
+import { first, initial, isEqual } from 'lodash-es'
import { STATE_PROPS } from '../constants.js'
import { getIn } from '../utils/immutabilityHelpers.js'
import { compileJSONPointer, parseJSONPointer } from '../utils/jsonPointer.js'
@@ -65,6 +65,26 @@ export function expandSelection (doc, state, anchorPath, focusPath) {
throw new Error('Failed to create selection')
}
+/**
+ *
+ * @param {Selection} selection
+ * @return {Path} Returns parent path
+ */
+export function getParentPath (selection) {
+ if (selection.beforePath) {
+ return initial(selection.beforePath)
+ }
+
+ if (selection.appendPath) {
+ return selection.appendPath
+ }
+
+ if (selection.paths) {
+ const firstPath = first(selection.paths)
+ return initial(firstPath)
+ }
+}
+
/**
* @param {JSONPatchDocument} operations
* @returns {MultiSelection}
diff --git a/src/logic/selection.test.js b/src/logic/selection.test.js
index 5ac5cce..0197d06 100644
--- a/src/logic/selection.test.js
+++ b/src/logic/selection.test.js
@@ -1,5 +1,5 @@
import assert from 'assert'
-import { expandSelection } from './selection.js'
+import { expandSelection, getParentPath } from './selection.js'
import { syncState } from './documentState.js'
describe ('selection', () => {
@@ -65,4 +65,14 @@ describe ('selection', () => {
['obj', 'arr']
])
})
+
+ it('should get parent path from a selection', () => {
+ assert.deepStrictEqual(getParentPath({ beforePath: ['a', 'b']}), ['a'])
+ assert.deepStrictEqual(getParentPath({ appendPath: ['a', 'b']}), ['a', 'b'])
+ assert.deepStrictEqual(getParentPath({ paths:[
+ ['a', 'b'],
+ ['a', 'c'],
+ ['a', 'd']
+ ]}), ['a'])
+ })
})
diff --git a/src/types.js b/src/types.js
index 162b830..ecf5040 100644
--- a/src/types.js
+++ b/src/types.js
@@ -80,5 +80,6 @@
* @typedef {Object} MenuDropdownItem
* @property {string} text
* @property {function} onClick
+ * @property {string} [title=undefined]
* @property {boolean} [default=false]
- **/
+ */