|
@@ -3,21 +3,21 @@
|
|
|
* For licensing, see LICENSE.md.
|
|
* For licensing, see LICENSE.md.
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-import Document from '../../src/model/document';
|
|
|
|
|
-import DocumentFragment from '../../src/model/documentfragment';
|
|
|
|
|
-import Element from '../../src/model/element';
|
|
|
|
|
-import Text from '../../src/model/text';
|
|
|
|
|
-import TextProxy from '../../src/model/textproxy';
|
|
|
|
|
-import Position from '../../src/model/position';
|
|
|
|
|
-import Range from '../../src/model/range';
|
|
|
|
|
-import writer from '../../src/model/writer';
|
|
|
|
|
-import { getData } from '../../src/dev-utils/model';
|
|
|
|
|
|
|
+import Document from '../../../src/model/document';
|
|
|
|
|
+import DocumentFragment from '../../../src/model/documentfragment';
|
|
|
|
|
+import Element from '../../../src/model/element';
|
|
|
|
|
+import Text from '../../../src/model/text';
|
|
|
|
|
+import TextProxy from '../../../src/model/textproxy';
|
|
|
|
|
+import Position from '../../../src/model/position';
|
|
|
|
|
+import Range from '../../../src/model/range';
|
|
|
|
|
+import utils from '../../../src/model/operation/utils';
|
|
|
|
|
+import { getData } from '../../../src/dev-utils/model';
|
|
|
|
|
|
|
|
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
|
|
|
|
|
|
let doc, root;
|
|
let doc, root;
|
|
|
|
|
|
|
|
-describe( 'writer', () => {
|
|
|
|
|
|
|
+describe( 'writer utils', () => {
|
|
|
beforeEach( () => {
|
|
beforeEach( () => {
|
|
|
doc = new Document();
|
|
doc = new Document();
|
|
|
doc.schema.allow( { name: '$text', inside: '$root' } );
|
|
doc.schema.allow( { name: '$text', inside: '$root' } );
|
|
@@ -38,19 +38,19 @@ describe( 'writer', () => {
|
|
|
|
|
|
|
|
describe( 'insert', () => {
|
|
describe( 'insert', () => {
|
|
|
it( 'should insert nodes between nodes', () => {
|
|
it( 'should insert nodes between nodes', () => {
|
|
|
- writer.insert( Position.createAt( root, 3 ), [ 'xxx', new Element( 'p' ) ] );
|
|
|
|
|
|
|
+ utils.insert( Position.createAt( root, 3 ), [ 'xxx', new Element( 'p' ) ] );
|
|
|
|
|
|
|
|
expectData( 'fooxxx<p></p><$text bold="true">bar</$text><image src="img.jpg"></image>xyz' );
|
|
expectData( 'fooxxx<p></p><$text bold="true">bar</$text><image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should split text node if nodes at inserted at offset inside text node', () => {
|
|
it( 'should split text node if nodes at inserted at offset inside text node', () => {
|
|
|
- writer.insert( Position.createAt( root, 5 ), new Element( 'p' ) );
|
|
|
|
|
|
|
+ utils.insert( Position.createAt( root, 5 ), new Element( 'p' ) );
|
|
|
|
|
|
|
|
expectData( 'foo<$text bold="true">ba</$text><p></p><$text bold="true">r</$text><image src="img.jpg"></image>xyz' );
|
|
expectData( 'foo<$text bold="true">ba</$text><p></p><$text bold="true">r</$text><image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should merge text nodes if possible', () => {
|
|
it( 'should merge text nodes if possible', () => {
|
|
|
- writer.insert( Position.createAt( root, 3 ), new Text( 'xxx', { bold: true } ) );
|
|
|
|
|
|
|
+ utils.insert( Position.createAt( root, 3 ), new Text( 'xxx', { bold: true } ) );
|
|
|
|
|
|
|
|
expectData( 'foo<$text bold="true">xxxbar</$text><image src="img.jpg"></image>xyz' );
|
|
expectData( 'foo<$text bold="true">xxxbar</$text><image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
@@ -59,21 +59,21 @@ describe( 'writer', () => {
|
|
|
describe( 'remove', () => {
|
|
describe( 'remove', () => {
|
|
|
it( 'should remove nodes in given range', () => {
|
|
it( 'should remove nodes in given range', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
|
- writer.remove( range );
|
|
|
|
|
|
|
+ utils.remove( range );
|
|
|
|
|
|
|
|
expectData( 'foo<image src="img.jpg"></image>xyz' );
|
|
expectData( 'foo<image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should split text node if range starts or ends inside text node', () => {
|
|
it( 'should split text node if range starts or ends inside text node', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 1, root, 5 );
|
|
const range = Range.createFromParentsAndOffsets( root, 1, root, 5 );
|
|
|
- writer.remove( range );
|
|
|
|
|
|
|
+ utils.remove( range );
|
|
|
|
|
|
|
|
expectData( 'f<$text bold="true">r</$text><image src="img.jpg"></image>xyz' );
|
|
expectData( 'f<$text bold="true">r</$text><image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should merge text nodes if possible', () => {
|
|
it( 'should merge text nodes if possible', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 7 );
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 7 );
|
|
|
- writer.remove( range );
|
|
|
|
|
|
|
+ utils.remove( range );
|
|
|
|
|
|
|
|
expectData( 'fooxyz' );
|
|
expectData( 'fooxyz' );
|
|
|
expect( root.childCount ).to.equal( 1 );
|
|
expect( root.childCount ).to.equal( 1 );
|
|
@@ -81,89 +81,66 @@ describe( 'writer', () => {
|
|
|
|
|
|
|
|
it( 'should throw if given range is not flat', () => {
|
|
it( 'should throw if given range is not flat', () => {
|
|
|
expect( () => {
|
|
expect( () => {
|
|
|
- writer.remove( new Range( new Position( root, [ 0 ] ), new Position( root, [ 1, 2 ] ) ) );
|
|
|
|
|
- } ).to.throw( CKEditorError, /model-writer-remove-range-not-flat/ );
|
|
|
|
|
|
|
+ utils.remove( new Range( new Position( root, [ 0 ] ), new Position( root, [ 1, 2 ] ) ) );
|
|
|
|
|
+ } ).to.throw( CKEditorError, /operation-utils-remove-range-not-flat/ );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
describe( 'move', () => {
|
|
describe( 'move', () => {
|
|
|
it( 'should move a range of nodes', () => {
|
|
it( 'should move a range of nodes', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
|
- writer.move( range, Position.createAt( root, 0 ) );
|
|
|
|
|
|
|
+ utils.move( range, Position.createAt( root, 0 ) );
|
|
|
|
|
|
|
|
expectData( '<$text bold="true">bar</$text>foo<image src="img.jpg"></image>xyz' );
|
|
expectData( '<$text bold="true">bar</$text>foo<image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- it( 'should use remove and insert methods', () => {
|
|
|
|
|
- sinon.spy( writer, 'remove' );
|
|
|
|
|
- sinon.spy( writer, 'insert' );
|
|
|
|
|
-
|
|
|
|
|
- const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
|
|
|
- const position = Position.createAt( root, 0 );
|
|
|
|
|
- writer.move( range, position );
|
|
|
|
|
-
|
|
|
|
|
- expect( writer.remove.calledWithExactly( range ) ).to.be.true;
|
|
|
|
|
- expect( writer.insert.calledWith( position ) ).to.be.true;
|
|
|
|
|
- } );
|
|
|
|
|
-
|
|
|
|
|
it( 'should correctly move if target position is in same element as moved range, but after range', () => {
|
|
it( 'should correctly move if target position is in same element as moved range, but after range', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
const range = Range.createFromParentsAndOffsets( root, 3, root, 6 );
|
|
|
- writer.move( range, Position.createAt( root, 10 ) );
|
|
|
|
|
|
|
+ utils.move( range, Position.createAt( root, 10 ) );
|
|
|
|
|
|
|
|
expectData( 'foo<image src="img.jpg"></image>xyz<$text bold="true">bar</$text>' );
|
|
expectData( 'foo<image src="img.jpg"></image>xyz<$text bold="true">bar</$text>' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should throw if given range is not flat', () => {
|
|
it( 'should throw if given range is not flat', () => {
|
|
|
expect( () => {
|
|
expect( () => {
|
|
|
- writer.move( new Range( new Position( root, [ 0 ] ), new Position( root, [ 1, 2 ] ) ), null );
|
|
|
|
|
- } ).to.throw( CKEditorError, /model-writer-move-range-not-flat/ );
|
|
|
|
|
|
|
+ utils.move( new Range( new Position( root, [ 0 ] ), new Position( root, [ 1, 2 ] ) ), null );
|
|
|
|
|
+ } ).to.throw( CKEditorError, /operation-utils-move-range-not-flat/ );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
describe( 'setAttribute', () => {
|
|
describe( 'setAttribute', () => {
|
|
|
it( 'should set attribute on given range of nodes', () => {
|
|
it( 'should set attribute on given range of nodes', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 6, root, 8 );
|
|
const range = Range.createFromParentsAndOffsets( root, 6, root, 8 );
|
|
|
- writer.setAttribute( range, 'newAttr', true );
|
|
|
|
|
|
|
+ utils.setAttribute( range, 'newAttr', true );
|
|
|
|
|
|
|
|
expectData( 'foo<$text bold="true">bar</$text><image newAttr="true" src="img.jpg"></image><$text newAttr="true">x</$text>yz' );
|
|
expectData( 'foo<$text bold="true">bar</$text><image newAttr="true" src="img.jpg"></image><$text newAttr="true">x</$text>yz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should remove attribute if null was passed as a value', () => {
|
|
it( 'should remove attribute if null was passed as a value', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 6, root, 7 );
|
|
const range = Range.createFromParentsAndOffsets( root, 6, root, 7 );
|
|
|
- writer.setAttribute( range, 'src', null );
|
|
|
|
|
|
|
+ utils.setAttribute( range, 'src', null );
|
|
|
|
|
|
|
|
expectData( 'foo<$text bold="true">bar</$text><image></image>xyz' );
|
|
expectData( 'foo<$text bold="true">bar</$text><image></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should merge nodes if possible', () => {
|
|
it( 'should merge nodes if possible', () => {
|
|
|
const range = Range.createFromParentsAndOffsets( root, 0, root, 3 );
|
|
const range = Range.createFromParentsAndOffsets( root, 0, root, 3 );
|
|
|
- writer.setAttribute( range, 'bold', true );
|
|
|
|
|
|
|
+ utils.setAttribute( range, 'bold', true );
|
|
|
|
|
|
|
|
expectData( '<$text bold="true">foobar</$text><image src="img.jpg"></image>xyz' );
|
|
expectData( '<$text bold="true">foobar</$text><image src="img.jpg"></image>xyz' );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
-
|
|
|
|
|
- describe( 'removeAttribute', () => {
|
|
|
|
|
- it( 'should use setAttribute', () => {
|
|
|
|
|
- sinon.spy( writer, 'setAttribute' );
|
|
|
|
|
-
|
|
|
|
|
- const range = Range.createFromParentsAndOffsets( root, 6, root, 7 );
|
|
|
|
|
- writer.removeAttribute( range, 'src' );
|
|
|
|
|
-
|
|
|
|
|
- expect( writer.setAttribute.calledWithExactly( range, 'src', null ) ).to.be.true;
|
|
|
|
|
- } );
|
|
|
|
|
- } );
|
|
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
describe( 'normalizeNodes', () => {
|
|
describe( 'normalizeNodes', () => {
|
|
|
it( 'should change single object into an array', () => {
|
|
it( 'should change single object into an array', () => {
|
|
|
const p = new Element( 'p' );
|
|
const p = new Element( 'p' );
|
|
|
|
|
|
|
|
- expect( writer.normalizeNodes( p ) ).to.deep.equal( [ p ] );
|
|
|
|
|
|
|
+ expect( utils.normalizeNodes( p ) ).to.deep.equal( [ p ] );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should change strings to text nodes', () => {
|
|
it( 'should change strings to text nodes', () => {
|
|
|
- const text = writer.normalizeNodes( 'abc' )[ 0 ];
|
|
|
|
|
|
|
+ const text = utils.normalizeNodes( 'abc' )[ 0 ];
|
|
|
|
|
|
|
|
expect( text ).to.be.instanceof( Text );
|
|
expect( text ).to.be.instanceof( Text );
|
|
|
expect( text.data ).to.equal( 'abc' );
|
|
expect( text.data ).to.equal( 'abc' );
|
|
@@ -173,7 +150,7 @@ describe( 'normalizeNodes', () => {
|
|
|
const textNode = new Text( 'abc' );
|
|
const textNode = new Text( 'abc' );
|
|
|
const textProxy = new TextProxy( textNode, 1, 1 );
|
|
const textProxy = new TextProxy( textNode, 1, 1 );
|
|
|
|
|
|
|
|
- const text = writer.normalizeNodes( textProxy )[ 0 ];
|
|
|
|
|
|
|
+ const text = utils.normalizeNodes( textProxy )[ 0 ];
|
|
|
|
|
|
|
|
expect( text ).to.be.instanceof( Text );
|
|
expect( text ).to.be.instanceof( Text );
|
|
|
expect( text.data ).to.equal( 'b' );
|
|
expect( text.data ).to.equal( 'b' );
|
|
@@ -182,11 +159,11 @@ describe( 'normalizeNodes', () => {
|
|
|
it( 'should not change elements', () => {
|
|
it( 'should not change elements', () => {
|
|
|
const p = new Element( 'p' );
|
|
const p = new Element( 'p' );
|
|
|
|
|
|
|
|
- expect( writer.normalizeNodes( p )[ 0 ] ).to.equal( p );
|
|
|
|
|
|
|
+ expect( utils.normalizeNodes( p )[ 0 ] ).to.equal( p );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should omit unrecognized objects', () => {
|
|
it( 'should omit unrecognized objects', () => {
|
|
|
- expect( writer.normalizeNodes( 1 ) ).to.deep.equal( [] );
|
|
|
|
|
|
|
+ expect( utils.normalizeNodes( 1 ) ).to.deep.equal( [] );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should accept arrays', () => {
|
|
it( 'should accept arrays', () => {
|
|
@@ -194,7 +171,7 @@ describe( 'normalizeNodes', () => {
|
|
|
const image = new Element( 'image' );
|
|
const image = new Element( 'image' );
|
|
|
const nodes = [ 'abc', text, image, 1, 'xyz' ];
|
|
const nodes = [ 'abc', text, image, 1, 'xyz' ];
|
|
|
|
|
|
|
|
- const normalized = writer.normalizeNodes( nodes );
|
|
|
|
|
|
|
+ const normalized = utils.normalizeNodes( nodes );
|
|
|
|
|
|
|
|
expect( normalized[ 0 ] ).to.be.instanceof( Text );
|
|
expect( normalized[ 0 ] ).to.be.instanceof( Text );
|
|
|
expect( normalized[ 1 ] ).to.equal( text );
|
|
expect( normalized[ 1 ] ).to.equal( text );
|
|
@@ -203,7 +180,7 @@ describe( 'normalizeNodes', () => {
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
it( 'should merge text nodes if mergeTextNodes flag is set to true', () => {
|
|
it( 'should merge text nodes if mergeTextNodes flag is set to true', () => {
|
|
|
- const normalized = writer.normalizeNodes( [ 'foo', 'bar' ], true );
|
|
|
|
|
|
|
+ const normalized = utils.normalizeNodes( [ 'foo', 'bar' ], true );
|
|
|
|
|
|
|
|
expect( normalized.length ).to.equal( 1 );
|
|
expect( normalized.length ).to.equal( 1 );
|
|
|
expect( normalized[ 0 ].data ).to.equal( 'foobar' );
|
|
expect( normalized[ 0 ].data ).to.equal( 'foobar' );
|
|
@@ -216,7 +193,7 @@ describe( 'normalizeNodes', () => {
|
|
|
'xyz'
|
|
'xyz'
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
- const normalized = writer.normalizeNodes( nodes, true );
|
|
|
|
|
|
|
+ const normalized = utils.normalizeNodes( nodes, true );
|
|
|
|
|
|
|
|
expect( normalized[ 0 ] ).to.be.instanceof( Text );
|
|
expect( normalized[ 0 ] ).to.be.instanceof( Text );
|
|
|
expect( normalized[ 0 ].getAttribute( 'bold' ) ).to.be.true;
|
|
expect( normalized[ 0 ].getAttribute( 'bold' ) ).to.be.true;
|