diff --git a/ts/editor/NoteEditor.svelte b/ts/editor/NoteEditor.svelte index 7d20850ee..212b55f8b 100644 --- a/ts/editor/NoteEditor.svelte +++ b/ts/editor/NoteEditor.svelte @@ -317,6 +317,41 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html let plainTextInputs: PlainTextInput[] = []; $: plainTextInputs = plainTextInputs.filter(Boolean); + function toggleRichTextInput(index: number): void { + const hidden = !richTextsHidden[index]; + richTextInputs[index].focusFlag.setFlag(!hidden); + richTextsHidden[index] = hidden; + if (hidden) { + plainTextInputs[index].api.refocus(); + } + } + + function togglePlainTextInput(index: number): void { + const hidden = !plainTextsHidden[index]; + plainTextInputs[index].focusFlag.setFlag(!hidden); + plainTextsHidden[index] = hidden; + if (hidden) { + richTextInputs[index].api.refocus(); + } + } + + function toggleField(index: number): void { + const collapsed = !fieldsCollapsed[index]; + fieldsCollapsed[index] = collapsed; + + const defaultInput = !plainTextDefaults[index] + ? richTextInputs[index] + : plainTextInputs[index]; + + if (!collapsed) { + defaultInput.api.refocus(); + } else if (!plainTextDefaults[index]) { + plainTextsHidden[index] = true; + } else { + richTextsHidden[index] = true; + } + } + const toolbar: Partial = {}; function setShrinkImages(shrinkByDefault: boolean) { @@ -332,7 +367,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { mathjaxConfig } from "../editable/mathjax-element"; import CollapseLabel from "./CollapseLabel.svelte"; - import { refocusInput } from "./helpers"; import * as oldEditorAdapter from "./old-editor-adapter"; onMount(() => { @@ -457,21 +491,7 @@ the AddCards dialog) should be implemented in the user of this component. { - fieldsCollapsed[index] = !fieldsCollapsed[index]; - - const defaultInput = !plainTextDefaults[index] - ? richTextInputs[index] - : plainTextInputs[index]; - - if (!fieldsCollapsed[index]) { - refocusInput(defaultInput.api); - } else if (!plainTextDefaults[index]) { - plainTextsHidden[index] = true; - } else { - richTextsHidden[index] = true; - } - }} + on:toggle={() => toggleField(index)} --icon-align="bottom" > @@ -489,14 +509,7 @@ the AddCards dialog) should be implemented in the user of this component. (fields[index] === $hoveredField || fields[index] === $focusedField)} bind:off={richTextsHidden[index]} - on:toggle={async () => { - richTextsHidden[index] = - !richTextsHidden[index]; - - if (!richTextsHidden[index]) { - refocusInput(richTextInputs[index].api); - } - }} + on:toggle={() => toggleRichTextInput(index)} /> {:else} { - plainTextsHidden[index] = - !plainTextsHidden[index]; - - if (!plainTextsHidden[index]) { - refocusInput(plainTextInputs[index].api); - } - }} + on:toggle={() => togglePlainTextInput(index)} /> {/if} { - do { - await new Promise(window.requestAnimationFrame); - } while (!api.focusable); - api.refocus(); +export class Flag { + private flag: boolean; + + constructor() { + this.flag = false; + } + + setFlag(on: boolean): void { + this.flag = on; + } + + /** Resets the flag to false and returns the previous value. */ + checkAndReset(): boolean { + const val = this.flag; + this.flag = false; + return val; + } } diff --git a/ts/editor/plain-text-input/PlainTextInput.svelte b/ts/editor/plain-text-input/PlainTextInput.svelte index 63336c8f9..f0ea47515 100644 --- a/ts/editor/plain-text-input/PlainTextInput.svelte +++ b/ts/editor/plain-text-input/PlainTextInput.svelte @@ -37,11 +37,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { baseOptions, gutterOptions, htmlanki } from "../code-mirror"; import CodeMirror from "../CodeMirror.svelte"; import { context as editingAreaContext } from "../EditingArea.svelte"; + import { Flag } from "../helpers"; import { context as noteEditorContext } from "../NoteEditor.svelte"; import removeProhibitedTags from "./remove-prohibited"; import { storedToUndecorated, undecoratedToStored } from "./transform"; export let hidden = false; + export const focusFlag = new Flag(); $: configuration = { mode: htmlanki, @@ -115,7 +117,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html $: { pushUpdate(!hidden); - tick().then(refresh); + tick().then(() => { + refresh(); + if (focusFlag.checkAndReset()) { + refocus(); + } + }); } function onChange({ detail: html }: CustomEvent): void { diff --git a/ts/editor/rich-text-input/RichTextInput.svelte b/ts/editor/rich-text-input/RichTextInput.svelte index 66c121828..60d3e90c5 100644 --- a/ts/editor/rich-text-input/RichTextInput.svelte +++ b/ts/editor/rich-text-input/RichTextInput.svelte @@ -64,7 +64,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { directionKey, fontFamilyKey, fontSizeKey } from "@tslib/context-keys"; import { promiseWithResolver } from "@tslib/promise"; import { singleCallback } from "@tslib/typing"; - import { getAllContexts, getContext, onMount } from "svelte"; + import { getAllContexts, getContext, onMount, tick } from "svelte"; import type { Readable } from "svelte/store"; import { placeCaretAfterContent } from "../../domlib/place-caret"; @@ -73,6 +73,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import useInputHandler from "../../sveltelib/input-handler"; import { pageTheme } from "../../sveltelib/theme"; import { context as editingAreaContext } from "../EditingArea.svelte"; + import { Flag } from "../helpers"; import { context as noteEditorContext } from "../NoteEditor.svelte"; import getNormalizingNodeStore from "./normalizing-node-store"; import useRichTextResolve from "./rich-text-resolve"; @@ -80,6 +81,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { fragmentToStored, storedToFragment } from "./transform"; export let hidden = false; + export const focusFlag = new Flag(); const { focusedInput } = noteEditorContext.get(); const { content, editingInputs } = editingAreaContext.get(); @@ -192,7 +194,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html $apiStore = null; } - $: pushUpdate(!hidden); + $: { + pushUpdate(!hidden); + if (focusFlag.checkAndReset()) { + tick().then(refocus); + } + } onMount(() => { $editingInputs.push(api);