@lexical/list 0.12.2 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,63 +16,54 @@ var utils = require('@lexical/utils');
16
16
  * LICENSE file in the root directory of this source tree.
17
17
  *
18
18
  */
19
+
19
20
  /**
20
21
  * Checks the depth of listNode from the root node.
21
22
  * @param listNode - The ListNode to be checked.
22
23
  * @returns The depth of the ListNode.
23
24
  */
24
-
25
25
  function $getListDepth(listNode) {
26
26
  let depth = 1;
27
27
  let parent = listNode.getParent();
28
-
29
28
  while (parent != null) {
30
29
  if ($isListItemNode(parent)) {
31
30
  const parentList = parent.getParent();
32
-
33
31
  if ($isListNode(parentList)) {
34
32
  depth++;
35
33
  parent = parentList.getParent();
36
34
  continue;
37
35
  }
38
-
39
36
  {
40
37
  throw Error(`A ListItemNode must have a ListNode for a parent.`);
41
38
  }
42
39
  }
43
-
44
40
  return depth;
45
41
  }
46
-
47
42
  return depth;
48
43
  }
44
+
49
45
  /**
50
46
  * Finds the nearest ancestral ListNode and returns it, throws an invariant if listItem is not a ListItemNode.
51
47
  * @param listItem - The node to be checked.
52
48
  * @returns The ListNode found.
53
49
  */
54
-
55
50
  function $getTopListNode(listItem) {
56
51
  let list = listItem.getParent();
57
-
58
52
  if (!$isListNode(list)) {
59
53
  {
60
54
  throw Error(`A ListItemNode must have a ListNode for a parent.`);
61
55
  }
62
56
  }
63
-
64
57
  let parent = list;
65
-
66
58
  while (parent !== null) {
67
59
  parent = parent.getParent();
68
-
69
60
  if ($isListNode(parent)) {
70
61
  list = parent;
71
62
  }
72
63
  }
73
-
74
64
  return list;
75
65
  }
66
+
76
67
  /**
77
68
  * A recursive Depth-First Search (Postorder Traversal) that finds all of a node's children
78
69
  * that are of type ListItemNode and returns them in an array.
@@ -80,33 +71,30 @@ function $getTopListNode(listItem) {
80
71
  * @returns An array containing all nodes of type ListItemNode found.
81
72
  */
82
73
  // This should probably be $getAllChildrenOfType
83
-
84
74
  function $getAllListItems(node) {
85
75
  let listItemNodes = [];
86
76
  const listChildren = node.getChildren().filter($isListItemNode);
87
-
88
77
  for (let i = 0; i < listChildren.length; i++) {
89
78
  const listItemNode = listChildren[i];
90
79
  const firstChild = listItemNode.getFirstChild();
91
-
92
80
  if ($isListNode(firstChild)) {
93
81
  listItemNodes = listItemNodes.concat($getAllListItems(firstChild));
94
82
  } else {
95
83
  listItemNodes.push(listItemNode);
96
84
  }
97
85
  }
98
-
99
86
  return listItemNodes;
100
87
  }
88
+
101
89
  /**
102
90
  * Checks to see if the passed node is a ListItemNode and has a ListNode as a child.
103
91
  * @param node - The node to be checked.
104
92
  * @returns true if the node is a ListItemNode and has a ListNode child, false otherwise.
105
93
  */
106
-
107
94
  function isNestedListNode(node) {
108
95
  return $isListItemNode(node) && $isListNode(node.getFirstChild());
109
96
  }
97
+
110
98
  /**
111
99
  * Takes a deeply nested ListNode or ListItemNode and traverses up the branch to delete the first
112
100
  * ancestral ListNode (which could be the root ListNode) or ListItemNode with siblings, essentially
@@ -114,7 +102,6 @@ function isNestedListNode(node) {
114
102
  * Should not break ListItem -> List -> ListItem chain as empty List/ItemNodes should be removed on .remove().
115
103
  * @param sublist - The nested ListNode or ListItemNode to be brought up the branch.
116
104
  */
117
-
118
105
  function $removeHighestEmptyListParent(sublist) {
119
106
  // Nodes may be repeatedly indented, to create deeply nested lists that each
120
107
  // contain just one bullet.
@@ -123,25 +110,21 @@ function $removeHighestEmptyListParent(sublist) {
123
110
  // (e.g. is actually part of the list contents) and delete that, or delete
124
111
  // the root of the list (if no list nodes have siblings.)
125
112
  let emptyListPtr = sublist;
126
-
127
113
  while (emptyListPtr.getNextSibling() == null && emptyListPtr.getPreviousSibling() == null) {
128
114
  const parent = emptyListPtr.getParent();
129
-
130
115
  if (parent == null || !($isListItemNode(emptyListPtr) || $isListNode(emptyListPtr))) {
131
116
  break;
132
117
  }
133
-
134
118
  emptyListPtr = parent;
135
119
  }
136
-
137
120
  emptyListPtr.remove();
138
121
  }
122
+
139
123
  /**
140
124
  * Wraps a node into a ListItemNode.
141
125
  * @param node - The node to be wrapped into a ListItemNode
142
126
  * @returns The ListItemNode which the passed node is wrapped in.
143
127
  */
144
-
145
128
  function wrapInListItem(node) {
146
129
  const listItemWrapper = $createListItemNode();
147
130
  return listItemWrapper.append(node);
@@ -154,15 +137,12 @@ function wrapInListItem(node) {
154
137
  * LICENSE file in the root directory of this source tree.
155
138
  *
156
139
  */
157
-
158
140
  function $isSelectingEmptyListItem(anchorNode, nodes) {
159
141
  return $isListItemNode(anchorNode) && (nodes.length === 0 || nodes.length === 1 && anchorNode.is(nodes[0]) && anchorNode.getChildrenSize() === 0);
160
142
  }
161
-
162
143
  function $getListItemValue(listItem) {
163
144
  const list = listItem.getParent();
164
145
  let value = 1;
165
-
166
146
  if (list != null) {
167
147
  if (!$isListNode(list)) {
168
148
  {
@@ -172,19 +152,16 @@ function $getListItemValue(listItem) {
172
152
  value = list.getStart();
173
153
  }
174
154
  }
175
-
176
155
  const siblings = listItem.getPreviousSiblings();
177
-
178
156
  for (let i = 0; i < siblings.length; i++) {
179
157
  const sibling = siblings[i];
180
-
181
158
  if ($isListItemNode(sibling) && !$isListNode(sibling.getFirstChild())) {
182
159
  value++;
183
160
  }
184
161
  }
185
-
186
162
  return value;
187
163
  }
164
+
188
165
  /**
189
166
  * Inserts a new ListNode. If the selection's anchor node is an empty ListItemNode and is a child of
190
167
  * the root/shadow root, it will replace the ListItemNode with a ListNode and the old ListItemNode.
@@ -195,55 +172,42 @@ function $getListItemValue(listItem) {
195
172
  * @param editor - The lexical editor.
196
173
  * @param listType - The type of list, "number" | "bullet" | "check".
197
174
  */
198
-
199
-
200
175
  function insertList(editor, listType) {
201
176
  editor.update(() => {
202
177
  const selection = lexical.$getSelection();
203
-
204
178
  if (lexical.$isRangeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection)) {
205
179
  const nodes = selection.getNodes();
206
180
  const anchor = selection.anchor;
207
181
  const anchorNode = anchor.getNode();
208
182
  const anchorNodeParent = anchorNode.getParent();
209
-
210
183
  if ($isSelectingEmptyListItem(anchorNode, nodes)) {
211
184
  const list = $createListNode(listType);
212
-
213
185
  if (lexical.$isRootOrShadowRoot(anchorNodeParent)) {
214
186
  anchorNode.replace(list);
215
187
  const listItem = $createListItemNode();
216
-
217
188
  if (lexical.$isElementNode(anchorNode)) {
218
189
  listItem.setFormat(anchorNode.getFormatType());
219
190
  listItem.setIndent(anchorNode.getIndent());
220
191
  }
221
-
222
192
  list.append(listItem);
223
193
  } else if ($isListItemNode(anchorNode)) {
224
194
  const parent = anchorNode.getParentOrThrow();
225
195
  append(list, parent.getChildren());
226
196
  parent.replace(list);
227
197
  }
228
-
229
198
  return;
230
199
  } else {
231
200
  const handled = new Set();
232
-
233
201
  for (let i = 0; i < nodes.length; i++) {
234
202
  const node = nodes[i];
235
-
236
203
  if (lexical.$isElementNode(node) && node.isEmpty() && !handled.has(node.getKey())) {
237
204
  createListOrMerge(node, listType);
238
205
  continue;
239
206
  }
240
-
241
207
  if (lexical.$isLeafNode(node)) {
242
208
  let parent = node.getParent();
243
-
244
209
  while (parent != null) {
245
210
  const parentKey = parent.getKey();
246
-
247
211
  if ($isListNode(parent)) {
248
212
  if (!handled.has(parentKey)) {
249
213
  const newListNode = $createListNode(listType);
@@ -252,17 +216,14 @@ function insertList(editor, listType) {
252
216
  updateChildrenListItemValue(newListNode);
253
217
  handled.add(parentKey);
254
218
  }
255
-
256
219
  break;
257
220
  } else {
258
221
  const nextParent = parent.getParent();
259
-
260
222
  if (lexical.$isRootOrShadowRoot(nextParent) && !handled.has(parentKey)) {
261
223
  handled.add(parentKey);
262
224
  createListOrMerge(parent, listType);
263
225
  break;
264
226
  }
265
-
266
227
  parent = nextParent;
267
228
  }
268
229
  }
@@ -272,32 +233,28 @@ function insertList(editor, listType) {
272
233
  }
273
234
  });
274
235
  }
275
-
276
236
  function append(node, nodesToAppend) {
277
237
  node.splice(node.getChildrenSize(), 0, nodesToAppend);
278
238
  }
279
-
280
239
  function createListOrMerge(node, listType) {
281
240
  if ($isListNode(node)) {
282
241
  return node;
283
242
  }
284
-
285
243
  const previousSibling = node.getPreviousSibling();
286
244
  const nextSibling = node.getNextSibling();
287
245
  const listItem = $createListItemNode();
288
246
  listItem.setFormat(node.getFormatType());
289
247
  listItem.setIndent(node.getIndent());
290
248
  append(listItem, node.getChildren());
291
-
292
249
  if ($isListNode(previousSibling) && listType === previousSibling.getListType()) {
293
250
  previousSibling.append(listItem);
294
- node.remove(); // if the same type of list is on both sides, merge them.
251
+ node.remove();
252
+ // if the same type of list is on both sides, merge them.
295
253
 
296
254
  if ($isListNode(nextSibling) && listType === nextSibling.getListType()) {
297
255
  append(previousSibling, nextSibling.getChildren());
298
256
  nextSibling.remove();
299
257
  }
300
-
301
258
  return previousSibling;
302
259
  } else if ($isListNode(nextSibling) && listType === nextSibling.getListType()) {
303
260
  nextSibling.getFirstChildOrThrow().insertBefore(listItem);
@@ -311,32 +268,28 @@ function createListOrMerge(node, listType) {
311
268
  return list;
312
269
  }
313
270
  }
271
+
314
272
  /**
315
273
  * A recursive function that goes through each list and their children, including nested lists,
316
274
  * appending list2 children after list1 children and updating ListItemNode values.
317
275
  * @param list1 - The first list to be merged.
318
276
  * @param list2 - The second list to be merged.
319
277
  */
320
-
321
-
322
278
  function mergeLists(list1, list2) {
323
279
  const listItem1 = list1.getLastChild();
324
280
  const listItem2 = list2.getFirstChild();
325
-
326
281
  if (listItem1 && listItem2 && isNestedListNode(listItem1) && isNestedListNode(listItem2)) {
327
282
  mergeLists(listItem1.getFirstChild(), listItem2.getFirstChild());
328
283
  listItem2.remove();
329
284
  }
330
-
331
285
  const toMerge = list2.getChildren();
332
-
333
286
  if (toMerge.length > 0) {
334
287
  list1.append(...toMerge);
335
288
  updateChildrenListItemValue(list1);
336
289
  }
337
-
338
290
  list2.remove();
339
291
  }
292
+
340
293
  /**
341
294
  * Searches for the nearest ancestral ListNode and removes it. If selection is an empty ListItemNode
342
295
  * it will remove the whole list, including the ListItemNode. For each ListItemNode in the ListNode,
@@ -344,63 +297,55 @@ function mergeLists(list1, list2) {
344
297
  * inside a ListItemNode will be appended to the new ParagraphNodes.
345
298
  * @param editor - The lexical editor.
346
299
  */
347
-
348
300
  function removeList(editor) {
349
301
  editor.update(() => {
350
302
  const selection = lexical.$getSelection();
351
-
352
303
  if (lexical.$isRangeSelection(selection)) {
353
304
  const listNodes = new Set();
354
305
  const nodes = selection.getNodes();
355
306
  const anchorNode = selection.anchor.getNode();
356
-
357
307
  if ($isSelectingEmptyListItem(anchorNode, nodes)) {
358
308
  listNodes.add($getTopListNode(anchorNode));
359
309
  } else {
360
310
  for (let i = 0; i < nodes.length; i++) {
361
311
  const node = nodes[i];
362
-
363
312
  if (lexical.$isLeafNode(node)) {
364
313
  const listItemNode = utils.$getNearestNodeOfType(node, ListItemNode);
365
-
366
314
  if (listItemNode != null) {
367
315
  listNodes.add($getTopListNode(listItemNode));
368
316
  }
369
317
  }
370
318
  }
371
319
  }
372
-
373
320
  for (const listNode of listNodes) {
374
321
  let insertionPoint = listNode;
375
322
  const listItems = $getAllListItems(listNode);
376
-
377
323
  for (const listItemNode of listItems) {
378
324
  const paragraph = lexical.$createParagraphNode();
379
325
  append(paragraph, listItemNode.getChildren());
380
326
  insertionPoint.insertAfter(paragraph);
381
- insertionPoint = paragraph; // When the anchor and focus fall on the textNode
327
+ insertionPoint = paragraph;
328
+
329
+ // When the anchor and focus fall on the textNode
382
330
  // we don't have to change the selection because the textNode will be appended to
383
331
  // the newly generated paragraph.
384
332
  // When selection is in empty nested list item, selection is actually on the listItemNode.
385
333
  // When the corresponding listItemNode is deleted and replaced by the newly generated paragraph
386
334
  // we should manually set the selection's focus and anchor to the newly generated paragraph.
387
-
388
335
  if (listItemNode.__key === selection.anchor.key) {
389
336
  selection.anchor.set(paragraph.getKey(), 0, 'element');
390
337
  }
391
-
392
338
  if (listItemNode.__key === selection.focus.key) {
393
339
  selection.focus.set(paragraph.getKey(), 0, 'element');
394
340
  }
395
-
396
341
  listItemNode.remove();
397
342
  }
398
-
399
343
  listNode.remove();
400
344
  }
401
345
  }
402
346
  });
403
347
  }
348
+
404
349
  /**
405
350
  * Takes the value of a child ListItemNode and makes it the value the ListItemNode
406
351
  * should be if it isn't already. If only certain children should be updated, they
@@ -408,18 +353,14 @@ function removeList(editor) {
408
353
  * @param list - The list whose children are updated.
409
354
  * @param children - An array of the children to be updated.
410
355
  */
411
-
412
356
  function updateChildrenListItemValue(list, children) {
413
357
  const childrenOrExisting = children || list.getChildren();
414
-
415
358
  if (childrenOrExisting !== undefined) {
416
359
  for (let i = 0; i < childrenOrExisting.length; i++) {
417
360
  const child = childrenOrExisting[i];
418
-
419
361
  if ($isListItemNode(child)) {
420
362
  const prevValue = child.getValue();
421
363
  const nextValue = $getListItemValue(child);
422
-
423
364
  if (prevValue !== nextValue) {
424
365
  child.setValue(nextValue);
425
366
  }
@@ -427,70 +368,63 @@ function updateChildrenListItemValue(list, children) {
427
368
  }
428
369
  }
429
370
  }
371
+
430
372
  /**
431
373
  * Adds an empty ListNode/ListItemNode chain at listItemNode, so as to
432
374
  * create an indent effect. Won't indent ListItemNodes that have a ListNode as
433
375
  * a child, but does merge sibling ListItemNodes if one has a nested ListNode.
434
376
  * @param listItemNode - The ListItemNode to be indented.
435
377
  */
436
-
437
378
  function $handleIndent(listItemNode) {
438
379
  // go through each node and decide where to move it.
439
380
  const removed = new Set();
440
-
441
381
  if (isNestedListNode(listItemNode) || removed.has(listItemNode.getKey())) {
442
382
  return;
443
383
  }
384
+ const parent = listItemNode.getParent();
444
385
 
445
- const parent = listItemNode.getParent(); // We can cast both of the below `isNestedListNode` only returns a boolean type instead of a user-defined type guards
446
-
386
+ // We can cast both of the below `isNestedListNode` only returns a boolean type instead of a user-defined type guards
447
387
  const nextSibling = listItemNode.getNextSibling();
448
- const previousSibling = listItemNode.getPreviousSibling(); // if there are nested lists on either side, merge them all together.
388
+ const previousSibling = listItemNode.getPreviousSibling();
389
+ // if there are nested lists on either side, merge them all together.
449
390
 
450
391
  if (isNestedListNode(nextSibling) && isNestedListNode(previousSibling)) {
451
392
  const innerList = previousSibling.getFirstChild();
452
-
453
393
  if ($isListNode(innerList)) {
454
394
  innerList.append(listItemNode);
455
395
  const nextInnerList = nextSibling.getFirstChild();
456
-
457
396
  if ($isListNode(nextInnerList)) {
458
397
  const children = nextInnerList.getChildren();
459
398
  append(innerList, children);
460
399
  nextSibling.remove();
461
400
  removed.add(nextSibling.getKey());
462
401
  }
463
-
464
402
  updateChildrenListItemValue(innerList);
465
403
  }
466
404
  } else if (isNestedListNode(nextSibling)) {
467
405
  // if the ListItemNode is next to a nested ListNode, merge them
468
406
  const innerList = nextSibling.getFirstChild();
469
-
470
407
  if ($isListNode(innerList)) {
471
408
  const firstChild = innerList.getFirstChild();
472
-
473
409
  if (firstChild !== null) {
474
410
  firstChild.insertBefore(listItemNode);
475
411
  }
476
-
477
412
  updateChildrenListItemValue(innerList);
478
413
  }
479
414
  } else if (isNestedListNode(previousSibling)) {
480
415
  const innerList = previousSibling.getFirstChild();
481
-
482
416
  if ($isListNode(innerList)) {
483
417
  innerList.append(listItemNode);
484
418
  updateChildrenListItemValue(innerList);
485
419
  }
486
420
  } else {
487
421
  // otherwise, we need to create a new nested ListNode
422
+
488
423
  if ($isListNode(parent)) {
489
424
  const newListItem = $createListItemNode();
490
425
  const newList = $createListNode(parent.getListType());
491
426
  newListItem.append(newList);
492
427
  newList.append(listItemNode);
493
-
494
428
  if (previousSibling) {
495
429
  previousSibling.insertAfter(newListItem);
496
430
  } else if (nextSibling) {
@@ -498,49 +432,45 @@ function $handleIndent(listItemNode) {
498
432
  } else {
499
433
  parent.append(newListItem);
500
434
  }
501
-
502
435
  updateChildrenListItemValue(newList);
503
436
  }
504
437
  }
505
-
506
438
  if ($isListNode(parent)) {
507
439
  updateChildrenListItemValue(parent);
508
440
  }
509
441
  }
442
+
510
443
  /**
511
444
  * Removes an indent by removing an empty ListNode/ListItemNode chain. An indented ListItemNode
512
445
  * has a great grandparent node of type ListNode, which is where the ListItemNode will reside
513
446
  * within as a child.
514
447
  * @param listItemNode - The ListItemNode to remove the indent (outdent).
515
448
  */
516
-
517
449
  function $handleOutdent(listItemNode) {
518
450
  // go through each node and decide where to move it.
451
+
519
452
  if (isNestedListNode(listItemNode)) {
520
453
  return;
521
454
  }
522
-
523
455
  const parentList = listItemNode.getParent();
524
456
  const grandparentListItem = parentList ? parentList.getParent() : undefined;
525
- const greatGrandparentList = grandparentListItem ? grandparentListItem.getParent() : undefined; // If it doesn't have these ancestors, it's not indented.
457
+ const greatGrandparentList = grandparentListItem ? grandparentListItem.getParent() : undefined;
458
+ // If it doesn't have these ancestors, it's not indented.
526
459
 
527
460
  if ($isListNode(greatGrandparentList) && $isListItemNode(grandparentListItem) && $isListNode(parentList)) {
528
461
  // if it's the first child in it's parent list, insert it into the
529
462
  // great grandparent list before the grandparent
530
463
  const firstChild = parentList ? parentList.getFirstChild() : undefined;
531
464
  const lastChild = parentList ? parentList.getLastChild() : undefined;
532
-
533
465
  if (listItemNode.is(firstChild)) {
534
466
  grandparentListItem.insertBefore(listItemNode);
535
-
536
467
  if (parentList.isEmpty()) {
537
468
  grandparentListItem.remove();
538
- } // if it's the last child in it's parent list, insert it into the
469
+ }
470
+ // if it's the last child in it's parent list, insert it into the
539
471
  // great grandparent list after the grandparent.
540
-
541
472
  } else if (listItemNode.is(lastChild)) {
542
473
  grandparentListItem.insertAfter(listItemNode);
543
-
544
474
  if (parentList.isEmpty()) {
545
475
  grandparentListItem.remove();
546
476
  }
@@ -554,18 +484,18 @@ function $handleOutdent(listItemNode) {
554
484
  const nextSiblingsListItem = $createListItemNode();
555
485
  const nextSiblingsList = $createListNode(listType);
556
486
  nextSiblingsListItem.append(nextSiblingsList);
557
- append(nextSiblingsList, listItemNode.getNextSiblings()); // put the sibling nested lists on either side of the grandparent list item in the great grandparent.
558
-
487
+ append(nextSiblingsList, listItemNode.getNextSiblings());
488
+ // put the sibling nested lists on either side of the grandparent list item in the great grandparent.
559
489
  grandparentListItem.insertBefore(previousSiblingsListItem);
560
- grandparentListItem.insertAfter(nextSiblingsListItem); // replace the grandparent list item (now between the siblings) with the outdented list item.
561
-
490
+ grandparentListItem.insertAfter(nextSiblingsListItem);
491
+ // replace the grandparent list item (now between the siblings) with the outdented list item.
562
492
  grandparentListItem.replace(listItemNode);
563
493
  }
564
-
565
494
  updateChildrenListItemValue(parentList);
566
495
  updateChildrenListItemValue(greatGrandparentList);
567
496
  }
568
497
  }
498
+
569
499
  /**
570
500
  * Attempts to insert a ParagraphNode at selection and selects the new node. The selection must contain a ListItemNode
571
501
  * or a node that does not already contain text. If its grandparent is the root/shadow root, it will get the ListNode
@@ -575,31 +505,23 @@ function $handleOutdent(listItemNode) {
575
505
  * @returns true if a ParagraphNode was inserted succesfully, false if there is no selection
576
506
  * or the selection does not contain a ListItemNode or the node already holds text.
577
507
  */
578
-
579
508
  function $handleListInsertParagraph() {
580
509
  const selection = lexical.$getSelection();
581
-
582
510
  if (!lexical.$isRangeSelection(selection) || !selection.isCollapsed()) {
583
511
  return false;
584
- } // Only run this code on empty list items
585
-
586
-
512
+ }
513
+ // Only run this code on empty list items
587
514
  const anchor = selection.anchor.getNode();
588
-
589
515
  if (!$isListItemNode(anchor) || anchor.getChildrenSize() !== 0) {
590
516
  return false;
591
517
  }
592
-
593
518
  const topListNode = $getTopListNode(anchor);
594
519
  const parent = anchor.getParent();
595
-
596
520
  if (!$isListNode(parent)) {
597
521
  throw Error(`A ListItemNode must have a ListNode for a parent.`);
598
522
  }
599
-
600
523
  const grandparent = parent.getParent();
601
524
  let replacementNode;
602
-
603
525
  if (lexical.$isRootOrShadowRoot(grandparent)) {
604
526
  replacementNode = lexical.$createParagraphNode();
605
527
  topListNode.insertAfter(replacementNode);
@@ -609,13 +531,10 @@ function $handleListInsertParagraph() {
609
531
  } else {
610
532
  return false;
611
533
  }
612
-
613
534
  replacementNode.select();
614
535
  const nextSiblings = anchor.getNextSiblings();
615
-
616
536
  if (nextSiblings.length > 0) {
617
537
  const newList = $createListNode(parent.getListType());
618
-
619
538
  if (lexical.$isParagraphNode(replacementNode)) {
620
539
  replacementNode.insertAfter(newList);
621
540
  } else {
@@ -623,14 +542,13 @@ function $handleListInsertParagraph() {
623
542
  newListItem.append(newList);
624
543
  replacementNode.insertAfter(newListItem);
625
544
  }
626
-
627
545
  nextSiblings.forEach(sibling => {
628
546
  sibling.remove();
629
547
  newList.append(sibling);
630
548
  });
631
- } // Don't leave hanging nested empty lists
632
-
549
+ }
633
550
 
551
+ // Don't leave hanging nested empty lists
634
552
  $removeHighestEmptyListParent(anchor);
635
553
  return true;
636
554
  }
@@ -642,66 +560,54 @@ function $handleListInsertParagraph() {
642
560
  * LICENSE file in the root directory of this source tree.
643
561
  *
644
562
  */
645
-
646
563
  /** @noInheritDoc */
647
564
  class ListItemNode extends lexical.ElementNode {
648
565
  /** @internal */
649
566
 
650
567
  /** @internal */
568
+
651
569
  static getType() {
652
570
  return 'listitem';
653
571
  }
654
-
655
572
  static clone(node) {
656
573
  return new ListItemNode(node.__value, node.__checked, node.__key);
657
574
  }
658
-
659
575
  constructor(value, checked, key) {
660
576
  super(key);
661
577
  this.__value = value === undefined ? 1 : value;
662
578
  this.__checked = checked;
663
579
  }
664
-
665
580
  createDOM(config) {
666
581
  const element = document.createElement('li');
667
582
  const parent = this.getParent();
668
-
669
583
  if ($isListNode(parent) && parent.getListType() === 'check') {
670
584
  updateListItemChecked(element, this, null);
671
585
  }
672
-
673
586
  element.value = this.__value;
674
587
  $setListItemThemeClassNames(element, config.theme, this);
675
588
  return element;
676
589
  }
677
-
678
590
  updateDOM(prevNode, dom, config) {
679
591
  const parent = this.getParent();
680
-
681
592
  if ($isListNode(parent) && parent.getListType() === 'check') {
682
593
  updateListItemChecked(dom, this, prevNode);
683
- } // @ts-expect-error - this is always HTMLListItemElement
684
-
685
-
594
+ }
595
+ // @ts-expect-error - this is always HTMLListItemElement
686
596
  dom.value = this.__value;
687
597
  $setListItemThemeClassNames(dom, config.theme, this);
688
598
  return false;
689
599
  }
690
-
691
600
  static transform() {
692
601
  return node => {
693
602
  const parent = node.getParent();
694
-
695
603
  if ($isListNode(parent)) {
696
604
  updateChildrenListItemValue(parent);
697
-
698
605
  if (parent.getListType() !== 'check' && node.getChecked() != null) {
699
606
  node.setChecked(undefined);
700
607
  }
701
608
  }
702
609
  };
703
610
  }
704
-
705
611
  static importDOM() {
706
612
  return {
707
613
  li: node => ({
@@ -710,7 +616,6 @@ class ListItemNode extends lexical.ElementNode {
710
616
  })
711
617
  };
712
618
  }
713
-
714
619
  static importJSON(serializedNode) {
715
620
  const node = $createListItemNode();
716
621
  node.setChecked(serializedNode.checked);
@@ -719,20 +624,25 @@ class ListItemNode extends lexical.ElementNode {
719
624
  node.setDirection(serializedNode.direction);
720
625
  return node;
721
626
  }
722
-
627
+ exportDOM(editor) {
628
+ const element = this.createDOM(editor._config);
629
+ element.style.textAlign = this.getFormatType();
630
+ return {
631
+ element
632
+ };
633
+ }
723
634
  exportJSON() {
724
- return { ...super.exportJSON(),
635
+ return {
636
+ ...super.exportJSON(),
725
637
  checked: this.getChecked(),
726
638
  type: 'listitem',
727
639
  value: this.getValue(),
728
640
  version: 1
729
641
  };
730
642
  }
731
-
732
643
  append(...nodes) {
733
644
  for (let i = 0; i < nodes.length; i++) {
734
645
  const node = nodes[i];
735
-
736
646
  if (lexical.$isElementNode(node) && this.canMergeWith(node)) {
737
647
  const children = node.getChildren();
738
648
  this.append(...children);
@@ -741,19 +651,15 @@ class ListItemNode extends lexical.ElementNode {
741
651
  super.append(node);
742
652
  }
743
653
  }
744
-
745
654
  return this;
746
655
  }
747
-
748
656
  replace(replaceWithNode, includeChildren) {
749
657
  if ($isListItemNode(replaceWithNode)) {
750
658
  return super.replace(replaceWithNode);
751
659
  }
752
-
753
660
  this.setIndent(0);
754
661
  const list = this.getParentOrThrow();
755
662
  if (!$isListNode(list)) return replaceWithNode;
756
-
757
663
  if (list.__first === this.getKey()) {
758
664
  list.insertBefore(replaceWithNode);
759
665
  } else if (list.__last === this.getKey()) {
@@ -762,103 +668,83 @@ class ListItemNode extends lexical.ElementNode {
762
668
  // Split the list
763
669
  const newList = $createListNode(list.getListType());
764
670
  let nextSibling = this.getNextSibling();
765
-
766
671
  while (nextSibling) {
767
672
  const nodeToAppend = nextSibling;
768
673
  nextSibling = nextSibling.getNextSibling();
769
674
  newList.append(nodeToAppend);
770
675
  }
771
-
772
676
  list.insertAfter(replaceWithNode);
773
677
  replaceWithNode.insertAfter(newList);
774
678
  }
775
-
776
679
  if (includeChildren) {
777
680
  this.getChildren().forEach(child => {
778
681
  replaceWithNode.append(child);
779
682
  });
780
683
  }
781
-
782
684
  this.remove();
783
-
784
685
  if (list.getChildrenSize() === 0) {
785
686
  list.remove();
786
687
  }
787
-
788
688
  return replaceWithNode;
789
689
  }
790
-
791
690
  insertAfter(node, restoreSelection = true) {
792
691
  const listNode = this.getParentOrThrow();
793
-
794
692
  if (!$isListNode(listNode)) {
795
693
  {
796
694
  throw Error(`insertAfter: list node is not parent of list item node`);
797
695
  }
798
696
  }
799
-
800
697
  const siblings = this.getNextSiblings();
801
-
802
698
  if ($isListItemNode(node)) {
803
699
  const after = super.insertAfter(node, restoreSelection);
804
700
  const afterListNode = node.getParentOrThrow();
805
-
806
701
  if ($isListNode(afterListNode)) {
807
702
  updateChildrenListItemValue(afterListNode);
808
703
  }
809
-
810
704
  return after;
811
- } // Attempt to merge if the list is of the same type.
705
+ }
812
706
 
707
+ // Attempt to merge if the list is of the same type.
813
708
 
814
709
  if ($isListNode(node)) {
815
710
  let child = node;
816
711
  const children = node.getChildren();
817
-
818
712
  for (let i = children.length - 1; i >= 0; i--) {
819
713
  child = children[i];
820
714
  this.insertAfter(child, restoreSelection);
821
715
  }
822
-
823
716
  return child;
824
- } // Otherwise, split the list
825
- // Split the lists and insert the node in between them
826
-
717
+ }
827
718
 
719
+ // Otherwise, split the list
720
+ // Split the lists and insert the node in between them
828
721
  listNode.insertAfter(node, restoreSelection);
829
-
830
722
  if (siblings.length !== 0) {
831
723
  const newListNode = $createListNode(listNode.getListType());
832
724
  siblings.forEach(sibling => newListNode.append(sibling));
833
725
  node.insertAfter(newListNode, restoreSelection);
834
726
  }
835
-
836
727
  return node;
837
728
  }
838
-
839
729
  remove(preserveEmptyParent) {
840
730
  const prevSibling = this.getPreviousSibling();
841
731
  const nextSibling = this.getNextSibling();
842
732
  super.remove(preserveEmptyParent);
843
-
844
733
  if (prevSibling && nextSibling && isNestedListNode(prevSibling) && isNestedListNode(nextSibling)) {
845
734
  mergeLists(prevSibling.getFirstChild(), nextSibling.getFirstChild());
846
735
  nextSibling.remove();
847
736
  } else if (nextSibling) {
848
737
  const parent = nextSibling.getParent();
849
-
850
738
  if ($isListNode(parent)) {
851
739
  updateChildrenListItemValue(parent);
852
740
  }
853
741
  }
854
742
  }
855
-
856
743
  insertNewAfter(_, restoreSelection = true) {
857
744
  const newElement = $createListItemNode(this.__checked == null ? undefined : false);
858
745
  this.insertAfter(newElement, restoreSelection);
859
746
  return newElement;
860
747
  }
861
-
862
748
  collapseAtStart(selection) {
863
749
  const paragraph = lexical.$createParagraphNode();
864
750
  const children = this.getChildren();
@@ -866,7 +752,6 @@ class ListItemNode extends lexical.ElementNode {
866
752
  const listNode = this.getParentOrThrow();
867
753
  const listNodeParent = listNode.getParentOrThrow();
868
754
  const isIndented = $isListItemNode(listNodeParent);
869
-
870
755
  if (listNode.getChildrenSize() === 1) {
871
756
  if (isIndented) {
872
757
  // if the list node is nested, we just want to remove it,
@@ -875,17 +760,15 @@ class ListItemNode extends lexical.ElementNode {
875
760
  listNodeParent.select();
876
761
  } else {
877
762
  listNode.insertBefore(paragraph);
878
- listNode.remove(); // If we have selection on the list item, we'll need to move it
763
+ listNode.remove();
764
+ // If we have selection on the list item, we'll need to move it
879
765
  // to the paragraph
880
-
881
766
  const anchor = selection.anchor;
882
767
  const focus = selection.focus;
883
768
  const key = paragraph.getKey();
884
-
885
769
  if (anchor.type === 'element' && anchor.getNode().is(this)) {
886
770
  anchor.set(key, anchor.offset, 'element');
887
771
  }
888
-
889
772
  if (focus.type === 'element' && focus.getNode().is(this)) {
890
773
  focus.set(key, focus.offset, 'element');
891
774
  }
@@ -894,61 +777,47 @@ class ListItemNode extends lexical.ElementNode {
894
777
  listNode.insertBefore(paragraph);
895
778
  this.remove();
896
779
  }
897
-
898
780
  return true;
899
781
  }
900
-
901
782
  getValue() {
902
783
  const self = this.getLatest();
903
784
  return self.__value;
904
785
  }
905
-
906
786
  setValue(value) {
907
787
  const self = this.getWritable();
908
788
  self.__value = value;
909
789
  }
910
-
911
790
  getChecked() {
912
791
  const self = this.getLatest();
913
792
  return self.__checked;
914
793
  }
915
-
916
794
  setChecked(checked) {
917
795
  const self = this.getWritable();
918
796
  self.__checked = checked;
919
797
  }
920
-
921
798
  toggleChecked() {
922
799
  this.setChecked(!this.__checked);
923
800
  }
924
-
925
801
  getIndent() {
926
802
  // If we don't have a parent, we are likely serializing
927
803
  const parent = this.getParent();
928
-
929
804
  if (parent === null) {
930
805
  return this.getLatest().__indent;
931
- } // ListItemNode should always have a ListNode for a parent.
932
-
933
-
806
+ }
807
+ // ListItemNode should always have a ListNode for a parent.
934
808
  let listNodeParent = parent.getParentOrThrow();
935
809
  let indentLevel = 0;
936
-
937
810
  while ($isListItemNode(listNodeParent)) {
938
811
  listNodeParent = listNodeParent.getParentOrThrow().getParentOrThrow();
939
812
  indentLevel++;
940
813
  }
941
-
942
814
  return indentLevel;
943
815
  }
944
-
945
816
  setIndent(indent) {
946
817
  if (!(typeof indent === 'number' && indent > -1)) {
947
818
  throw Error(`Invalid indent value.`);
948
819
  }
949
-
950
820
  let currentIndent = this.getIndent();
951
-
952
821
  while (currentIndent !== indent) {
953
822
  if (currentIndent < indent) {
954
823
  $handleIndent(this);
@@ -958,108 +827,84 @@ class ListItemNode extends lexical.ElementNode {
958
827
  currentIndent--;
959
828
  }
960
829
  }
961
-
962
830
  return this;
963
831
  }
964
-
965
832
  insertBefore(nodeToInsert) {
966
833
  if ($isListItemNode(nodeToInsert)) {
967
834
  const parent = this.getParentOrThrow();
968
-
969
835
  if ($isListNode(parent)) {
970
836
  const siblings = this.getNextSiblings();
971
837
  updateChildrenListItemValue(parent, siblings);
972
838
  }
973
839
  }
974
-
975
840
  return super.insertBefore(nodeToInsert);
976
841
  }
977
-
978
842
  canInsertAfter(node) {
979
843
  return $isListItemNode(node);
980
844
  }
981
-
982
845
  canReplaceWith(replacement) {
983
846
  return $isListItemNode(replacement);
984
847
  }
985
-
986
848
  canMergeWith(node) {
987
849
  return lexical.$isParagraphNode(node) || $isListItemNode(node);
988
850
  }
989
-
990
851
  extractWithChild(child, selection) {
991
852
  if (!lexical.$isRangeSelection(selection)) {
992
853
  return false;
993
854
  }
994
-
995
855
  const anchorNode = selection.anchor.getNode();
996
856
  const focusNode = selection.focus.getNode();
997
857
  return this.isParentOf(anchorNode) && this.isParentOf(focusNode) && this.getTextContent().length === selection.getTextContent().length;
998
858
  }
999
-
1000
859
  isParentRequired() {
1001
860
  return true;
1002
861
  }
1003
-
1004
862
  createParentElementNode() {
1005
863
  return $createListNode('bullet');
1006
864
  }
1007
-
1008
865
  }
1009
-
1010
866
  function $setListItemThemeClassNames(dom, editorThemeClasses, node) {
1011
867
  const classesToAdd = [];
1012
868
  const classesToRemove = [];
1013
869
  const listTheme = editorThemeClasses.list;
1014
870
  const listItemClassName = listTheme ? listTheme.listitem : undefined;
1015
871
  let nestedListItemClassName;
1016
-
1017
872
  if (listTheme && listTheme.nested) {
1018
873
  nestedListItemClassName = listTheme.nested.listitem;
1019
874
  }
1020
-
1021
875
  if (listItemClassName !== undefined) {
1022
876
  const listItemClasses = listItemClassName.split(' ');
1023
877
  classesToAdd.push(...listItemClasses);
1024
878
  }
1025
-
1026
879
  if (listTheme) {
1027
880
  const parentNode = node.getParent();
1028
881
  const isCheckList = $isListNode(parentNode) && parentNode.getListType() === 'check';
1029
882
  const checked = node.getChecked();
1030
-
1031
883
  if (!isCheckList || checked) {
1032
884
  classesToRemove.push(listTheme.listitemUnchecked);
1033
885
  }
1034
-
1035
886
  if (!isCheckList || !checked) {
1036
887
  classesToRemove.push(listTheme.listitemChecked);
1037
888
  }
1038
-
1039
889
  if (isCheckList) {
1040
890
  classesToAdd.push(checked ? listTheme.listitemChecked : listTheme.listitemUnchecked);
1041
891
  }
1042
892
  }
1043
-
1044
893
  if (nestedListItemClassName !== undefined) {
1045
894
  const nestedListItemClasses = nestedListItemClassName.split(' ');
1046
-
1047
895
  if (node.getChildren().some(child => $isListNode(child))) {
1048
896
  classesToAdd.push(...nestedListItemClasses);
1049
897
  } else {
1050
898
  classesToRemove.push(...nestedListItemClasses);
1051
899
  }
1052
900
  }
1053
-
1054
901
  if (classesToRemove.length > 0) {
1055
902
  utils.removeClassNamesFromElement(dom, ...classesToRemove);
1056
903
  }
1057
-
1058
904
  if (classesToAdd.length > 0) {
1059
905
  utils.addClassNamesToElement(dom, ...classesToAdd);
1060
906
  }
1061
907
  }
1062
-
1063
908
  function updateListItemChecked(dom, listItemNode, prevListItemNode, listNode) {
1064
909
  // Only add attributes for leaf list items
1065
910
  if ($isListNode(listItemNode.getFirstChild())) {
@@ -1069,35 +914,32 @@ function updateListItemChecked(dom, listItemNode, prevListItemNode, listNode) {
1069
914
  } else {
1070
915
  dom.setAttribute('role', 'checkbox');
1071
916
  dom.setAttribute('tabIndex', '-1');
1072
-
1073
917
  if (!prevListItemNode || listItemNode.__checked !== prevListItemNode.__checked) {
1074
918
  dom.setAttribute('aria-checked', listItemNode.getChecked() ? 'true' : 'false');
1075
919
  }
1076
920
  }
1077
921
  }
1078
-
1079
922
  function convertListItemElement(domNode) {
1080
923
  const checked = utils.isHTMLElement(domNode) && domNode.getAttribute('aria-checked') === 'true';
1081
924
  return {
1082
925
  node: $createListItemNode(checked)
1083
926
  };
1084
927
  }
928
+
1085
929
  /**
1086
930
  * Creates a new List Item node, passing true/false will convert it to a checkbox input.
1087
931
  * @param checked - Is the List Item a checkbox and, if so, is it checked? undefined/null: not a checkbox, true/false is a checkbox and checked/unchecked, respectively.
1088
932
  * @returns The new List Item.
1089
933
  */
1090
-
1091
-
1092
934
  function $createListItemNode(checked) {
1093
935
  return lexical.$applyNodeReplacement(new ListItemNode(undefined, checked));
1094
936
  }
937
+
1095
938
  /**
1096
939
  * Checks to see if the node is a ListItemNode.
1097
940
  * @param node - The node to be checked.
1098
941
  * @returns true if the node is a ListItemNode, false otherwise.
1099
942
  */
1100
-
1101
943
  function $isListItemNode(node) {
1102
944
  return node instanceof ListItemNode;
1103
945
  }
@@ -1109,7 +951,6 @@ function $isListItemNode(node) {
1109
951
  * LICENSE file in the root directory of this source tree.
1110
952
  *
1111
953
  */
1112
-
1113
954
  /** @noInheritDoc */
1114
955
  class ListNode extends lexical.ElementNode {
1115
956
  /** @internal */
@@ -1117,67 +958,56 @@ class ListNode extends lexical.ElementNode {
1117
958
  /** @internal */
1118
959
 
1119
960
  /** @internal */
961
+
1120
962
  static getType() {
1121
963
  return 'list';
1122
964
  }
1123
-
1124
965
  static clone(node) {
1125
966
  const listType = node.__listType || TAG_TO_LIST_TYPE[node.__tag];
1126
967
  return new ListNode(listType, node.__start, node.__key);
1127
968
  }
1128
-
1129
969
  constructor(listType, start, key) {
1130
970
  super(key);
1131
-
1132
971
  const _listType = TAG_TO_LIST_TYPE[listType] || listType;
1133
-
1134
972
  this.__listType = _listType;
1135
973
  this.__tag = _listType === 'number' ? 'ol' : 'ul';
1136
974
  this.__start = start;
1137
975
  }
1138
-
1139
976
  getTag() {
1140
977
  return this.__tag;
1141
978
  }
1142
-
1143
979
  setListType(type) {
1144
980
  const writable = this.getWritable();
1145
981
  writable.__listType = type;
1146
982
  writable.__tag = type === 'number' ? 'ol' : 'ul';
1147
983
  }
1148
-
1149
984
  getListType() {
1150
985
  return this.__listType;
1151
986
  }
1152
-
1153
987
  getStart() {
1154
988
  return this.__start;
1155
- } // View
989
+ }
1156
990
 
991
+ // View
1157
992
 
1158
993
  createDOM(config, _editor) {
1159
994
  const tag = this.__tag;
1160
995
  const dom = document.createElement(tag);
1161
-
1162
996
  if (this.__start !== 1) {
1163
997
  dom.setAttribute('start', String(this.__start));
1164
- } // @ts-expect-error Internal field.
1165
-
1166
-
998
+ }
999
+ // @ts-expect-error Internal field.
1167
1000
  dom.__lexicalListType = this.__listType;
1168
1001
  setListThemeClassNames(dom, config.theme, this);
1169
1002
  return dom;
1170
1003
  }
1171
-
1172
1004
  updateDOM(prevNode, dom, config) {
1173
1005
  if (prevNode.__tag !== this.__tag) {
1174
1006
  return true;
1175
1007
  }
1176
-
1177
1008
  setListThemeClassNames(dom, config.theme, this);
1178
1009
  return false;
1179
1010
  }
1180
-
1181
1011
  static importDOM() {
1182
1012
  return {
1183
1013
  ol: node => ({
@@ -1190,7 +1020,6 @@ class ListNode extends lexical.ElementNode {
1190
1020
  })
1191
1021
  };
1192
1022
  }
1193
-
1194
1023
  static importJSON(serializedNode) {
1195
1024
  const node = $createListNode(serializedNode.listType, serializedNode.start);
1196
1025
  node.setFormat(serializedNode.format);
@@ -1198,29 +1027,25 @@ class ListNode extends lexical.ElementNode {
1198
1027
  node.setDirection(serializedNode.direction);
1199
1028
  return node;
1200
1029
  }
1201
-
1202
1030
  exportDOM(editor) {
1203
1031
  const {
1204
1032
  element
1205
1033
  } = super.exportDOM(editor);
1206
-
1207
1034
  if (element && utils.isHTMLElement(element)) {
1208
1035
  if (this.__start !== 1) {
1209
1036
  element.setAttribute('start', String(this.__start));
1210
1037
  }
1211
-
1212
1038
  if (this.__listType === 'check') {
1213
1039
  element.setAttribute('__lexicalListType', 'check');
1214
1040
  }
1215
1041
  }
1216
-
1217
1042
  return {
1218
1043
  element
1219
1044
  };
1220
1045
  }
1221
-
1222
1046
  exportJSON() {
1223
- return { ...super.exportJSON(),
1047
+ return {
1048
+ ...super.exportJSON(),
1224
1049
  listType: this.getListType(),
1225
1050
  start: this.getStart(),
1226
1051
  tag: this.getTag(),
@@ -1228,24 +1053,19 @@ class ListNode extends lexical.ElementNode {
1228
1053
  version: 1
1229
1054
  };
1230
1055
  }
1231
-
1232
1056
  canBeEmpty() {
1233
1057
  return false;
1234
1058
  }
1235
-
1236
1059
  canIndent() {
1237
1060
  return false;
1238
1061
  }
1239
-
1240
1062
  append(...nodesToAppend) {
1241
1063
  for (let i = 0; i < nodesToAppend.length; i++) {
1242
1064
  const currentNode = nodesToAppend[i];
1243
-
1244
1065
  if ($isListItemNode(currentNode)) {
1245
1066
  super.append(currentNode);
1246
1067
  } else {
1247
1068
  const listItemNode = $createListItemNode();
1248
-
1249
1069
  if ($isListNode(currentNode)) {
1250
1070
  listItemNode.append(currentNode);
1251
1071
  } else if (lexical.$isElementNode(currentNode)) {
@@ -1254,26 +1074,20 @@ class ListNode extends lexical.ElementNode {
1254
1074
  } else {
1255
1075
  listItemNode.append(currentNode);
1256
1076
  }
1257
-
1258
1077
  super.append(listItemNode);
1259
1078
  }
1260
1079
  }
1261
-
1262
1080
  updateChildrenListItemValue(this);
1263
1081
  return this;
1264
1082
  }
1265
-
1266
1083
  extractWithChild(child) {
1267
1084
  return $isListItemNode(child);
1268
1085
  }
1269
-
1270
1086
  }
1271
-
1272
1087
  function setListThemeClassNames(dom, editorThemeClasses, node) {
1273
1088
  const classesToAdd = [];
1274
1089
  const classesToRemove = [];
1275
1090
  const listTheme = editorThemeClasses.list;
1276
-
1277
1091
  if (listTheme !== undefined) {
1278
1092
  const listLevelsClassNames = listTheme[`${node.__tag}Depth`] || [];
1279
1093
  const listDepth = $getListDepth(node) - 1;
@@ -1282,29 +1096,23 @@ function setListThemeClassNames(dom, editorThemeClasses, node) {
1282
1096
  const listClassName = listTheme[node.__tag];
1283
1097
  let nestedListClassName;
1284
1098
  const nestedListTheme = listTheme.nested;
1285
-
1286
1099
  if (nestedListTheme !== undefined && nestedListTheme.list) {
1287
1100
  nestedListClassName = nestedListTheme.list;
1288
1101
  }
1289
-
1290
1102
  if (listClassName !== undefined) {
1291
1103
  classesToAdd.push(listClassName);
1292
1104
  }
1293
-
1294
1105
  if (listLevelClassName !== undefined) {
1295
1106
  const listItemClasses = listLevelClassName.split(' ');
1296
1107
  classesToAdd.push(...listItemClasses);
1297
-
1298
1108
  for (let i = 0; i < listLevelsClassNames.length; i++) {
1299
1109
  if (i !== normalizedListDepth) {
1300
1110
  classesToRemove.push(node.__tag + i);
1301
1111
  }
1302
1112
  }
1303
1113
  }
1304
-
1305
1114
  if (nestedListClassName !== undefined) {
1306
1115
  const nestedListItemClasses = nestedListClassName.split(' ');
1307
-
1308
1116
  if (listDepth > 1) {
1309
1117
  classesToAdd.push(...nestedListItemClasses);
1310
1118
  } else {
@@ -1312,32 +1120,26 @@ function setListThemeClassNames(dom, editorThemeClasses, node) {
1312
1120
  }
1313
1121
  }
1314
1122
  }
1315
-
1316
1123
  if (classesToRemove.length > 0) {
1317
1124
  utils.removeClassNamesFromElement(dom, ...classesToRemove);
1318
1125
  }
1319
-
1320
1126
  if (classesToAdd.length > 0) {
1321
1127
  utils.addClassNamesToElement(dom, ...classesToAdd);
1322
1128
  }
1323
1129
  }
1130
+
1324
1131
  /*
1325
1132
  * This function normalizes the children of a ListNode after the conversion from HTML,
1326
1133
  * ensuring that they are all ListItemNodes and contain either a single nested ListNode
1327
1134
  * or some other inline content.
1328
1135
  */
1329
-
1330
-
1331
1136
  function normalizeChildren(nodes) {
1332
1137
  const normalizedListItems = [];
1333
-
1334
1138
  for (let i = 0; i < nodes.length; i++) {
1335
1139
  const node = nodes[i];
1336
-
1337
1140
  if ($isListItemNode(node)) {
1338
1141
  normalizedListItems.push(node);
1339
1142
  const children = node.getChildren();
1340
-
1341
1143
  if (children.length > 1) {
1342
1144
  children.forEach(child => {
1343
1145
  if ($isListNode(child)) {
@@ -1349,14 +1151,11 @@ function normalizeChildren(nodes) {
1349
1151
  normalizedListItems.push(wrapInListItem(node));
1350
1152
  }
1351
1153
  }
1352
-
1353
1154
  return normalizedListItems;
1354
1155
  }
1355
-
1356
1156
  function convertListNode(domNode) {
1357
1157
  const nodeName = domNode.nodeName.toLowerCase();
1358
1158
  let node = null;
1359
-
1360
1159
  if (nodeName === 'ol') {
1361
1160
  // @ts-ignore
1362
1161
  const start = domNode.start;
@@ -1368,33 +1167,31 @@ function convertListNode(domNode) {
1368
1167
  node = $createListNode('bullet');
1369
1168
  }
1370
1169
  }
1371
-
1372
1170
  return {
1373
1171
  after: normalizeChildren,
1374
1172
  node
1375
1173
  };
1376
1174
  }
1377
-
1378
1175
  const TAG_TO_LIST_TYPE = {
1379
1176
  ol: 'number',
1380
1177
  ul: 'bullet'
1381
1178
  };
1179
+
1382
1180
  /**
1383
1181
  * Creates a ListNode of listType.
1384
1182
  * @param listType - The type of list to be created. Can be 'number', 'bullet', or 'check'.
1385
1183
  * @param start - Where an ordered list starts its count, start = 1 if left undefined.
1386
1184
  * @returns The new ListNode
1387
1185
  */
1388
-
1389
1186
  function $createListNode(listType, start = 1) {
1390
1187
  return lexical.$applyNodeReplacement(new ListNode(listType, start));
1391
1188
  }
1189
+
1392
1190
  /**
1393
1191
  * Checks to see if the node is a ListNode.
1394
1192
  * @param node - The node to be checked.
1395
1193
  * @returns true if the node is a ListNode, false otherwise.
1396
1194
  */
1397
-
1398
1195
  function $isListNode(node) {
1399
1196
  return node instanceof ListNode;
1400
1197
  }