|
|
@@ -10,26 +10,24 @@ import deleteContents from '/ckeditor5/engine/model/composer/deletecontents.js';
|
|
|
import { setData, getData } from '/ckeditor5/engine/dev-utils/model.js';
|
|
|
|
|
|
describe( 'Delete utils', () => {
|
|
|
- let document;
|
|
|
+ let doc;
|
|
|
|
|
|
beforeEach( () => {
|
|
|
- document = new Document();
|
|
|
- document.createRoot();
|
|
|
+ doc = new Document();
|
|
|
+ doc.createRoot();
|
|
|
|
|
|
- const schema = document.schema;
|
|
|
+ const schema = doc.schema;
|
|
|
|
|
|
- // Note: We used short names instead of "image", "paragraph", etc. to make the tests shorter.
|
|
|
- // We could use any random names in fact, but using HTML tags may explain the tests a bit better.
|
|
|
- schema.registerItem( 'img', '$inline' );
|
|
|
- schema.registerItem( 'p', '$block' );
|
|
|
- schema.registerItem( 'h1', '$block' );
|
|
|
+ schema.registerItem( 'image', '$inline' );
|
|
|
+ schema.registerItem( 'paragraph', '$block' );
|
|
|
+ schema.registerItem( 'heading1', '$block' );
|
|
|
schema.registerItem( 'pchild' );
|
|
|
|
|
|
- schema.allow( { name: 'pchild', inside: 'p' } );
|
|
|
+ schema.allow( { name: 'pchild', inside: 'paragraph' } );
|
|
|
schema.allow( { name: '$text', inside: '$root' } );
|
|
|
- schema.allow( { name: 'img', inside: '$root' } );
|
|
|
+ schema.allow( { name: 'image', inside: '$root' } );
|
|
|
schema.allow( { name: '$text', attributes: [ 'bold', 'italic' ] } );
|
|
|
- schema.allow( { name: 'p', attributes: [ 'align' ] } );
|
|
|
+ schema.allow( { name: 'paragraph', attributes: [ 'align' ] } );
|
|
|
} );
|
|
|
|
|
|
describe( 'deleteContents', () => {
|
|
|
@@ -47,11 +45,11 @@ describe( 'Delete utils', () => {
|
|
|
);
|
|
|
|
|
|
it( 'deletes single character (backward selection)' , () => {
|
|
|
- setData( document, 'f[o]o', { lastRangeBackward: true } );
|
|
|
+ setData( doc, 'f[o]o', { lastRangeBackward: true } );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection );
|
|
|
+ deleteContents( doc.batch(), doc.selection );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( 'f[]o' );
|
|
|
+ expect( getData( doc ) ).to.equal( 'f[]o' );
|
|
|
} );
|
|
|
|
|
|
test(
|
|
|
@@ -62,25 +60,25 @@ describe( 'Delete utils', () => {
|
|
|
|
|
|
test(
|
|
|
'deletes whole text between nodes',
|
|
|
- '<img></img>[foo]<img></img>',
|
|
|
- '<img></img>[]<img></img>'
|
|
|
+ '<image></image>[foo]<image></image>',
|
|
|
+ '<image></image>[]<image></image>'
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'deletes an element',
|
|
|
- 'x[<img></img>]y',
|
|
|
+ 'x[<image></image>]y',
|
|
|
'x[]y'
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'deletes a bunch of nodes',
|
|
|
- 'w[x<img></img>y]z',
|
|
|
+ 'w[x<image></image>y]z',
|
|
|
'w[]z'
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'does not break things when option.merge passed',
|
|
|
- 'w[x<img></img>y]z',
|
|
|
+ 'w[x<image></image>y]z',
|
|
|
'w[]z',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
@@ -88,47 +86,53 @@ describe( 'Delete utils', () => {
|
|
|
|
|
|
describe( 'with text attributes', () => {
|
|
|
it( 'deletes characters (first half has attrs)', () => {
|
|
|
- setData( document, '<$text bold="true">fo[o</$text>b]ar', { selectionAttributes: {
|
|
|
+ setData( doc, '<$text bold="true">fo[o</$text>b]ar', { selectionAttributes: {
|
|
|
bold: true
|
|
|
} } );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection );
|
|
|
+ deleteContents( doc.batch(), doc.selection );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( '<$text bold="true">fo[]</$text>ar' );
|
|
|
- expect( document.selection.getAttribute( 'bold' ) ).to.equal( true );
|
|
|
+ expect( getData( doc ) ).to.equal( '<$text bold="true">fo[]</$text>ar' );
|
|
|
+ expect( doc.selection.getAttribute( 'bold' ) ).to.equal( true );
|
|
|
} );
|
|
|
|
|
|
it( 'deletes characters (2nd half has attrs)', () => {
|
|
|
- setData( document, 'fo[o<$text bold="true">b]ar</$text>', { selectionAttributes: {
|
|
|
+ setData( doc, 'fo[o<$text bold="true">b]ar</$text>', { selectionAttributes: {
|
|
|
bold: true
|
|
|
} } );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection );
|
|
|
+ deleteContents( doc.batch(), doc.selection );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( 'fo[]<$text bold="true">ar</$text>' );
|
|
|
- expect( document.selection.getAttribute( 'bold' ) ).to.undefined;
|
|
|
+ expect( getData( doc ) ).to.equal( 'fo[]<$text bold="true">ar</$text>' );
|
|
|
+ expect( doc.selection.getAttribute( 'bold' ) ).to.undefined;
|
|
|
} );
|
|
|
|
|
|
it( 'clears selection attrs when emptied content', () => {
|
|
|
- setData( document, '<p>x</p><p>[<$text bold="true">foo</$text>]</p><p>y</p>', { selectionAttributes: {
|
|
|
- bold: true
|
|
|
- } } );
|
|
|
-
|
|
|
- deleteContents( document.batch(), document.selection );
|
|
|
-
|
|
|
- expect( getData( document ) ).to.equal( '<p>x</p><p>[]</p><p>y</p>' );
|
|
|
- expect( document.selection.getAttribute( 'bold' ) ).to.undefined;
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<paragraph>x</paragraph><paragraph>[<$text bold="true">foo</$text>]</paragraph><paragraph>y</paragraph>',
|
|
|
+ {
|
|
|
+ selectionAttributes: {
|
|
|
+ bold: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ deleteContents( doc.batch(), doc.selection );
|
|
|
+
|
|
|
+ expect( getData( doc ) ).to.equal( '<paragraph>x</paragraph><paragraph>[]</paragraph><paragraph>y</paragraph>' );
|
|
|
+ expect( doc.selection.getAttribute( 'bold' ) ).to.undefined;
|
|
|
} );
|
|
|
|
|
|
it( 'leaves selection attributes when text contains them', () => {
|
|
|
- setData( document, '<p>x<$text bold="true">a[foo]b</$text>y</p>', { selectionAttributes: {
|
|
|
+ setData( doc, '<paragraph>x<$text bold="true">a[foo]b</$text>y</paragraph>', { selectionAttributes: {
|
|
|
bold: true
|
|
|
} } );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection );
|
|
|
+ deleteContents( doc.batch(), doc.selection );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( '<p>x<$text bold="true">a[]b</$text>y</p>' );
|
|
|
- expect( document.selection.getAttribute( 'bold' ) ).to.equal( true );
|
|
|
+ expect( getData( doc ) ).to.equal( '<paragraph>x<$text bold="true">a[]b</$text>y</paragraph>' );
|
|
|
+ expect( doc.selection.getAttribute( 'bold' ) ).to.equal( true );
|
|
|
} );
|
|
|
} );
|
|
|
|
|
|
@@ -144,113 +148,117 @@ describe( 'Delete utils', () => {
|
|
|
describe( 'in multi-element scenarios', () => {
|
|
|
test(
|
|
|
'do not merge when no need to',
|
|
|
- '<p>x</p><p>[foo]</p><p>y</p>',
|
|
|
- '<p>x</p><p>[]</p><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>[foo]</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>[]</paragraph><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges second element into the first one (same name)',
|
|
|
- '<p>x</p><p>fo[o</p><p>b]ar</p><p>y</p>',
|
|
|
- '<p>x</p><p>fo[]ar</p><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[o</paragraph><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[]ar</paragraph><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'does not merge second element into the first one (same name, !option.merge)',
|
|
|
- '<p>x</p><p>fo[o</p><p>b]ar</p><p>y</p>',
|
|
|
- '<p>x</p><p>fo[]</p><p>ar</p><p>y</p>'
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[o</paragraph><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[]</paragraph><paragraph>ar</paragraph><paragraph>y</paragraph>'
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges second element into the first one (same name)',
|
|
|
- '<p>x</p><p>fo[o</p><p>b]ar</p><p>y</p>',
|
|
|
- '<p>x</p><p>fo[]ar</p><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[o</paragraph><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><paragraph>fo[]ar</paragraph><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges second element into the first one (different name)',
|
|
|
- '<p>x</p><h1>fo[o</h1><p>b]ar</p><p>y</p>',
|
|
|
- '<p>x</p><h1>fo[]ar</h1><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><heading1>fo[o</heading1><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><heading1>fo[]ar</heading1><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
it( 'merges second element into the first one (different name, backward selection)', () => {
|
|
|
- setData( document, '<p>x</p><h1>fo[o</h1><p>b]ar</p><p>y</p>', { lastRangeBackward: true } );
|
|
|
+ setData(
|
|
|
+ doc,
|
|
|
+ '<paragraph>x</paragraph><heading1>fo[o</heading1><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ { lastRangeBackward: true }
|
|
|
+ );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection, { merge: true } );
|
|
|
+ deleteContents( doc.batch(), doc.selection, { merge: true } );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( '<p>x</p><h1>fo[]ar</h1><p>y</p>' );
|
|
|
+ expect( getData( doc ) ).to.equal( '<paragraph>x</paragraph><heading1>fo[]ar</heading1><paragraph>y</paragraph>' );
|
|
|
} );
|
|
|
|
|
|
test(
|
|
|
'merges second element into the first one (different attrs)',
|
|
|
- '<p>x</p><p align="l">fo[o</p><p>b]ar</p><p>y</p>',
|
|
|
- '<p>x</p><p align="l">fo[]ar</p><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><paragraph align="l">fo[o</paragraph><paragraph>b]ar</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><paragraph align="l">fo[]ar</paragraph><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges second element to an empty first element',
|
|
|
- '<p>x</p><h1>[</h1><p>fo]o</p><p>y</p>',
|
|
|
- '<p>x</p><h1>[]o</h1><p>y</p>',
|
|
|
+ '<paragraph>x</paragraph><heading1>[</heading1><paragraph>fo]o</paragraph><paragraph>y</paragraph>',
|
|
|
+ '<paragraph>x</paragraph><heading1>[]o</heading1><paragraph>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges elements when deep nested',
|
|
|
- '<p>x<pchild>fo[o</pchild></p><p><pchild>b]ar</pchild>y</p>',
|
|
|
- '<p>x<pchild>fo[]ar</pchild>y</p>',
|
|
|
+ '<paragraph>x<pchild>fo[o</pchild></paragraph><paragraph><pchild>b]ar</pchild>y</paragraph>',
|
|
|
+ '<paragraph>x<pchild>fo[]ar</pchild>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
// For code coverage reasons.
|
|
|
test(
|
|
|
'merges element when selection is in two consecutive nodes even when it is empty',
|
|
|
- '<p>foo[</p><p>]bar</p>',
|
|
|
- '<p>foo[]bar</p>',
|
|
|
+ '<paragraph>foo[</paragraph><paragraph>]bar</paragraph>',
|
|
|
+ '<paragraph>foo[]bar</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
// If you disagree with this case please read the notes before this section.
|
|
|
test(
|
|
|
'merges elements when left end deep nested',
|
|
|
- '<p>x<pchild>fo[o</pchild></p><p>b]ary</p>',
|
|
|
- '<p>x<pchild>fo[]</pchild>ary</p>',
|
|
|
+ '<paragraph>x<pchild>fo[o</pchild></paragraph><paragraph>b]ary</paragraph>',
|
|
|
+ '<paragraph>x<pchild>fo[]</pchild>ary</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
// If you disagree with this case please read the notes before this section.
|
|
|
test(
|
|
|
'merges elements when right end deep nested',
|
|
|
- '<p>xfo[o</p><p><pchild>b]ar</pchild>y<img></img></p>',
|
|
|
- '<p>xfo[]<pchild>ar</pchild>y<img></img></p>',
|
|
|
+ '<paragraph>xfo[o</paragraph><paragraph><pchild>b]ar</pchild>y<image></image></paragraph>',
|
|
|
+ '<paragraph>xfo[]<pchild>ar</pchild>y<image></image></paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'merges elements when more content in the right branch',
|
|
|
- '<p>xfo[o</p><p>b]a<pchild>r</pchild>y</p>',
|
|
|
- '<p>xfo[]a<pchild>r</pchild>y</p>',
|
|
|
+ '<paragraph>xfo[o</paragraph><paragraph>b]a<pchild>r</pchild>y</paragraph>',
|
|
|
+ '<paragraph>xfo[]a<pchild>r</pchild>y</paragraph>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
|
|
|
test(
|
|
|
'leaves just one element when all selected',
|
|
|
- '<h1>[x</h1><p>foo</p><p>y]</p>',
|
|
|
- '<h1>[]</h1>',
|
|
|
+ '<heading1>[x</heading1><paragraph>foo</paragraph><paragraph>y]</paragraph>',
|
|
|
+ '<heading1>[]</heading1>',
|
|
|
{ merge: true }
|
|
|
);
|
|
|
} );
|
|
|
|
|
|
function test( title, input, output, options ) {
|
|
|
it( title, () => {
|
|
|
- setData( document, input );
|
|
|
+ setData( doc, input );
|
|
|
|
|
|
- deleteContents( document.batch(), document.selection, options );
|
|
|
+ deleteContents( doc.batch(), doc.selection, options );
|
|
|
|
|
|
- expect( getData( document ) ).to.equal( output );
|
|
|
+ expect( getData( doc ) ).to.equal( output );
|
|
|
} );
|
|
|
}
|
|
|
} );
|