Lexical: Aligned new empty item behaviour for nested lists
- Makes enter on empty nested list item un-nest instead of just creating new list items. - Also updated existing lists tests to use newer helper setup.
This commit is contained in:
parent
ace8af077d
commit
fca8f928a3
|
@ -776,6 +776,7 @@ export function dispatchKeydownEventForNode(node: LexicalNode, editor: LexicalEd
|
||||||
key,
|
key,
|
||||||
});
|
});
|
||||||
nodeDomEl?.dispatchEvent(event);
|
nodeDomEl?.dispatchEvent(event);
|
||||||
|
editor.commitUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dispatchKeydownEventForSelectedNode(editor: LexicalEditor, key: string) {
|
export function dispatchKeydownEventForSelectedNode(editor: LexicalEditor, key: string) {
|
||||||
|
|
|
@ -271,11 +271,18 @@ export class ListItemNode extends ElementNode {
|
||||||
insertNewAfter(
|
insertNewAfter(
|
||||||
_: RangeSelection,
|
_: RangeSelection,
|
||||||
restoreSelection = true,
|
restoreSelection = true,
|
||||||
): ListItemNode | ParagraphNode {
|
): ListItemNode | ParagraphNode | null {
|
||||||
|
|
||||||
if (this.getTextContent().trim() === '' && this.isLastChild()) {
|
if (this.getTextContent().trim() === '' && this.isLastChild()) {
|
||||||
const list = this.getParentOrThrow<ListNode>();
|
const list = this.getParentOrThrow<ListNode>();
|
||||||
if (!$isListItemNode(list.getParent())) {
|
const parentListItem = list.getParent();
|
||||||
|
if ($isListItemNode(parentListItem)) {
|
||||||
|
// Un-nest list item if empty nested item
|
||||||
|
parentListItem.insertAfter(this);
|
||||||
|
this.selectStart();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// Insert empty paragraph after list if adding after last empty child
|
||||||
const paragraph = $createParagraphNode();
|
const paragraph = $createParagraphNode();
|
||||||
list.insertAfter(paragraph, restoreSelection);
|
list.insertAfter(paragraph, restoreSelection);
|
||||||
this.remove();
|
this.remove();
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
import {
|
import {
|
||||||
$createParagraphNode,
|
$createParagraphNode,
|
||||||
$createRangeSelection,
|
$createRangeSelection,
|
||||||
$getRoot,
|
$getRoot, LexicalEditor,
|
||||||
TextNode,
|
TextNode,
|
||||||
} from 'lexical';
|
} from 'lexical';
|
||||||
import {
|
import {
|
||||||
|
createTestContext, destroyFromContext,
|
||||||
expectHtmlToBeEqual,
|
expectHtmlToBeEqual,
|
||||||
html,
|
html,
|
||||||
initializeUnitTest,
|
|
||||||
} from 'lexical/__tests__/utils';
|
} from 'lexical/__tests__/utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -24,23 +24,24 @@ import {
|
||||||
ListItemNode,
|
ListItemNode,
|
||||||
ListNode,
|
ListNode,
|
||||||
} from '../..';
|
} from '../..';
|
||||||
|
import {EditorUiContext} from "../../../../ui/framework/core";
|
||||||
const editorConfig = Object.freeze({
|
import {$htmlToBlockNodes} from "../../../../utils/nodes";
|
||||||
namespace: '',
|
|
||||||
theme: {
|
|
||||||
list: {
|
|
||||||
listitem: 'my-listItem-item-class',
|
|
||||||
nested: {
|
|
||||||
listitem: 'my-nested-list-listItem-class',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('LexicalListItemNode tests', () => {
|
describe('LexicalListItemNode tests', () => {
|
||||||
initializeUnitTest((testEnv) => {
|
|
||||||
|
let context!: EditorUiContext;
|
||||||
|
let editor!: LexicalEditor;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
context = createTestContext();
|
||||||
|
editor = context.editor;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
destroyFromContext(context);
|
||||||
|
});
|
||||||
|
|
||||||
test('ListItemNode.constructor', async () => {
|
test('ListItemNode.constructor', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const listItemNode = new ListItemNode();
|
const listItemNode = new ListItemNode();
|
||||||
|
@ -54,13 +55,12 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ListItemNode.createDOM()', async () => {
|
test('ListItemNode.createDOM()', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const listItemNode = new ListItemNode();
|
const listItemNode = new ListItemNode();
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
listItemNode.createDOM(editorConfig).outerHTML,
|
listItemNode.createDOM(editor._config).outerHTML,
|
||||||
html`
|
html`
|
||||||
<li value="1"></li>
|
<li value="1"></li>
|
||||||
`,
|
`,
|
||||||
|
@ -80,12 +80,11 @@ describe('LexicalListItemNode tests', () => {
|
||||||
|
|
||||||
describe('ListItemNode.updateDOM()', () => {
|
describe('ListItemNode.updateDOM()', () => {
|
||||||
test('base', async () => {
|
test('base', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const listItemNode = new ListItemNode();
|
const listItemNode = new ListItemNode();
|
||||||
|
|
||||||
const domElement = listItemNode.createDOM(editorConfig);
|
const domElement = listItemNode.createDOM(editor._config);
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
domElement.outerHTML,
|
domElement.outerHTML,
|
||||||
|
@ -98,7 +97,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
const result = newListItemNode.updateDOM(
|
const result = newListItemNode.updateDOM(
|
||||||
listItemNode,
|
listItemNode,
|
||||||
domElement,
|
domElement,
|
||||||
editorConfig,
|
editor._config,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
|
@ -113,14 +112,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('nested list', async () => {
|
test('nested list', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const parentListNode = new ListNode('bullet', 1);
|
const parentListNode = new ListNode('bullet', 1);
|
||||||
const parentlistItemNode = new ListItemNode();
|
const parentlistItemNode = new ListItemNode();
|
||||||
|
|
||||||
parentListNode.append(parentlistItemNode);
|
parentListNode.append(parentlistItemNode);
|
||||||
const domElement = parentlistItemNode.createDOM(editorConfig);
|
const domElement = parentlistItemNode.createDOM(editor._config);
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
domElement.outerHTML,
|
domElement.outerHTML,
|
||||||
|
@ -134,7 +132,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
const result = parentlistItemNode.updateDOM(
|
const result = parentlistItemNode.updateDOM(
|
||||||
parentlistItemNode,
|
parentlistItemNode,
|
||||||
domElement,
|
domElement,
|
||||||
editorConfig,
|
editor._config,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
|
@ -156,7 +154,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
let listItemNode3: ListItemNode;
|
let listItemNode3: ListItemNode;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const root = $getRoot();
|
const root = $getRoot();
|
||||||
|
@ -175,7 +172,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -198,7 +195,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('another list item node', async () => {
|
test('another list item node', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const newListItemNode = new ListItemNode();
|
const newListItemNode = new ListItemNode();
|
||||||
|
@ -208,7 +204,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -231,14 +227,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('first list item with a non list item node', async () => {
|
test('first list item with a non list item node', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -265,7 +260,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -286,7 +281,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('last list item with a non list item node', async () => {
|
test('last list item with a non list item node', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const paragraphNode = $createParagraphNode();
|
const paragraphNode = $createParagraphNode();
|
||||||
|
@ -294,7 +288,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -315,7 +309,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('middle list item with a non list item node', async () => {
|
test('middle list item with a non list item node', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const paragraphNode = $createParagraphNode();
|
const paragraphNode = $createParagraphNode();
|
||||||
|
@ -323,7 +316,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -346,7 +339,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the only list item with a non list item node', async () => {
|
test('the only list item with a non list item node', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
listItemNode2.remove();
|
listItemNode2.remove();
|
||||||
|
@ -354,7 +346,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -375,7 +367,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -393,7 +385,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - x
|
// - x
|
||||||
// - B
|
// - B
|
||||||
test('siblings are not nested', async () => {
|
test('siblings are not nested', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -414,7 +405,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -438,7 +429,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -461,7 +452,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - x
|
// - x
|
||||||
// - B
|
// - B
|
||||||
test('the previous sibling is nested', async () => {
|
test('the previous sibling is nested', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -486,7 +476,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -509,7 +499,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -531,7 +521,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - x
|
// - x
|
||||||
// - B
|
// - B
|
||||||
test('the next sibling is nested', async () => {
|
test('the next sibling is nested', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -556,7 +545,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1">
|
<li value="1">
|
||||||
|
@ -579,7 +568,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1">
|
<li value="1">
|
||||||
|
@ -601,7 +590,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - x
|
// - x
|
||||||
// - B
|
// - B
|
||||||
test('both siblings are nested', async () => {
|
test('both siblings are nested', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -630,7 +618,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -657,7 +645,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -680,7 +668,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - x
|
// - x
|
||||||
// - B
|
// - B
|
||||||
test('the previous sibling is nested deeper than the next sibling', async () => {
|
test('the previous sibling is nested deeper than the next sibling', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -716,7 +703,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -750,7 +737,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -780,7 +767,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - B1
|
// - B1
|
||||||
// - B2
|
// - B2
|
||||||
test('the next sibling is nested deeper than the previous sibling', async () => {
|
test('the next sibling is nested deeper than the previous sibling', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -816,7 +802,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -850,7 +836,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -881,7 +867,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
// - B1
|
// - B1
|
||||||
// - B2
|
// - B2
|
||||||
test('both siblings are deeply nested', async () => {
|
test('both siblings are deeply nested', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
let x: ListItemNode;
|
let x: ListItemNode;
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
|
@ -924,7 +909,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -965,7 +950,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
await editor.update(() => x.remove());
|
await editor.update(() => x.remove());
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.innerHTML,
|
context.editorDOM.innerHTML,
|
||||||
html`
|
html`
|
||||||
<ul>
|
<ul>
|
||||||
<li value="1" style="list-style: none;">
|
<li value="1" style="list-style: none;">
|
||||||
|
@ -1001,7 +986,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
let listItemNode3: ListItemNode;
|
let listItemNode3: ListItemNode;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const root = $getRoot();
|
const root = $getRoot();
|
||||||
|
@ -1020,7 +1004,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1043,14 +1027,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('first list item', async () => {
|
test('first list item', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
listItemNode1.insertNewAfter($createRangeSelection());
|
listItemNode1.insertNewAfter($createRangeSelection());
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1074,14 +1057,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('last list item', async () => {
|
test('last list item', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
listItemNode3.insertNewAfter($createRangeSelection());
|
listItemNode3.insertNewAfter($createRangeSelection());
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1105,14 +1087,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('middle list item', async () => {
|
test('middle list item', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
listItemNode3.insertNewAfter($createRangeSelection());
|
listItemNode3.insertNewAfter($createRangeSelection());
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1136,15 +1117,13 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the only list item', async () => {
|
test('the only list item', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
listItemNode2.remove();
|
listItemNode2.remove();
|
||||||
listItemNode3.remove();
|
listItemNode3.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1164,7 +1143,7 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expectHtmlToBeEqual(
|
expectHtmlToBeEqual(
|
||||||
testEnv.outerHTML,
|
context.editorDOM.outerHTML,
|
||||||
html`
|
html`
|
||||||
<div
|
<div
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
|
@ -1182,9 +1161,48 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('$createListItemNode()', async () => {
|
describe('ListItemNode.insertNewAfter()', () => {
|
||||||
const {editor} = testEnv;
|
test('new items after empty nested items un-nests the current item instead of creating new', () => {
|
||||||
|
let nestedItem!: ListItemNode;
|
||||||
|
const input = `<ul>
|
||||||
|
<li>
|
||||||
|
Item A
|
||||||
|
<ul><li>Nested item A</li></ul>
|
||||||
|
</li>
|
||||||
|
<li>Item B</li>
|
||||||
|
</ul>`;
|
||||||
|
|
||||||
|
editor.updateAndCommit(() => {
|
||||||
|
const root = $getRoot();
|
||||||
|
root.append(...$htmlToBlockNodes(editor, input));
|
||||||
|
const list = root.getFirstChild() as ListNode;
|
||||||
|
const itemA = list.getFirstChild() as ListItemNode;
|
||||||
|
const nestedList = itemA.getLastChild() as ListNode;
|
||||||
|
nestedItem = nestedList.getFirstChild() as ListItemNode;
|
||||||
|
nestedList.selectEnd();
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.updateAndCommit(() => {
|
||||||
|
nestedItem.insertNewAfter($createRangeSelection());
|
||||||
|
const newItem = nestedItem.getNextSibling() as ListItemNode;
|
||||||
|
newItem.insertNewAfter($createRangeSelection());
|
||||||
|
});
|
||||||
|
|
||||||
|
expectHtmlToBeEqual(
|
||||||
|
context.editorDOM.innerHTML,
|
||||||
|
html`<ul>
|
||||||
|
<li value="1">
|
||||||
|
<span data-lexical-text="true">Item A</span>
|
||||||
|
<ul><li value="1"><span data-lexical-text="true">Nested item A</span></li></ul>
|
||||||
|
</li>
|
||||||
|
<li value="2"><br></li>
|
||||||
|
<li value="3"><span data-lexical-text="true">Item B</span></li>
|
||||||
|
</ul>`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('$createListItemNode()', async () => {
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const listItemNode = new ListItemNode();
|
const listItemNode = new ListItemNode();
|
||||||
|
|
||||||
|
@ -1197,8 +1215,6 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('$isListItemNode()', async () => {
|
test('$isListItemNode()', async () => {
|
||||||
const {editor} = testEnv;
|
|
||||||
|
|
||||||
await editor.update(() => {
|
await editor.update(() => {
|
||||||
const listItemNode = new ListItemNode();
|
const listItemNode = new ListItemNode();
|
||||||
|
|
||||||
|
@ -1206,4 +1222,3 @@ describe('LexicalListItemNode tests', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ describe('Keyboard-handling service tests', () => {
|
||||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||||
|
|
||||||
dispatchKeydownEventForNode(detailsPara, editor, 'ArrowDown');
|
dispatchKeydownEventForNode(detailsPara, editor, 'ArrowDown');
|
||||||
editor.commitUpdates();
|
|
||||||
|
|
||||||
editor.getEditorState().read(() => {
|
editor.getEditorState().read(() => {
|
||||||
lastRootChild = $getRoot().getLastChild();
|
lastRootChild = $getRoot().getLastChild();
|
||||||
|
@ -79,10 +78,7 @@ describe('Keyboard-handling service tests', () => {
|
||||||
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
expect(lastRootChild).toBeInstanceOf(DetailsNode);
|
||||||
|
|
||||||
dispatchKeydownEventForNode(detailsPara, editor, 'Enter');
|
dispatchKeydownEventForNode(detailsPara, editor, 'Enter');
|
||||||
editor.commitUpdates();
|
|
||||||
|
|
||||||
dispatchKeydownEventForSelectedNode(editor, 'Enter');
|
dispatchKeydownEventForSelectedNode(editor, 'Enter');
|
||||||
editor.commitUpdates();
|
|
||||||
|
|
||||||
let detailsChildren!: LexicalNode[];
|
let detailsChildren!: LexicalNode[];
|
||||||
let lastDetailsText!: string;
|
let lastDetailsText!: string;
|
||||||
|
@ -115,7 +111,6 @@ describe('Keyboard-handling service tests', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
dispatchKeydownEventForNode(listItemB, editor, 'Tab');
|
dispatchKeydownEventForNode(listItemB, editor, 'Tab');
|
||||||
editor.commitUpdates();
|
|
||||||
|
|
||||||
editor.getEditorState().read(() => {
|
editor.getEditorState().read(() => {
|
||||||
const list = $getRoot().getChildren()[0] as ListNode;
|
const list = $getRoot().getChildren()[0] as ListNode;
|
||||||
|
|
Loading…
Reference in New Issue