@@ -210,7 +210,7 @@ describe("KeyboardShortcutsExtension hardBreakShortcut", () => {
210210 } ) ;
211211} ) ;
212212
213- describe ( "KeyboardShortcutsExtension backspaceBehavior " , ( ) => {
213+ describe ( "KeyboardShortcutsExtension Backspace " , ( ) => {
214214 let editor : BlockNoteEditor | undefined ;
215215
216216 afterEach ( ( ) => {
@@ -219,7 +219,6 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
219219 } ) ;
220220
221221 function createEditor (
222- backspaceBehavior : "unindent" | "merge" | undefined ,
223222 content : string ,
224223 type :
225224 | "paragraph"
@@ -228,7 +227,6 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
228227 | "checkListItem" = "paragraph" ,
229228 ) {
230229 const instance = BlockNoteEditor . create ( {
231- backspaceBehavior,
232230 trailingBlock : false ,
233231 initialContent : [
234232 {
@@ -276,20 +274,8 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
276274 }
277275
278276 describe . each ( [ "" , "Current" ] ) ( "Backspace with content %j" , ( content ) => {
279- it . each ( [ undefined , "unindent" ] as const ) (
280- "unindents with backspaceBehavior=%s" ,
281- ( behavior ) => {
282- const instance = createEditor ( behavior , content ) ;
283- pressKey ( instance , "Backspace" ) ;
284- expectUnindented ( instance ) ;
285- expect ( instance . getBlock ( "current" ) ?. content ) . toEqual (
286- content ? [ { type : "text" , text : content , styles : { } } ] : [ ] ,
287- ) ;
288- } ,
289- ) ;
290-
291277 it ( "merges without changing following siblings' nesting" , ( ) => {
292- const instance = createEditor ( "merge" , content ) ;
278+ const instance = createEditor ( content ) ;
293279 pressKey ( instance , "Backspace" ) ;
294280
295281 expect ( instance . document . map ( ( block ) => block . id ) ) . toEqual ( [ "parent" ] ) ;
@@ -304,16 +290,16 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
304290 } ) ;
305291 } ) ;
306292
307- it ( "still unindents with Shift-Tab in merge mode " , ( ) => {
308- const instance = createEditor ( "merge" , " Current") ;
293+ it ( "still unindents with Shift-Tab" , ( ) => {
294+ const instance = createEditor ( "Current" ) ;
309295 pressKey ( instance , "Shift-Tab" ) ;
310296 expectUnindented ( instance ) ;
311297 } ) ;
312298
313299 it . each ( [ "bulletListItem" , "numberedListItem" , "checkListItem" ] as const ) (
314300 "converts %s to a paragraph before merging" ,
315301 ( type ) => {
316- const instance = createEditor ( "merge" , " Current", type ) ;
302+ const instance = createEditor ( "Current" , type ) ;
317303 pressKey ( instance , "Backspace" ) ;
318304 expect ( instance . getBlock ( "current" ) ?. type ) . toBe ( "paragraph" ) ;
319305 expect (
@@ -328,7 +314,7 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
328314 ) ;
329315
330316 it ( "does not merge when the cursor is inside the block" , ( ) => {
331- const instance = createEditor ( "merge" , " Current") ;
317+ const instance = createEditor ( "Current" ) ;
332318 instance . setTextCursorPosition ( "current" , "end" ) ;
333319 // The shortcut must leave normal character deletion to the browser.
334320 pressKey ( instance , "Backspace" ) ;
@@ -341,7 +327,7 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
341327 } ) ;
342328
343329 function createScenario ( initialContent : PartialBlock [ ] ) {
344- const instance = createEditor ( "merge" , " ") ;
330+ const instance = createEditor ( "" ) ;
345331 instance . replaceBlocks ( instance . document , initialContent ) ;
346332 instance . setTextCursorPosition ( "current" , "start" ) ;
347333 return instance ;
@@ -750,7 +736,7 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
750736 } ) ;
751737
752738 it ( "deletes selected text before attempting to merge or unindent" , ( ) => {
753- const instance = createEditor ( "merge" , " Current") ;
739+ const instance = createEditor ( "Current" ) ;
754740 const start = instance . prosemirrorView . state . selection . from ;
755741 instance . prosemirrorView . dispatch (
756742 instance . prosemirrorView . state . tr . setSelection (
@@ -770,21 +756,18 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
770756 ) . toEqual ( [ "before" , "current" , "after" ] ) ;
771757 } ) ;
772758
773- it . each ( [ "unindent" , "merge" ] as const ) (
774- "Delete still merges forward with backspaceBehavior=%s" ,
775- ( behavior ) => {
776- const instance = createEditor ( behavior , "Current" ) ;
777- instance . setTextCursorPosition ( "before" , "end" ) ;
778- pressKey ( instance , "Delete" ) ;
779- expect ( instance . getBlock ( "current" ) ) . toBeUndefined ( ) ;
780- expect ( instance . getBlock ( "before" ) ?. content ) . toEqual ( [
781- { type : "text" , text : "BeforeCurrent" , styles : { } } ,
782- ] ) ;
783- expect (
784- instance . getBlock ( "parent" ) ?. children . map ( ( block ) => block . id ) ,
785- ) . toEqual ( [ "before" , "after" ] ) ;
786- } ,
787- ) ;
759+ it ( "Delete still merges forward" , ( ) => {
760+ const instance = createEditor ( "Current" ) ;
761+ instance . setTextCursorPosition ( "before" , "end" ) ;
762+ pressKey ( instance , "Delete" ) ;
763+ expect ( instance . getBlock ( "current" ) ) . toBeUndefined ( ) ;
764+ expect ( instance . getBlock ( "before" ) ?. content ) . toEqual ( [
765+ { type : "text" , text : "BeforeCurrent" , styles : { } } ,
766+ ] ) ;
767+ expect (
768+ instance . getBlock ( "parent" ) ?. children . map ( ( block ) => block . id ) ,
769+ ) . toEqual ( [ "before" , "after" ] ) ;
770+ } ) ;
788771
789772 it . each ( [ "image" , "table" ] as const ) (
790773 "promotes descendants of an empty only child under %s and supports undo" ,
@@ -894,4 +877,103 @@ describe("KeyboardShortcutsExtension backspaceBehavior", () => {
894877 ] ) ;
895878 expect ( instance . getBlock ( "current" ) ) . toBeUndefined ( ) ;
896879 } ) ;
880+
881+ it . each ( [ false , true ] ) (
882+ "matches PR examples 2 and 4 (previous block has children: %s)" ,
883+ ( nestedTarget ) => {
884+ const instance = createScenario ( [
885+ {
886+ id : "parent" ,
887+ content : "Parent" ,
888+ children : nestedTarget ? [ { id : "target" , content : "Target" } ] : [ ] ,
889+ } ,
890+ {
891+ id : "current" ,
892+ content : "Current" ,
893+ children : [ { id : "child" , content : "Child" } ] ,
894+ } ,
895+ ] ) ;
896+ pressKey ( instance , "Backspace" ) ;
897+ expect ( instance . document . map ( ( block ) => block . id ) ) . toEqual ( [
898+ "parent" ,
899+ "child" ,
900+ ] ) ;
901+ const target = nestedTarget ? "target" : "parent" ;
902+ expect ( instance . getBlock ( target ) ?. content ) . toEqual ( [
903+ {
904+ type : "text" ,
905+ text : `${ nestedTarget ? "Target" : "Parent" } Current` ,
906+ styles : { } ,
907+ } ,
908+ ] ) ;
909+ expect ( instance . getTextCursorPosition ( ) . block . id ) . toBe ( target ) ;
910+ expect ( instance . prosemirrorView . state . selection . $from . parentOffset ) . toBe (
911+ 6 ,
912+ ) ;
913+ expect ( instance . getBlock ( "child" ) ?. content ) . toEqual ( [
914+ { type : "text" , text : "Child" , styles : { } } ,
915+ ] ) ;
916+ } ,
917+ ) ;
918+
919+ it ( "deletes a selected nested image" , ( ) => {
920+ const instance = createScenario ( [
921+ {
922+ id : "parent" ,
923+ content : "Parent" ,
924+ children : [
925+ { id : "current" , type : "image" } ,
926+ { id : "after" , content : "After" } ,
927+ ] ,
928+ } ,
929+ ] ) ;
930+ const info = getBlockInfoFromSelection ( instance . prosemirrorView . state ) ;
931+ if ( ! info . isBlockContainer ) {
932+ throw new Error ( "Expected image block" ) ;
933+ }
934+ instance . prosemirrorView . dispatch (
935+ instance . prosemirrorView . state . tr . setSelection (
936+ NodeSelection . create (
937+ instance . prosemirrorView . state . doc ,
938+ info . blockContent . beforePos ,
939+ ) ,
940+ ) ,
941+ ) ;
942+ pressKey ( instance , "Backspace" ) ;
943+ expect ( instance . getBlock ( "current" ) ) . toBeUndefined ( ) ;
944+ expect (
945+ instance . getBlock ( "parent" ) ?. children . map ( ( block ) => block . id ) ,
946+ ) . toEqual ( [ "after" ] ) ;
947+ } ) ;
948+
949+ it ( "does nothing at the start of a nested table cell" , ( ) => {
950+ const instance = createScenario ( [
951+ {
952+ id : "parent" ,
953+ content : "Parent" ,
954+ children : [
955+ { id : "current" , ...parentSpec ( "table" ) } ,
956+ { id : "after" , content : "After" } ,
957+ ] ,
958+ } ,
959+ ] ) ;
960+ let pos : number | undefined ;
961+ instance . prosemirrorView . state . doc . descendants ( ( node , nodePos ) => {
962+ if ( node . isText && node . text === "First" ) {
963+ pos = nodePos ;
964+ }
965+ } ) ;
966+ if ( pos === undefined ) {
967+ throw new Error ( "Expected table cell text" ) ;
968+ }
969+ instance . prosemirrorView . dispatch (
970+ instance . prosemirrorView . state . tr . setSelection (
971+ TextSelection . create ( instance . prosemirrorView . state . doc , pos ) ,
972+ ) ,
973+ ) ;
974+ const before = instance . document ;
975+ pressKey ( instance , "Backspace" ) ;
976+ expect ( instance . document ) . toEqual ( before ) ;
977+ expect ( instance . prosemirrorView . state . selection . from ) . toBe ( pos ) ;
978+ } ) ;
897979} ) ;
0 commit comments