mirror of
https://github.com/ankitects/anki.git
synced 2025-11-10 14:47:12 -05:00
Move caretToEnd logic out of focus handling
This commit is contained in:
parent
6db7897601
commit
972993b42e
5 changed files with 36 additions and 45 deletions
|
|
@ -6,16 +6,12 @@ import type { EditingArea } from ".";
|
|||
import { getCurrentField } from ".";
|
||||
import { bridgeCommand } from "./lib";
|
||||
import { getNoteId } from "./noteId";
|
||||
import { updateButtonState } from "./toolbar";
|
||||
|
||||
let changeTimer: number | null = null;
|
||||
|
||||
export function triggerChangeTimer(currentField: EditingArea): void {
|
||||
clearChangeTimer();
|
||||
changeTimer = setTimeout(function () {
|
||||
updateButtonState();
|
||||
saveField(currentField, "key");
|
||||
}, 600);
|
||||
changeTimer = setTimeout(() => saveField(currentField, "key"), 600);
|
||||
}
|
||||
|
||||
function clearChangeTimer(): void {
|
||||
|
|
|
|||
|
|
@ -1,55 +1,23 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
import { EditingArea } from ".";
|
||||
import type { EditingArea } from ".";
|
||||
|
||||
import { bridgeCommand } from "./lib";
|
||||
import { enableButtons, disableButtons } from "./toolbar";
|
||||
import { saveField } from "./changeTimer";
|
||||
|
||||
function caretToEnd(currentField: EditingArea): void {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(currentField.editable);
|
||||
range.collapse(false);
|
||||
const selection = currentField.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
function focusField(field: EditingArea, moveCaretToEnd: boolean): void {
|
||||
field.focusEditable();
|
||||
bridgeCommand(`focus:${field.ord}`);
|
||||
|
||||
if (moveCaretToEnd) {
|
||||
caretToEnd(field);
|
||||
}
|
||||
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
// For distinguishing focus by refocusing window from deliberate focus
|
||||
let previousActiveElement: EditingArea | null = null;
|
||||
|
||||
export function onFocus(evt: FocusEvent): void {
|
||||
const currentField = evt.currentTarget as EditingArea;
|
||||
const previousFocus = evt.relatedTarget as EditingArea;
|
||||
|
||||
if (
|
||||
!(previousFocus instanceof EditingArea) ||
|
||||
previousFocus === previousActiveElement
|
||||
) {
|
||||
const moveCaretToEnd =
|
||||
Boolean(previousFocus) || !Boolean(previousActiveElement);
|
||||
|
||||
focusField(currentField, moveCaretToEnd);
|
||||
}
|
||||
currentField.focusEditable();
|
||||
bridgeCommand(`focus:${currentField.ord}`);
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
export function onBlur(evt: FocusEvent): void {
|
||||
const previousFocus = evt.currentTarget as EditingArea;
|
||||
const currentFieldUnchanged = previousFocus === document.activeElement;
|
||||
|
||||
saveField(previousFocus, previousFocus === document.activeElement ? "key" : "blur");
|
||||
// other widget or window focused; current field unchanged
|
||||
previousActiveElement = previousFocus;
|
||||
saveField(previousFocus, currentFieldUnchanged ? "key" : "blur");
|
||||
disableButtons();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
import type { EditingArea } from ".";
|
||||
|
||||
export function nodeIsElement(node: Node): node is Element {
|
||||
return node.nodeType === Node.ELEMENT_NODE;
|
||||
}
|
||||
|
|
@ -66,3 +68,12 @@ const INLINE_TAGS = [
|
|||
export function nodeIsInline(node: Node): boolean {
|
||||
return !nodeIsElement(node) || INLINE_TAGS.includes(node.tagName);
|
||||
}
|
||||
|
||||
export function caretToEnd(currentField: EditingArea): void {
|
||||
const range = document.createRange();
|
||||
range.selectNodeContents(currentField.editable);
|
||||
range.collapse(false);
|
||||
const selection = currentField.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Copyright: Ankitects Pty Ltd and contributors
|
||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
import { nodeIsInline } from "./helpers";
|
||||
import { nodeIsInline, caretToEnd } from "./helpers";
|
||||
import { bridgeCommand } from "./lib";
|
||||
import { saveField } from "./changeTimer";
|
||||
import { filterHTML } from "./htmlFilter";
|
||||
|
|
@ -34,6 +34,8 @@ export function focusField(n: number): void {
|
|||
|
||||
if (field) {
|
||||
field.editingArea.focusEditable();
|
||||
caretToEnd(field.editingArea);
|
||||
updateButtonState();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||
|
||||
import { EditingArea } from ".";
|
||||
import { nodeIsElement } from "./helpers";
|
||||
import { caretToEnd, nodeIsElement } from "./helpers";
|
||||
import { triggerChangeTimer } from "./changeTimer";
|
||||
import { updateButtonState } from "./toolbar";
|
||||
|
||||
function inListItem(currentField: EditingArea): boolean {
|
||||
const anchor = currentField.getSelection()!.anchorNode!;
|
||||
|
|
@ -21,6 +22,7 @@ function inListItem(currentField: EditingArea): boolean {
|
|||
export function onInput(event: Event): void {
|
||||
// make sure IME changes get saved
|
||||
triggerChangeTimer(event.currentTarget as EditingArea);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
export function onKey(evt: KeyboardEvent): void {
|
||||
|
|
@ -59,6 +61,18 @@ export function onKey(evt: KeyboardEvent): void {
|
|||
triggerChangeTimer(currentField);
|
||||
}
|
||||
|
||||
globalThis.addEventListener("keydown", (evt: KeyboardEvent) => {
|
||||
if (evt.code === "Tab") {
|
||||
globalThis.addEventListener("focusin", (evt: FocusEvent) => {
|
||||
const newFocusTarget = evt.target;
|
||||
if (newFocusTarget instanceof EditingArea) {
|
||||
caretToEnd(newFocusTarget);
|
||||
updateButtonState();
|
||||
}
|
||||
}, { once: true })
|
||||
}
|
||||
})
|
||||
|
||||
export function onKeyUp(evt: KeyboardEvent): void {
|
||||
const currentField = evt.currentTarget as EditingArea;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue