mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
Revert "Preserve HTML formatting inside clozes (#3038)"
This reverts commit 58b2475f42
.
Rolling this back for now, as it may cause regressions. We can give it
another try at the start of the next beta-testing period.
This commit is contained in:
parent
5062cb37c7
commit
e911b4b69a
7 changed files with 19 additions and 95 deletions
|
@ -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")
|
||||||
|
|
|
@ -54,16 +54,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: "}}",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -387,7 +387,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
import { ImageOcclusionFieldIndexes } from "@tslib/anki/image_occlusion_pb";
|
import { ImageOcclusionFieldIndexes } from "@tslib/anki/image_occlusion_pb";
|
||||||
import { getImageOcclusionFields } from "@tslib/backend";
|
import { getImageOcclusionFields } from "@tslib/backend";
|
||||||
import { wrapClozeInternal, wrapInternal } from "@tslib/wrap";
|
import { wrapInternal } from "@tslib/wrap";
|
||||||
import Shortcut from "components/Shortcut.svelte";
|
import Shortcut from "components/Shortcut.svelte";
|
||||||
import ImageOcclusionPage from "image-occlusion/ImageOcclusionPage.svelte";
|
import ImageOcclusionPage from "image-occlusion/ImageOcclusionPage.svelte";
|
||||||
import ImageOcclusionPicker from "image-occlusion/ImageOcclusionPicker.svelte";
|
import ImageOcclusionPicker from "image-occlusion/ImageOcclusionPicker.svelte";
|
||||||
|
@ -541,16 +541,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,
|
||||||
|
@ -569,7 +559,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,
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -38,7 +38,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
|
||||||
|
|
|
@ -260,11 +260,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,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
// 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";
|
||||||
import { nodeIsElement } from "./dom";
|
|
||||||
|
|
||||||
function wrappedExceptForWhitespace(text: string, front: string, back: string): string {
|
function wrappedExceptForWhitespace(text: string, front: string, back: string): string {
|
||||||
const match = text.match(/^(\s*)([^]*?)(\s*)$/)!;
|
const match = text.match(/^(\s*)([^]*?)(\s*)$/)!;
|
||||||
|
@ -55,70 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expand the range to include parent nodes whose children are already included.
|
|
||||||
// This is to work around .extractContents() adding redundant empty elements
|
|
||||||
let startParent: Node | null = range.startContainer.parentNode;
|
|
||||||
if (
|
|
||||||
startParent !== base
|
|
||||||
&& startParent?.firstChild === range.startContainer && range.startOffset === 0
|
|
||||||
) {
|
|
||||||
range.setStartBefore(startParent);
|
|
||||||
}
|
|
||||||
let endParent: Node | null = range.endContainer.parentNode;
|
|
||||||
if (
|
|
||||||
endParent !== base
|
|
||||||
&& endParent?.lastChild === range.endContainer && (
|
|
||||||
(!nodeIsElement(range.endContainer)
|
|
||||||
&& range.endOffset === range.endContainer.textContent?.length)
|
|
||||||
|| (nodeIsElement(range.endContainer)
|
|
||||||
&& range.endOffset === range.endContainer.childNodes.length)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
range.setEndAfter(endParent);
|
|
||||||
}
|
|
||||||
let expand: boolean;
|
|
||||||
do {
|
|
||||||
expand = false;
|
|
||||||
if (
|
|
||||||
startParent
|
|
||||||
&& startParent.parentNode !== base && startParent.parentNode?.firstChild === startParent
|
|
||||||
&& range.isPointInRange(startParent.parentNode, startParent.parentNode?.childNodes.length)
|
|
||||||
) {
|
|
||||||
startParent = startParent.parentNode;
|
|
||||||
range.setStartBefore(startParent);
|
|
||||||
expand = true;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
endParent && endParent.parentNode !== base && endParent.parentNode?.lastChild === endParent
|
|
||||||
&& range.isPointInRange(endParent.parentNode, 0)
|
|
||||||
) {
|
|
||||||
endParent = endParent.parentNode;
|
|
||||||
range.setEndAfter(endParent);
|
|
||||||
expand = true;
|
|
||||||
}
|
|
||||||
if (range.endOffset === 0) {
|
|
||||||
range.setEndBefore(range.endContainer);
|
|
||||||
expand = true;
|
|
||||||
}
|
|
||||||
} while (expand);
|
|
||||||
|
|
||||||
const fragment = range.extractContents();
|
|
||||||
if (fragment.childNodes.length === 0) {
|
|
||||||
document.execCommand("inserthtml", false, `{{c${n}::}}`);
|
|
||||||
} else {
|
|
||||||
const startNode = document.createTextNode(`{{c${n}::`);
|
|
||||||
const endNode = document.createTextNode("}}");
|
|
||||||
range.insertNode(endNode);
|
|
||||||
range.insertNode(fragment);
|
|
||||||
range.insertNode(startNode);
|
|
||||||
placeCaretAfter(endNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue