934a9bd24b
This is to provide minimal closures for the mutable file-local variables: - changeTimer - previousActiveElement - currentNoteId This makes it clear, that they should not be used, but rather the functions which wrap them in an API
61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import type { EditingArea } from ".";
|
|
|
|
import { bridgeCommand } from "./lib";
|
|
import { enableButtons, disableButtons } from "./toolbar";
|
|
import { saveField } from "./changeTimer";
|
|
|
|
function isElementInViewport(element: Element): boolean {
|
|
const rect = element.getBoundingClientRect();
|
|
|
|
return (
|
|
rect.top >= 0 &&
|
|
rect.left >= 0 &&
|
|
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
|
);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// 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;
|
|
|
|
if (currentField === previousActiveElement) {
|
|
return;
|
|
}
|
|
|
|
currentField.focusEditable();
|
|
bridgeCommand(`focus:${currentField.ord}`);
|
|
enableButtons();
|
|
// do this twice so that there's no flicker on newer versions
|
|
caretToEnd(currentField);
|
|
// scroll if bottom of element off the screen
|
|
if (!isElementInViewport(currentField)) {
|
|
currentField.scrollIntoView(false /* alignToBottom */);
|
|
}
|
|
}
|
|
|
|
export function onBlur(evt: FocusEvent): void {
|
|
const currentField = evt.currentTarget as EditingArea;
|
|
|
|
if (currentField === previousActiveElement) {
|
|
// other widget or window focused; current field unchanged
|
|
saveField(currentField, "key");
|
|
previousActiveElement = currentField;
|
|
} else {
|
|
saveField(currentField, "blur");
|
|
disableButtons();
|
|
previousActiveElement = null;
|
|
}
|
|
}
|