diff --git a/src/lib/components/modes/tablemode/TableMode.svelte b/src/lib/components/modes/tablemode/TableMode.svelte index 201edd41..c1881eda 100644 --- a/src/lib/components/modes/tablemode/TableMode.svelte +++ b/src/lib/components/modes/tablemode/TableMode.svelte @@ -1172,7 +1172,7 @@ selectInside: false, refJsonEditor, json, - documentState, + selection: documentState.selection, readOnly, parser, onPatch: handlePatch, @@ -1352,7 +1352,7 @@ onPaste({ clipboardText, json, - documentState, + selection: documentState.selection, readOnly, parser, onPatch: handlePatch, @@ -1686,6 +1686,7 @@ class:no-main-menu={!mainMenuBar} on:mousedown={handleMouseDown} on:keydown={handleKeyDown} + on:paste={handlePaste} on:contextmenu={handleContextMenu} bind:this={refJsonEditor} > @@ -1711,7 +1712,6 @@ tabindex="-1" class="jse-hidden-input" bind:this={refHiddenInput} - on:paste={handlePaste} /> {#if containsValidArray} diff --git a/src/lib/components/modes/treemode/TreeMode.svelte b/src/lib/components/modes/treemode/TreeMode.svelte index 99e765bb..651a1719 100644 --- a/src/lib/components/modes/treemode/TreeMode.svelte +++ b/src/lib/components/modes/treemode/TreeMode.svelte @@ -722,7 +722,7 @@ documentState = { ...documentState, - selection: createMultiSelection([], []) + selection: createValueSelection([], false) } } @@ -898,7 +898,7 @@ onPaste({ clipboardText, json, - documentState, + selection: documentState.selection, readOnly, parser, onPatch: handlePatch, @@ -1014,7 +1014,7 @@ selectInside: true, refJsonEditor, json, - documentState, + selection: documentState.selection, readOnly, parser, onPatch: handlePatch, @@ -1112,7 +1112,7 @@ selectInside: true, refJsonEditor, json, - documentState, + selection: documentState.selection, readOnly, parser, onPatch: handlePatch, @@ -2095,6 +2095,7 @@ class:no-main-menu={!mainMenuBar} on:keydown={handleKeyDown} on:mousedown={handleMouseDown} + on:paste={handlePaste} on:contextmenu={handleContextMenu} bind:this={refJsonEditor} > @@ -2135,7 +2136,6 @@ tabindex="-1" class="jse-hidden-input" bind:this={refHiddenInput} - on:paste={handlePaste} /> {#if json === undefined} diff --git a/src/lib/logic/actions.ts b/src/lib/logic/actions.ts index 376cbf8f..755a3904 100644 --- a/src/lib/logic/actions.ts +++ b/src/lib/logic/actions.ts @@ -28,7 +28,8 @@ import type { OnChange, OnChangeText, OnPatch, - OnJSONSelect + OnJSONSelect, + JSONSelection } from '$lib/types' import { createDebug } from '$lib/utils/debug.js' import { @@ -124,7 +125,7 @@ type RepairModalCallback = (text: string, onApply: (repairedText: string) => voi interface OnPasteAction { clipboardText: string json: JSONValue | undefined - documentState: DocumentState + selection: JSONSelection | null readOnly: boolean parser: JSONParser onPatch: OnPatch @@ -136,7 +137,7 @@ interface OnPasteAction { export function onPaste({ clipboardText, json, - documentState, + selection, readOnly, parser, onPatch, @@ -149,11 +150,11 @@ export function onPaste({ function doPaste(pastedText: string) { if (json !== undefined) { - const selection = documentState.selection || createMultiSelection([], []) + const selectionNonNull = selection || createValueSelection([], false) - const operations = insert(json, selection, pastedText, parser) + const operations = insert(json, selectionNonNull, pastedText, parser) - debug('paste', { pastedText, operations, selection }) + debug('paste', { pastedText, operations, selectionNonNull }) onPatch(operations, (patchedJson, patchedState) => { let updatedState = patchedState @@ -486,7 +487,7 @@ export interface OnInsert { selectInside: boolean refJsonEditor: HTMLElement json: JSONValue | undefined - documentState: DocumentState + selection: JSONSelection | null readOnly: boolean parser: JSONParser onPatch: OnPatch @@ -499,21 +500,21 @@ export function onInsert({ selectInside, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, onReplaceJson }: OnInsert): void { - if (readOnly || !documentState.selection) { + if (readOnly) { return } - const newValue = createNewValue(json, documentState.selection, insertType) + const newValue = createNewValue(json, selection, insertType) if (json !== undefined) { const data = parser.stringify(newValue) - const operations = insert(json, documentState.selection, data, parser) + const operations = insert(json, selection, data, parser) debug('onInsert', { insertType, operations, newValue, data }) const operation = last( @@ -543,7 +544,7 @@ export function onInsert({ state: expandPath( patchedJson, { - ...documentState, + ...patchedState, selection: isObject(parent) ? createKeySelection(path, true) : createValueSelection(path, true) @@ -584,7 +585,7 @@ export interface OnInsertCharacter { selectInside: boolean refJsonEditor: HTMLElement json: JSONValue | undefined - documentState: DocumentState + selection: JSONSelection | null readOnly: boolean parser: JSONParser onPatch: OnPatch @@ -598,7 +599,7 @@ export async function onInsertCharacter({ selectInside, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, @@ -607,16 +608,16 @@ export async function onInsertCharacter({ }: OnInsertCharacter) { // a regular key like a, A, _, etc is entered. // Replace selected contents with a new value having this first character as text - if (readOnly || !documentState.selection) { + if (readOnly) { return } - if (isKeySelection(documentState.selection)) { + if (isKeySelection(selection)) { // only replace contents when not yet in edit mode (can happen when entering // multiple characters very quickly after each other due to the async handling) - const replaceContents = !documentState.selection.edit + const replaceContents = !selection.edit - onSelect({ ...documentState.selection, edit: true }) + onSelect({ ...selection, edit: true }) tick2(() => insertActiveElementContents(refJsonEditor, char, replaceContents)) return } @@ -627,7 +628,7 @@ export async function onInsertCharacter({ selectInside, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, @@ -639,20 +640,20 @@ export async function onInsertCharacter({ selectInside, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, onReplaceJson }) } else { - if (isValueSelection(documentState.selection) && json !== undefined) { - if (!isObjectOrArray(getIn(json, documentState.selection.path))) { + if (isValueSelection(selection) && json !== undefined) { + if (!isObjectOrArray(getIn(json, selection.path))) { // only replace contents when not yet in edit mode (can happen when entering // multiple characters very quickly after each other due to the async handling) - const replaceContents = !documentState.selection.edit + const replaceContents = !selection.edit - onSelect({ ...documentState.selection, edit: true }) + onSelect({ ...selection, edit: true }) tick2(() => insertActiveElementContents(refJsonEditor, char, replaceContents)) } else { // TODO: replace the object/array with editing a text in edit mode? @@ -666,7 +667,7 @@ export async function onInsertCharacter({ char, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, @@ -680,7 +681,7 @@ interface OnInsertValueWithCharacter { char: string refJsonEditor: HTMLElement json: JSONValue | undefined - documentState: DocumentState + selection: JSONSelection | null readOnly: boolean parser: JSONParser onPatch: OnPatch @@ -691,13 +692,13 @@ async function onInsertValueWithCharacter({ char, refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, onReplaceJson }: OnInsertValueWithCharacter) { - if (readOnly || !documentState.selection) { + if (readOnly) { return } @@ -707,7 +708,7 @@ async function onInsertValueWithCharacter({ selectInside: false, // not relevant, we insert a value, not an object or array refJsonEditor, json, - documentState, + selection, readOnly, parser, onPatch, @@ -716,7 +717,7 @@ async function onInsertValueWithCharacter({ // only replace contents when not yet in edit mode (can happen when entering // multiple characters very quickly after each other due to the async handling) - const replaceContents = !isEditingSelection(documentState.selection) + const replaceContents = !isEditingSelection(selection) tick2(() => insertActiveElementContents(refJsonEditor, char, replaceContents)) } diff --git a/src/lib/logic/documentState.ts b/src/lib/logic/documentState.ts index ade9c629..aa553fd0 100644 --- a/src/lib/logic/documentState.ts +++ b/src/lib/logic/documentState.ts @@ -47,6 +47,7 @@ import type { import { CaretType } from '$lib/types.js' import { int } from '../utils/numberUtils.js' import { isLargeContent } from '$lib/utils/jsonUtils.js' +import { createValueSelection } from './selection.js' type OnCreateSelection = (json: JSONValue, documentState: DocumentState) => JSONSelection @@ -61,7 +62,7 @@ export function createDocumentState(props?: CreateDocumentStateProps): DocumentS expandedMap: {}, enforceStringMap: {}, visibleSectionsMap: {}, - selection: null, + selection: createValueSelection([], false), sortedColumn: null } diff --git a/src/lib/logic/selection.ts b/src/lib/logic/selection.ts index 15bd254b..c9dc5e4e 100644 --- a/src/lib/logic/selection.ts +++ b/src/lib/logic/selection.ts @@ -471,7 +471,7 @@ export function getInitialSelection(json: JSONValue, documentState: DocumentStat } const path = visiblePaths[index] - return path.length === 0 || Array.isArray(getIn(json, initial(path))) + return path === undefined || path.length === 0 || Array.isArray(getIn(json, initial(path))) ? createValueSelection(path, false) // Array items and root object/array do not have a key, so select value in that case : createKeySelection(path, false) }