diff --git a/src/deletecommand.js b/src/deletecommand.js index 7865dd4..d47dca0 100644 --- a/src/deletecommand.js +++ b/src/deletecommand.js @@ -120,8 +120,8 @@ export default class DeleteCommand extends Command { * we want to replace the entire content with a paragraph if: * * * the current limit element is empty, - * * the paragraph is allowed in the common ancestor, - * * other paragraph does not occur in the editor. + * * the paragraph is allowed in the limit element, + * * other empty paragraph does not occur in the limit element. * * See https://github.com/ckeditor/ckeditor5-typing/issues/61. * @@ -138,9 +138,10 @@ export default class DeleteCommand extends Command { const document = this.editor.document; const selection = document.selection; const limitElement = document.schema.getLimitElement( selection ); + // If a collapsed selection contains the whole content it means that the content is empty // (from the user perspective). - const limitElementIsEmpty = selection.isCollapsed && selection.isEntireContentSelected( limitElement ); + const limitElementIsEmpty = selection.isCollapsed && selection.containsEntireContent( limitElement ); if ( !limitElementIsEmpty ) { return false; @@ -150,8 +151,10 @@ export default class DeleteCommand extends Command { return false; } - // Does nothing if editor already contains an empty paragraph. - if ( selection.getFirstRange().getCommonAncestor().name === 'paragraph' ) { + const limitElementFirstChild = limitElement.getChild( 0 ); + + // Does nothing if limit element already contains an empty paragraph. + if ( limitElementFirstChild && limitElementFirstChild.name === 'paragraph' ) { return false; } diff --git a/tests/deletecommand.js b/tests/deletecommand.js index 99cff7b..406a832 100644 --- a/tests/deletecommand.js +++ b/tests/deletecommand.js @@ -147,7 +147,7 @@ describe( 'DeleteCommand', () => { editor.execute( 'delete' ); - expect( getData( doc, { selection: true } ) ).to.equal( '[]' ); + expect( getData( doc ) ).to.equal( '[]' ); } ); it( 'leaves an empty paragraph after removing the whole content inside limit element', () => { @@ -157,24 +157,40 @@ describe( 'DeleteCommand', () => { setData( doc, 'Foo' + - '
' + - '[Header 1' + - 'Some text.]' + - '
' + + '
' + + '[Header 1' + + 'Some text.]' + + '
' + 'Bar.' ); editor.execute( 'delete' ); - expect( getData( doc, { selection: true } ) ).to.equal( + expect( getData( doc ) ).to.equal( 'Foo' + '
' + - '[]' + + '[]' + '
' + 'Bar.' ); } ); + it( 'leaves an empty paragraph after removing another paragraph from block element', () => { + doc.schema.registerItem( 'section', '$block' ); + doc.schema.registerItem( 'blockQuote', '$block' ); + doc.schema.limits.add( 'section' ); + doc.schema.allow( { name: 'section', inside: '$root' } ); + doc.schema.allow( { name: 'paragraph', inside: 'section' } ); + doc.schema.allow( { name: 'blockQuote', inside: 'section' } ); + doc.schema.allow( { name: 'paragraph', inside: 'blockQuote' } ); + + setData( doc, '
[]
' ); + + editor.execute( 'delete' ); + + expect( getData( doc ) ).to.equal( '
[]
' ); + } ); + it( 'leaves an empty paragraph after removing the whole content when root element was not added as Schema.limits', () => { doc.schema.limits.delete( '$root' ); @@ -190,7 +206,7 @@ describe( 'DeleteCommand', () => { editor.execute( 'delete' ); - expect( getData( doc, { selection: true } ) ).to.equal( '[]' ); + expect( getData( doc ) ).to.equal( '[]' ); } ); it( 'does not replace an element when Backspace or Delete key is held', () => { @@ -200,17 +216,17 @@ describe( 'DeleteCommand', () => { editor.execute( 'delete', { sequence } ); } - expect( getData( doc, { selection: true } ) ).to.equal( '[]' ); + expect( getData( doc ) ).to.equal( '[]' ); } ); - it( 'does not replace an element if a paragraph is a common ancestor', () => { + it( 'does not replace with paragraph in another paragraph already occurs in limit element', () => { setData( doc, '[]' ); - const element = doc.selection.getFirstRange().getCommonAncestor(); + const element = doc.getRoot().getNodeByPath( [ 0 ] ); editor.execute( 'delete' ); - expect( element ).is.equal( doc.selection.getFirstRange().getCommonAncestor() ); + expect( element ).is.equal( doc.getRoot().getNodeByPath( [ 0 ] ) ); } ); it( 'does not replace an element if a paragraph is not allowed in current position', () => { @@ -221,7 +237,7 @@ describe( 'DeleteCommand', () => { editor.execute( 'delete' ); // Returned data: '[]' instead of the heading element. - expect( getData( doc, { selection: true } ) ).to.equal( '[]' ); + expect( getData( doc ) ).to.equal( '[]' ); } ); } ); } );