/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/* global document */
import Typing from '../src/typing';
import DeleteCommand from '../src/deletecommand';
import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
import Heading from '@ckeditor/ckeditor5-heading/src/heading';
import List from '@ckeditor/ckeditor5-list/src/list';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
describe( 'DeleteCommand integration', () => {
let editor, model;
beforeEach( () => {
return ModelTestEditor
.create( {
plugins: [ UndoEditing ],
typing: {
undoStep: 3
}
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;
const command = new DeleteCommand( editor, 'backward' );
editor.commands.add( 'delete', command );
// Mock paragraph feature.
model.schema.register( 'paragraph', { inheritAllFrom: '$block' } );
model.schema.extend( 'paragraph', { allowIn: '$block' } );
model.schema.register( 'softBreak', { allowWhere: '$text', isInline: true } );
model.schema.register( 'img', {
allowWhere: '$text',
isObject: true
} );
model.schema.extend( '$text', { allowIn: 'img' } );
} );
} );
afterEach( () => {
return editor.destroy();
} );
function assertOutput( output ) {
expect( getData( model ) ).to.equal( output );
}
describe( 'with undo', () => {
it( 'deletes characters (and group changes in batches) and rollbacks', () => {
setData( model, '123456789[]' );
for ( let i = 0; i < 3; ++i ) {
editor.execute( 'delete' );
}
editor.execute( 'undo' );
assertOutput( '123456789[]' );
} );
it( 'deletes characters (and group changes in batches) and rollbacks - test step', () => {
setData( model, '123456789[]' );
for ( let i = 0; i < 6; ++i ) {
editor.execute( 'delete' );
}
editor.execute( 'undo' );
assertOutput( '123456[]' );
editor.execute( 'undo' );
assertOutput( '123456789[]' );
} );
it( 'deletes elements (and group changes in batches) and rollbacks', () => {
setData( model, '
1
2
3
4
5
6[]' );
for ( let i = 0; i < 3; ++i ) {
editor.execute( 'delete' );
}
editor.execute( 'undo' );
assertOutput( '
1
2
3
4
5
6[]' );
} );
it( 'merges elements (and group changes in batches) and rollbacks', () => {
setData( model, '123456[]78' );
for ( let i = 0; i < 6; ++i ) {
editor.execute( 'delete' );
}
editor.execute( 'undo' );
// Deleted 6,5,4, does not count.
// It's not the most elegant solution, but is the best if we don't want to make complicated algorithm.
assertOutput( '123[]78' );
editor.execute( 'undo' );
// Selection restoing in undo is not 100% correct so slight miss-settings are expected as long as
// the selection makes any sense and is near the correct position.
assertOutput( '123456[]78' );
} );
it( 'merges elements (and group changes in batches) and rollbacks - non-collapsed selection', () => {
setData( model, '12345[67]8' );
editor.execute( 'delete' );
editor.execute( 'delete' );
editor.execute( 'delete' );
editor.execute( 'undo' );
assertOutput( '1234[]8' );
editor.execute( 'undo' );
assertOutput( '12345[67]8' );
} );
} );
describe( 'with DataController.deleteContent', () => {
beforeEach( () => {
model.schema.register( 'h1', { inheritAllFrom: '$block' } );
} );
it( 'should replace content with paragraph - if whole content is selected', () => {
setData( model, '[foo
bar]' );
editor.execute( 'delete' );
assertOutput( '[]' );
} );
it( 'should not replace content with paragraph - if not whole content is selected', () => {
setData( model, 'f[oo
bar]' );
editor.execute( 'delete' );
assertOutput( 'f[]
' );
} );
it( 'should not replace content with paragraph - if selection was collapsed', () => {
setData( model, '[]' );
editor.execute( 'delete' );
assertOutput( '[]
' );
} );
} );
describe( 'with multi-range selection', () => {
let element, editor, model;
beforeEach( () => {
element = document.createElement( 'div' );
document.body.appendChild( element );
return ClassicEditor
.create( element, {
plugins: [ Typing, Heading, List, Image, ImageCaption, Paragraph, BlockQuote ]
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;
} );
} );
afterEach( () => {
element.remove();
return editor.destroy();
} );
it( 'should not throw an error if content with the image is being removed', () => {
setData( model,
'OL List i[tem 1' +
'OL List item 2]' +
'[Caption' +
'' +
'Quote' +
'Quoted UL List item 1' +
'Quote]d UL List item 2' +
'Quote' +
'
'
);
expect( () => {
editor.execute( 'delete' );
} ).to.not.throw();
} );
} );
// See: https://github.com/ckeditor/ckeditor5/issues/1064
it( 'should remove entire word in a paragraph that contains the soft break', () => {
setData( model, 'Foo.Bar[]' );
editor.execute( 'delete', { unit: 'word' } );
assertOutput( 'Foo.[]' );
} );
} );