mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Fix some cloze handling regressions (#3086)
* Place cursor inside empty clozes * Remove empty <li> after being added
This commit is contained in:
parent
9c733848b8
commit
31e2dc1409
1 changed files with 13 additions and 48 deletions
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
import { placeCaretAfter } from "../domlib/place-caret";
|
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*)$/)!;
|
||||||
|
@ -63,56 +62,10 @@ export function wrapClozeInternal(base: Element, n: number): void {
|
||||||
return;
|
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();
|
const fragment = range.extractContents();
|
||||||
if (fragment.childNodes.length === 0) {
|
if (fragment.childNodes.length === 0) {
|
||||||
document.execCommand("inserthtml", false, `{{c${n}::}}`);
|
document.execCommand("inserthtml", false, `{{c${n}::}}`);
|
||||||
|
moveCursorInside(selection, "}}");
|
||||||
} else {
|
} else {
|
||||||
const startNode = document.createTextNode(`{{c${n}::`);
|
const startNode = document.createTextNode(`{{c${n}::`);
|
||||||
const endNode = document.createTextNode("}}");
|
const endNode = document.createTextNode("}}");
|
||||||
|
@ -120,5 +73,17 @@ export function wrapClozeInternal(base: Element, n: number): void {
|
||||||
range.insertNode(fragment);
|
range.insertNode(fragment);
|
||||||
range.insertNode(startNode);
|
range.insertNode(startNode);
|
||||||
placeCaretAfter(endNode);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue