11import { $createTextNode , $getSelection , BaseSelection , LexicalEditor , TextNode } from "lexical" ;
22import { $getBlockElementNodesInSelection , $selectNodes , $toggleSelection } from "./selection" ;
3- import { nodeHasInset } from "./nodes" ;
3+ import { $sortNodes , nodeHasInset } from "./nodes" ;
44import { $createListItemNode , $createListNode , $isListItemNode , $isListNode , ListItemNode } from "@lexical/list" ;
55
66
@@ -49,16 +49,11 @@ export function $unnestListItem(node: ListItemNode): ListItemNode {
4949 }
5050
5151 const laterSiblings = node . getNextSiblings ( ) ;
52-
5352 parentListItem . insertAfter ( node ) ;
5453 if ( list . getChildren ( ) . length === 0 ) {
5554 list . remove ( ) ;
5655 }
5756
58- if ( parentListItem . getChildren ( ) . length === 0 ) {
59- parentListItem . remove ( ) ;
60- }
61-
6257 if ( laterSiblings . length > 0 ) {
6358 const childList = $createListNode ( list . getListType ( ) ) ;
6459 childList . append ( ...laterSiblings ) ;
@@ -69,23 +64,54 @@ export function $unnestListItem(node: ListItemNode): ListItemNode {
6964 list . remove ( ) ;
7065 }
7166
67+ if ( parentListItem . getChildren ( ) . length === 0 ) {
68+ parentListItem . remove ( ) ;
69+ }
70+
7271 return node ;
7372}
7473
7574function getListItemsForSelection ( selection : BaseSelection | null ) : ( ListItemNode | null ) [ ] {
7675 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+ }
7886
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 = [ ] ;
79101 outer: for ( const node of nodes ) {
80102 if ( $isListItemNode ( node ) ) {
81- listItemNodes . push ( node ) ;
103+ if ( ! itemsToIgnore . has ( node . getKey ( ) ) ) {
104+ listItemNodes . push ( node ) ;
105+ }
82106 continue ;
83107 }
84108
85109 const parents = node . getParents ( ) ;
86110 for ( const parent of parents ) {
87111 if ( $isListItemNode ( parent ) ) {
88- listItemNodes . push ( parent ) ;
112+ if ( ! itemsToIgnore . has ( parent . getKey ( ) ) ) {
113+ listItemNodes . push ( parent ) ;
114+ }
89115 continue outer;
90116 }
91117 }
@@ -110,7 +136,8 @@ function $reduceDedupeListItems(listItems: (ListItemNode|null)[]): ListItemNode[
110136 }
111137 }
112138
113- return Object . values ( listItemMap ) ;
139+ const items = Object . values ( listItemMap ) ;
140+ return $sortNodes ( items ) as ListItemNode [ ] ;
114141}
115142
116143export function $setInsetForSelection ( editor : LexicalEditor , change : number ) : void {
0 commit comments