diff --git a/ts/editor/Tag.svelte b/ts/editor/Tag.svelte index 91b48940d..145a6b586 100644 --- a/ts/editor/Tag.svelte +++ b/ts/editor/Tag.svelte @@ -49,6 +49,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html on:tagadd on:tagjoinprevious on:tagjoinnext + on:tagmoveprevious + on:tagmovenext on:mount={(event) => event.detail.input.focus()} /> {:else} diff --git a/ts/editor/TagEditor.svelte b/ts/editor/TagEditor.svelte index 24eb9d3cc..b4425cb6d 100644 --- a/ts/editor/TagEditor.svelte +++ b/ts/editor/TagEditor.svelte @@ -88,6 +88,23 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html setPosition(length); } + function moveToPreviousTag(index: number): void { + if (index === 0 || tags.length === 1) { + return; + } + + const before = tags.splice(index - 1, 1)[0]; + tags.splice(index, 0, before); + tags = tags; + } + + function moveToNextTag(index: number): void { + if (index === tags.length - 1 || tags.length === 1) { + return; + } + // TODO + } + function appendTag(): void { const names = tags.map(getName); if (!names.includes(newName) && newName.length > 0) { @@ -107,6 +124,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html setPosition(popped.name.length); } } + + function moveToLastTag(): void { + appendTag(); + } @@ -132,6 +153,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html joinWithPreviousTag(index, detail.setPosition)} on:tagjoinnext={({ detail }) => joinWithNextTag(index, detail.setPosition)} + on:tagmoveprevious={() => moveToPreviousTag(index)} + on:tagmovenext={() => moveToNextTag(index)} /> {/each} @@ -144,6 +167,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html on:tagadd={appendTag} on:tagjoinprevious={({ detail }) => joinWithLastTag(detail.setPosition)} + on:tagmoveprevious={moveToLastTag} /> diff --git a/ts/editor/TagInput.svelte b/ts/editor/TagInput.svelte index c28d476fb..00df08c7e 100644 --- a/ts/editor/TagInput.svelte +++ b/ts/editor/TagInput.svelte @@ -11,6 +11,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const dispatch = createEventDispatcher(); + function caretAtStart(): boolean { + return input.selectionStart === 0 && input.selectionEnd === 0; + } + + function caretAtEnd(): boolean { + return ( + input.selectionStart === input.value.length && + input.selectionEnd === input.value.length + ); + } + function setPosition(position: number): void { setTimeout(() => input.setSelectionRange(position, position)); } @@ -21,7 +32,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } function onBackspace(event: KeyboardEvent) { - if (input.selectionStart === 0 && input.selectionEnd === 0) { + if (caretAtStart()) { dispatch("tagjoinprevious", { setPosition }); event.preventDefault(); } else if (name.endsWith("::")) { @@ -31,10 +42,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } function onDelete(event: KeyboardEvent) { - if ( - input.selectionStart === input.value.length && - input.selectionEnd === input.value.length - ) { + if (caretAtEnd()) { dispatch("tagjoinnext", { setPosition }); event.preventDefault(); } else if (name.endsWith("::")) { @@ -47,6 +55,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html if (event.code === "Space") { name += "::"; event.preventDefault(); + } else if (event.code === "ArrowLeft" && caretAtStart()) { + dispatch("tagmoveprevious"); + event.preventDefault(); + } else if (event.code === "ArrowRight" && caretAtEnd()) { + dispatch("tagmovenext"); + event.preventDefault(); } else if (event.code === "Backspace") { onBackspace(event); } else if (event.code === "Delete") {