/** * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md. */ import { clear } from '../../../src/view/writer'; import Range from '../../../src/view/range'; import { stringify, parse } from '../../../src/dev-utils/view'; import ContainerElement from '../../../src/view/containerelement'; import AttributeElement from '../../../src/view/attributeelement'; import EmptyElement from '../../../src/view/emptyelement'; import UIElement from '../../../src/view/uielement'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; describe( 'writer', () => { // Executes test using `parse` and `stringify` utils functions. Uses range delimiters `[]{}` to create ranges. // // @param {Object} elementToRemove // @param {String} input // @param {String} expectedResult function test( elementToRemove, input, expectedResult ) { const { view, selection } = parse( input ); clear( selection.getFirstRange(), elementToRemove ); expect( stringify( view, null, { showType: true } ) ).to.equal( expectedResult ); } describe( 'clear', () => { it( 'should throw when range placed in two containers', () => { const p1 = new ContainerElement( 'p' ); const p2 = new ContainerElement( 'p' ); expect( () => { clear( Range.createFromParentsAndOffsets( p1, 0, p2, 0 ) ); } ).to.throw( CKEditorError, 'view-writer-invalid-range-container' ); } ); it( 'should throw when range has no parent container', () => { const el = new AttributeElement( 'b' ); expect( () => { clear( Range.createFromParentsAndOffsets( el, 0, el, 0 ) ); } ).to.throw( CKEditorError, 'view-writer-invalid-range-container' ); } ); it( 'should remove matched element from range', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, '[bar]', 'br' ); } ); it( 'should remove matched element from range when range is inside text node', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'F{oo ba}r', 'Fo bar' ); } ); it( 'should remove multiple matched elements from range', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, '[Foo bar]', 'Fo br' ); } ); it( 'should remove multiple matched elements from range when range is inside text node', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'F{oo ba}r', 'Fo ar' ); } ); it( 'should remove only matched element', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'F{oo ba}r', 'Foo ar' ); } ); it( 'should remove part of node when range ends inside this node', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'f{ooba}r', 'foor' ); } ); it( 'should remove part of node when range starts inside this node', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'foob{arbi}z', 'foobbiz' ); } ); it( 'should remove part of node when range starts and ends inside this node', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, 'foob{a}rbiz', 'foobrbiz' ); } ); it( 'should merge after removing', () => { const elementToRemove = new AttributeElement( 'b' ); test( elementToRemove, '' + 'fo{oab}iz' + '', 'foobiz' ); } ); it( 'should remove EmptyElement', () => { const elementToRemove = new EmptyElement( 'img' ); test( elementToRemove, 'f{ooba}r', 'foobar' ); } ); it( 'should remove UIElement', () => { const elementToRemove = new UIElement( 'span' ); test( elementToRemove, 'f{ooba}r', 'foobar' ); } ); it( 'should remove ContainerElement', () => { const elementToRemove = new ContainerElement( 'p' ); test( elementToRemove, '[foobarbiz]', 'foobiz' ); } ); } ); } );