@@ -63,29 +63,13 @@ const sink = (tr: Transaction, range: NodeRange, itemType: NodeType) => {
6363 ) ,
6464 ) ;
6565
66- // After sinking, lift any nested <li> children back out
67- const from = range . start ;
68- const $movedPos = tr . doc . resolve ( from ) ;
69- const movedItem = $movedPos . nodeAfter ;
70-
71- if ( movedItem ) {
72- movedItem . forEach ( ( child , offset ) => {
73- if ( child . type === parent . type ) {
74- const nestedStart = from + offset + 1 ;
75- const nestedEnd = nestedStart + child . nodeSize ;
76- const $liStart = tr . doc . resolve ( nestedStart + 1 ) ;
77- const $liEnd = tr . doc . resolve ( nestedEnd - 1 ) ;
78- const liftRange = $liStart . blockRange ( $liEnd , ( node ) => node . type === itemType ) ;
79-
80- if ( liftRange ) {
81- const targetDepth = liftTarget ( liftRange ) ;
82- if ( targetDepth !== null ) {
83- tr . lift ( liftRange , targetDepth ) ;
84- }
85- }
86- }
87- } ) ;
88- }
66+ // Log the new position of the moved <li>
67+ const oldPos = range . start ;
68+ const newPos = tr . mapping . map ( oldPos , 1 ) ; // 1 = map as if the step was inserted after
69+ console . log ( '[sink] moved <li> new pos:' , newPos , 'node:' , tr . doc . nodeAt ( newPos ) ?. type . name ) ;
70+
71+ // Lift any nested lists that ended up inside the moved <li>
72+ liftNestedLists ( tr , itemType , parent . type , newPos ) ;
8973
9074 return true ;
9175} ;
@@ -140,6 +124,51 @@ function getListItemsToTransform(
140124 return listItemsPoses ;
141125}
142126
127+ /**
128+ * Lifts all nested lists (<ul>/<ol>) that are direct children of the list item at `liPos`.
129+ *
130+ * @param tr The working transaction
131+ * @param itemType The node type representing a list_item
132+ * @param listType The node type representing the surrounding list (bullet_list / ordered_list)
133+ * @param liPos The absolute position of the moved <li> in the current transaction
134+ */
135+ function liftNestedLists (
136+ tr : Transaction ,
137+ itemType : NodeType ,
138+ listType : NodeType ,
139+ liPos : number ,
140+ ) : void {
141+ const movedItem = tr . doc . nodeAt ( liPos ) ;
142+ if ( ! movedItem ) return ;
143+
144+ movedItem . forEach ( ( child , offset ) => {
145+ // Detect nested list nodes of the same type (i.e., another bullet_list or ordered_list)
146+ if ( child . type === listType ) {
147+ const nestedStart = liPos + 1 + offset ; // +1 to move inside <li> content
148+ const nestedEnd = nestedStart + child . nodeSize ;
149+
150+ const $nestedStart = tr . doc . resolve ( nestedStart + 1 ) ; // first node inside nested list
151+ const $nestedEnd = tr . doc . resolve ( nestedEnd - 1 ) ; // last node inside nested list
152+
153+ const liftRange = $nestedStart . blockRange ( $nestedEnd , ( node ) => node . type === itemType ) ;
154+ if ( liftRange ) {
155+ const target = liftTarget ( liftRange ) ;
156+ if ( target !== null ) {
157+ console . log (
158+ '[sink] lifting nested list' ,
159+ 'range:' ,
160+ liftRange . start ,
161+ liftRange . end ,
162+ 'target depth:' ,
163+ target ,
164+ ) ;
165+ tr . lift ( liftRange , target ) ;
166+ }
167+ }
168+ }
169+ } ) ;
170+ }
171+
143172export function sinkOnlySelectedListItem ( itemType : NodeType ) : Command {
144173 return ( { tr, selection} , dispatch ) => {
145174 const { $from, $to, from, to} = selection ;
@@ -166,20 +195,23 @@ export function sinkOnlySelectedListItem(itemType: NodeType): Command {
166195 const mappedStart = tr . mapping . map ( startPos ) ;
167196 const mappedEnd = tr . mapping . map ( endPos ) ;
168197
169- console . log ( 'startPos: endPos' , startPos , endPos ) ;
170- console . log ( 'mapped startPos: endPos ' , mappedStart , mappedEnd ) ;
171-
172198 let j = 0 ;
173199 while ( j < tr . doc . nodeSize - 1 ) {
174200 const node = tr . doc . nodeAt ( j ) ;
175201 console . log ( 'node' , j , node ?. type . name ) ;
176202 j ++ ;
177203 }
178204
179- const start = startPos ;
180- const end = endPos ;
205+ const start = mappedStart ;
206+ const end = mappedEnd ;
181207
182208 const startNode = tr . doc . nodeAt ( start ) ;
209+ const $start = tr . doc . resolve ( start ) ;
210+ const $end = tr . doc . resolve ( end ) ;
211+
212+ console . log ( '[startPos: endPos]' , startPos , endPos ) ;
213+ console . log ( '[mapped startPos: endPos]' , mappedStart , mappedEnd ) ;
214+ console . log ( '[$start, $end]' , $start . pos , $end . pos , 'j:' , j ) ;
183215 console . log ( '[startNode]' , startNode ?. type , 'startNode size' , startNode ?. nodeSize ) ;
184216 console . log (
185217 '[start, end]' ,
@@ -189,10 +221,6 @@ export function sinkOnlySelectedListItem(itemType: NodeType): Command {
189221 start + ( startNode ?. nodeSize ?? 0 ) ,
190222 ) ;
191223
192- const $start = tr . doc . resolve ( start ) ;
193- const $end = tr . doc . resolve ( end ) ;
194-
195- console . log ( '[$start, $end]' , $start . pos , $end . pos , 'j:' , j ) ;
196224 const range = $start . blockRange ( $end ) ;
197225
198226 if ( range ) {
0 commit comments