diff --git a/ts/editable/Mathjax.svelte b/ts/editable/Mathjax.svelte index 80102898c..cc56a1b2c 100644 --- a/ts/editable/Mathjax.svelte +++ b/ts/editable/Mathjax.svelte @@ -41,11 +41,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html let image: HTMLImageElement; - export function moveCaretAfter(): void { + export function moveCaretAfter(position?: [number, number]): void { // This should trigger a focusing of the Mathjax Handle image.dispatchEvent( new CustomEvent("movecaretafter", { - detail: image, + detail: { image, position }, bubbles: true, composed: true, }), diff --git a/ts/editable/mathjax-element.ts b/ts/editable/mathjax-element.ts index 1cfbcfdba..f2b24e335 100644 --- a/ts/editable/mathjax-element.ts +++ b/ts/editable/mathjax-element.ts @@ -121,7 +121,15 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax }); if (this.hasAttribute("focusonmount")) { - this.component.moveCaretAfter(); + let position: [number, number] | undefined = undefined; + + if (this.getAttribute("focusonmount")!.length > 0) { + position = this.getAttribute("focusonmount")! + .split(",") + .map(Number) as [number, number]; + } + + this.component.moveCaretAfter(position); } this.setAttribute("contentEditable", "false"); diff --git a/ts/editor/code-mirror.ts b/ts/editor/code-mirror.ts index 91f137ba7..f9dbb9d3e 100644 --- a/ts/editor/code-mirror.ts +++ b/ts/editor/code-mirror.ts @@ -52,9 +52,12 @@ export const gutterOptions: CodeMirror.EditorConfiguration = { foldGutter: true, }; -export function focusAndCaretAfter(editor: CodeMirror.Editor): void { +export function focusAndSetCaret( + editor: CodeMirror.Editor, + position: CodeMirror.Position = { line: editor.lineCount(), ch: 0 }, +): void { editor.focus(); - editor.setCursor(editor.lineCount(), 0); + editor.setCursor(position); } interface OpenCodeMirrorOptions { diff --git a/ts/editor/editor-toolbar/LatexButton.svelte b/ts/editor/editor-toolbar/LatexButton.svelte index a4c831388..ffd535dc1 100644 --- a/ts/editor/editor-toolbar/LatexButton.svelte +++ b/ts/editor/editor-toolbar/LatexButton.svelte @@ -35,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } function onMathjaxChemistry(): void { - surround("\\ce{", "}"); + surround('\\ce{', "}"); } function onLatex(): void { diff --git a/ts/editor/mathjax-overlay/MathjaxEditor.svelte b/ts/editor/mathjax-overlay/MathjaxEditor.svelte index b1657f449..dfd74f6a4 100644 --- a/ts/editor/mathjax-overlay/MathjaxEditor.svelte +++ b/ts/editor/mathjax-overlay/MathjaxEditor.svelte @@ -10,7 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import * as tr from "../../lib/ftl"; import { noop } from "../../lib/functional"; import { getPlatformString } from "../../lib/shortcuts"; - import { baseOptions, focusAndCaretAfter, latex } from "../code-mirror"; + import { baseOptions, focusAndSetCaret, latex } from "../code-mirror"; import type { CodeMirrorAPI } from "../CodeMirror.svelte"; import CodeMirror from "../CodeMirror.svelte"; @@ -33,58 +33,60 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html mode: latex, }; + /* These are not reactive, but only operate on initialization */ + export let position: CodeMirrorLib.Position | undefined = undefined; export let selectAll: boolean; const dispatch = createEventDispatcher(); let codeMirror = {} as CodeMirrorAPI; - onMount(() => - codeMirror.editor.then((editor) => { - focusAndCaretAfter(editor); + onMount(async () => { + const editor = await codeMirror.editor; - if (selectAll) { - editor.execCommand("selectAll"); - } + focusAndSetCaret(editor, position); - let direction: "start" | "end" | undefined = undefined; + if (selectAll) { + editor.execCommand("selectAll"); + } - editor.on( - "keydown", - (_instance: CodeMirrorLib.Editor, event: KeyboardEvent): void => { - if (event.key === "ArrowLeft") { - direction = "start"; - } else if (event.key === "ArrowRight") { - direction = "end"; - } - }, - ); + let direction: "start" | "end" | undefined = undefined; - editor.on( - "beforeSelectionChange", - ( - instance: CodeMirrorLib.Editor, - obj: CodeMirrorLib.EditorSelectionChange, - ): void => { - const { anchor } = obj.ranges[0]; + editor.on( + "keydown", + (_instance: CodeMirrorLib.Editor, event: KeyboardEvent): void => { + if (event.key === "ArrowLeft") { + direction = "start"; + } else if (event.key === "ArrowRight") { + direction = "end"; + } + }, + ); - if (anchor["hitSide"]) { - if (instance.getValue().length === 0) { - if (direction) { - dispatch(`moveout${direction}`); - } - } else if (anchor.line === 0 && anchor.ch === 0) { - dispatch("moveoutstart"); - } else { - dispatch("moveoutend"); + editor.on( + "beforeSelectionChange", + ( + instance: CodeMirrorLib.Editor, + obj: CodeMirrorLib.EditorSelectionChange, + ): void => { + const { anchor } = obj.ranges[0]; + + if (anchor["hitSide"]) { + if (instance.getValue().length === 0) { + if (direction) { + dispatch(`moveout${direction}`); } + } else if (anchor.line === 0 && anchor.ch === 0) { + dispatch("moveoutstart"); + } else { + dispatch("moveoutend"); } + } - direction = undefined; - }, - ); - }), - ); + direction = undefined; + }, + ); + }); /** * Escape characters which are technically legal in Mathjax, but confuse HTML. diff --git a/ts/editor/mathjax-overlay/MathjaxHandle.svelte b/ts/editor/mathjax-overlay/MathjaxHandle.svelte index a81da07be..6f13d384d 100644 --- a/ts/editor/mathjax-overlay/MathjaxHandle.svelte +++ b/ts/editor/mathjax-overlay/MathjaxHandle.svelte @@ -3,6 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -->