瀏覽代碼

Changed: Introduced DocumentSelection.getSnapshot, fixed bug in Selection.setFocus.

Szymon Cofalik 9 年之前
父節點
當前提交
c45e11a05d

+ 14 - 0
packages/ckeditor5-engine/src/model/documentselection.js

@@ -128,6 +128,20 @@ export default class DocumentSelection extends Selection {
 	}
 
 	/**
+	 * Creates an instance of {@link engine.model.Selection} that has same ranges and direction as this selection. Since
+	 * this will be instance of `Selection` instead of `DocumentSelection`, it will not be automatically updated or rendered,
+	 * so it can be used in algorithms using and modifying selection.
+	 *
+	 * @returns {engine.model.Selection} Selection instance which ranges and direction is equal to this selection.
+	 */
+	getSnapshot() {
+		const selection = new Selection();
+		selection.setRanges( this.getRanges(), this.isBackward );
+
+		return selection;
+	}
+
+	/**
 	 * Removes all attributes from the selection.
 	 *
 	 * @fires engine.model.DocumentSelection#change:attribute

+ 4 - 4
packages/ckeditor5-engine/src/model/selection.js

@@ -197,15 +197,15 @@ export default class Selection {
 	 * describing in which way the selection is made (see {@link #addRange}).
 	 *
 	 * @fires engine.model.Selection#change:range
-	 * @param {Array.<engine.model.Range>} newRanges Array of ranges to set.
+	 * @param {Iterable.<engine.model.Range>} newRanges Iterable set of ranges that should be set.
 	 * @param {Boolean} [isLastBackward] Flag describing if last added range was selected forward - from start to end (`false`)
 	 * or backward - from end to start (`true`). Defaults to `false`.
 	 */
 	setRanges( newRanges, isLastBackward ) {
 		this._ranges = [];
 
-		for ( let i = 0; i < newRanges.length; i++ ) {
-			this._pushRange( newRanges[ i ] );
+		for ( let range of newRanges ) {
+			this._pushRange( range );
 		}
 
 		this._lastRangeBackward = !!isLastBackward;
@@ -241,7 +241,7 @@ export default class Selection {
 	 * first parameter is a node.
 	 */
 	setFocus( nodeOrPosition, offset ) {
-		if ( this._ranges.length === 0 ) {
+		if ( this.anchor === null ) {
 			/**
 			 * Cannot set selection focus if there are no ranges in selection.
 			 *

+ 33 - 1
packages/ckeditor5-engine/tests/model/documentselection.js

@@ -275,7 +275,39 @@ describe( 'DocumentSelection', () => {
 		} );
 	} );
 
-	// Selection uses LiveRanges so here are only simple test to see if integration is
+	describe( 'getSnapshot', () => {
+		it( 'should return a Selection instance with default range if no ranges were added', () => {
+			const snapshot = selection.getSnapshot();
+
+			expect( selection.isBackward ).to.equal( snapshot.isBackward );
+
+			const snapshotRanges = Array.from( snapshot.getRanges() );
+
+			expect( snapshotRanges.length ).to.equal( 1 );
+			expect( snapshotRanges[ 0 ].start.path ).to.deep.equal( [ 0, 0 ] );
+			expect( snapshotRanges[ 0 ].end.path ).to.deep.equal( [ 0, 0 ] );
+		} );
+
+		it( 'should return a Selection instance with same ranges and direction as this selection', () => {
+			selection.addRange( liveRange );
+			selection.addRange( range, true );
+
+			const snapshot = selection.getSnapshot();
+
+			expect( selection.isBackward ).to.equal( snapshot.isBackward );
+
+			const selectionRanges = Array.from( selection.getRanges() );
+			const snapshotRanges = Array.from( snapshot.getRanges() );
+
+			expect( selectionRanges.length ).to.equal( snapshotRanges.length );
+
+			for ( let i = 0; i < selectionRanges.length; i++ ) {
+				expect( selectionRanges[ i ].isEqual( snapshotRanges[ i ] ) ).to.be.true;
+			}
+		} );
+	} );
+
+	// DocumentSelection uses LiveRanges so here are only simple test to see if integration is
 	// working well, without getting into complicated corner cases.
 	describe( 'after applying an operation should get updated and not fire update event', () => {
 		let spy;