mirror of
https://github.com/docmost/docmost.git
synced 2026-09-11 07:56:54 +08:00
113 lines
2.8 KiB
TypeScript
113 lines
2.8 KiB
TypeScript
import { Editor, Node } from "@tiptap/core";
|
|
import { GapCursor } from "@tiptap/pm/gapcursor";
|
|
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
|
import { StarterKit } from "@tiptap/starter-kit";
|
|
import { describe, expect, it } from "vitest";
|
|
import { TiptapDocument } from "./document";
|
|
|
|
const Footnotes = Node.create({
|
|
name: "footnotes",
|
|
group: "",
|
|
content: "paragraph*",
|
|
isolating: true,
|
|
renderHTML() {
|
|
return ["ol", { class: "footnotes" }, 0];
|
|
},
|
|
});
|
|
|
|
const AtomBlock = Node.create({
|
|
name: "atomBlock",
|
|
group: "block",
|
|
atom: true,
|
|
renderHTML() {
|
|
return ["div", { "data-atom-block": "" }];
|
|
},
|
|
});
|
|
|
|
const IsolatingBlock = Node.create({
|
|
name: "isolatingBlock",
|
|
group: "block",
|
|
content: "paragraph+",
|
|
isolating: true,
|
|
renderHTML() {
|
|
return ["div", { "data-isolating-block": "" }, 0];
|
|
},
|
|
});
|
|
|
|
function createEditor(content: object[]) {
|
|
const element = document.createElement("div");
|
|
document.body.appendChild(element);
|
|
|
|
return new Editor({
|
|
element,
|
|
extensions: [
|
|
TiptapDocument,
|
|
StarterKit.configure({ document: false }),
|
|
Footnotes,
|
|
AtomBlock,
|
|
IsolatingBlock,
|
|
],
|
|
content: { type: "doc", content },
|
|
});
|
|
}
|
|
|
|
function pressKey(editor: Editor, key: string, keyCode: number) {
|
|
editor.view.dom.dispatchEvent(
|
|
new KeyboardEvent("keydown", {
|
|
key,
|
|
keyCode,
|
|
bubbles: true,
|
|
cancelable: true,
|
|
}),
|
|
);
|
|
}
|
|
|
|
describe("TiptapDocument", () => {
|
|
it("stops on the gap when arrowing down from a selected block node", () => {
|
|
const editor = createEditor([
|
|
{ type: "atomBlock" },
|
|
{ type: "atomBlock" },
|
|
{ type: "paragraph" },
|
|
]);
|
|
const gapPos = editor.state.doc.child(0).nodeSize;
|
|
editor.view.dispatch(
|
|
editor.state.tr.setSelection(
|
|
NodeSelection.create(editor.state.doc, 0),
|
|
),
|
|
);
|
|
|
|
pressKey(editor, "ArrowDown", 40);
|
|
|
|
expect(editor.state.selection).toBeInstanceOf(GapCursor);
|
|
expect(editor.state.selection.head).toBe(gapPos);
|
|
|
|
editor.destroy();
|
|
});
|
|
|
|
it("stops on the gap when arrowing right out of an isolating block", () => {
|
|
const paragraph = (text: string) => ({
|
|
type: "paragraph",
|
|
content: [{ type: "text", text }],
|
|
});
|
|
const editor = createEditor([
|
|
{ type: "isolatingBlock", content: [paragraph("a")] },
|
|
{ type: "isolatingBlock", content: [paragraph("b")] },
|
|
{ type: "paragraph" },
|
|
]);
|
|
const gapPos = editor.state.doc.child(0).nodeSize;
|
|
const endOfFirstText = gapPos - 2;
|
|
editor.view.dispatch(
|
|
editor.state.tr.setSelection(
|
|
TextSelection.create(editor.state.doc, endOfFirstText),
|
|
),
|
|
);
|
|
|
|
pressKey(editor, "ArrowRight", 39);
|
|
|
|
expect(editor.state.selection).toBeInstanceOf(GapCursor);
|
|
expect(editor.state.selection.head).toBe(gapPos);
|
|
|
|
editor.destroy();
|
|
});
|
|
});
|