Browse Source

WIP - DocumentSelection.

Maciej Bukowski 8 years ago
parent
commit
b32f85901b

+ 21 - 4
packages/ckeditor5-engine/src/model/documentselection.js

@@ -16,6 +16,7 @@ import Position from './position';
 import Selection from './selection';
 import Text from './text';
 import TextProxy from './textproxy';
+import Range from './range';
 
 const storePrefix = 'selection:';
 
@@ -223,7 +224,23 @@ export default class DocumentSelection {
 	 * @param {*} offset
 	 */
 	_moveFocusTo( itemOrPosition, offset ) {
-		this._selection.moveFocusTo( itemOrPosition, offset );
+		const newFocus = Position.createAt( itemOrPosition, offset );
+
+		if ( newFocus.compareWith( this.focus ) == 'same' ) {
+			return;
+		}
+
+		const anchor = this.anchor;
+
+		if ( this._selection.length ) {
+			this._selection._popRange();
+		}
+
+		if ( newFocus.compareWith( anchor ) == 'before' ) {
+			this._selection.addRange( new Range( newFocus, anchor ), true );
+		} else {
+			this._selection.addRange( new Range( anchor, newFocus ) );
+		}
 	}
 
 	/**
@@ -237,12 +254,12 @@ export default class DocumentSelection {
 
 	/**
 	 * @protected
-	 * @param {*} key
+	 * @param {String} key
 	 * @param {*} value
 	 */
 	_setAttribute( key, value ) {
 		// Store attribute in parent element if the selection is collapsed in an empty node.
-		if ( this._selection.isCollapsed && this._selection.anchor.parent.isEmpty ) {
+		if ( this.isCollapsed && this._selection.anchor.parent.isEmpty ) {
 			this._storeAttribute( key, value );
 		}
 
@@ -574,7 +591,7 @@ export default class DocumentSelection {
 	 * @returns {Iterable.<*>}
 	 */
 	* _getStoredAttributes() {
-		const selectionParent = this.getFirstRange().start.parent;
+		const selectionParent = this.getFirstPosition().parent;
 
 		if ( this.isCollapsed && selectionParent.isEmpty ) {
 			for ( const key of selectionParent.getAttributeKeys() ) {

+ 5 - 3
packages/ckeditor5-engine/src/model/selection.js

@@ -302,7 +302,7 @@ export default class Selection {
 	 * @param {module:engine/model/selection~Selection|module:engine/model/position~Position|
 	 * Iterable.<module:engine/model/range~Range>|module:engine/model/range~Range|null} selectable
 	 */
-	setTo( selectable ) {
+	setTo( selectable, isLastBackward = false ) {
 		if ( !selectable ) {
 			this.removeAllRanges();
 		} else if ( selectable instanceof Selection ) {
@@ -311,10 +311,12 @@ export default class Selection {
 			this.setRanges( [ selectable ] );
 		} else if ( isIterable( selectable ) ) {
 			// We assume that the selectable is an iterable of ranges.
-			this.setRanges( selectable );
-		} else {
+			this.setRanges( selectable, isLastBackward );
+		} else if ( selectable instanceof Position ) {
 			// We assume that the selectable is a position.
 			this.setRanges( [ new Range( selectable ) ] );
+		} else {
+			throw new CKEditorError( 'model-selection-added-not-selectable' );
 		}
 	}
 

+ 7 - 6
packages/ckeditor5-engine/tests/model/documentselection.js

@@ -247,7 +247,7 @@ describe( 'DocumentSelection', () => {
 		it( 'should unbind all events', () => {
 			selection._setTo( [ range, liveRange ] );
 
-			const ranges = selection._ranges;
+			const ranges = Array.from( selection.getRanges() );
 
 			sinon.spy( ranges[ 0 ], 'detach' );
 			sinon.spy( ranges[ 1 ], 'detach' );
@@ -267,7 +267,7 @@ describe( 'DocumentSelection', () => {
 			const startPos = selection.getFirstPosition();
 			const endPos = Position.createAt( root, 'end' );
 
-			selection.moveFocusTo( endPos );
+			selection._moveFocusTo( endPos );
 
 			expect( selection.anchor.compareWith( startPos ) ).to.equal( 'same' );
 			expect( selection.focus.compareWith( endPos ) ).to.equal( 'same' );
@@ -281,7 +281,7 @@ describe( 'DocumentSelection', () => {
 
 			selection._setTo( new Range( startPos, endPos ) );
 
-			selection.moveFocusTo( newEndPos );
+			selection._moveFocusTo( newEndPos );
 
 			expect( spy.calledOnce ).to.be.true;
 		} );
@@ -291,12 +291,13 @@ describe( 'DocumentSelection', () => {
 		let spy, ranges;
 
 		beforeEach( () => {
-			selection._setTo( [ liveRange, range ] );
+			selection._selection.addRange( liveRange );
+			selection._selection.addRange( range );
 
 			spy = sinon.spy();
 			selection.on( 'change:range', spy );
 
-			ranges = Array.from( selection._ranges );
+			ranges = Array.from( selection.getRanges() );
 
 			sinon.spy( ranges[ 0 ], 'detach' );
 			sinon.spy( ranges[ 1 ], 'detach' );
@@ -339,7 +340,7 @@ describe( 'DocumentSelection', () => {
 		it( 'should detach removed ranges', () => {
 			selection._setTo( [ liveRange, range ] );
 
-			const oldRanges = Array.from( selection._ranges );
+			const oldRanges = Array.from( selection.getRanges() );
 
 			sinon.spy( oldRanges[ 0 ], 'detach' );
 			sinon.spy( oldRanges[ 1 ], 'detach' );