@@ -110,10 +110,10 @@ export const BlockContainer = Node.create<IBlock>({
110
110
111
111
return true ;
112
112
} ,
113
- // Deletes a block at a given position and sets the selection to where the block was .
113
+ // Deletes a block at a given position.
114
114
BNDeleteBlock :
115
115
( posInBlock ) =>
116
- ( { state, view , dispatch } ) => {
116
+ ( { state, dispatch } ) => {
117
117
const blockInfo = getBlockInfoFromPos ( state . doc , posInBlock ) ;
118
118
if ( blockInfo === undefined ) {
119
119
return false ;
@@ -123,10 +123,82 @@ export const BlockContainer = Node.create<IBlock>({
123
123
124
124
if ( dispatch ) {
125
125
state . tr . deleteRange ( startPos , endPos ) ;
126
- state . tr . setSelection (
127
- new TextSelection ( state . doc . resolve ( startPos + 1 ) )
126
+ }
127
+
128
+ return true ;
129
+ } ,
130
+ // Updates a block at a given position.
131
+ BNUpdateBlock :
132
+ ( posInBlock , block ) =>
133
+ ( { state, dispatch } ) => {
134
+ const blockInfo = getBlockInfoFromPos ( state . doc , posInBlock ) ;
135
+ if ( blockInfo === undefined ) {
136
+ return false ;
137
+ }
138
+
139
+ const { startPos, endPos, node, contentNode } = blockInfo ;
140
+
141
+ if ( dispatch ) {
142
+ // Adds blockGroup node with child blocks if necessary.
143
+ if ( block . children !== undefined ) {
144
+ const childNodes = [ ] ;
145
+
146
+ // Creates ProseMirror nodes for each child block, including their descendants.
147
+ for ( const child of block . children ) {
148
+ childNodes . push ( blockToNode ( child , state . schema ) ) ;
149
+ }
150
+
151
+ // Checks if a blockGroup node already exists.
152
+ if ( node . childCount === 2 ) {
153
+ // Replaces all child nodes in the existing blockGroup with the ones created earlier.
154
+ state . tr . replace (
155
+ startPos + contentNode . nodeSize + 1 ,
156
+ endPos - 1 ,
157
+ new Slice ( Fragment . from ( childNodes ) , 0 , 0 )
158
+ ) ;
159
+ } else {
160
+ // Inserts a new blockGroup containing the child nodes created earlier.
161
+ state . tr . insert (
162
+ startPos + contentNode . nodeSize ,
163
+ state . schema . nodes [ "blockGroup" ] . create ( { } , childNodes )
164
+ ) ;
165
+ }
166
+ }
167
+
168
+ // Replaces the blockContent node's content if necessary.
169
+ if ( block . content !== undefined ) {
170
+ let content : PMNode [ ] = [ ] ;
171
+
172
+ // Checks if the provided content is a string or InlineContent[] type.
173
+ if ( typeof block . content === "string" ) {
174
+ // Adds a single text node with no marks to the content.
175
+ content . push ( state . schema . text ( block . content ) ) ;
176
+ } else {
177
+ // Adds a text node with the provided styles converted into marks to the content, for each InlineContent
178
+ // object.
179
+ content = inlineContentToNodes ( block . content , state . schema ) ;
180
+ }
181
+
182
+ // Replaces the contents of the blockContent node with the previously created text node(s).
183
+ state . tr . replace (
184
+ startPos + 1 ,
185
+ startPos + contentNode . nodeSize - 1 ,
186
+ new Slice ( Fragment . from ( content ) , 0 , 0 )
187
+ ) ;
188
+ }
189
+
190
+ // Changes the block type and adds the provided props as node attributes. Also preserves all existing node
191
+ // attributes that are compatible with the new type.
192
+ state . tr . setNodeMarkup (
193
+ startPos ,
194
+ block . type === undefined
195
+ ? undefined
196
+ : state . schema . nodes [ block . type ] ,
197
+ {
198
+ ...contentNode . attrs ,
199
+ ...block . props ,
200
+ }
128
201
) ;
129
- view . focus ( ) ;
130
202
}
131
203
132
204
return true ;
@@ -283,112 +355,6 @@ export const BlockContainer = Node.create<IBlock>({
283
355
284
356
return true ;
285
357
} ,
286
- // Updates a block to the given specification.
287
- BNUpdateBlock :
288
- ( posInBlock , block ) =>
289
- ( { state, dispatch } ) => {
290
- const blockInfo = getBlockInfoFromPos ( state . doc , posInBlock ) ;
291
- if ( blockInfo === undefined ) {
292
- return false ;
293
- }
294
-
295
- const { startPos, endPos, node, contentNode } = blockInfo ;
296
-
297
- if ( dispatch ) {
298
- // Adds blockGroup node with child blocks if necessary.
299
- if ( block . children !== undefined ) {
300
- const childNodes = [ ] ;
301
-
302
- // Creates ProseMirror nodes for each child block, including their descendants.
303
- for ( const child of block . children ) {
304
- childNodes . push ( blockToNode ( child , state . schema ) ) ;
305
- }
306
-
307
- // Checks if a blockGroup node already exists.
308
- if ( node . childCount === 2 ) {
309
- // Replaces all child nodes in the existing blockGroup with the ones created earlier.
310
- state . tr . replace (
311
- startPos + contentNode . nodeSize + 1 ,
312
- endPos - 1 ,
313
- new Slice ( Fragment . from ( childNodes ) , 0 , 0 )
314
- ) ;
315
- } else {
316
- // Inserts a new blockGroup containing the child nodes created earlier.
317
- state . tr . insert (
318
- startPos + contentNode . nodeSize ,
319
- state . schema . nodes [ "blockGroup" ] . create ( { } , childNodes )
320
- ) ;
321
- }
322
- }
323
-
324
- // Replaces the blockContent node's content if necessary.
325
- if ( block . content !== undefined ) {
326
- let content : PMNode [ ] = [ ] ;
327
-
328
- // Checks if the provided content is a string or InlineContent[] type.
329
- if ( typeof block . content === "string" ) {
330
- // Adds a single text node with no marks to the content.
331
- content . push ( state . schema . text ( block . content ) ) ;
332
- } else {
333
- // Adds a text node with the provided styles converted into marks to the content, for each InlineContent
334
- // object.
335
- content = inlineContentToNodes ( block . content , state . schema ) ;
336
- }
337
-
338
- // Replaces the contents of the blockContent node with the previously created text node(s).
339
- state . tr . replace (
340
- startPos + 1 ,
341
- startPos + contentNode . nodeSize - 1 ,
342
- new Slice ( Fragment . from ( content ) , 0 , 0 )
343
- ) ;
344
- }
345
-
346
- // Changes the block type and adds the provided props as node attributes. Also preserves all existing node
347
- // attributes that are compatible with the new type.
348
- state . tr . setNodeMarkup (
349
- startPos ,
350
- block . type === undefined
351
- ? undefined
352
- : state . schema . nodes [ block . type ] ,
353
- {
354
- ...contentNode . attrs ,
355
- ...block . props ,
356
- }
357
- ) ;
358
- }
359
-
360
- return true ;
361
- } ,
362
- // Updates a block to the given specification if it's empty, otherwise creates a new block from that specification
363
- // below it.
364
- BNCreateOrUpdateBlock :
365
- ( posInBlock , block ) =>
366
- ( { state, chain } ) => {
367
- const blockInfo = getBlockInfoFromPos ( state . doc , posInBlock ) ;
368
- if ( blockInfo === undefined ) {
369
- return false ;
370
- }
371
-
372
- const { node, startPos, endPos } = blockInfo ;
373
-
374
- if ( node . textContent . length === 0 ) {
375
- const oldBlockContentPos = startPos + 1 ;
376
-
377
- return chain ( )
378
- . BNUpdateBlock ( posInBlock , block )
379
- . setTextSelection ( oldBlockContentPos )
380
- . run ( ) ;
381
- } else {
382
- const newBlockInsertionPos = endPos + 1 ;
383
- const newBlockContentPos = newBlockInsertionPos + 1 ;
384
-
385
- return chain ( )
386
- . BNCreateBlock ( newBlockInsertionPos )
387
- . BNUpdateBlock ( newBlockContentPos , block )
388
- . setTextSelection ( newBlockContentPos )
389
- . run ( ) ;
390
- }
391
- } ,
392
358
} ;
393
359
} ,
394
360
0 commit comments