Revert "Revert "Revert "Preserve HTML formatting inside clozes (#3038)"""

This reverts commit 9c733848b8.
This commit is contained in:
Damien Elmes 2024-05-14 20:03:58 +07:00
parent e50a768e44
commit f639c3660a
9 changed files with 21 additions and 62 deletions

@ -1 +1 @@
Subproject commit 056ff810563e7a7220aa723611abdf832ed7f437 Subproject commit c74c15b7f82c0f184910e5b6f695b635e6d81faf

@ -1 +1 @@
Subproject commit 45155310c3302cbbbe645dec52ca196894422463 Subproject commit 06ad12df7a2c8400cf64e9c7b986e9ee722e5b38

View file

@ -1246,7 +1246,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
highest += 1 highest += 1
# must start at 1 # must start at 1
highest = max(1, highest) highest = max(1, highest)
self.web.eval("wrapCloze(%d);" % highest) self.web.eval("wrap('{{c%d::', '}}');" % highest)
def setupForegroundButton(self) -> None: def setupForegroundButton(self) -> None:
self.fcolour = self.mw.pm.profile.get("lastColour", "#00f") self.fcolour = self.mw.pm.profile.get("lastColour", "#00f")

View file

@ -56,16 +56,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async function onIncrementCloze(): Promise<void> { async function onIncrementCloze(): Promise<void> {
const highestCloze = getCurrentHighestCloze(true); const highestCloze = getCurrentHighestCloze(true);
dispatch("cloze", { dispatch("surround", {
n: highestCloze, prefix: `{{c${highestCloze}::`,
suffix: "}}",
}); });
} }
async function onSameCloze(): Promise<void> { async function onSameCloze(): Promise<void> {
const highestCloze = getCurrentHighestCloze(false); const highestCloze = getCurrentHighestCloze(false);
dispatch("cloze", { dispatch("surround", {
n: highestCloze, prefix: `{{c${highestCloze}::`,
suffix: "}}",
}); });
} }

View file

@ -393,7 +393,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { ImageOcclusionFieldIndexes } from "@generated/anki/image_occlusion_pb"; import { ImageOcclusionFieldIndexes } from "@generated/anki/image_occlusion_pb";
import { getImageOcclusionFields } from "@generated/backend"; import { getImageOcclusionFields } from "@generated/backend";
import { wrapClozeInternal, wrapInternal } from "@tslib/wrap"; import { wrapInternal } from "@tslib/wrap";
import Shortcut from "$lib/components/Shortcut.svelte"; import Shortcut from "$lib/components/Shortcut.svelte";
@ -548,16 +548,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}); });
} }
function wrapCloze(n: number): void {
if (!$focusedInput || !editingInputIsRichText($focusedInput)) {
return;
}
$focusedInput.element.then((element) => {
wrapClozeInternal(element, n);
});
}
Object.assign(globalThis, { Object.assign(globalThis, {
saveSession, saveSession,
setFields, setFields,
@ -576,7 +566,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
setNoteId, setNoteId,
setNotetypeMeta, setNotetypeMeta,
wrap, wrap,
wrapCloze,
setMathjaxEnabled, setMathjaxEnabled,
setShrinkImages, setShrinkImages,
setCloseHTMLTags, setCloseHTMLTags,

View file

@ -3,7 +3,7 @@ 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
--> -->
<script lang="ts"> <script lang="ts">
import { wrapClozeInternal } from "@tslib/wrap"; import { wrapInternal } from "@tslib/wrap";
import ClozeButtons from "../ClozeButtons.svelte"; import ClozeButtons from "../ClozeButtons.svelte";
import { context as noteEditorContext } from "../NoteEditor.svelte"; import { context as noteEditorContext } from "../NoteEditor.svelte";
@ -13,11 +13,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: richTextAPI = $focusedInput as RichTextInputAPI; $: richTextAPI = $focusedInput as RichTextInputAPI;
async function onCloze({ detail }): Promise<void> { async function onSurround({ detail }): Promise<void> {
const richText = await richTextAPI.element; const richText = await richTextAPI.element;
const { n } = detail; const { prefix, suffix } = detail;
wrapClozeInternal(richText, n);
wrapInternal(richText, prefix, suffix, false);
} }
</script> </script>
<ClozeButtons on:cloze={onCloze} /> <ClozeButtons on:surround={onSurround} />

View file

@ -40,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</IconButton> </IconButton>
</ButtonGroup> </ButtonGroup>
<ClozeButtons on:cloze alwaysEnabled={true} /> <ClozeButtons on:surround alwaysEnabled={true} />
<ButtonGroup> <ButtonGroup>
<IconButton <IconButton

View file

@ -261,11 +261,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
clear(); clear();
} }
}} }}
on:cloze={async ({ detail }) => { on:surround={async ({ detail }) => {
const editor = await mathjaxEditor.editor; const editor = await mathjaxEditor.editor;
const { n } = detail; const { prefix, suffix } = detail;
editor.replaceSelection( editor.replaceSelection(
`{{c${n}::` + editor.getSelection() + "}}", prefix + editor.getSelection() + suffix,
); );
}} }}
/> />

View file

@ -1,7 +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 { placeCaretAfter } from "../domlib/place-caret";
import { getRange, getSelection } from "./cross-browser"; import { getRange, getSelection } from "./cross-browser";
function wrappedExceptForWhitespace(text: string, front: string, back: string): string { function wrappedExceptForWhitespace(text: string, front: string, back: string): string {
@ -54,36 +53,3 @@ export function wrapInternal(
moveCursorInside(selection, back); moveCursorInside(selection, back);
} }
} }
export function wrapClozeInternal(base: Element, n: number): void {
const selection = getSelection(base)!;
const range = getRange(selection);
if (!range) {
return;
}
const fragment = range.extractContents();
if (fragment.childNodes.length === 0) {
document.execCommand("inserthtml", false, `{{c${n}::}}`);
moveCursorInside(selection, "}}");
} else {
const startNode = document.createTextNode(`{{c${n}::`);
const endNode = document.createTextNode("}}");
range.insertNode(endNode);
range.insertNode(fragment);
range.insertNode(startNode);
placeCaretAfter(endNode);
// Remove empty <li> elements added by extractContents()
const elementsToCheck = [
startNode.previousElementSibling,
startNode.nextElementSibling,
endNode.previousElementSibling,
endNode.nextElementSibling,
];
for (const element of elementsToCheck) {
if (element?.tagName === "LI" && !element?.textContent?.trim()) {
element.remove();
}
}
}
}