Procházet zdrojové kódy

Merge pull request #1075 from ckeditor/t/1074

Feature: Enhanced Selection#setTo(), introducedSelection#setIn(), Selection#setOn(), Range.createCollapsedAt() and renamed few existing Selection methods for both model and view. Closes #1074.

BREAKING CHANGE: Renamed Selection#collapse to Selection#setCollapsedAt.
BREAKING CHANGE: Renamed Selection#setFocus to Selection#moveFocusTo.
Piotr Jasiun před 8 roky
rodič
revize
32277ec729

+ 2 - 2
packages/ckeditor5-engine/src/controller/deletecontent.js

@@ -70,7 +70,7 @@ export default function deleteContent( selection, batch, options = {} ) {
 		mergeBranches( batch, startPos, endPos );
 		mergeBranches( batch, startPos, endPos );
 	}
 	}
 
 
-	selection.collapse( startPos );
+	selection.setCollapsedAt( startPos );
 
 
 	// 4. Autoparagraphing.
 	// 4. Autoparagraphing.
 	// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).
 	// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).
@@ -181,7 +181,7 @@ function insertParagraph( batch, position, selection ) {
 	const paragraph = new Element( 'paragraph' );
 	const paragraph = new Element( 'paragraph' );
 	batch.insert( position, paragraph );
 	batch.insert( position, paragraph );
 
 
-	selection.collapse( paragraph );
+	selection.setCollapsedAt( paragraph );
 }
 }
 
 
 function replaceEntireContentWithParagraph( batch, selection ) {
 function replaceEntireContentWithParagraph( batch, selection ) {

+ 1 - 1
packages/ckeditor5-engine/src/controller/modifyselection.js

@@ -64,7 +64,7 @@ export default function modifySelection( dataController, selection, options = {}
 		const position = tryExtendingTo( data, next.value );
 		const position = tryExtendingTo( data, next.value );
 
 
 		if ( position ) {
 		if ( position ) {
-			selection.setFocus( position );
+			selection.moveFocusTo( position );
 
 
 			return;
 			return;
 		}
 		}

+ 15 - 0
packages/ckeditor5-engine/src/model/range.js

@@ -716,6 +716,21 @@ export default class Range {
 		return this.createFromPositionAndShift( Position.createBefore( item ), item.offsetSize );
 		return this.createFromPositionAndShift( Position.createBefore( item ), item.offsetSize );
 	}
 	}
 
 
+	/**
+	 * Creates a collapsed range at given {@link module:engine/model/position~Position position}
+	 * or on the given {@link module:engine/model/item~Item item}.
+	 *
+	 * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition
+	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
+	 * first parameter is a {@link module:engine/model/item~Item model item}.
+	 */
+	static createCollapsedAt( itemOrPosition, offset ) {
+		const start = Position.createAt( itemOrPosition, offset );
+		const end = Position.createFromPosition( start );
+
+		return new Range( start, end );
+	}
+
 	/**
 	/**
 	 * Combines all ranges from the passed array into a one range. At least one range has to be passed.
 	 * Combines all ranges from the passed array into a one range. At least one range has to be passed.
 	 * Passed ranges must not have common parts.
 	 * Passed ranges must not have common parts.

+ 42 - 10
packages/ckeditor5-engine/src/model/selection.js

@@ -15,6 +15,7 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
 import mapsEqual from '@ckeditor/ckeditor5-utils/src/mapsequal';
 import mapsEqual from '@ckeditor/ckeditor5-utils/src/mapsequal';
+import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
 
 
 /**
 /**
  * `Selection` is a group of {@link module:engine/model/range~Range ranges} which has a direction specified by
  * `Selection` is a group of {@link module:engine/model/range~Range ranges} which has a direction specified by
@@ -334,16 +335,47 @@ export default class Selection {
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets this selection's ranges and direction to the ranges and direction of the given selection.
+	 * Sets this selection's ranges and direction to the specified location based on the given
+	 * {@link module:engine/model/selection~Selection selection}, {@link module:engine/model/position~Position position},
+	 * {@link module:engine/model/range~Range range} or an iterable of {@link module:engine/model/range~Range ranges}.
 	 *
 	 *
-	 * @param {module:engine/model/selection~Selection} otherSelection
+	 * @param {module:engine/model/selection~Selection|module:engine/model/position~Position|
+	 * Iterable.<module:engine/model/range~Range>|module:engine/model/range~Range} selectable
 	 */
 	 */
-	setTo( otherSelection ) {
-		this.setRanges( otherSelection.getRanges(), otherSelection.isBackward );
+	setTo( selectable ) {
+		if ( selectable instanceof Selection ) {
+			this.setRanges( selectable.getRanges(), selectable.isBackward );
+		} else if ( selectable instanceof Range ) {
+			this.setRanges( [ selectable ] );
+		} else if ( isIterable( selectable ) ) {
+			// We assume that the selectable is an iterable of ranges.
+			this.setRanges( selectable );
+		} else {
+			// We assume that the selectable is a position.
+			this.setRanges( [ new Range( selectable ) ] );
+		}
+	}
+
+	/**
+	 * Sets this selection in the provided element.
+	 *
+	 * @param {module:engine/model/element~Element} element
+	 */
+	setIn( element ) {
+		this.setRanges( [ Range.createIn( element ) ] );
+	}
+
+	/**
+	 * Sets this selection on the provided item.
+	 *
+	 * @param {module:engine/model/item~Item} item
+	 */
+	setOn( item ) {
+		this.setRanges( [ Range.createOn( item ) ] );
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets collapsed selection in the specified location.
+	 * Sets collapsed selection at the specified location.
 	 *
 	 *
 	 * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.
 	 * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.
 	 *
 	 *
@@ -352,7 +384,7 @@ export default class Selection {
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * first parameter is a {@link module:engine/model/item~Item model item}.
 	 * first parameter is a {@link module:engine/model/item~Item model item}.
 	 */
 	 */
-	collapse( itemOrPosition, offset ) {
+	setCollapsedAt( itemOrPosition, offset ) {
 		const pos = Position.createAt( itemOrPosition, offset );
 		const pos = Position.createAt( itemOrPosition, offset );
 		const range = new Range( pos, pos );
 		const range = new Range( pos, pos );
 
 
@@ -390,7 +422,7 @@ export default class Selection {
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets {@link module:engine/model/selection~Selection#focus} to the specified location.
+	 * Moves {@link module:engine/model/selection~Selection#focus} to the specified location.
 	 *
 	 *
 	 * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.
 	 * The location can be specified in the same form as {@link module:engine/model/position~Position.createAt} parameters.
 	 *
 	 *
@@ -399,15 +431,15 @@ export default class Selection {
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * first parameter is a {@link module:engine/model/item~Item model item}.
 	 * first parameter is a {@link module:engine/model/item~Item model item}.
 	 */
 	 */
-	setFocus( itemOrPosition, offset ) {
+	moveFocusTo( itemOrPosition, offset ) {
 		if ( this.anchor === null ) {
 		if ( this.anchor === null ) {
 			/**
 			/**
 			 * Cannot set selection focus if there are no ranges in selection.
 			 * Cannot set selection focus if there are no ranges in selection.
 			 *
 			 *
-			 * @error model-selection-setFocus-no-ranges
+			 * @error model-selection-moveFocusTo-no-ranges
 			 */
 			 */
 			throw new CKEditorError(
 			throw new CKEditorError(
-				'model-selection-setFocus-no-ranges: Cannot set selection focus if there are no ranges in selection.'
+				'model-selection-moveFocusTo-no-ranges: Cannot set selection focus if there are no ranges in selection.'
 			);
 			);
 		}
 		}
 
 

+ 2 - 2
packages/ckeditor5-engine/src/view/observer/mutationobserver.js

@@ -240,8 +240,8 @@ export default class MutationObserver extends Observer {
 			// Anchor and focus has to be properly mapped to view.
 			// Anchor and focus has to be properly mapped to view.
 			if ( viewSelectionAnchor && viewSelectionFocus ) {
 			if ( viewSelectionAnchor && viewSelectionFocus ) {
 				viewSelection = new ViewSelection();
 				viewSelection = new ViewSelection();
-				viewSelection.collapse( viewSelectionAnchor );
-				viewSelection.setFocus( viewSelectionFocus );
+				viewSelection.setCollapsedAt( viewSelectionAnchor );
+				viewSelection.moveFocusTo( viewSelectionFocus );
 			}
 			}
 		}
 		}
 
 

+ 16 - 1
packages/ckeditor5-engine/src/view/range.js

@@ -440,9 +440,24 @@ export default class Range {
 	static createOn( item ) {
 	static createOn( item ) {
 		return this.createFromPositionAndShift( Position.createBefore( item ), 1 );
 		return this.createFromPositionAndShift( Position.createBefore( item ), 1 );
 	}
 	}
+
+	/**
+	 * Creates a collapsed range at given {@link module:engine/view/position~Position position}
+	 * or on the given {@link module:engine/view/item~Item item}.
+	 *
+	 * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition
+	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
+	 * first parameter is a {@link module:engine/view/item~Item view item}.
+	 */
+	static createCollapsedAt( itemOrPosition, offset ) {
+		const start = Position.createAt( itemOrPosition, offset );
+		const end = Position.createFromPosition( start );
+
+		return new Range( start, end );
+	}
 }
 }
 
 
-// Function used by getEnlagred and getTrimmed methods.
+// Function used by getEnlarged and getTrimmed methods.
 function enlargeTrimSkip( value ) {
 function enlargeTrimSkip( value ) {
 	if ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {
 	if ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {
 		return true;
 		return true;

+ 45 - 12
packages/ckeditor5-engine/src/view/selection.js

@@ -14,6 +14,7 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
 import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
 import Element from './element';
 import Element from './element';
 import count from '@ckeditor/ckeditor5-utils/src/count';
 import count from '@ckeditor/ckeditor5-utils/src/count';
+import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
 
 
 /**
 /**
  * Class representing selection in tree view.
  * Class representing selection in tree view.
@@ -429,19 +430,49 @@ export default class Selection {
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets this selection's ranges and direction to the ranges and direction of the given selection.
+	 * Sets this selection's ranges and direction to the specified location based on the given
+	 * {@link module:engine/view/selection~Selection selection}, {@link module:engine/view/position~Position position},
+	 * {@link module:engine/view/range~Range range} or an iterable of {@link module:engine/view/range~Range ranges}.
 	 *
 	 *
-	 * @param {module:engine/view/selection~Selection} otherSelection
+	 * @param {module:engine/view/selection~Selection|module:engine/view/position~Position|
+	 * Iterable.<module:engine/view/range~Range>|module:engine/view/range~Range} selectable
 	 */
 	 */
-	setTo( otherSelection ) {
-		this._isFake = otherSelection._isFake;
-		this._fakeSelectionLabel = otherSelection._fakeSelectionLabel;
+	setTo( selectable ) {
+		if ( selectable instanceof Selection ) {
+			this._isFake = selectable._isFake;
+			this._fakeSelectionLabel = selectable._fakeSelectionLabel;
+			this.setRanges( selectable.getRanges(), selectable.isBackward );
+		} else if ( selectable instanceof Range ) {
+			this.setRanges( [ selectable ] );
+		} else if ( isIterable( selectable ) ) {
+			// We assume that the selectable is an iterable of ranges.
+			this.setRanges( selectable );
+		} else {
+			// We assume that the selectable is a position.
+			this.setRanges( [ new Range( selectable ) ] );
+		}
+	}
 
 
-		this.setRanges( otherSelection.getRanges(), otherSelection.isBackward );
+	/**
+	 * Sets this selection in the provided element.
+	 *
+	 * @param {module:engine/view/element~Element} element
+	 */
+	setIn( element ) {
+		this.setRanges( [ Range.createIn( element ) ] );
+	}
+
+	/**
+	 * Sets this selection on the provided item.
+	 *
+	 * @param {module:engine/view/item~Item} item
+	 */
+	setOn( item ) {
+		this.setRanges( [ Range.createOn( item ) ] );
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets collapsed selection in the specified location.
+	 * Sets collapsed selection at the specified location.
 	 *
 	 *
 	 * The location can be specified in the same form as {@link module:engine/view/position~Position.createAt} parameters.
 	 * The location can be specified in the same form as {@link module:engine/view/position~Position.createAt} parameters.
 	 *
 	 *
@@ -450,7 +481,7 @@ export default class Selection {
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * first parameter is a {@link module:engine/view/item~Item view item}.
 	 * first parameter is a {@link module:engine/view/item~Item view item}.
 	 */
 	 */
-	collapse( itemOrPosition, offset ) {
+	setCollapsedAt( itemOrPosition, offset ) {
 		const pos = Position.createAt( itemOrPosition, offset );
 		const pos = Position.createAt( itemOrPosition, offset );
 		const range = new Range( pos, pos );
 		const range = new Range( pos, pos );
 
 
@@ -488,7 +519,7 @@ export default class Selection {
 	}
 	}
 
 
 	/**
 	/**
-	 * Sets {@link #focus} to the specified location.
+	 * Moves {@link #focus} to the specified location.
 	 *
 	 *
 	 * The location can be specified in the same form as {@link module:engine/view/position~Position.createAt} parameters.
 	 * The location can be specified in the same form as {@link module:engine/view/position~Position.createAt} parameters.
 	 *
 	 *
@@ -497,14 +528,16 @@ export default class Selection {
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * @param {Number|'end'|'before'|'after'} [offset=0] Offset or one of the flags. Used only when
 	 * first parameter is a {@link module:engine/view/item~Item view item}.
 	 * first parameter is a {@link module:engine/view/item~Item view item}.
 	 */
 	 */
-	setFocus( itemOrPosition, offset ) {
+	moveFocusTo( itemOrPosition, offset ) {
 		if ( this.anchor === null ) {
 		if ( this.anchor === null ) {
 			/**
 			/**
 			 * Cannot set selection focus if there are no ranges in selection.
 			 * Cannot set selection focus if there are no ranges in selection.
 			 *
 			 *
-			 * @error view-selection-setFocus-no-ranges
+			 * @error view-selection-moveFocusTo-no-ranges
 			 */
 			 */
-			throw new CKEditorError( 'view-selection-setFocus-no-ranges: Cannot set selection focus if there are no ranges in selection.' );
+			throw new CKEditorError(
+				'view-selection-moveFocusTo-no-ranges: Cannot set selection focus if there are no ranges in selection.'
+			);
 		}
 		}
 
 
 		const newFocus = Position.createAt( itemOrPosition, offset );
 		const newFocus = Position.createAt( itemOrPosition, offset );

+ 7 - 7
packages/ckeditor5-engine/tests/dev-utils/model.js

@@ -272,7 +272,7 @@ describe( 'model test utils', () => {
 
 
 			it( 'writes selection in an empty root', () => {
 			it( 'writes selection in an empty root', () => {
 				const root = document.createRoot( '$root', 'empty' );
 				const root = document.createRoot( '$root', 'empty' );
-				selection.collapse( root );
+				selection.setCollapsedAt( root );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'[]'
 					'[]'
@@ -280,7 +280,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed in an element', () => {
 			it( 'writes selection collapsed in an element', () => {
-				selection.collapse( root );
+				selection.setCollapsedAt( root );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'[]<a></a>foo<$text bold="true">bar</$text><b></b>'
 					'[]<a></a>foo<$text bold="true">bar</$text><b></b>'
@@ -288,7 +288,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed in a text', () => {
 			it( 'writes selection collapsed in a text', () => {
-				selection.collapse( root, 3 );
+				selection.setCollapsedAt( root, 3 );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'<a></a>fo[]o<$text bold="true">bar</$text><b></b>'
 					'<a></a>fo[]o<$text bold="true">bar</$text><b></b>'
@@ -296,7 +296,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed at the text left boundary', () => {
 			it( 'writes selection collapsed at the text left boundary', () => {
-				selection.collapse( elA, 'after' );
+				selection.setCollapsedAt( elA, 'after' );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'<a></a>[]foo<$text bold="true">bar</$text><b></b>'
 					'<a></a>[]foo<$text bold="true">bar</$text><b></b>'
@@ -304,7 +304,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed at the text right boundary', () => {
 			it( 'writes selection collapsed at the text right boundary', () => {
-				selection.collapse( elB, 'before' );
+				selection.setCollapsedAt( elB, 'before' );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'<a></a>foo<$text bold="true">bar[]</$text><b></b>'
 					'<a></a>foo<$text bold="true">bar[]</$text><b></b>'
@@ -312,7 +312,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed at the end of the root', () => {
 			it( 'writes selection collapsed at the end of the root', () => {
-				selection.collapse( root, 'end' );
+				selection.setCollapsedAt( root, 'end' );
 
 
 				// Needed due to https://github.com/ckeditor/ckeditor5-engine/issues/320.
 				// Needed due to https://github.com/ckeditor/ckeditor5-engine/issues/320.
 				selection.clearAttributes();
 				selection.clearAttributes();
@@ -323,7 +323,7 @@ describe( 'model test utils', () => {
 			} );
 			} );
 
 
 			it( 'writes selection collapsed selection in a text with attributes', () => {
 			it( 'writes selection collapsed selection in a text with attributes', () => {
-				selection.collapse( root, 5 );
+				selection.setCollapsedAt( root, 5 );
 
 
 				expect( stringify( root, selection ) ).to.equal(
 				expect( stringify( root, selection ) ).to.equal(
 					'<a></a>foo<$text bold="true">b[]ar</$text><b></b>'
 					'<a></a>foo<$text bold="true">b[]ar</$text><b></b>'

+ 10 - 10
packages/ckeditor5-engine/tests/model/documentselection.js

@@ -212,13 +212,13 @@ describe( 'DocumentSelection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'collapse()', () => {
+	describe( 'setCollapsedAt()', () => {
 		it( 'detaches all existing ranges', () => {
 		it( 'detaches all existing ranges', () => {
 			selection.addRange( range );
 			selection.addRange( range );
 			selection.addRange( liveRange );
 			selection.addRange( liveRange );
 
 
 			const spy = testUtils.sinon.spy( LiveRange.prototype, 'detach' );
 			const spy = testUtils.sinon.spy( LiveRange.prototype, 'detach' );
-			selection.collapse( root );
+			selection.setCollapsedAt( root );
 
 
 			expect( spy.calledTwice ).to.be.true;
 			expect( spy.calledTwice ).to.be.true;
 		} );
 		} );
@@ -244,12 +244,12 @@ describe( 'DocumentSelection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'setFocus()', () => {
+	describe( 'moveFocusTo()', () => {
 		it( 'modifies default range', () => {
 		it( 'modifies default range', () => {
 			const startPos = selection.getFirstPosition();
 			const startPos = selection.getFirstPosition();
 			const endPos = Position.createAt( root, 'end' );
 			const endPos = Position.createAt( root, 'end' );
 
 
-			selection.setFocus( endPos );
+			selection.moveFocusTo( endPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -263,7 +263,7 @@ describe( 'DocumentSelection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( spy.calledOnce ).to.be.true;
 			expect( spy.calledOnce ).to.be.true;
 		} );
 		} );
@@ -637,7 +637,7 @@ describe( 'DocumentSelection', () => {
 
 
 		describe( 'RemoveOperation', () => {
 		describe( 'RemoveOperation', () => {
 			it( 'fix selection range if it ends up in graveyard #1', () => {
 			it( 'fix selection range if it ends up in graveyard #1', () => {
-				selection.collapse( new Position( root, [ 1, 3 ] ) );
+				selection.setCollapsedAt( new Position( root, [ 1, 3 ] ) );
 
 
 				doc.applyOperation( wrapInDelta(
 				doc.applyOperation( wrapInDelta(
 					new RemoveOperation(
 					new RemoveOperation(
@@ -876,14 +876,14 @@ describe( 'DocumentSelection', () => {
 			} );
 			} );
 
 
 			it( 'should overwrite any previously set attributes', () => {
 			it( 'should overwrite any previously set attributes', () => {
-				selection.collapse( new Position( root, [ 5, 0 ] ) );
+				selection.setCollapsedAt( new Position( root, [ 5, 0 ] ) );
 
 
 				selection.setAttribute( 'x', true );
 				selection.setAttribute( 'x', true );
 				selection.setAttribute( 'y', true );
 				selection.setAttribute( 'y', true );
 
 
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ], [ 'x', true ], [ 'y', true ] ] );
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ], [ 'x', true ], [ 'y', true ] ] );
 
 
-				selection.collapse( new Position( root, [ 1 ] ) );
+				selection.setCollapsedAt( new Position( root, [ 1 ] ) );
 
 
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'a', true ] ] );
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'a', true ] ] );
 			} );
 			} );
@@ -898,14 +898,14 @@ describe( 'DocumentSelection', () => {
 			} );
 			} );
 
 
 			it( 'should not fire change:attribute event if attributes did not change', () => {
 			it( 'should not fire change:attribute event if attributes did not change', () => {
-				selection.collapse( new Position( root, [ 5, 0 ] ) );
+				selection.setCollapsedAt( new Position( root, [ 5, 0 ] ) );
 
 
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ] ] );
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ] ] );
 
 
 				const spy = sinon.spy();
 				const spy = sinon.spy();
 				selection.on( 'change:attribute', spy );
 				selection.on( 'change:attribute', spy );
 
 
-				selection.collapse( new Position( root, [ 5, 1 ] ) );
+				selection.setCollapsedAt( new Position( root, [ 5, 1 ] ) );
 
 
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ] ] );
 				expect( Array.from( selection.getAttributes() ) ).to.deep.equal( [ [ 'd', true ] ] );
 				expect( spy.called ).to.be.false;
 				expect( spy.called ).to.be.false;

+ 22 - 0
packages/ckeditor5-engine/tests/model/range.js

@@ -176,6 +176,28 @@ describe( 'Range', () => {
 			} );
 			} );
 		} );
 		} );
 
 
+		describe( 'createCollapsedAt()', () => {
+			it( 'should return new collapsed range at the given item position', () => {
+				const item = new Element( 'p', null, new Text( 'foo' ) );
+				const range = Range.createCollapsedAt( item );
+
+				expect( range.start.parent ).to.equal( item );
+				expect( range.start.offset ).to.equal( 0 );
+
+				expect( range.isCollapsed ).to.be.true;
+			} );
+
+			it( 'should return new collapse range at the given item position and offset', () => {
+				const item = new Element( 'p', null, new Text( 'foo' ) );
+				const range = Range.createCollapsedAt( item, 1 );
+
+				expect( range.start.parent ).to.equal( item );
+				expect( range.start.offset ).to.equal( 1 );
+
+				expect( range.isCollapsed ).to.be.true;
+			} );
+		} );
+
 		describe( 'createFromParentsAndOffsets()', () => {
 		describe( 'createFromParentsAndOffsets()', () => {
 			it( 'should return range', () => {
 			it( 'should return range', () => {
 				const range = Range.createFromParentsAndOffsets( root, 0, p, 2 );
 				const range = Range.createFromParentsAndOffsets( root, 0, p, 2 );

+ 95 - 26
packages/ckeditor5-engine/tests/model/selection.js

@@ -234,19 +234,52 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'collapse()', () => {
+	describe( 'setIn()', () => {
+		it( 'should set selection inside an element', () => {
+			const element = new Element( 'p', null, [ new Text( 'foo' ), new Text( 'bar' ) ] );
+
+			selection.setIn( element );
+
+			const ranges = Array.from( selection.getRanges() );
+			expect( ranges.length ).to.equal( 1 );
+			expect( ranges[ 0 ].start.parent ).to.equal( element );
+			expect( ranges[ 0 ].start.offset ).to.deep.equal( 0 );
+			expect( ranges[ 0 ].end.parent ).to.equal( element );
+			expect( ranges[ 0 ].end.offset ).to.deep.equal( 6 );
+		} );
+	} );
+
+	describe( 'setOn()', () => {
+		it( 'should set selection on an item', () => {
+			const textNode1 = new Text( 'foo' );
+			const textNode2 = new Text( 'bar' );
+			const textNode3 = new Text( 'baz' );
+			const element = new Element( 'p', null, [ textNode1, textNode2, textNode3 ] );
+
+			selection.setOn( textNode2 );
+
+			const ranges = Array.from( selection.getRanges() );
+			expect( ranges.length ).to.equal( 1 );
+			expect( ranges[ 0 ].start.parent ).to.equal( element );
+			expect( ranges[ 0 ].start.offset ).to.deep.equal( 3 );
+			expect( ranges[ 0 ].end.parent ).to.equal( element );
+			expect( ranges[ 0 ].end.offset ).to.deep.equal( 6 );
+		} );
+	} );
+
+	describe( 'setCollapsedAt()', () => {
 		it( 'fires change:range', () => {
 		it( 'fires change:range', () => {
 			const spy = sinon.spy();
 			const spy = sinon.spy();
 
 
 			selection.on( 'change:range', spy );
 			selection.on( 'change:range', spy );
 
 
-			selection.collapse( root );
+			selection.setCollapsedAt( root );
 
 
 			expect( spy.calledOnce ).to.be.true;
 			expect( spy.calledOnce ).to.be.true;
 		} );
 		} );
 
 
 		it( 'sets selection at the 0 offset if second parameter not passed', () => {
 		it( 'sets selection at the 0 offset if second parameter not passed', () => {
-			selection.collapse( root );
+			selection.setCollapsedAt( root );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -256,7 +289,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'sets selection at given offset in given parent', () => {
 		it( 'sets selection at given offset in given parent', () => {
-			selection.collapse( root, 3 );
+			selection.setCollapsedAt( root, 3 );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -266,7 +299,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'sets selection at the end of the given parent', () => {
 		it( 'sets selection at the end of the given parent', () => {
-			selection.collapse( root, 'end' );
+			selection.setCollapsedAt( root, 'end' );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -276,7 +309,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'sets selection before the specified element', () => {
 		it( 'sets selection before the specified element', () => {
-			selection.collapse( root.getChild( 1 ), 'before' );
+			selection.setCollapsedAt( root.getChild( 1 ), 'before' );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -286,7 +319,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'sets selection after the specified element', () => {
 		it( 'sets selection after the specified element', () => {
-			selection.collapse( root.getChild( 1 ), 'after' );
+			selection.setCollapsedAt( root.getChild( 1 ), 'after' );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -298,7 +331,7 @@ describe( 'Selection', () => {
 		it( 'sets selection at the specified position', () => {
 		it( 'sets selection at the specified position', () => {
 			const pos = Position.createFromParentAndOffset( root, 3 );
 			const pos = Position.createFromParentAndOffset( root, 3 );
 
 
-			selection.collapse( pos );
+			selection.setCollapsedAt( pos );
 
 
 			expect( selection ).to.have.property( 'isCollapsed', true );
 			expect( selection ).to.have.property( 'isCollapsed', true );
 
 
@@ -308,7 +341,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'setFocus()', () => {
+	describe( 'moveFocusTo()', () => {
 		it( 'keeps all existing ranges and fires no change:range when no modifications needed', () => {
 		it( 'keeps all existing ranges and fires no change:range when no modifications needed', () => {
 			selection.addRange( range );
 			selection.addRange( range );
 			selection.addRange( liveRange );
 			selection.addRange( liveRange );
@@ -316,7 +349,7 @@ describe( 'Selection', () => {
 			const spy = sinon.spy();
 			const spy = sinon.spy();
 			selection.on( 'change:range', spy );
 			selection.on( 'change:range', spy );
 
 
-			selection.setFocus( selection.focus );
+			selection.moveFocusTo( selection.focus );
 
 
 			expect( count( selection.getRanges() ) ).to.equal( 2 );
 			expect( count( selection.getRanges() ) ).to.equal( 2 );
 			expect( spy.callCount ).to.equal( 0 );
 			expect( spy.callCount ).to.equal( 0 );
@@ -328,7 +361,7 @@ describe( 'Selection', () => {
 			const spy = sinon.spy();
 			const spy = sinon.spy();
 			selection.on( 'change:range', spy );
 			selection.on( 'change:range', spy );
 
 
-			selection.setFocus( Position.createAt( root, 'end' ) );
+			selection.moveFocusTo( Position.createAt( root, 'end' ) );
 
 
 			expect( spy.calledOnce ).to.be.true;
 			expect( spy.calledOnce ).to.be.true;
 		} );
 		} );
@@ -337,17 +370,17 @@ describe( 'Selection', () => {
 			const endPos = Position.createAt( root, 'end' );
 			const endPos = Position.createAt( root, 'end' );
 
 
 			expect( () => {
 			expect( () => {
-				selection.setFocus( endPos );
-			} ).to.throw( CKEditorError, /model-selection-setFocus-no-ranges/ );
+				selection.moveFocusTo( endPos );
+			} ).to.throw( CKEditorError, /model-selection-moveFocusTo-no-ranges/ );
 		} );
 		} );
 
 
 		it( 'modifies existing collapsed selection', () => {
 		it( 'modifies existing collapsed selection', () => {
 			const startPos = Position.createAt( root, 1 );
 			const startPos = Position.createAt( root, 1 );
 			const endPos = Position.createAt( root, 2 );
 			const endPos = Position.createAt( root, 2 );
 
 
-			selection.collapse( startPos );
+			selection.setCollapsedAt( startPos );
 
 
-			selection.setFocus( endPos );
+			selection.moveFocusTo( endPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -357,9 +390,9 @@ describe( 'Selection', () => {
 			const startPos = Position.createAt( root, 1 );
 			const startPos = Position.createAt( root, 1 );
 			const endPos = Position.createAt( root, 0 );
 			const endPos = Position.createAt( root, 0 );
 
 
-			selection.collapse( startPos );
+			selection.setCollapsedAt( startPos );
 
 
-			selection.setFocus( endPos );
+			selection.moveFocusTo( endPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -373,7 +406,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -386,7 +419,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -400,7 +433,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ), true );
 			selection.addRange( new Range( startPos, endPos ), true );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -414,7 +447,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ), true );
 			selection.addRange( new Range( startPos, endPos ), true );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -437,7 +470,7 @@ describe( 'Selection', () => {
 
 
 			selection.on( 'change:range', spy );
 			selection.on( 'change:range', spy );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			const ranges = Array.from( selection.getRanges() );
 			const ranges = Array.from( selection.getRanges() );
 
 
@@ -458,7 +491,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( startPos );
+			selection.moveFocusTo( startPos );
 
 
 			expect( selection.focus.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.isCollapsed ).to.be.true;
 			expect( selection.isCollapsed ).to.be.true;
@@ -472,7 +505,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( root, 'end' );
+			selection.moveFocusTo( root, 'end' );
 
 
 			expect( spy.calledOnce ).to.be.true;
 			expect( spy.calledOnce ).to.be.true;
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -588,6 +621,42 @@ describe( 'Selection', () => {
 			expect( selection.setRanges.calledOnce ).to.be.true;
 			expect( selection.setRanges.calledOnce ).to.be.true;
 			spy.restore();
 			spy.restore();
 		} );
 		} );
+
+		it( 'should set selection on the given Range using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+
+			selection.setTo( range1 );
+
+			expect( Array.from( selection.getRanges() ) ).to.deep.equal( [ range1 ] );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
+
+		it( 'should set selection on the given iterable of Ranges using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+
+			selection.setTo( new Set( [ range1, range2 ] ) );
+
+			expect( Array.from( selection.getRanges() ) ).to.deep.equal( [ range1, range2 ] );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
+
+		it( 'should set collapsed selection on the given Position using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+			const position = new Position( root, [ 4 ] );
+
+			selection.setTo( position );
+
+			expect( Array.from( selection.getRanges() ).length ).to.equal( 1 );
+			expect( Array.from( selection.getRanges() )[ 0 ].start ).to.deep.equal( position );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.isCollapsed ).to.be.true;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
 	} );
 	} );
 
 
 	describe( 'getFirstRange()', () => {
 	describe( 'getFirstRange()', () => {
@@ -740,7 +809,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'should do nothing if selection was already collapsed', () => {
 		it( 'should do nothing if selection was already collapsed', () => {
-			selection.collapse( range1.start );
+			selection.setCollapsedAt( range1.start );
 
 
 			const spy = sinon.spy( selection, 'fire' );
 			const spy = sinon.spy( selection, 'fire' );
 
 
@@ -776,7 +845,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 
 
 		it( 'should do nothing if selection was already collapsed', () => {
 		it( 'should do nothing if selection was already collapsed', () => {
-			selection.collapse( range1.start );
+			selection.setCollapsedAt( range1.start );
 
 
 			const spy = sinon.spy( selection, 'fire' );
 			const spy = sinon.spy( selection, 'fire' );
 
 

+ 2 - 2
packages/ckeditor5-engine/tests/view/observer/selectionobserver.js

@@ -315,8 +315,8 @@ describe( 'SelectionObserver', () => {
 			const viewAnchor = viewDocument.domConverter.domPositionToView( sel.anchorNode, sel.anchorOffset );
 			const viewAnchor = viewDocument.domConverter.domPositionToView( sel.anchorNode, sel.anchorOffset );
 			const viewFocus = viewDocument.domConverter.domPositionToView( sel.focusNode, sel.focusOffset );
 			const viewFocus = viewDocument.domConverter.domPositionToView( sel.focusNode, sel.focusOffset );
 
 
-			viewSel.collapse( viewAnchor );
-			viewSel.setFocus( viewFocus );
+			viewSel.setCollapsedAt( viewAnchor );
+			viewSel.moveFocusTo( viewFocus );
 
 
 			viewDocument.render();
 			viewDocument.render();
 		} );
 		} );

+ 22 - 0
packages/ckeditor5-engine/tests/view/range.js

@@ -675,6 +675,28 @@ describe( 'Range', () => {
 			} );
 			} );
 		} );
 		} );
 
 
+		describe( 'createCollapsedAt()', () => {
+			it( 'should return new collapsed range at the given item position', () => {
+				const item = new Element( 'p', null, new Text( 'foo' ) );
+				const range = Range.createCollapsedAt( item );
+
+				expect( range.start.parent ).to.equal( item );
+				expect( range.start.offset ).to.equal( 0 );
+
+				expect( range.isCollapsed ).to.be.true;
+			} );
+
+			it( 'should return new collapse range at the given item position and offset', () => {
+				const item = new Element( 'p', null, new Text( 'foo' ) );
+				const range = Range.createCollapsedAt( item, 1 );
+
+				expect( range.start.parent ).to.equal( item );
+				expect( range.start.offset ).to.equal( 1 );
+
+				expect( range.isCollapsed ).to.be.true;
+			} );
+		} );
+
 		describe( 'createFromParentsAndOffsets', () => {
 		describe( 'createFromParentsAndOffsets', () => {
 			it( 'should return range', () => {
 			it( 'should return range', () => {
 				const range = Range.createFromParentsAndOffsets( div, 0, foz, 1 );
 				const range = Range.createFromParentsAndOffsets( div, 0, foz, 1 );

+ 96 - 28
packages/ckeditor5-engine/tests/view/selection.js

@@ -106,10 +106,10 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'setFocus', () => {
+	describe( 'moveFocusTo', () => {
 		it( 'keeps all existing ranges when no modifications needed', () => {
 		it( 'keeps all existing ranges when no modifications needed', () => {
 			selection.addRange( range1 );
 			selection.addRange( range1 );
-			selection.setFocus( selection.focus );
+			selection.moveFocusTo( selection.focus );
 
 
 			expect( count( selection.getRanges() ) ).to.equal( 1 );
 			expect( count( selection.getRanges() ) ).to.equal( 1 );
 		} );
 		} );
@@ -118,17 +118,17 @@ describe( 'Selection', () => {
 			const endPos = Position.createAt( el, 'end' );
 			const endPos = Position.createAt( el, 'end' );
 
 
 			expect( () => {
 			expect( () => {
-				selection.setFocus( endPos );
-			} ).to.throw( CKEditorError, /view-selection-setFocus-no-ranges/ );
+				selection.moveFocusTo( endPos );
+			} ).to.throw( CKEditorError, /view-selection-moveFocusTo-no-ranges/ );
 		} );
 		} );
 
 
 		it( 'modifies existing collapsed selection', () => {
 		it( 'modifies existing collapsed selection', () => {
 			const startPos = Position.createAt( el, 1 );
 			const startPos = Position.createAt( el, 1 );
 			const endPos = Position.createAt( el, 2 );
 			const endPos = Position.createAt( el, 2 );
 
 
-			selection.collapse( startPos );
+			selection.setCollapsedAt( startPos );
 
 
-			selection.setFocus( endPos );
+			selection.moveFocusTo( endPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -138,9 +138,9 @@ describe( 'Selection', () => {
 			const startPos = Position.createAt( el, 1 );
 			const startPos = Position.createAt( el, 1 );
 			const endPos = Position.createAt( el, 0 );
 			const endPos = Position.createAt( el, 0 );
 
 
-			selection.collapse( startPos );
+			selection.setCollapsedAt( startPos );
 
 
-			selection.setFocus( endPos );
+			selection.moveFocusTo( endPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -154,7 +154,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -167,7 +167,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -181,7 +181,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ), true );
 			selection.addRange( new Range( startPos, endPos ), true );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -195,7 +195,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ), true );
 			selection.addRange( new Range( startPos, endPos ), true );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.anchor.compareWith( endPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -214,7 +214,7 @@ describe( 'Selection', () => {
 			selection.addRange( new Range( startPos1, endPos1 ) );
 			selection.addRange( new Range( startPos1, endPos1 ) );
 			selection.addRange( new Range( startPos2, endPos2 ) );
 			selection.addRange( new Range( startPos2, endPos2 ) );
 
 
-			selection.setFocus( newEndPos );
+			selection.moveFocusTo( newEndPos );
 
 
 			const ranges = Array.from( selection.getRanges() );
 			const ranges = Array.from( selection.getRanges() );
 
 
@@ -233,7 +233,7 @@ describe( 'Selection', () => {
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
 
 
-			selection.setFocus( startPos );
+			selection.moveFocusTo( startPos );
 
 
 			expect( selection.focus.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.isCollapsed ).to.be.true;
 			expect( selection.isCollapsed ).to.be.true;
@@ -247,7 +247,7 @@ describe( 'Selection', () => {
 			const spy = sinon.stub( Position, 'createAt' ).returns( newEndPos );
 			const spy = sinon.stub( Position, 'createAt' ).returns( newEndPos );
 
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.addRange( new Range( startPos, endPos ) );
-			selection.setFocus( el, 'end' );
+			selection.moveFocusTo( el, 'end' );
 
 
 			expect( spy.calledOnce ).to.be.true;
 			expect( spy.calledOnce ).to.be.true;
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( newEndPos ) ).to.equal( 'same' );
@@ -600,7 +600,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'removeAllRanges', () => {
+	describe( 'removeAllRanges()', () => {
 		it( 'should remove all ranges and fire change event', done => {
 		it( 'should remove all ranges and fire change event', done => {
 			selection.addRange( range1 );
 			selection.addRange( range1 );
 			selection.addRange( range2 );
 			selection.addRange( range2 );
@@ -622,7 +622,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'setRanges', () => {
+	describe( 'setRanges()', () => {
 		it( 'should throw an error when range is invalid', () => {
 		it( 'should throw an error when range is invalid', () => {
 			expect( () => {
 			expect( () => {
 				selection.setRanges( [ { invalid: 'range' } ] );
 				selection.setRanges( [ { invalid: 'range' } ] );
@@ -645,8 +645,8 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'setTo', () => {
-		it( 'should return true if selections equal', () => {
+	describe( 'setTo()', () => {
+		it( 'should set selection ranges from the given selection', () => {
 			selection.addRange( range1 );
 			selection.addRange( range1 );
 
 
 			const otherSelection = new Selection();
 			const otherSelection = new Selection();
@@ -664,6 +664,41 @@ describe( 'Selection', () => {
 			expect( selection.anchor.isEqual( range3.end ) ).to.be.true;
 			expect( selection.anchor.isEqual( range3.end ) ).to.be.true;
 		} );
 		} );
 
 
+		it( 'should set selection on the given Range using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+
+			selection.setTo( range1 );
+
+			expect( Array.from( selection.getRanges() ) ).to.deep.equal( [ range1 ] );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
+
+		it( 'should set selection on the given iterable of Ranges using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+
+			selection.setTo( new Set( [ range1, range2 ] ) );
+
+			expect( Array.from( selection.getRanges() ) ).to.deep.equal( [ range1, range2 ] );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
+
+		it( 'should set collapsed selection on the given Position using setRanges method', () => {
+			const spy = sinon.spy( selection, 'setRanges' );
+
+			selection.setTo( range1.start );
+
+			expect( Array.from( selection.getRanges() ).length ).to.equal( 1 );
+			expect( Array.from( selection.getRanges() )[ 0 ].start ).to.deep.equal( range1.start );
+			expect( selection.isBackward ).to.be.false;
+			expect( selection.isCollapsed ).to.be.true;
+			expect( selection.setRanges.calledOnce ).to.be.true;
+			spy.restore();
+		} );
+
 		it( 'should fire change event', done => {
 		it( 'should fire change event', done => {
 			selection.on( 'change', () => {
 			selection.on( 'change', () => {
 				expect( selection.rangeCount ).to.equal( 1 );
 				expect( selection.rangeCount ).to.equal( 1 );
@@ -688,7 +723,40 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'collapse', () => {
+	describe( 'setIn()', () => {
+		it( 'should set selection inside an element', () => {
+			const element = new Element( 'p', null, [ new Text( 'foo' ), new Text( 'bar' ) ] );
+
+			selection.setIn( element );
+
+			const ranges = Array.from( selection.getRanges() );
+			expect( ranges.length ).to.equal( 1 );
+			expect( ranges[ 0 ].start.parent ).to.equal( element );
+			expect( ranges[ 0 ].start.offset ).to.deep.equal( 0 );
+			expect( ranges[ 0 ].end.parent ).to.equal( element );
+			expect( ranges[ 0 ].end.offset ).to.deep.equal( 2 );
+		} );
+	} );
+
+	describe( 'setOn()', () => {
+		it( 'should set selection on an item', () => {
+			const textNode1 = new Text( 'foo' );
+			const textNode2 = new Text( 'bar' );
+			const textNode3 = new Text( 'baz' );
+			const element = new Element( 'p', null, [ textNode1, textNode2, textNode3 ] );
+
+			selection.setOn( textNode2 );
+
+			const ranges = Array.from( selection.getRanges() );
+			expect( ranges.length ).to.equal( 1 );
+			expect( ranges[ 0 ].start.parent ).to.equal( element );
+			expect( ranges[ 0 ].start.offset ).to.deep.equal( 1 );
+			expect( ranges[ 0 ].end.parent ).to.equal( element );
+			expect( ranges[ 0 ].end.offset ).to.deep.equal( 2 );
+		} );
+	} );
+
+	describe( 'setCollapsedAt()', () => {
 		beforeEach( () => {
 		beforeEach( () => {
 			selection.setRanges( [ range1, range2 ] );
 			selection.setRanges( [ range1, range2 ] );
 		} );
 		} );
@@ -696,7 +764,7 @@ describe( 'Selection', () => {
 		it( 'should collapse selection at position', () => {
 		it( 'should collapse selection at position', () => {
 			const position = new Position( el, 4 );
 			const position = new Position( el, 4 );
 
 
-			selection.collapse( position );
+			selection.setCollapsedAt( position );
 			const range = selection.getFirstRange();
 			const range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( el );
 			expect( range.start.parent ).to.equal( el );
@@ -708,14 +776,14 @@ describe( 'Selection', () => {
 			const foo = new Text( 'foo' );
 			const foo = new Text( 'foo' );
 			const p = new Element( 'p', null, foo );
 			const p = new Element( 'p', null, foo );
 
 
-			selection.collapse( foo );
+			selection.setCollapsedAt( foo );
 			let range = selection.getFirstRange();
 			let range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( foo );
 			expect( range.start.parent ).to.equal( foo );
 			expect( range.start.offset ).to.equal( 0 );
 			expect( range.start.offset ).to.equal( 0 );
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 
 
-			selection.collapse( p, 1 );
+			selection.setCollapsedAt( p, 1 );
 			range = selection.getFirstRange();
 			range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( p );
 			expect( range.start.parent ).to.equal( p );
@@ -727,21 +795,21 @@ describe( 'Selection', () => {
 			const foo = new Text( 'foo' );
 			const foo = new Text( 'foo' );
 			const p = new Element( 'p', null, foo );
 			const p = new Element( 'p', null, foo );
 
 
-			selection.collapse( foo, 'end' );
+			selection.setCollapsedAt( foo, 'end' );
 			let range = selection.getFirstRange();
 			let range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( foo );
 			expect( range.start.parent ).to.equal( foo );
 			expect( range.start.offset ).to.equal( 3 );
 			expect( range.start.offset ).to.equal( 3 );
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 
 
-			selection.collapse( foo, 'before' );
+			selection.setCollapsedAt( foo, 'before' );
 			range = selection.getFirstRange();
 			range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( p );
 			expect( range.start.parent ).to.equal( p );
 			expect( range.start.offset ).to.equal( 0 );
 			expect( range.start.offset ).to.equal( 0 );
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 			expect( range.start.isEqual( range.end ) ).to.be.true;
 
 
-			selection.collapse( foo, 'after' );
+			selection.setCollapsedAt( foo, 'after' );
 			range = selection.getFirstRange();
 			range = selection.getFirstRange();
 
 
 			expect( range.start.parent ).to.equal( p );
 			expect( range.start.parent ).to.equal( p );
@@ -750,7 +818,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'collapseToStart', () => {
+	describe( 'collapseToStart()', () => {
 		it( 'should collapse to start position and fire change event', done => {
 		it( 'should collapse to start position and fire change event', done => {
 			selection.setRanges( [ range1, range2, range3 ] );
 			selection.setRanges( [ range1, range2, range3 ] );
 			selection.once( 'change', () => {
 			selection.once( 'change', () => {
@@ -773,7 +841,7 @@ describe( 'Selection', () => {
 		} );
 		} );
 	} );
 	} );
 
 
-	describe( 'collapseToEnd', () => {
+	describe( 'collapseToEnd()', () => {
 		it( 'should collapse to end position and fire change event', done => {
 		it( 'should collapse to end position and fire change event', done => {
 			selection.setRanges( [ range1, range2, range3 ] );
 			selection.setRanges( [ range1, range2, range3 ] );
 			selection.once( 'change', () => {
 			selection.once( 'change', () => {