Remove logic for pulling editor field in view

This commit is contained in:
Henrik Giesel 2021-02-23 12:55:04 +01:00
parent 69448365c4
commit 5bb90aa8a5
3 changed files with 17 additions and 64 deletions

View File

@ -1,31 +1,12 @@
/* Copyright: Ankitects Pty Ltd and contributors /* Copyright: Ankitects Pty Ltd and contributors
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
import type { EditingArea, EditorField } from "."; import type { EditingArea } from ".";
import { bridgeCommand } from "./lib"; import { bridgeCommand } from "./lib";
import { enableButtons, disableButtons } from "./toolbar"; import { enableButtons, disableButtons } from "./toolbar";
import { saveField } from "./changeTimer"; import { saveField } from "./changeTimer";
enum ViewportRelativePosition {
Contained,
ExceedTop,
ExceedBottom,
}
function isFieldInViewport(
element: Element,
toolbarHeight: number
): ViewportRelativePosition {
const rect = element.getBoundingClientRect();
return rect.top <= toolbarHeight
? ViewportRelativePosition.ExceedTop
: rect.bottom >= (window.innerHeight || document.documentElement.clientHeight)
? ViewportRelativePosition.ExceedBottom
: ViewportRelativePosition.Contained;
}
function caretToEnd(currentField: EditingArea): void { function caretToEnd(currentField: EditingArea): void {
const range = document.createRange(); const range = document.createRange();
range.selectNodeContents(currentField.editable); range.selectNodeContents(currentField.editable);
@ -35,45 +16,30 @@ function caretToEnd(currentField: EditingArea): void {
selection.addRange(range); selection.addRange(range);
} }
function focusField(field: EditingArea) {
field.focusEditable();
bridgeCommand(`focus:${field.ord}`);
enableButtons();
caretToEnd(field);
}
// For distinguishing focus by refocusing window from deliberate focus // For distinguishing focus by refocusing window from deliberate focus
let previousActiveElement: EditingArea | null = null; let previousActiveElement: EditingArea | null = null;
export function onFocus(evt: FocusEvent): void { export function onFocus(evt: FocusEvent): void {
const currentField = evt.currentTarget as EditingArea; const currentField = evt.currentTarget as EditingArea;
const previousFocus = evt.relatedTarget as EditingArea;
if (currentField === previousActiveElement) { if (previousFocus === previousActiveElement || !previousFocus) {
return; focusField(currentField)
} }
const editorField = currentField.parentElement! as EditorField;
const toolbarHeight = document.getElementById("topbutsOuter")!.clientHeight;
switch (isFieldInViewport(editorField, toolbarHeight)) {
case ViewportRelativePosition.ExceedBottom:
editorField.scrollIntoView(false);
break;
case ViewportRelativePosition.ExceedTop:
editorField.scrollIntoView(true);
window.scrollBy(0, -toolbarHeight);
break;
}
currentField.focusEditable();
bridgeCommand(`focus:${currentField.ord}`);
enableButtons();
// do this twice so that there's no flicker on newer versions
caretToEnd(currentField);
} }
export function onBlur(evt: FocusEvent): void { export function onBlur(evt: FocusEvent): void {
const currentField = evt.currentTarget as EditingArea; const previousFocus = evt.currentTarget as EditingArea;
if (currentField === document.activeElement) { saveField(previousFocus, previousFocus === document.activeElement ? "key" : "blur");
// other widget or window focused; current field unchanged // other widget or window focused; current field unchanged
saveField(currentField, "key"); previousActiveElement = previousFocus;
previousActiveElement = currentField; disableButtons();
} else {
saveField(currentField, "blur");
disableButtons();
previousActiveElement = null;
}
} }

View File

@ -5,7 +5,7 @@ import { nodeIsInline } from "./helpers";
import { bridgeCommand } from "./lib"; import { bridgeCommand } from "./lib";
import { saveField } from "./changeTimer"; import { saveField } from "./changeTimer";
import { filterHTML } from "./htmlFilter"; import { filterHTML } from "./htmlFilter";
import { updateButtonState, maybeDisableButtons } from "./toolbar"; import { updateButtonState } from "./toolbar";
import { onInput, onKey, onKeyUp } from "./inputHandlers"; import { onInput, onKey, onKeyUp } from "./inputHandlers";
import { onFocus, onBlur } from "./focusHandlers"; import { onFocus, onBlur } from "./focusHandlers";
@ -298,8 +298,6 @@ export function setFields(fields: [string, string][]): void {
forEditorField(fields, (field, [name, fieldContent]) => forEditorField(fields, (field, [name, fieldContent]) =>
field.initialize(name, color, fieldContent) field.initialize(name, color, fieldContent)
); );
maybeDisableButtons();
} }
export function setBackgrounds(cols: ("dupe" | "")[]) { export function setBackgrounds(cols: ("dupe" | "")[]) {

View File

@ -1,8 +1,6 @@
/* Copyright: Ankitects Pty Ltd and contributors /* Copyright: Ankitects Pty Ltd and contributors
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
import { EditingArea } from ".";
export function updateButtonState(): void { export function updateButtonState(): void {
const buts = ["bold", "italic", "underline", "superscript", "subscript"]; const buts = ["bold", "italic", "underline", "superscript", "subscript"];
for (const name of buts) { for (const name of buts) {
@ -30,15 +28,6 @@ export function enableButtons(): void {
$("button.linkb").prop("disabled", false); $("button.linkb").prop("disabled", false);
} }
// disable the buttons if a field is not currently focused
export function maybeDisableButtons(): void {
if (document.activeElement instanceof EditingArea) {
enableButtons();
} else {
disableButtons();
}
}
export function setFGButton(col: string): void { export function setFGButton(col: string): void {
document.getElementById("forecolor")!.style.backgroundColor = col; document.getElementById("forecolor")!.style.backgroundColor = col;
} }