1
1
import { $createTextNode , $getSelection , BaseSelection , LexicalEditor , TextNode } from "lexical" ;
2
2
import { $getBlockElementNodesInSelection , $selectNodes , $toggleSelection } from "./selection" ;
3
- import { nodeHasInset } from "./nodes" ;
3
+ import { $sortNodes , nodeHasInset } from "./nodes" ;
4
4
import { $createListItemNode , $createListNode , $isListItemNode , $isListNode , ListItemNode } from "@lexical/list" ;
5
5
6
6
@@ -49,16 +49,11 @@ export function $unnestListItem(node: ListItemNode): ListItemNode {
49
49
}
50
50
51
51
const laterSiblings = node . getNextSiblings ( ) ;
52
-
53
52
parentListItem . insertAfter ( node ) ;
54
53
if ( list . getChildren ( ) . length === 0 ) {
55
54
list . remove ( ) ;
56
55
}
57
56
58
- if ( parentListItem . getChildren ( ) . length === 0 ) {
59
- parentListItem . remove ( ) ;
60
- }
61
-
62
57
if ( laterSiblings . length > 0 ) {
63
58
const childList = $createListNode ( list . getListType ( ) ) ;
64
59
childList . append ( ...laterSiblings ) ;
@@ -69,23 +64,54 @@ export function $unnestListItem(node: ListItemNode): ListItemNode {
69
64
list . remove ( ) ;
70
65
}
71
66
67
+ if ( parentListItem . getChildren ( ) . length === 0 ) {
68
+ parentListItem . remove ( ) ;
69
+ }
70
+
72
71
return node ;
73
72
}
74
73
75
74
function getListItemsForSelection ( selection : BaseSelection | null ) : ( ListItemNode | null ) [ ] {
76
75
const nodes = selection ?. getNodes ( ) || [ ] ;
77
- const listItemNodes = [ ] ;
76
+ let [ start , end ] = selection ?. getStartEndPoints ( ) || [ null , null ] ;
77
+
78
+ // Ensure we ignore parent list items of the top-most list item since,
79
+ // although technically part of the selection, from a user point of
80
+ // view the selection does not spread to encompass this outer element.
81
+ const itemsToIgnore : Set < string > = new Set ( ) ;
82
+ if ( selection && start ) {
83
+ if ( selection . isBackward ( ) && end ) {
84
+ [ end , start ] = [ start , end ] ;
85
+ }
78
86
87
+ const startParents = start . getNode ( ) . getParents ( ) ;
88
+ let foundList = false ;
89
+ for ( const parent of startParents ) {
90
+ if ( $isListItemNode ( parent ) ) {
91
+ if ( foundList ) {
92
+ itemsToIgnore . add ( parent . getKey ( ) ) ;
93
+ } else {
94
+ foundList = true ;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ const listItemNodes = [ ] ;
79
101
outer: for ( const node of nodes ) {
80
102
if ( $isListItemNode ( node ) ) {
81
- listItemNodes . push ( node ) ;
103
+ if ( ! itemsToIgnore . has ( node . getKey ( ) ) ) {
104
+ listItemNodes . push ( node ) ;
105
+ }
82
106
continue ;
83
107
}
84
108
85
109
const parents = node . getParents ( ) ;
86
110
for ( const parent of parents ) {
87
111
if ( $isListItemNode ( parent ) ) {
88
- listItemNodes . push ( parent ) ;
112
+ if ( ! itemsToIgnore . has ( parent . getKey ( ) ) ) {
113
+ listItemNodes . push ( parent ) ;
114
+ }
89
115
continue outer;
90
116
}
91
117
}
@@ -110,7 +136,8 @@ function $reduceDedupeListItems(listItems: (ListItemNode|null)[]): ListItemNode[
110
136
}
111
137
}
112
138
113
- return Object . values ( listItemMap ) ;
139
+ const items = Object . values ( listItemMap ) ;
140
+ return $sortNodes ( items ) as ListItemNode [ ] ;
114
141
}
115
142
116
143
export function $setInsetForSelection ( editor : LexicalEditor , change : number ) : void {
0 commit comments