Implement cloze buttons in Mathjax editor (#1860)

* Introduce RichTextClozeButtons

* Implement cloze buttons in Mathjax editor
This commit is contained in:
Henrik Giesel 2022-05-13 05:04:20 +02:00 committed by GitHub
parent 52438fe4c9
commit b6fb64fde1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 34 deletions

View File

@ -3,19 +3,18 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { createEventDispatcher } from "svelte";
import { get } from "svelte/store";
import ButtonGroup from "../../components/ButtonGroup.svelte";
import IconButton from "../../components/IconButton.svelte";
import Shortcut from "../../components/Shortcut.svelte";
import * as tr from "../../lib/ftl";
import { isApplePlatform } from "../../lib/platform";
import { getPlatformString } from "../../lib/shortcuts";
import { wrapInternal } from "../../lib/wrap";
import { context as noteEditorContext } from "../NoteEditor.svelte";
import type { RichTextInputAPI } from "../rich-text-input";
import { editingInputIsRichText } from "../rich-text-input";
import ButtonGroup from "../components/ButtonGroup.svelte";
import IconButton from "../components/IconButton.svelte";
import Shortcut from "../components/Shortcut.svelte";
import * as tr from "../lib/ftl";
import { isApplePlatform } from "../lib/platform";
import { getPlatformString } from "../lib/shortcuts";
import { clozeIcon, incrementClozeIcon } from "./icons";
import { context as noteEditorContext } from "./NoteEditor.svelte";
import { editingInputIsRichText } from "./rich-text-input";
const { focusedInput, fields } = noteEditorContext.get();
@ -48,20 +47,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return Math.max(1, highest);
}
$: richTextAPI = $focusedInput as RichTextInputAPI;
const dispatch = createEventDispatcher();
async function onIncrementCloze(): Promise<void> {
const richText = await richTextAPI.element;
const highestCloze = getCurrentHighestCloze(true);
wrapInternal(richText, `{{c${highestCloze}::`, "}}", false);
dispatch("surround", {
prefix: `{{c${highestCloze}::`,
suffix: "}}",
});
}
async function onSameCloze(): Promise<void> {
const richText = await richTextAPI.element;
const highestCloze = getCurrentHighestCloze(false);
wrapInternal(richText, `{{c${highestCloze}::`, "}}", false);
dispatch("surround", {
prefix: `{{c${highestCloze}::`,
suffix: "}}",
});
}
$: disabled = !editingInputIsRichText($focusedInput);

View File

@ -56,9 +56,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Item from "../../components/Item.svelte";
import StickyContainer from "../../components/StickyContainer.svelte";
import BlockButtons from "./BlockButtons.svelte";
import ClozeButtons from "./ClozeButtons.svelte";
import InlineButtons from "./InlineButtons.svelte";
import NotetypeButtons from "./NotetypeButtons.svelte";
import RichTextClozeButtons from "./RichTextClozeButtons.svelte";
import TemplateButtons from "./TemplateButtons.svelte";
export let size: number;
@ -108,7 +108,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</Item>
<Item id="cloze">
<ClozeButtons />
<RichTextClozeButtons />
</Item>
</DynamicallySlottable>
</ButtonToolbar>

View File

@ -0,0 +1,23 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="ts">
import { wrapInternal } from "../../lib/wrap";
import ClozeButtons from "../ClozeButtons.svelte";
import { context as noteEditorContext } from "../NoteEditor.svelte";
import type { RichTextInputAPI } from "../rich-text-input";
const { focusedInput } = noteEditorContext.get();
$: richTextAPI = $focusedInput as RichTextInputAPI;
async function onSurround({ detail }): Promise<void> {
const richText = await richTextAPI.element;
const { prefix, suffix } = detail;
wrapInternal(richText, prefix, suffix, false);
}
</script>
<ClozeButtons on:surround={onSurround} />

View File

@ -24,8 +24,6 @@ export { default as underlineIcon } from "bootstrap-icons/icons/type-underline.s
export const arrowIcon =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="transparent" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2 5l6 6 6-6"/></svg>';
export { default as incrementClozeIcon } from "../../icons/contain-plus.svg";
export { default as clozeIcon } from "@mdi/svg/svg/contain.svg";
export { default as functionIcon } from "@mdi/svg/svg/function-variant.svg";
export { default as paperclipIcon } from "@mdi/svg/svg/paperclip.svg";
export { default as micIcon } from "bootstrap-icons/icons/mic.svg";

View File

@ -3,3 +3,4 @@
export type { EditorToolbarAPI } from "./EditorToolbar.svelte";
export { default as EditorToolbar, editorToolbar } from "./EditorToolbar.svelte";
export { default as ClozeButtons } from "./EditorToolbar.svelte";

View File

@ -3,8 +3,10 @@
/// <reference types="../lib/image-import" />
export { default as incrementClozeIcon } from "../icons/contain-plus.svg";
export { default as alertIcon } from "@mdi/svg/svg/alert.svg";
export { default as htmlOn } from "@mdi/svg/svg/code-tags.svg";
export { default as clozeIcon } from "@mdi/svg/svg/contain.svg";
export { default as richTextOff } from "@mdi/svg/svg/eye-off-outline.svg";
export { default as richTextOn } from "@mdi/svg/svg/eye-outline.svg";
export { default as stickyOff } from "@mdi/svg/svg/pin-off-outline.svg";

View File

@ -10,6 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import IconButton from "../../components/IconButton.svelte";
import { hasBlockAttribute } from "../../lib/dom";
import * as tr from "../../lib/ftl";
import ClozeButtons from "../ClozeButtons.svelte";
import { blockIcon, deleteIcon, inlineIcon } from "./icons";
export let element: Element;
@ -48,6 +49,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
>
</ButtonGroup>
<ClozeButtons on:surround />
<ButtonGroup>
<IconButton
tooltip={tr.actionsDelete()}

View File

@ -99,6 +99,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
/>
</div>
<slot editor={codeMirror} />
<style lang="scss">
.mathjax-editor {
:global(.CodeMirror) {

View File

@ -47,21 +47,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:blur={() => dispatch("reset")}
on:moveoutstart
on:moveoutend
/>
let:editor={mathjaxEditor}
>
<Shortcut
keyCombination={acceptShortcut}
on:action={() => dispatch("moveoutend")}
/>
<Shortcut
keyCombination={acceptShortcut}
on:action={() => dispatch("moveoutend")}
/>
<MathjaxButtons
{element}
on:delete={() => {
placeCaretAfter(element);
element.remove();
dispatch("reset");
}}
on:surround={async ({ detail }) => {
const editor = await mathjaxEditor.editor;
const { prefix, suffix } = detail;
<MathjaxButtons
{element}
on:delete={() => {
placeCaretAfter(element);
element.remove();
dispatch("reset");
}}
/>
editor.replaceSelection(prefix + editor.getSelection() + suffix);
}}
/>
</MathjaxEditor>
</DropdownMenu>
</div>