|
|
@@ -248,6 +248,34 @@ describe( 'Selection', () => {
|
|
|
} );
|
|
|
} );
|
|
|
|
|
|
+ describe( 'focus', () => {
|
|
|
+ let r3;
|
|
|
+ beforeEach( () => {
|
|
|
+ const r1 = Range.createFromParentsAndOffsets( root, 2, root, 4 );
|
|
|
+ const r2 = Range.createFromParentsAndOffsets( root, 4, root, 6 );
|
|
|
+ r3 = Range.createFromParentsAndOffsets( root, 1, root, 2 );
|
|
|
+ selection.addRange( r1 );
|
|
|
+ selection.addRange( r2 );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should return correct focus when last added range is not backward one', () => {
|
|
|
+ selection.addRange( r3 );
|
|
|
+
|
|
|
+ expect( selection.focus.isEqual( r3.end ) ).to.be.true;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should return correct focus when last added range is backward one', () => {
|
|
|
+ selection.addRange( r3, true );
|
|
|
+
|
|
|
+ expect( selection.focus.isEqual( r3.start ) ).to.be.true;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should return null if no ranges in selection', () => {
|
|
|
+ selection.removeAllRanges();
|
|
|
+ expect( selection.focus ).to.be.null;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
describe( 'setFocus', () => {
|
|
|
it( 'keeps all existing ranges and fires no change:range when no modifications needed', () => {
|
|
|
selection.addRange( range );
|
|
|
@@ -553,4 +581,118 @@ describe( 'Selection', () => {
|
|
|
}
|
|
|
} );
|
|
|
} );
|
|
|
+
|
|
|
+ describe( 'attributes interface', () => {
|
|
|
+ let rangeInFullP;
|
|
|
+
|
|
|
+ beforeEach( () => {
|
|
|
+ root.insertChildren( 0, [
|
|
|
+ new Element( 'p', [], 'foobar' ),
|
|
|
+ new Element( 'p', [], [] )
|
|
|
+ ] );
|
|
|
+
|
|
|
+ rangeInFullP = new Range( new Position( root, [ 0, 4 ] ), new Position( root, [ 0, 4 ] ) );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'setAttribute', () => {
|
|
|
+ it( 'should set given attribute on the selection', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+
|
|
|
+ expect( selection.getAttribute( 'foo' ) ).to.equal( 'bar' );
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should fire change:attribute event', () => {
|
|
|
+ let spy = sinon.spy();
|
|
|
+ selection.on( 'change:attribute', spy );
|
|
|
+
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+
|
|
|
+ expect( spy.called ).to.be.true;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'getAttribute', () => {
|
|
|
+ it( 'should return undefined if element does not contain given attribute', () => {
|
|
|
+ expect( selection.getAttribute( 'abc' ) ).to.be.undefined;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'getAttributes', () => {
|
|
|
+ it( 'should return an iterator that iterates over all attributes set on the text fragment', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+ selection.setAttribute( 'abc', 'xyz' );
|
|
|
+
|
|
|
+ let attrs = Array.from( selection.getAttributes() );
|
|
|
+
|
|
|
+ expect( attrs ).to.deep.equal( [ [ 'foo', 'bar' ], [ 'abc', 'xyz' ] ] );
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'hasAttribute', () => {
|
|
|
+ it( 'should return true if element contains attribute with given key', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+
|
|
|
+ expect( selection.hasAttribute( 'foo' ) ).to.be.true;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should return false if element does not contain attribute with given key', () => {
|
|
|
+ expect( selection.hasAttribute( 'abc' ) ).to.be.false;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'clearAttributes', () => {
|
|
|
+ it( 'should remove all attributes from the element', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+ selection.setAttribute( 'abc', 'xyz' );
|
|
|
+
|
|
|
+ selection.clearAttributes();
|
|
|
+
|
|
|
+ expect( selection.getAttribute( 'foo' ) ).to.be.undefined;
|
|
|
+ expect( selection.getAttribute( 'abc' ) ).to.be.undefined;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should fire change:attribute event', () => {
|
|
|
+ let spy = sinon.spy();
|
|
|
+ selection.on( 'change:attribute', spy );
|
|
|
+
|
|
|
+ selection.clearAttributes();
|
|
|
+
|
|
|
+ expect( spy.called ).to.be.true;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'removeAttribute', () => {
|
|
|
+ it( 'should remove attribute', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'foo', 'bar' );
|
|
|
+ selection.removeAttribute( 'foo' );
|
|
|
+
|
|
|
+ expect( selection.getAttribute( 'foo' ) ).to.be.undefined;
|
|
|
+ } );
|
|
|
+
|
|
|
+ it( 'should fire change:attribute event', () => {
|
|
|
+ let spy = sinon.spy();
|
|
|
+ selection.on( 'change:attribute', spy );
|
|
|
+
|
|
|
+ selection.removeAttribute( 'foo' );
|
|
|
+
|
|
|
+ expect( spy.called ).to.be.true;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+
|
|
|
+ describe( 'setAttributesTo', () => {
|
|
|
+ it( 'should remove all attributes set on element and set the given ones', () => {
|
|
|
+ selection.setRanges( [ rangeInFullP ] );
|
|
|
+ selection.setAttribute( 'abc', 'xyz' );
|
|
|
+ selection.setAttributesTo( { foo: 'bar' } );
|
|
|
+
|
|
|
+ expect( selection.getAttribute( 'foo' ) ).to.equal( 'bar' );
|
|
|
+ expect( selection.getAttribute( 'abc' ) ).to.be.undefined;
|
|
|
+ } );
|
|
|
+ } );
|
|
|
+ } );
|
|
|
} );
|