diff --git a/ts/editor/codable.ts b/ts/editor/codable.ts index def1b1c08..c46c8fee0 100644 --- a/ts/editor/codable.ts +++ b/ts/editor/codable.ts @@ -21,6 +21,11 @@ const codeMirrorOptions = { const parser = new DOMParser(); +function parseHTML(html: string): string { + const doc = parser.parseFromString(html, "text/html"); + return doc.documentElement.innerHTML; +} + export class Codable extends HTMLTextAreaElement { codeMirror: CodeMirror | undefined; active: boolean; @@ -30,18 +35,29 @@ export class Codable extends HTMLTextAreaElement { this.active = false; } + set fieldHTML(content: string) { + this.value = content; + } + + get fieldHTML(): string { + return parseHTML(this.codeMirror.getValue()); + } + connectedCallback(): void { this.setAttribute("hidden", ""); } setup(html: string): void { this.active = true; - this.value = html; + this.fieldHTML = html; this.codeMirror = CodeMirror.fromTextArea(this, codeMirrorOptions); } focus(): void { this.codeMirror.focus(); + } + + caretToEnd(): void { this.codeMirror.setCursor(this.codeMirror.lineCount(), 0); } @@ -49,8 +65,6 @@ export class Codable extends HTMLTextAreaElement { this.active = false; this.codeMirror.toTextArea(); this.codeMirror = undefined; - - const doc = parser.parseFromString(this.value, "text/html"); - return doc.documentElement.innerHTML; + return parseHTML(this.value); } } diff --git a/ts/editor/editable.ts b/ts/editor/editable.ts index 680bdf35c..9161bf248 100644 --- a/ts/editor/editable.ts +++ b/ts/editor/editable.ts @@ -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"; function containsInlineContent(field: Element): boolean { if (field.childNodes.length === 0) { @@ -36,4 +36,8 @@ export class Editable extends HTMLElement { connectedCallback(): void { this.setAttribute("contenteditable", ""); } + + caretToEnd() { + caretToEnd(this); + } } diff --git a/ts/editor/editingArea.ts b/ts/editor/editingArea.ts index f03f62dfd..41ad580f5 100644 --- a/ts/editor/editingArea.ts +++ b/ts/editor/editingArea.ts @@ -10,7 +10,6 @@ import type { Codable } from "./codable"; import { updateActiveButtons } from "./toolbar"; import { bridgeCommand } from "./lib"; -import { caretToEnd } from "./helpers"; import { onInput, onKey, onKeyUp } from "./inputHandlers"; import { onFocus, onBlur } from "./focusHandlers"; @@ -51,16 +50,20 @@ export class EditingArea extends HTMLDivElement { this.shadowRoot!.appendChild(this.codable); } + get activeInput(): Editable | Codable { + return this.codable.active ? this.codable : this.editable; + } + get ord(): number { return Number(this.getAttribute("ord")); } set fieldHTML(content: string) { - this.editable.fieldHTML = content; + this.activeInput.fieldHTML = content; } get fieldHTML(): string { - return this.editable.fieldHTML; + return this.activeInput.fieldHTML; } connectedCallback(): void { @@ -119,12 +122,24 @@ export class EditingArea extends HTMLDivElement { return this.shadowRoot!.getSelection()!; } - focusEditable(): void { - this.editable.focus(); + focus(): void { + this.activeInput.focus(); } + blur(): void { + this.activeInput.blur(); + } + + /* legacy */ + focusEditable(): void { + focus(); + } blurEditable(): void { - this.editable.blur(); + blur(); + } + + caretToEnd(): void { + this.activeInput.caretToEnd(); } hasFocus(): boolean { @@ -135,21 +150,17 @@ export class EditingArea extends HTMLDivElement { const hadFocus = this.hasFocus(); if (this.codable.active) { - const html = this.codable.teardown(); - this.fieldHTML = html; - + this.fieldHTML = this.codable.teardown(); this.editable.hidden = false; - if (hadFocus) { - this.focusEditable(); - caretToEnd(this); - } } else { this.editable.hidden = true; + console.log("eyo", this.fieldHTML); this.codable.setup(this.fieldHTML); + } - if (hadFocus) { - this.codable.focus(); - } + if (hadFocus) { + this.focus(); + this.caretToEnd(); } } } diff --git a/ts/editor/helpers.ts b/ts/editor/helpers.ts index 871feb1c7..240a12611 100644 --- a/ts/editor/helpers.ts +++ b/ts/editor/helpers.ts @@ -69,11 +69,11 @@ export function nodeIsInline(node: Node): boolean { return !nodeIsElement(node) || INLINE_TAGS.includes(node.tagName); } -export function caretToEnd(currentField: EditingArea): void { +export function caretToEnd(node: Node): void { const range = document.createRange(); - range.selectNodeContents(currentField.editable); + range.selectNodeContents(node); range.collapse(false); - const selection = currentField.getSelection(); + const selection = (node.getRootNode() as Document | ShadowRoot).getSelection()!; selection.removeAllRanges(); selection.addRange(range); } diff --git a/ts/editor/index.ts b/ts/editor/index.ts index 88295b255..333b8415d 100644 --- a/ts/editor/index.ts +++ b/ts/editor/index.ts @@ -11,7 +11,6 @@ import { setupI18n, ModuleName } from "lib/i18n"; import "./fields.css"; -import { caretToEnd } from "./helpers"; import { saveField } from "./changeTimer"; import { EditorField } from "./editorField"; @@ -52,7 +51,7 @@ export function focusField(n: number): void { if (field) { field.editingArea.focusEditable(); - caretToEnd(field.editingArea); + field.editingArea.caretToEnd(); updateActiveButtons(new Event("manualfocus")); } } diff --git a/ts/editor/inputHandlers.ts b/ts/editor/inputHandlers.ts index f80011537..d717741b0 100644 --- a/ts/editor/inputHandlers.ts +++ b/ts/editor/inputHandlers.ts @@ -7,7 +7,7 @@ import { updateActiveButtons } from "./toolbar"; import { EditingArea } from "./editingArea"; -import { caretToEnd, nodeIsElement, getBlockElement } from "./helpers"; +import { nodeIsElement, getBlockElement } from "./helpers"; import { triggerChangeTimer } from "./changeTimer"; import { registerShortcut } from "lib/shortcuts"; @@ -59,7 +59,7 @@ export function onKey(evt: KeyboardEvent): void { function updateFocus(evt: FocusEvent) { const newFocusTarget = evt.target; if (newFocusTarget instanceof EditingArea) { - caretToEnd(newFocusTarget); + newFocusTarget.caretToEnd(); updateActiveButtons(evt); } }