/** * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md. */ /* bender-tags: treeview */ 'use strict'; import Writer from '/ckeditor5/engine/treeview/writer.js'; import Element from '/ckeditor5/engine/treeview/element.js'; import ContainerElement from '/ckeditor5/engine/treeview/containerelement.js'; import AttributeElement from '/ckeditor5/engine/treeview/attributeelement.js'; import Position from '/ckeditor5/engine/treeview/position.js'; import Range from '/ckeditor5/engine/treeview/range.js'; import Text from '/ckeditor5/engine/treeview/text.js'; import utils from '/tests/engine/treeview/writer/_utils/utils.js'; import CKEditorError from '/ckeditor5/utils/ckeditorerror.js'; describe( 'Writer', () => { const create = utils.create; const test = utils.test; let writer; beforeEach( () => { writer = new Writer(); } ); describe( 'unwrap', () => { it( 'should do nothing on collapsed ranges', () => { const description = { instanceOf: ContainerElement, name: 'p', children: [ { instanceOf: Text, data: 'foo', rangeStart: 1, rangeEnd: 1 } ] }; const created = create( writer, description ); const newRange = writer.unwrap( created.range, new AttributeElement( 'b' ), 1 ); test( writer, newRange, created.node, description ); } ); it( 'should do nothing on single text node', () => { //
[{foobar}]
const description = { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: Text, data: 'foobar' } ] }; const created = create( writer, description ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, description ); } ); it( 'should throw error when element is not instance of AttributeElement', () => { const container = new ContainerElement( 'p', null, new AttributeElement( 'b', null, new Text( 'foo' ) ) ); const range = new Range( new Position( container, 0 ), new Position( container, 1 ) ); const b = new Element( 'b' ); expect( () => { writer.unwrap( range, b ); } ).to.throw( CKEditorError, 'treeview-writer-unwrap-invalid-attribute' ); } ); it( 'should throw error when range placed in two containers', () => { const container1 = new ContainerElement( 'p' ); const container2 = new ContainerElement( 'p' ); const range = new Range( new Position( container1, 0 ), new Position( container2, 1 ) ); const b = new AttributeElement( 'b' ); expect( () => { writer.unwrap( range, b, 1 ); } ).to.throw( CKEditorError, 'treeview-writer-invalid-range-container' ); } ); it( 'should unwrap single node', () => { //[{foobar}]
->
[{foobar}]
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'foobar' } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: Text, data: 'foobar' } ] } ); } ); it( 'should not unwrap attributes with different priorities #1', () => { //[{foobar}]
->
[{foobar}]
// Unwrapped with but using different priority. const description = { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'foobar' } ] } ] }; const created = create( writer, description ); const b = new AttributeElement( 'b' ); b.priority = 2; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, description ); } ); it( 'should not unwrap attributes with different priorities #2', () => { //[{foo}{bar}{baz}]
->
[{foo}bar{baz}]
// around `bar` has different priority than others. const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 3, children: [ { instanceOf: AttributeElement, name: 'b', priority: 2, children: [ { instanceOf: Text, data: 'foo' } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: AttributeElement, name: 'b', priority: 2, children: [ { instanceOf: Text, data: 'baz' } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 2; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 3, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: Text, data: 'baz' } ] } ); } ); it( 'should unwrap part of the node', () => { //[{baz}{foo]bar}
->
[{bazfoo}]{bar}
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, children: [ { instanceOf: Text, data: 'baz' }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'foobar', rangeEnd: 3 } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: Text, data: 'bazfoo' }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] } ] } ); } ); it( 'should unwrap nested attributes', () => { //[{foobar}]
->[{foobar}]
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'foobar' } ] } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'foobar' } ] } ] } ); } ); it( 'should merge unwrapped nodes #1', () => { //{foo}[{bar}]{bom}
->{foo[bar]bom}
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 1, rangeEnd: 2, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: Text, data: 'bom' } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', children: [ { instanceOf: Text, data: 'foobarbom', rangeStart: 3, rangeEnd: 6 } ] } ); } ); it( 'should merge unwrapped nodes #2', () => { //{foo}{bar}[{bazqux}]
->{foo}{bar[bazqux}]
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 2, rangeEnd: 3, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bazqux' } ] } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeEnd: 2, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'barbazqux', rangeStart: 3 } ] } ] } ); } ); it( 'should merge unwrapped nodes #3', () => { //{foo}{bar}[{baz]qux}
->{foo}{bar[baz}]{qux}
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 2, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bazqux', rangeEnd: 3 } ] } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeEnd: 2, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'barbaz', rangeStart: 3 } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'qux' } ] } ] } ] } ); } ); it( 'should merge unwrapped nodes #4', () => { //{foo}{bar}[{baz}]qux
->{foo}{bar[baz]qux}
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 2, rangeEnd: 3, children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'baz' } ] } ] }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'qux' } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', children: [ { instanceOf: Text, data: 'foo' }, { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'barbazqux', rangeStart: 3, rangeEnd: 6 } ] } ] } ); } ); it( 'should merge unwrapped nodes #5', () => { //[{foo}{bar}{baz}]
->[{foobarbaz}]
const created = create( writer, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 3, children: [ { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'foo' } ] } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'bar' } ] } ] }, { instanceOf: AttributeElement, name: 'b', priority: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'baz' } ] } ] } ] } ); const b = new AttributeElement( 'b' ); b.priority = 1; const newRange = writer.unwrap( created.range, b ); test( writer, newRange, created.node, { instanceOf: ContainerElement, name: 'p', rangeStart: 0, rangeEnd: 1, children: [ { instanceOf: AttributeElement, name: 'u', priority: 1, children: [ { instanceOf: Text, data: 'foobarbaz' } ] } ] } ); } ); it( 'should unwrap mixed ranges #1', () => { //[{foo}]
->[{foo}]
{ //[{foo]}
->[{foo}]