2 createTestContext, destroyFromContext,
3 dispatchKeydownEventForNode,
4 dispatchKeydownEventForSelectedNode,
5 } from "lexical/__tests__/utils";
7 $createParagraphNode, $createTextNode,
8 $getRoot, $getSelection, LexicalEditor, LexicalNode,
9 ParagraphNode, TextNode,
11 import {$createDetailsNode, DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
12 import {registerKeyboardHandling} from "../keyboard-handling";
13 import {registerRichText} from "@lexical/rich-text";
14 import {EditorUiContext} from "../../ui/framework/core";
15 import {$createListItemNode, $createListNode, ListItemNode, ListNode} from "@lexical/list";
17 describe('Keyboard-handling service tests', () => {
19 let context!: EditorUiContext;
20 let editor!: LexicalEditor;
23 context = createTestContext();
24 editor = context.editor;
25 registerRichText(editor);
26 registerKeyboardHandling(context);
30 destroyFromContext(context);
33 test('Details: down key on last lines creates new sibling node', () => {
34 let lastRootChild!: LexicalNode|null;
35 let detailsPara!: ParagraphNode;
37 editor.updateAndCommit(() => {
38 const root = $getRoot()
39 const details = $createDetailsNode();
40 detailsPara = $createParagraphNode();
41 details.append(detailsPara);
42 $getRoot().append(details);
45 lastRootChild = root.getLastChild();
48 expect(lastRootChild).toBeInstanceOf(DetailsNode);
50 dispatchKeydownEventForNode(detailsPara, editor, 'ArrowDown');
52 editor.getEditorState().read(() => {
53 lastRootChild = $getRoot().getLastChild();
56 expect(lastRootChild).toBeInstanceOf(ParagraphNode);
59 test('Details: enter on last empty block creates new sibling node', () => {
60 registerRichText(editor);
62 let lastRootChild!: LexicalNode|null;
63 let detailsPara!: ParagraphNode;
65 editor.updateAndCommit(() => {
66 const root = $getRoot()
67 const details = $createDetailsNode();
68 const text = $createTextNode('Hello!');
69 detailsPara = $createParagraphNode();
70 detailsPara.append(text);
71 details.append(detailsPara);
72 $getRoot().append(details);
75 lastRootChild = root.getLastChild();
78 expect(lastRootChild).toBeInstanceOf(DetailsNode);
80 dispatchKeydownEventForNode(detailsPara, editor, 'Enter');
81 dispatchKeydownEventForSelectedNode(editor, 'Enter');
83 let detailsChildren!: LexicalNode[];
84 let lastDetailsText!: string;
86 editor.getEditorState().read(() => {
87 detailsChildren = (lastRootChild as DetailsNode).getChildren();
88 lastRootChild = $getRoot().getLastChild();
89 lastDetailsText = detailsChildren[0].getTextContent();
92 expect(lastRootChild).toBeInstanceOf(ParagraphNode);
93 expect(detailsChildren).toHaveLength(1);
94 expect(lastDetailsText).toBe('Hello!');
97 test('Lists: tab on empty list item insets item', () => {
100 let listItemB!: ListItemNode;
102 editor.updateAndCommit(() => {
103 const root = $getRoot();
104 list = $createListNode('bullet');
105 const listItemA = $createListItemNode();
106 listItemA.append($createTextNode('Hello!'));
107 listItemB = $createListItemNode();
108 list.append(listItemA, listItemB);
110 listItemB.selectStart();
113 dispatchKeydownEventForNode(listItemB, editor, 'Tab');
115 editor.getEditorState().read(() => {
116 const list = $getRoot().getChildren()[0] as ListNode;
117 const listChild = list.getChildren()[0] as ListItemNode;
118 const children = listChild.getChildren();
119 expect(children).toHaveLength(2);
120 expect(children[0]).toBeInstanceOf(TextNode);
121 expect(children[0].getTextContent()).toBe('Hello!');
122 expect(children[1]).toBeInstanceOf(ListNode);
124 const innerList = children[1] as ListNode;
125 const selectedNode = $getSelection()?.getNodes()[0];
126 expect(selectedNode).toBeInstanceOf(ListItemNode);
127 expect(selectedNode?.getKey()).toBe(innerList.getChildren()[0].getKey());