Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/keyboard/enter.ts
1697 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
// What happens when you hit the enter key.
7
8
import { Editor, Element, Transforms } from "slate";
9
import { isElementOfType } from "../elements";
10
import { emptyParagraph, isWhitespaceParagraph } from "../padding";
11
import { register } from "./register";
12
import {
13
isAtBeginningOfBlock,
14
isAtEndOfBlock,
15
moveCursorToBeginningOfBlock,
16
} from "../control";
17
import { containingBlock } from "../slate-util";
18
import { markdownAutoformat } from "../format/auto-format";
19
20
register({ key: "Enter" }, ({ editor }) => {
21
markdownAutoformat(editor);
22
const fragment = editor.getFragment();
23
const x = fragment?.[0];
24
25
if (isElementOfType(x, "heading")) {
26
// If you hit enter in a heading,
27
Transforms.insertNodes(editor, [emptyParagraph()], {
28
match: (node) => isElementOfType(node, "heading"),
29
});
30
return true;
31
}
32
33
if (isElementOfType(x, "paragraph")) {
34
// If you hit enter in a paragraph, the default behavior is creating
35
// another empty paragraph. We do a bunch of special cases so that
36
// our document corresponds much more closely to what markdown
37
// actually supports.
38
39
if (isWhitespaceParagraph(containingBlock(editor)?.[0])) {
40
return true;
41
}
42
const prev = Editor.previous(editor);
43
if (prev == null) return false;
44
if (isWhitespaceParagraph(prev[0])) {
45
return true;
46
}
47
return false;
48
}
49
50
if (isElementOfType(x, ["bullet_list", "ordered_list"])) {
51
const atEnd = isAtEndOfBlock(editor, { mode: "lowest" });
52
const atBeginning = isAtBeginningOfBlock(editor, { mode: "lowest" });
53
Transforms.insertNodes(
54
editor,
55
[{ type: "list_item", children: [{ text: "" }] } as Element],
56
{
57
match: (node) => isElementOfType(node, "list_item"),
58
mode: "lowest",
59
}
60
);
61
if (atBeginning) {
62
// done
63
Transforms.move(editor, { distance: 1, unit: "line" });
64
return true;
65
}
66
if (atEnd) {
67
// done
68
return true;
69
}
70
// Not at beginning or end, so above insertNodes actually
71
// splits the list item so we end up
72
// with an extra blank one, which we now remove.
73
Transforms.removeNodes(editor, {
74
match: (node) => isElementOfType(node, "list_item"),
75
});
76
moveCursorToBeginningOfBlock(editor);
77
return true;
78
}
79
return false;
80
});
81
82