mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Fix field not restored if active (#1639)
* Fix field not being restored after Undo, if field also has focus * Execute moveCaretToEnd after undoing a change - Otherwise the caret might be placed in seemingly random positions * Fix wording of comments * Remove autofocus functionality of EditingArea - instead await a tick in focusField - We used the autofocus prop for the initial focus setting when opening the editor. However it seems that awaiting tick in focusField also does the trick.
This commit is contained in:
parent
c5280cd056
commit
0c81bbce04
5 changed files with 30 additions and 26 deletions
|
@ -9,10 +9,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
export interface EditingInputAPI {
|
export interface EditingInputAPI {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
focus(): void;
|
|
||||||
refocus(): void;
|
|
||||||
focusable: boolean;
|
focusable: boolean;
|
||||||
moveCaretToEnd(): void;
|
/**
|
||||||
|
* The reaction to a user-initiated focus, e.g. by clicking on the
|
||||||
|
* editor label, or pressing Tab.
|
||||||
|
*/
|
||||||
|
focus(): void;
|
||||||
|
/**
|
||||||
|
* Behaves similar to a refresh, e.g. sync with content, put the caret
|
||||||
|
* into a neutral position, and/or clear selections.
|
||||||
|
*/
|
||||||
|
refocus(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditingAreaAPI {
|
export interface EditingAreaAPI {
|
||||||
|
@ -29,7 +36,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, setContext as svelteSetContext } from "svelte";
|
import { setContext as svelteSetContext } from "svelte";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
import { fontFamilyKey, fontSizeKey } from "../lib/context-keys";
|
import { fontFamilyKey, fontSizeKey } from "../lib/context-keys";
|
||||||
|
@ -46,7 +53,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
svelteSetContext(fontSizeKey, fontSizeStore);
|
svelteSetContext(fontSizeKey, fontSizeStore);
|
||||||
|
|
||||||
export let content: Writable<string>;
|
export let content: Writable<string>;
|
||||||
export let autofocus = false;
|
|
||||||
|
|
||||||
let editingArea: HTMLElement;
|
let editingArea: HTMLElement;
|
||||||
let focusTrap: FocusTrap;
|
let focusTrap: FocusTrap;
|
||||||
|
@ -130,12 +136,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
});
|
});
|
||||||
|
|
||||||
setContextProperty(api);
|
setContextProperty(api);
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (autofocus) {
|
|
||||||
focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FocusTrap bind:this={focusTrap} on:focus={focusEditingInputInsteadIfAvailable} />
|
<FocusTrap bind:this={focusTrap} on:focus={focusEditingInputInsteadIfAvailable} />
|
||||||
|
|
|
@ -44,7 +44,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
export let content: Writable<string>;
|
export let content: Writable<string>;
|
||||||
export let field: FieldData;
|
export let field: FieldData;
|
||||||
export let autofocus = false;
|
|
||||||
|
|
||||||
const directionStore = writable<"ltr" | "rtl">();
|
const directionStore = writable<"ltr" | "rtl">();
|
||||||
setContext(directionKey, directionStore);
|
setContext(directionKey, directionStore);
|
||||||
|
@ -88,7 +87,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</LabelContainer>
|
</LabelContainer>
|
||||||
<EditingArea
|
<EditingArea
|
||||||
{content}
|
{content}
|
||||||
{autofocus}
|
|
||||||
fontFamily={field.fontFamily}
|
fontFamily={field.fontFamily}
|
||||||
fontSize={field.fontSize}
|
fontSize={field.fontSize}
|
||||||
api={editingArea}
|
api={editingArea}
|
||||||
|
|
|
@ -34,7 +34,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount, tick } from "svelte";
|
||||||
import { get, writable } from "svelte/store";
|
import { get, writable } from "svelte/store";
|
||||||
|
|
||||||
import Absolute from "../components/Absolute.svelte";
|
import Absolute from "../components/Absolute.svelte";
|
||||||
|
@ -125,12 +125,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
plainTextsHidden = fonts.map((_, index) => plainTextsHidden[index] ?? true);
|
plainTextsHidden = fonts.map((_, index) => plainTextsHidden[index] ?? true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let focusTo: number = 0;
|
export function focusField(index: number | null): void {
|
||||||
export function focusField(n: number): void {
|
tick().then(() => {
|
||||||
if (typeof n === "number") {
|
if (typeof index === "number") {
|
||||||
focusTo = n;
|
if (!(index in fields)) {
|
||||||
fields[focusTo].editingArea?.refocus();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fields[index].editingArea?.refocus();
|
||||||
|
} else {
|
||||||
|
$focusedInput?.refocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let textColor: string = "black";
|
let textColor: string = "black";
|
||||||
|
@ -298,7 +304,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
<EditorField
|
<EditorField
|
||||||
{field}
|
{field}
|
||||||
content={fieldStores[index]}
|
content={fieldStores[index]}
|
||||||
autofocus={index === focusTo}
|
|
||||||
api={fields[index]}
|
api={fields[index]}
|
||||||
on:focusin={() => {
|
on:focusin={() => {
|
||||||
$focusedField = fields[index];
|
$focusedField = fields[index];
|
||||||
|
|
|
@ -83,13 +83,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
codeMirror?.editor.focus();
|
codeMirror?.editor.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function moveCaretToEnd(): void {
|
||||||
|
codeMirror?.editor.setCursor(codeMirror.editor.lineCount(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
function refocus(): void {
|
function refocus(): void {
|
||||||
(codeMirror?.editor as any).display.input.blur();
|
(codeMirror?.editor as any).display.input.blur();
|
||||||
focus();
|
focus();
|
||||||
}
|
moveCaretToEnd();
|
||||||
|
|
||||||
function moveCaretToEnd(): void {
|
|
||||||
codeMirror?.editor.setCursor(codeMirror.editor.lineCount(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle(): boolean {
|
function toggle(): boolean {
|
||||||
|
|
|
@ -19,7 +19,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
shadowRoot: Promise<ShadowRoot>;
|
shadowRoot: Promise<ShadowRoot>;
|
||||||
element: Promise<HTMLElement>;
|
element: Promise<HTMLElement>;
|
||||||
moveCaretToEnd(): void;
|
moveCaretToEnd(): void;
|
||||||
refocus(): void;
|
|
||||||
toggle(): boolean;
|
toggle(): boolean;
|
||||||
preventResubscription(): () => void;
|
preventResubscription(): () => void;
|
||||||
getTriggerOnNextInsert(): Trigger<OnInsertCallback>;
|
getTriggerOnNextInsert(): Trigger<OnInsertCallback>;
|
||||||
|
@ -196,6 +195,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
richTextPromise.then((richText) => {
|
richTextPromise.then((richText) => {
|
||||||
richText.blur();
|
richText.blur();
|
||||||
richText.focus();
|
richText.focus();
|
||||||
|
moveCaretToEnd();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
focusable: !hidden,
|
focusable: !hidden,
|
||||||
|
|
Loading…
Reference in a new issue