Implement cloze buttons in Mathjax editor (#1860)
* Introduce RichTextClozeButtons * Implement cloze buttons in Mathjax editor
This commit is contained in:
parent
52438fe4c9
commit
b6fb64fde1
@ -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);
|
@ -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>
|
||||
|
23
ts/editor/editor-toolbar/RichTextClozeButtons.svelte
Normal file
23
ts/editor/editor-toolbar/RichTextClozeButtons.svelte
Normal 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} />
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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()}
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user