mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-08-07 23:03:00 +03:00
Lexical: Improved list tab handling, Improved test utils
- Made tab work on empty list items - Improved select preservation on single list item tab - Altered test context creation for more standard testing
This commit is contained in:
@@ -1,95 +1,135 @@
|
||||
import {
|
||||
createTestContext,
|
||||
createTestContext, destroyFromContext,
|
||||
dispatchKeydownEventForNode,
|
||||
dispatchKeydownEventForSelectedNode,
|
||||
initializeUnitTest
|
||||
} from "lexical/__tests__/utils";
|
||||
import {
|
||||
$createParagraphNode, $createTextNode,
|
||||
$getRoot, LexicalNode,
|
||||
ParagraphNode,
|
||||
$getRoot, $getSelection, LexicalEditor, LexicalNode,
|
||||
ParagraphNode, TextNode,
|
||||
} from "lexical";
|
||||
import {$createDetailsNode, DetailsNode} from "@lexical/rich-text/LexicalDetailsNode";
|
||||
import {registerKeyboardHandling} from "../keyboard-handling";
|
||||
import {registerRichText} from "@lexical/rich-text";
|
||||
import {EditorUiContext} from "../../ui/framework/core";
|
||||
import {$createListItemNode, $createListNode, ListItemNode, ListNode} from "@lexical/list";
|
||||
|
||||
describe('Keyboard-handling service tests', () => {
|
||||
initializeUnitTest((testEnv) => {
|
||||
|
||||
test('Details: down key on last lines creates new sibling node', () => {
|
||||
const {editor} = testEnv;
|
||||
let context!: EditorUiContext;
|
||||
let editor!: LexicalEditor;
|
||||
|
||||
registerRichText(editor);
|
||||
registerKeyboardHandling(createTestContext(testEnv));
|
||||
beforeEach(() => {
|
||||
context = createTestContext();
|
||||
editor = context.editor;
|
||||
registerRichText(editor);
|
||||
registerKeyboardHandling(context);
|
||||
});
|
||||
|
||||
let lastRootChild!: LexicalNode|null;
|
||||
let detailsPara!: ParagraphNode;
|
||||
afterEach(() => {
|
||||
destroyFromContext(context);
|
||||
});
|
||||
|
||||
editor.updateAndCommit(() => {
|
||||
const root = $getRoot()
|
||||
const details = $createDetailsNode();
|
||||
detailsPara = $createParagraphNode();
|
||||
details.append(detailsPara);
|
||||
$getRoot().append(details);
|
||||
detailsPara.select();
|
||||
test('Details: down key on last lines creates new sibling node', () => {
|
||||
let lastRootChild!: LexicalNode|null;
|
||||
let detailsPara!: ParagraphNode;
|
||||
|
||||
lastRootChild = root.getLastChild();
|
||||
});
|
||||
editor.updateAndCommit(() => {
|
||||
const root = $getRoot()
|
||||
const details = $createDetailsNode();
|
||||
detailsPara = $createParagraphNode();
|
||||
details.append(detailsPara);
|
||||
$getRoot().append(details);
|
||||
detailsPara.select();
|
||||
|
||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||
|
||||
dispatchKeydownEventForNode(detailsPara, editor, 'ArrowDown');
|
||||
editor.commitUpdates();
|
||||
|
||||
editor.getEditorState().read(() => {
|
||||
lastRootChild = $getRoot().getLastChild();
|
||||
});
|
||||
|
||||
expect(lastRootChild).toBeInstanceOf(ParagraphNode);
|
||||
lastRootChild = root.getLastChild();
|
||||
});
|
||||
|
||||
test('Details: enter on last empy block creates new sibling node', () => {
|
||||
const {editor} = testEnv;
|
||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||
|
||||
registerRichText(editor);
|
||||
registerKeyboardHandling(createTestContext(testEnv));
|
||||
dispatchKeydownEventForNode(detailsPara, editor, 'ArrowDown');
|
||||
editor.commitUpdates();
|
||||
|
||||
let lastRootChild!: LexicalNode|null;
|
||||
let detailsPara!: ParagraphNode;
|
||||
editor.getEditorState().read(() => {
|
||||
lastRootChild = $getRoot().getLastChild();
|
||||
});
|
||||
|
||||
editor.updateAndCommit(() => {
|
||||
const root = $getRoot()
|
||||
const details = $createDetailsNode();
|
||||
const text = $createTextNode('Hello!');
|
||||
detailsPara = $createParagraphNode();
|
||||
detailsPara.append(text);
|
||||
details.append(detailsPara);
|
||||
$getRoot().append(details);
|
||||
text.selectEnd();
|
||||
expect(lastRootChild).toBeInstanceOf(ParagraphNode);
|
||||
});
|
||||
|
||||
lastRootChild = root.getLastChild();
|
||||
});
|
||||
test('Details: enter on last empty block creates new sibling node', () => {
|
||||
registerRichText(editor);
|
||||
|
||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||
let lastRootChild!: LexicalNode|null;
|
||||
let detailsPara!: ParagraphNode;
|
||||
|
||||
dispatchKeydownEventForNode(detailsPara, editor, 'Enter');
|
||||
editor.commitUpdates();
|
||||
editor.updateAndCommit(() => {
|
||||
const root = $getRoot()
|
||||
const details = $createDetailsNode();
|
||||
const text = $createTextNode('Hello!');
|
||||
detailsPara = $createParagraphNode();
|
||||
detailsPara.append(text);
|
||||
details.append(detailsPara);
|
||||
$getRoot().append(details);
|
||||
text.selectEnd();
|
||||
|
||||
dispatchKeydownEventForSelectedNode(editor, 'Enter');
|
||||
editor.commitUpdates();
|
||||
lastRootChild = root.getLastChild();
|
||||
});
|
||||
|
||||
let detailsChildren!: LexicalNode[];
|
||||
let lastDetailsText!: string;
|
||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||
|
||||
editor.getEditorState().read(() => {
|
||||
detailsChildren = (lastRootChild as DetailsNode).getChildren();
|
||||
lastRootChild = $getRoot().getLastChild();
|
||||
lastDetailsText = detailsChildren[0].getTextContent();
|
||||
});
|
||||
dispatchKeydownEventForNode(detailsPara, editor, 'Enter');
|
||||
editor.commitUpdates();
|
||||
|
||||
expect(lastRootChild).toBeInstanceOf(ParagraphNode);
|
||||
expect(detailsChildren).toHaveLength(1);
|
||||
expect(lastDetailsText).toBe('Hello!');
|
||||
dispatchKeydownEventForSelectedNode(editor, 'Enter');
|
||||
editor.commitUpdates();
|
||||
|
||||
let detailsChildren!: LexicalNode[];
|
||||
let lastDetailsText!: string;
|
||||
|
||||
editor.getEditorState().read(() => {
|
||||
detailsChildren = (lastRootChild as DetailsNode).getChildren();
|
||||
lastRootChild = $getRoot().getLastChild();
|
||||
lastDetailsText = detailsChildren[0].getTextContent();
|
||||
});
|
||||
|
||||
expect(lastRootChild).toBeInstanceOf(ParagraphNode);
|
||||
expect(detailsChildren).toHaveLength(1);
|
||||
expect(lastDetailsText).toBe('Hello!');
|
||||
});
|
||||
|
||||
test('Lists: tab on empty list item insets item', () => {
|
||||
|
||||
let list!: ListNode;
|
||||
let listItemB!: ListItemNode;
|
||||
|
||||
editor.updateAndCommit(() => {
|
||||
const root = $getRoot();
|
||||
list = $createListNode('bullet');
|
||||
const listItemA = $createListItemNode();
|
||||
listItemA.append($createTextNode('Hello!'));
|
||||
listItemB = $createListItemNode();
|
||||
list.append(listItemA, listItemB);
|
||||
root.append(list);
|
||||
listItemB.selectStart();
|
||||
});
|
||||
|
||||
dispatchKeydownEventForNode(listItemB, editor, 'Tab');
|
||||
editor.commitUpdates();
|
||||
|
||||
editor.getEditorState().read(() => {
|
||||
const list = $getRoot().getChildren()[0] as ListNode;
|
||||
const listChild = list.getChildren()[0] as ListItemNode;
|
||||
const children = listChild.getChildren();
|
||||
expect(children).toHaveLength(2);
|
||||
expect(children[0]).toBeInstanceOf(TextNode);
|
||||
expect(children[0].getTextContent()).toBe('Hello!');
|
||||
expect(children[1]).toBeInstanceOf(ListNode);
|
||||
|
||||
const innerList = children[1] as ListNode;
|
||||
const selectedNode = $getSelection()?.getNodes()[0];
|
||||
expect(selectedNode).toBeInstanceOf(ListItemNode);
|
||||
expect(selectedNode?.getKey()).toBe(innerList.getChildren()[0].getKey());
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user