8
0
Просмотр исходного кода

Fixed: infinite selection fixing loop.

Szymon Cofalik 9 лет назад
Родитель
Сommit
3467750ce7

+ 16 - 8
packages/ckeditor5-engine/src/conversion/view-selection-to-model-converters.js

@@ -10,6 +10,8 @@
  * @namespace engine.conversion.viewSelectionToModel
  */
 
+import ModelSelection from '../model/selection.js';
+
 /**
  * Function factory, creates a callback function which converts a {@link engine.view.Selection view selection} taken
  * from the {@link engine.view.Document#selectionChange} event and sets in on the {@link engine.model.Document#selection model}.
@@ -26,15 +28,21 @@
  */
 export function convertSelectionChange( modelDocument, mapper ) {
 	return ( evt, data ) => {
-		modelDocument.enqueueChanges( () => {
-			const viewSelection = data.newSelection;
-			const ranges = [];
+		const viewSelection = data.newSelection;
+		const modelSelection = new ModelSelection();
+
+		const ranges = [];
+
+		for ( let viewRange of viewSelection.getRanges() ) {
+			ranges.push( mapper.toModelRange( viewRange ) );
+		}
 
-			for ( let viewRange of viewSelection.getRanges() ) {
-				ranges.push( mapper.toModelRange( viewRange ) );
-			}
+		modelSelection.setRanges( ranges, viewSelection.isBackward );
 
-			modelDocument.selection.setRanges( ranges, viewSelection.isBackward );
-		} );
+		if ( !modelSelection.isEqual( modelDocument.selection ) ) {
+			modelDocument.enqueueChanges( () => {
+				modelDocument.selection.setTo( modelSelection );
+			} );
+		}
 	};
 }

+ 13 - 9
packages/ckeditor5-engine/src/model/selection.js

@@ -125,25 +125,29 @@ export default class Selection {
 	}
 
 	/**
-	 * Checks whether, this selection is equal to given selection. Selections equal if they have the same ranges and directions.
+	 * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,
+	 * same number of ranges and all ranges from one selection equal to a range from other selection.
 	 *
 	 * @param {engine.model.Selection} otherSelection Selection to compare with.
 	 * @returns {Boolean} `true` if selections are equal, `false` otherwise.
 	 */
 	isEqual( otherSelection ) {
-		const rangeCount = this.rangeCount;
-
-		if ( rangeCount != otherSelection.rangeCount ) {
+		if ( !this.anchor.isEqual( otherSelection.anchor ) || !this.focus.isEqual( otherSelection.focus ) ) {
 			return false;
 		}
 
-		for ( let i = 0; i < this.rangeCount; i++ ) {
-			if ( !this._ranges[ i ].isEqual( otherSelection._ranges[ i ] ) ) {
-				return false;
-			}
+		if ( this.rangeCount != otherSelection.rangeCount ) {
+			return false;
 		}
 
-		return this.isBackward === otherSelection.isBackward;
+		// Every range from this selection...
+		return Array.from( this.getRanges() ).every( ( rangeA ) => {
+			// ...Has a range in other selection...
+			return Array.from( otherSelection.getRanges() ).some( ( rangeB ) => {
+				// That it is equal to.
+				return rangeA.isEqual( rangeB );
+			} );
+		} );
 	}
 
 	/**

+ 0 - 4
packages/ckeditor5-engine/src/view/observer/selectionobserver.js

@@ -151,10 +151,6 @@ export default class SelectionObserver extends Observer {
 			newSelection: newViewSelection,
 			domSelection: domSelection
 		} );
-
-		// If nothing changes on `selectionChange` event, at this point we have "dirty DOM" (changed) and de-synched
-		// view (which has not been changed). In order to "reset DOM" we render the view again.
-		this.document.render();
 	}
 
 	/**