From e608486a53c59cb53b3cf1240884d7d2147fd345 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 10 Mar 2022 14:55:35 +0100 Subject: [PATCH] fix: implement quick keys Ctrl+F and Ctrl+H to open the find dialog whilst editing a key or value --- README.md | 1 + .../components/controls/EditableDiv.svelte | 15 +++++++- .../components/modes/treemode/JSONKey.svelte | 4 +- .../components/modes/treemode/JSONNode.svelte | 7 +++- .../modes/treemode/JSONValue.svelte | 6 ++- .../components/modes/treemode/TreeMode.svelte | 37 ++++++++++--------- .../value/components/EditableValue.svelte | 2 + src/lib/plugins/value/renderValue.js | 5 ++- 8 files changed, 52 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 87e12e18..290a6729 100644 --- a/README.md +++ b/README.md @@ -345,6 +345,7 @@ type RenderValueProps = { onPatch: (patch: JSONPatchDocument, newSelection: Selection | null) => void onPasteJson: (pastedJson: { path: Path; contents: JSON }) => void onSelect: (selection: Selection) => void + onFind: (findAndReplace: boolean) => void } type ValueNormalization = { diff --git a/src/lib/components/controls/EditableDiv.svelte b/src/lib/components/controls/EditableDiv.svelte index bfbaeb22..76c5ad61 100644 --- a/src/lib/components/controls/EditableDiv.svelte +++ b/src/lib/components/controls/EditableDiv.svelte @@ -20,6 +20,7 @@ export let shortText = false export let onChange export let onCancel + export let onFind export let onPaste = noop export let onValueClass = () => '' @@ -68,7 +69,7 @@ function handleValueKeyDown(event) { event.stopPropagation() - const combo = keyComboFromEvent(event) + const combo = keyComboFromEvent(event).replace(/^Command\+/, 'Ctrl+') if (combo === 'Escape') { // cancel changes (needed to prevent triggering a change onDestroy) @@ -84,6 +85,16 @@ const newValue = getDomValue() onChange(newValue, UPDATE_SELECTION.NEXT_INSIDE) } + + if (combo === 'Ctrl+F') { + event.preventDefault() + onFind(false) + } + + if (combo === 'Ctrl+H') { + event.preventDefault() + onFind(true) + } } function handleValuePaste(event) { @@ -109,6 +120,8 @@ closed = true if (newValue !== value) { onChange(newValue, UPDATE_SELECTION.SELF) + } else { + onCancel() } } } diff --git a/src/lib/components/modes/treemode/JSONKey.svelte b/src/lib/components/modes/treemode/JSONKey.svelte index 10412dc3..749b5c17 100644 --- a/src/lib/components/modes/treemode/JSONKey.svelte +++ b/src/lib/components/modes/treemode/JSONKey.svelte @@ -6,13 +6,14 @@ import { SELECTION_TYPE } from '$lib/logic/selection' import SearchResultHighlighter from './highlight/SearchResultHighlighter.svelte' import EditableDiv from '../../controls/EditableDiv.svelte' - import { addNewLineSuffix } from '$lib/utils/domUtils.js' + import { addNewLineSuffix } from '$lib/utils/domUtils' import { UPDATE_SELECTION } from '../../../constants.js' export let path export let key export let readOnly export let onUpdateKey + export let onFind export let selection /** @type {ValueNormalization} */ @@ -71,6 +72,7 @@ shortText onChange={handleChangeValue} onCancel={handleCancelChange} + {onFind} /> {:else}
diff --git a/src/lib/components/modes/treemode/JSONNode.svelte b/src/lib/components/modes/treemode/JSONNode.svelte index 2fa5f43b..b57cfe06 100644 --- a/src/lib/components/modes/treemode/JSONNode.svelte +++ b/src/lib/components/modes/treemode/JSONNode.svelte @@ -38,7 +38,7 @@ import JSONValue from './JSONValue.svelte' import { singleton } from './singleton.js' import ValidationError from './ValidationError.svelte' - import { STATE_ENFORCE_STRING } from '$lib/constants.js' + import { STATE_ENFORCE_STRING } from '$lib/constants' // eslint-disable-next-line no-undef-init export let value @@ -52,6 +52,7 @@ export let onInsert export let onExpand export let onSelect + export let onFind export let onPasteJson export let onRenderValue export let onContextMenu @@ -386,6 +387,7 @@ {onInsert} {onExpand} {onSelect} + {onFind} {onPasteJson} {onExpandSection} {onRenderValue} @@ -511,6 +513,7 @@ {onInsert} {onExpand} {onSelect} + {onFind} {onPasteJson} {onExpandSection} {onRenderValue} @@ -529,6 +532,7 @@ searchResult={searchResult?.[key]?.[STATE_SEARCH_PROPERTY]} onUpdateKey={handleUpdateKey} {onSelect} + {onFind} /> {#if !readOnly && selectionObj && selectionObj.type === SELECTION_TYPE.KEY && !selectionObj.edit && isEqual(selectionObj.focusPath, path.concat(key))} @@ -567,6 +571,7 @@ searchResult={searchResult ? searchResult[STATE_SEARCH_VALUE] : undefined} {onPatch} {onSelect} + {onFind} {onPasteJson} {onRenderValue} /> diff --git a/src/lib/components/modes/treemode/JSONValue.svelte b/src/lib/components/modes/treemode/JSONValue.svelte index ca9ea3aa..2b806191 100644 --- a/src/lib/components/modes/treemode/JSONValue.svelte +++ b/src/lib/components/modes/treemode/JSONValue.svelte @@ -1,7 +1,7 @@ diff --git a/src/lib/components/modes/treemode/TreeMode.svelte b/src/lib/components/modes/treemode/TreeMode.svelte index 99f23342..f7e1b3fd 100644 --- a/src/lib/components/modes/treemode/TreeMode.svelte +++ b/src/lib/components/modes/treemode/TreeMode.svelte @@ -1515,6 +1515,22 @@ } } + /** + * @param {boolean} findAndReplace + */ + function openFind(findAndReplace) { + debug('openFind', { findAndReplace }) + + showSearch = false + showReplace = false + + tick().then(() => { + // trick to make sure the focus goes to the search box + showSearch = true + showReplace = findAndReplace + }) + } + function handleExpandSection(path, section) { debug('handleExpandSection', path, section) @@ -1684,28 +1700,12 @@ if (combo === 'Ctrl+F') { event.preventDefault() - - showSearch = false - showReplace = false - - tick().then(() => { - // trick to make sure the focus goes to the search box - showSearch = true - showReplace = false - }) + openFind(false) } if (combo === 'Ctrl+H') { event.preventDefault() - - showSearch = false - showReplace = false - - tick().then(() => { - // trick to make sure the focus goes to the search box - showSearch = true - showReplace = true - }) + openFind(true) } if (combo === 'Ctrl+Z') { @@ -2027,6 +2027,7 @@ onInsert={handleInsert} onExpand={handleExpand} onSelect={handleSelect} + onFind={openFind} onPasteJson={handlePasteJson} onExpandSection={handleExpandSection} {onRenderValue} diff --git a/src/lib/plugins/value/components/EditableValue.svelte b/src/lib/plugins/value/components/EditableValue.svelte index b07ac69c..47d92dd5 100644 --- a/src/lib/plugins/value/components/EditableValue.svelte +++ b/src/lib/plugins/value/components/EditableValue.svelte @@ -15,6 +15,7 @@ export let onPatch export let onPasteJson export let onSelect + export let onFind function convert(value) { return enforceString ? value : stringConvert(value) @@ -80,5 +81,6 @@ onChange={handleChangeValue} onCancel={handleCancelChange} onPaste={handlePaste} + {onFind} onValueClass={handleOnValueClass} /> diff --git a/src/lib/plugins/value/renderValue.js b/src/lib/plugins/value/renderValue.js index 696948e4..a6fd6eee 100644 --- a/src/lib/plugins/value/renderValue.js +++ b/src/lib/plugins/value/renderValue.js @@ -19,7 +19,8 @@ export function renderValue({ normalization, onPatch, onPasteJson, - onSelect + onSelect, + onFind }) { const renderers = [] @@ -40,7 +41,7 @@ export function renderValue({ if (isEditing) { renderers.push({ component: EditableValue, - props: { path, value, enforceString, normalization, onPatch, onPasteJson, onSelect } + props: { path, value, enforceString, normalization, onPatch, onPasteJson, onSelect, onFind } }) }