|
|
@@ -11,8 +11,151 @@ import Writer from '/ckeditor5/core/treeview/writer.js';
|
|
|
import Element from '/ckeditor5/core/treeview/element.js';
|
|
|
import Text from '/ckeditor5/core/treeview/text.js';
|
|
|
import Position from '/ckeditor5/core/treeview/position.js';
|
|
|
+import Range from '/ckeditor5/core/treeview/range.js';
|
|
|
|
|
|
describe( 'Writer', () => {
|
|
|
+ /**
|
|
|
+ * Helper function that is used to test output of writer methods by providing declarative description of the
|
|
|
+ * expected output.
|
|
|
+ * Examples:
|
|
|
+ * test element: `<p>fo[o<b>ba]r</b></p>`
|
|
|
+ * description: {
|
|
|
+ * name: 'p',
|
|
|
+ * instanceOf: Element,
|
|
|
+ * children:[
|
|
|
+ * {
|
|
|
+ * instanceOf: Text,
|
|
|
+ * data: 'foo',
|
|
|
+ * rangeStart: 2
|
|
|
+ * },
|
|
|
+ * {
|
|
|
+ * name: 'b'
|
|
|
+ * instanceOf: Element
|
|
|
+ * priority: 1,
|
|
|
+ * children: [
|
|
|
+ * { instanceOf: Text, data: 'bar', rangeEnd: 2 }
|
|
|
+ * ]
|
|
|
+ * }
|
|
|
+ * ]
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * @param {core.treeView.Writer} writer Writer instance. Used to test priority.
|
|
|
+ * @param {core.treeView.Range|core.treeView.Position } location Range instance or Position instance.
|
|
|
+ * Treated as Range when when `rangeStart`, `rangeEnd` is used, treated as Position when `position` is used.
|
|
|
+ * @param {core.treeView.Node} node Element to check.
|
|
|
+ * @param {Object} description Object describing expected element and its children.
|
|
|
+ */
|
|
|
+ function test( writer, location, node, description ) {
|
|
|
+ if ( description.instanceOf ) {
|
|
|
+ expect( node ).to.be.instanceof( description.instanceOf );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.name ) {
|
|
|
+ expect( node.name ).to.equal( description.name );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.data ) {
|
|
|
+ expect( node.data ).to.equal( description.data );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.priority !== undefined ) {
|
|
|
+ expect( writer.getPriority( node ) ).to.equal( description.priority );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.rangeStart !== undefined ) {
|
|
|
+ expect( location.start.parent ).to.equal( node );
|
|
|
+ expect( location.start.offset ).to.equal( description.rangeStart );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.attributes ) {
|
|
|
+ Object.keys( description.attributes ).forEach( ( key ) => {
|
|
|
+ expect( node.getAttribute( key ) ).to.equal( description.attributes[ key ] );
|
|
|
+ } );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.rengeEnd !== undefined ) {
|
|
|
+ expect( location.end.parent ).to.equal( node );
|
|
|
+ expect( location.end.offset ).to.equal( description.rengeEnd );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.position !== undefined ) {
|
|
|
+ expect( location.parent ).to.equal( node );
|
|
|
+ expect( location.offset ).to.equal( description.position );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.children ) {
|
|
|
+ expect( node.getChildCount() ).to.equal( description.children.length );
|
|
|
+ description.children.forEach( ( desc, index ) => {
|
|
|
+ test( writer, location, node.getChild( index ), desc );
|
|
|
+ } );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Helper function that is used to create treeView elements from description object.
|
|
|
+ *
|
|
|
+ * @param {core.treeView.Writer} writer Writer instance. Used to set priorities.
|
|
|
+ * @param {Object} description Description object.
|
|
|
+ * @param {core.treeView.Range} [range] Optional parameter, used in recurrent calls.
|
|
|
+ * @param {core.treeView.Position} [position] Optional parameter, used in recurrent calls.
|
|
|
+ * @returns {Object} Returns object with `node`, `range`, `position` fields, containing created node and, optionally
|
|
|
+ * range and position if description object contain information about them.
|
|
|
+ */
|
|
|
+ function create( writer, description, range, position ) {
|
|
|
+ const node = new description.instanceOf();
|
|
|
+
|
|
|
+ if ( !range ) {
|
|
|
+ range = Range.createFromParentsAndOffsets( node, 0, node, 0 );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( !position ) {
|
|
|
+ position = new Position( node, 0 );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.name ) {
|
|
|
+ node.name = description.name;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.data ) {
|
|
|
+ node.data = description.data;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.attributes ) {
|
|
|
+ Object.keys( description.attributes ).forEach( ( key ) => {
|
|
|
+ node.setAttribute( key, description.attributes[ key ] );
|
|
|
+ } );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.priority !== undefined ) {
|
|
|
+ writer.setPriority( node, description.priority );
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.rangeStart !== undefined ) {
|
|
|
+ range.start.parent = node;
|
|
|
+ range.start.offset = description.rangeStart;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.rangeEnd !== undefined ) {
|
|
|
+ range.end.parent = node;
|
|
|
+ range.end.offset = description.rangeEnd;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.position !== undefined ) {
|
|
|
+ position.parent = node;
|
|
|
+ position.offset = description.position;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( description.children ) {
|
|
|
+ description.children.forEach( ( desc, index ) => {
|
|
|
+ const created = create( writer, desc, range, position );
|
|
|
+ node.insertChildren( index, created.node );
|
|
|
+ } );
|
|
|
+ }
|
|
|
+
|
|
|
+ return { node, range, position };
|
|
|
+ }
|
|
|
+
|
|
|
describe( 'isContainer', () => {
|
|
|
it( 'should return true for container elements', () => {
|
|
|
const containerElement = new Element( 'p' );
|
|
|
@@ -60,337 +203,973 @@ describe( 'Writer', () => {
|
|
|
} );
|
|
|
|
|
|
describe( 'breakAttributes', () => {
|
|
|
- // Start position is at the begin of the text node.
|
|
|
- // After breaking it should be at the begin of the 'p' element.
|
|
|
- it( '<p>|foobar</p>', () => {
|
|
|
+ // <p>{|foobar}</p> -> <p>|{foobar}</p>
|
|
|
+ it( '<p>{|foobar}</p>', () => {
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const element = new Element( 'p', {}, [ text ] );
|
|
|
- const position = new Position( text, 0 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const newParent = newPosition.parent;
|
|
|
-
|
|
|
- expect( newPosition.offset ).to.equal( 0 );
|
|
|
- expect( newParent ).to.equal( element );
|
|
|
- expect( newParent.getChildCount() ).to.equal( 1 );
|
|
|
- expect( newParent.getChild( 0 ) ).to.equal( text );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 0 }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 0,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // Start position is located in the middle of text node.
|
|
|
- // After breaking it should be located inside 'p' element, between two text nodes 'foo' and 'bar'.
|
|
|
it( '<p>foo|bar</p>', () => {
|
|
|
+ // <p>{foo|bar}</p> -> <p>{foo}|{bar}</p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const element = new Element( 'p', {}, [ text ] );
|
|
|
- const position = new Position( text, 3 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const newParent = newPosition.parent;
|
|
|
-
|
|
|
- expect( newPosition.offset ).to.equal( 1 );
|
|
|
- expect( newParent ).to.equal( element );
|
|
|
- expect( newParent.getChildCount() ).to.equal( 2 );
|
|
|
- expect( newParent.getChild( 0 ) ).to.be.instanceOf( Text );
|
|
|
- expect( newParent.getChild( 1 ) ).to.be.instanceOf( Text );
|
|
|
- expect( newParent.getChild( 0 ).data ).to.equal( 'foo' );
|
|
|
- expect( newParent.getChild( 1 ).data ).to.equal( 'bar' );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' },
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // Start position is at the end of the text node.
|
|
|
- // After breaking it should be at the end of the 'p' element.
|
|
|
- it( '<p>foobar|</p>', () => {
|
|
|
+ it( '<p>{foobar|}</p>', () => {
|
|
|
+ // <p>{foobar|}</p> -> <p>{foobar}|</p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const element = new Element( 'p', {}, [ text ] );
|
|
|
- const position = new Position( text, 6 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const newParent = newPosition.parent;
|
|
|
-
|
|
|
- expect( newPosition.offset ).to.equal( 1 );
|
|
|
- expect( newParent ).to.equal( element );
|
|
|
- expect( newParent.getChildCount() ).to.equal( 1 );
|
|
|
- expect( newParent.getChild( 0 ) ).to.equal( text );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 6 }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // <p><b>foo|bar</b></p> -> <p><b>foo</b>|<b>bar</b></p>
|
|
|
- it( '<p><b>foo|bar</b></p>', () => {
|
|
|
+ it( '<p><b>{foo|bar}</b></p>', () => {
|
|
|
+ // <p><b>{foo|bar}</b></p> -> <p><b>{foo}</b>|<b>{bar}</b></p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const b = new Element( 'b', { attribute: 'value' }, [ text ] );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( text, 3 );
|
|
|
- writer.setPriority( b, 1 );
|
|
|
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const parent = newPosition.parent;
|
|
|
-
|
|
|
- expect( parent ).to.equal( p );
|
|
|
- expect( newPosition.offset ).to.equal( 1 );
|
|
|
- expect( p.getChildCount() ).to.equal( 2 );
|
|
|
- const child1 = p.getChild( 0 );
|
|
|
- const child2 = p.getChild( 1 );
|
|
|
- expect( child1 ).to.be.instanceOf( Element );
|
|
|
- expect( child1.same( b ) ).to.be.true;
|
|
|
- expect( writer.getPriority( child1 ) ).to.equal( 1 );
|
|
|
- expect( child1.getChildCount() ).to.equal( 1 );
|
|
|
- expect( child1.getChild( 0 ).data ).to.equal( 'foo' );
|
|
|
- expect( child2 ).to.be.instanceOf( Element );
|
|
|
- expect( child2.same( b ) ).to.be.true;
|
|
|
- expect( writer.getPriority( child2 ) ).to.equal( 1 );
|
|
|
- expect( child2.getChildCount() ).to.equal( 1 );
|
|
|
- expect( child2.getChild( 0 ).data ).to.equal( 'bar' );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // <p><b><u>|foobar</u></b></p> -> <p>|<b><u>foobar</u></b></p>
|
|
|
- it( '<p><b><u>|foobar</u></b></p>', () => {
|
|
|
+ it( '<p><b><u>{|foobar}</u></b></p>', () => {
|
|
|
+ // <p><b><u>{|foobar}</u></b></p> -> <p>|<b><u>{foobar}</u></b></p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const u = new Element( 'u', { foo: 'bar' }, [ text ] );
|
|
|
- const b = new Element( 'b', { baz: 'qux' }, [ u ] );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( text, 0 );
|
|
|
- writer.setPriority( u, 10 );
|
|
|
- writer.setPriority( b, 5 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const parent = newPosition.parent;
|
|
|
-
|
|
|
- expect( parent ).to.equal( p );
|
|
|
- expect( newPosition.offset ).to.equal( 0 );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- const b1 = p.getChild( 0 );
|
|
|
- expect( b1 ).to.equal( b );
|
|
|
- expect( writer.getPriority( b1 ) ).to.equal( 5 );
|
|
|
- expect( b1.getChildCount() ).to.equal( 1 );
|
|
|
- const u1 = b.getChild( 0 );
|
|
|
- expect( u1 ).to.equal( u );
|
|
|
- expect( writer.getPriority( u1 ) ).to.equal( 10 );
|
|
|
- expect( u1.getChildCount() ).to.equal( 1 );
|
|
|
- const text1 = u1.getChild( 0 );
|
|
|
- expect( text1 ).to.equal( text );
|
|
|
- expect( text1.data ).to.equal( 'foobar' );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 0 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 0,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // <p><b><u>foo|bar</u></b></p> -> <p><b><u>foo</u></b>|<b></u>bar</u></b></p>
|
|
|
- it( '<p><b><u>foo|bar</u></b></p>', () => {
|
|
|
+ // <p><b><u>{foo|ba}r</u></b></p> -> <p><b><u>{foo}</u></b>|<b></u>{bar}</u></b></p>
|
|
|
+ it( '<p><b><u>{foo|bar}</u></b></p>', () => {
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const u = new Element( 'u', { foo: 'bar' }, [ text ] );
|
|
|
- const b = new Element( 'b', { baz: 'qux' }, [ u ] );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( text, 3 );
|
|
|
- writer.setPriority( u, 1 );
|
|
|
- writer.setPriority( b, 1 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const parent = newPosition.parent;
|
|
|
-
|
|
|
- expect( parent ).to.equal( p );
|
|
|
- expect( newPosition.offset ).to.equal( 1 );
|
|
|
- expect( parent.getChildCount() ).to.equal( 2 );
|
|
|
- const b1 = parent.getChild( 0 );
|
|
|
- const b2 = parent.getChild( 1 );
|
|
|
- expect( b1.same( b ) ).to.be.true;
|
|
|
- expect( b2.same( b ) ).to.be.true;
|
|
|
- expect( b1.getChildCount() ).to.equal( 1 );
|
|
|
- expect( b2.getChildCount() ).to.equal( 1 );
|
|
|
-
|
|
|
- const u1 = b1.getChild( 0 );
|
|
|
- const u2 = b2.getChild( 0 );
|
|
|
-
|
|
|
- expect( u1.same( u ) ).to.be.true;
|
|
|
- expect( u2.same( u ) ).to.be.true;
|
|
|
-
|
|
|
- expect( u1.getChildCount() ).to.equal( 1 );
|
|
|
- expect( u2.getChildCount() ).to.equal( 1 );
|
|
|
- expect( u1.getChild( 0 ).data ).to.equal( 'foo' );
|
|
|
- expect( u2.getChild( 0 ).data ).to.equal( 'bar' );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- // <p><b><u>foobar|</u></b></p> -> <p><b><u>foobar</u></b>|</p>
|
|
|
- it( '<p><b><u>foobar|</u></b></p>', () => {
|
|
|
+ it( '<p><b><u>{foobar|}</u></b></p>', () => {
|
|
|
+ // <p><b><u>{foobar|}</u></b></p> -> <p><b><u>{foobar}</u></b>|</p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const u = new Element( 'u', { foo: 'bar' }, [ text ] );
|
|
|
- const b = new Element( 'b', { baz: 'qux' }, [ u ] );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( text, 6 );
|
|
|
- writer.setPriority( u, 1 );
|
|
|
- writer.setPriority( b, 1 );
|
|
|
-
|
|
|
- const newPosition = writer.breakAttributes( position );
|
|
|
- const parent = newPosition.parent;
|
|
|
-
|
|
|
- expect( parent ).to.equal( p );
|
|
|
- expect( newPosition.offset ).to.equal( 1 );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- const b1 = p.getChild( 0 );
|
|
|
- expect( b1.same( b ) ).to.be.true;
|
|
|
- expect( b1.getChildCount() ).to.equal( 1 );
|
|
|
- const u1 = b.getChild( 0 );
|
|
|
- expect( u1.same( u ) ).to.be.true;
|
|
|
- expect( u1.getChildCount() ).to.equal( 1 );
|
|
|
- const text1 = u1.getChild( 0 );
|
|
|
- expect( text1.same( text ) ).to.be.true;
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 6 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.breakAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
} );
|
|
|
|
|
|
describe( 'mergeAttributes', () => {
|
|
|
- // <p>{fo|obar}</p>
|
|
|
it( 'should not merge if inside text node', () => {
|
|
|
+ // <p>{fo|obar}</p>
|
|
|
const writer = new Writer();
|
|
|
- const text = new Text( 'foobar' );
|
|
|
- const p = new Element( 'p', [], [ text ] );
|
|
|
- const position = new Position( text, 2 );
|
|
|
-
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
-
|
|
|
- expect( newPosition.isEqual( position ) ).to.be.true;
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- const text1 = p.getChild( 0 );
|
|
|
- expect( text1 ).to.equal( text );
|
|
|
- expect( text1.data ).to.equal( 'foobar' );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 2 }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer, description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
} );
|
|
|
|
|
|
it( 'should return same position when inside empty container', () => {
|
|
|
// <p>|</p>
|
|
|
const writer = new Writer();
|
|
|
- const p = new Element( 'p' );
|
|
|
- const position = new Position( p, 0 );
|
|
|
-
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
-
|
|
|
- expect( newPosition.isEqual( position ) ).to.be.true;
|
|
|
+ const description = { instanceOf: Element, name: 'p', position: 0 };
|
|
|
+ const created = create( writer, description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
} );
|
|
|
|
|
|
it( 'should not merge when position is placed at the beginning of the container', () => {
|
|
|
// <p>|<b></b></p>
|
|
|
const writer = new Writer();
|
|
|
- const b = new Element( 'b' );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( p, 0 );
|
|
|
- writer.setPriority( b, 1 );
|
|
|
-
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
-
|
|
|
- expect( newPosition.isEqual( position ) );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 0,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer, description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
} );
|
|
|
|
|
|
it( 'should not merge when position is placed at the end of the container', () => {
|
|
|
// <p><b></b>|</p>
|
|
|
const writer = new Writer();
|
|
|
- const b = new Element( 'b' );
|
|
|
- const p = new Element( 'p', {}, [ b ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
- writer.setPriority( b, 1 );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer, description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
+ } );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ it( 'should merge when placed between two text nodes', () => {
|
|
|
+ // <p>{foo}|{bar}</p> -> <p>{foo|bar}</p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' },
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ } );
|
|
|
|
|
|
- expect( newPosition.isEqual( position ) );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b );
|
|
|
+ it( 'should merge when placed between similar attribute nodes', () => {
|
|
|
+ // <p><b foo="bar"></b>|<b foo="bar"></b></p> -> <p><b foo="bar">|</b></p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ position: 0,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- it( 'should merge when placed between two text nodes', () => {
|
|
|
- // <p>{foo}|{bar}</p>
|
|
|
- // <p>{foo|bar}</p>
|
|
|
+ it( 'should not merge when placed between non-similar attribute nodes', () => {
|
|
|
+ // <p><b foo="bar"></b>|<b foo="baz"></b></p> ->
|
|
|
+ // <p><b foo="bar"></b>|<b foo="baz"></b></p>
|
|
|
const writer = new Writer();
|
|
|
- const text1 = new Text( 'foo' );
|
|
|
- const text2 = new Text( 'bar' );
|
|
|
- const p = new Element( 'p', {}, [ text1, text2 ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'baz' }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer, description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
+ } );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ it( 'should not merge when placed between similar attribute nodes with different priority', () => {
|
|
|
+ // <p><b foo="bar"></b>|<b foo="bar"></b></p> -> <p><b foo="bar"></b>|<b foo="bar"></b></p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 2,
|
|
|
+ attributes: { foo: 'bar' }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer,description );
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+ test( writer, newPosition, created.node, description );
|
|
|
+ } );
|
|
|
|
|
|
- expect( newPosition.parent ).is.equal( text1 );
|
|
|
- expect( newPosition.offset ).is.equal( 3 );
|
|
|
- expect( text1.data ).to.equal( 'foobar' );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( text1 );
|
|
|
+ it( 'should merge attribute nodes and their contents if possible', () => {
|
|
|
+ // <p><b foo="bar">{foo}</b>|<b foo="bar">{bar}</b></p>
|
|
|
+ // <p><b foo="bar">{foo}|{bar}</b></p>
|
|
|
+ // <p><b foo="bar">{foo|bar}</b></p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ position: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' },
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' },
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newPosition = writer.mergeAttributes( created.position );
|
|
|
+
|
|
|
+ test( writer, newPosition, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ attributes: { foo: 'bar' },
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
+ } );
|
|
|
|
|
|
- it( 'should merge when placed between similar attribute nodes', () => {
|
|
|
- // <p><b foo="bar"></b>|<b foo="bar"></b></p>
|
|
|
- // <p><b foo="bar">|</b></p>
|
|
|
+ describe( 'insert', () => {
|
|
|
+ it( 'should insert text', () => {
|
|
|
+ // <p>{foo|bar}</p> insert {baz}
|
|
|
+ // <p>{foo[baz]bar}</p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', position: 3 }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const newRange = writer.insert( created.position, new Text( 'baz' ) );
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobazbar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should merge attributes', () => {
|
|
|
+ // <p><b>{foo|bar}</b></p> insert <b>{baz}</b>
|
|
|
+ // <p><b>{foobazbar}</b></p>
|
|
|
const writer = new Writer();
|
|
|
- const b1 = new Element( 'b', { foo: 'bar' } );
|
|
|
- const b2 = new Element( 'b', { foo: 'bar' } );
|
|
|
- const p = new Element( 'p', {}, [ b1, b2 ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
+ const text = new Text( 'foobar' );
|
|
|
+ const b1 = new Element( 'b', null, text );
|
|
|
+ const p = new Element( 'p', null, b1 );
|
|
|
+ const position = new Position( text, 3 );
|
|
|
+ const insertText = new Text( 'baz' );
|
|
|
+ const b2 = new Element( 'b', null, insertText );
|
|
|
+
|
|
|
writer.setPriority( b1, 1 );
|
|
|
writer.setPriority( b2, 1 );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ writer.insert( position, b2 );
|
|
|
|
|
|
- expect( newPosition.parent ).to.equal( b1 );
|
|
|
- expect( newPosition.offset ).to.equal( 0 );
|
|
|
expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b1 );
|
|
|
+ const b3 = p.getChild( 0 );
|
|
|
+ expect( b3 ).to.be.instanceof( Element );
|
|
|
+ expect( b3.name ).to.equal( 'b' );
|
|
|
+ expect( b3.getChildCount() ).to.equal( 1 );
|
|
|
+ const newText = b3.getChild( 0 );
|
|
|
+ expect( newText ).to.be.instanceof( Text );
|
|
|
+ expect( newText.data ).to.equal( 'foobazbar' );
|
|
|
} );
|
|
|
+ } );
|
|
|
|
|
|
- it( 'should not merge when placed between non-similar attribute nodes', () => {
|
|
|
- // <p><b foo="bar"></b>|<b foo="baz"></b></p>
|
|
|
- // <p><b foo="bar"></b>|<b foo="baz"></b></p>
|
|
|
+ describe( 'wrap', () => {
|
|
|
+ //// <p>[{foobar}]</p>
|
|
|
+ //// wrap <b>
|
|
|
+ //// <p>[<b>{foobar}<b>]</p>
|
|
|
+ //it( 'wraps single text node', () => {
|
|
|
+ // const writer = new Writer();
|
|
|
+ // const text = new Text( 'foobar' );
|
|
|
+ // const p = new Element( 'p', null, [ text ] );
|
|
|
+ // const b = new Element( 'b' );
|
|
|
+ // const range = new Range(
|
|
|
+ // new Position( p, 0 ),
|
|
|
+ // new Position( p, 1 )
|
|
|
+ // );
|
|
|
+ //
|
|
|
+ // const newRange = writer.wrap( range, b, 1 );
|
|
|
+ //
|
|
|
+ // expect( p.getChildCount() ).to.equal( 1 );
|
|
|
+ // expect( p.getChild( 0 ) ).to.equal( b );
|
|
|
+ // expect( b.getChildCount() ).to.equal( 1 );
|
|
|
+ // expect( b.getChild( 0 ) ).to.equal( text );
|
|
|
+ // expect( text.data ).to.equal( 'foobar' );
|
|
|
+ // expect( newRange.start.parent ).to.equal( p );
|
|
|
+ // expect( newRange.start.offset ).to.equal( 0 );
|
|
|
+ // expect( newRange.end.parent ).to.equal( p );
|
|
|
+ // expect( newRange.end.offset ).to.equal( 1 );
|
|
|
+ //} );
|
|
|
+
|
|
|
+ //// <p>[{foo]bar}</p>
|
|
|
+ //// <p>[<b>{foo}</b>]{bar}</p>
|
|
|
+ //it( 'wraps part of single text node', () => {
|
|
|
+ // const writer = new Writer();
|
|
|
+ // const text = new Text( 'foobar' );
|
|
|
+ // const p = new Element( 'p', null, [ text ] );
|
|
|
+ // const b = new Element( 'b' );
|
|
|
+ // const range = new Range(
|
|
|
+ // new Position( p, 0 ),
|
|
|
+ // new Position( text, 3 )
|
|
|
+ // );
|
|
|
+ //
|
|
|
+ // const newRange = writer.wrap( range, b, 1 );
|
|
|
+ // expect( p.getChildCount() ).to.equal( 2 );
|
|
|
+ // const child1 = p.getChild( 0 );
|
|
|
+ // const child2 = p.getChild( 1 );
|
|
|
+ //
|
|
|
+ // expect( child1 ).to.be.instanceof( Element );
|
|
|
+ // expect( child1.same( b ) ).to.be.true;
|
|
|
+ // expect( child1.getChildCount() ).to.equal( 1 );
|
|
|
+ // const newText = child1.getChild( 0 );
|
|
|
+ // expect( newText ).to.be.instanceof( Text );
|
|
|
+ // expect( newText.data ).to.equal( 'foo' );
|
|
|
+ // expect( child2 ).to.be.instanceof( Text );
|
|
|
+ // expect( child2.data ).to.equal( 'bar' );
|
|
|
+ //
|
|
|
+ // expect( newRange.start.parent ).to.equal( p );
|
|
|
+ // expect( newRange.start.offset ).to.equal( 0 );
|
|
|
+ // expect( newRange.end.parent ).to.equal( p );
|
|
|
+ // expect( newRange.end.offset ).to.equal( 1 );
|
|
|
+ //} );
|
|
|
+
|
|
|
+ //it( 'tests', () => {
|
|
|
+ // const writer = new Writer();
|
|
|
+ // const text = new Text( 'foobar' );
|
|
|
+ // const text2 = new Text( 'bazquix' );
|
|
|
+ // const u = new Element( 'u', null, [ text2 ] );
|
|
|
+ // const p = new Element( 'p', null, [ text, u ] );
|
|
|
+ // const b = new Element( 'b' );
|
|
|
+ // const range = new Range(
|
|
|
+ // new Position( p, 0 ),
|
|
|
+ // new Position( p, 2 )
|
|
|
+ // );
|
|
|
+ //
|
|
|
+ // const newRange = writer.wrap( range, b, 1 );
|
|
|
+ //
|
|
|
+ // expect( p.getChildCount() ).to.equal( 1 );
|
|
|
+ // //expect( p.getChild( 0 ) ).to.equal( b );
|
|
|
+ // //expect( b.getChildCount() ).to.equal( 1 );
|
|
|
+ // //expect( b.getChild( 0 ) ).to.equal( text );
|
|
|
+ // //expect( text.data ).to.equal( 'foobar' );
|
|
|
+ // //expect( newRange.start.parent ).to.equal( p );
|
|
|
+ // //expect( newRange.start.offset ).to.equal( 0 );
|
|
|
+ // //expect( newRange.end.parent ).to.equal( p );
|
|
|
+ // //expect( newRange.end.offset ).to.equal( 1 );
|
|
|
+ //} );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'unwrap', () => {
|
|
|
+ it( 'should do nothing on single text node', () => {
|
|
|
+ // <p>[{foobar}]</p>
|
|
|
const writer = new Writer();
|
|
|
- const b1 = new Element( 'b', { foo: 'bar' } );
|
|
|
- const b2 = new Element( 'b', { foo: 'baz' } );
|
|
|
- const p = new Element( 'p', {}, [ b1, b2 ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
- writer.setPriority( b1, 1 );
|
|
|
- writer.setPriority( b2, 1 );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+
|
|
|
+ const created = create( writer, description );
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 1 );
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ test( writer, newRange, created.node, description );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should unwrap single node', () => {
|
|
|
+ // <p>[<b>{foobar}</b>]<p> -> <p>[{foobar}]</p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 1,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
|
|
|
- expect( newPosition.isEqual( position ) ).to.be.true;
|
|
|
- expect( p.getChildCount() ).to.equal( 2 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b1 );
|
|
|
- expect( p.getChild( 1 ) ).to.equal( b2 );
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 1 );
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
+
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
|
|
|
- it( 'should not merge when placed between similar attribute nodes with different priority', () => {
|
|
|
+ it( 'should not unwrap attributes with different priorities #1', () => {
|
|
|
+ // <p>[<b>{foobar}</b>]<p> -> <p>[<b>{foobar}</b>]</p>
|
|
|
const writer = new Writer();
|
|
|
- const b1 = new Element( 'b', { foo: 'bar' } );
|
|
|
- const b2 = new Element( 'b', { foo: 'bar' } );
|
|
|
- const p = new Element( 'p', {}, [ b1, b2 ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
- writer.setPriority( b1, 1 );
|
|
|
- writer.setPriority( b2, 2 );
|
|
|
+ const description = {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 1,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ const created = create( writer, description );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 2 );
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
|
|
|
- expect( newPosition.isEqual( position ) ).to.be.true;
|
|
|
- expect( p.getChildCount() ).to.equal( 2 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b1 );
|
|
|
- expect( p.getChild( 1 ) ).to.equal( b2 );
|
|
|
+ test( writer, newRange, created.node, description );
|
|
|
} );
|
|
|
|
|
|
- it( 'should merge attribute nodes and their contents if possible', () => {
|
|
|
- // <p><b foo="bar">{foo}</b>|<b foo="bar">{bar}</b></p>
|
|
|
- // <p><b foo="bar">{foo}|{bar}</b></p>
|
|
|
- // <p><b foo="bar">{foo|bar}</b></p>
|
|
|
+ it( 'should not unwrap attributes with different priorities #2', () => {
|
|
|
+ // <p>[<b>{foo}</b><b>{bar}</b><b>{baz}</b>]<p> -> <p>[{foo}<b>bar</b>{baz}]</p>
|
|
|
const writer = new Writer();
|
|
|
- const text1 = new Text( 'foo' );
|
|
|
- const text2 = new Text( 'bar' );
|
|
|
- const b1 = new Element( 'b', { foo: 'bar' }, [ text1 ] );
|
|
|
- const b2 = new Element( 'b', { foo: 'bar' }, [ text2 ] );
|
|
|
- const p = new Element( 'p', {}, [ b1, b2 ] );
|
|
|
- const position = new Position( p, 1 );
|
|
|
- writer.setPriority( b1, 1 );
|
|
|
- writer.setPriority( b2, 1 );
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 3,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 2,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 1,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 2,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'baz' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
|
|
|
- const newPosition = writer.mergeAttributes( position );
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 2 );
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
+
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 3,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ priority: 1,
|
|
|
+ name: 'b',
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ { instanceOf: Text, data: 'baz' }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ } );
|
|
|
|
|
|
- expect( newPosition.parent ).to.equal( text1 );
|
|
|
- expect( newPosition.offset ).to.equal( 3 );
|
|
|
- expect( p.getChildCount() ).to.equal( 1 );
|
|
|
- expect( p.getChild( 0 ) ).to.equal( b1 );
|
|
|
- expect( b1.getChildCount() ).to.equal( 1 );
|
|
|
- expect( b1.getChild( 0 ) ).to.equal( text1 );
|
|
|
- expect( text1.data ).to.equal( 'foobar' );
|
|
|
+ it( 'should unwrap part of the node', () => {
|
|
|
+ // <p>[{baz}<b>{foo]bar}</b><p> -> <p>[{bazfoo}]<b>{bar}</b></p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'baz' },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar', rangeEnd: 3 }
|
|
|
+ ]
|
|
|
+
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 1 );
|
|
|
+
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
+
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bazfoo' },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should unwrap nested attributes', () => {
|
|
|
+ // <p>[<u><b>{foobar}</b></u>]</p> -> <p>[<u>{foobar}</u>]</p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 1 );
|
|
|
+
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 0,
|
|
|
+ rangeEnd: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foobar' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should merge unwrapped nodes', () => {
|
|
|
+ // <p>{foo}<u>{bar}</u>[<b><u>{baz]qux}</u></b></p> -> <p>{foo}<u>{bar[baz}</u>]<b><u>{qux}</u></b></p>
|
|
|
+ const writer = new Writer();
|
|
|
+ const created = create( writer, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeStart: 2,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'foo' },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bar' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'bazqux', rangeEnd: 3 }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
+
|
|
|
+ const b = new Element( 'b' );
|
|
|
+ writer.setPriority( b, 1 );
|
|
|
+ const newRange = writer.unwrap( created.range, b );
|
|
|
+
|
|
|
+ test( writer, newRange, created.node, {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'p',
|
|
|
+ rangeEnd: 2,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Text,
|
|
|
+ data: 'foo'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'barbaz', rangeStart: 3 }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'b',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ instanceOf: Element,
|
|
|
+ name: 'u',
|
|
|
+ priority: 1,
|
|
|
+ children: [
|
|
|
+ { instanceOf: Text, data: 'qux' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ } );
|
|
|
} );
|
|
|
} );
|
|
|
} );
|