浏览代码

Changed: Moved correction listener to `model.DocumentSelection`.

Szymon Cofalik 8 年之前
父节点
当前提交
a157ada0a3

+ 0 - 18
packages/ckeditor5-engine/src/model/document.js

@@ -81,24 +81,6 @@ export default class Document {
 		 */
 		this.roots = new Collection( { idProperty: 'rootName' } );
 
-		// Add events that will ensure selection correctness.
-		this.selection.on( 'change:range', () => {
-			for ( const range of this.selection.getRanges() ) {
-				if ( !this._validateSelectionRange( range ) ) {
-					/**
-					 * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}
-					 * starts or ends at incorrect position.
-					 *
-					 * @error document-selection-wrong-position
-					 * @param {module:engine/model/range~Range} range
-					 */
-					throw new CKEditorError(
-						'document-selection-wrong-position: Range from document selection starts or ends at incorrect position.',
-						{ range }
-					);
-				}
-			}
-		} );
 
 		// Graveyard tree root. Document always have a graveyard root, which stores removed nodes.
 		this.createRoot( '$root', graveyardName );

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

@@ -84,6 +84,24 @@ export default class DocumentSelection extends Selection {
 		 */
 		this._attributePriority = new Map();
 
+		// Add events that will ensure selection correctness.
+		this.on( 'change:range', () => {
+			for ( const range of this.getRanges() ) {
+				if ( !this._document._validateSelectionRange( range ) ) {
+					/**
+					 * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}
+					 * starts or ends at incorrect position.
+					 *
+					 * @error document-selection-wrong-position
+					 * @param {module:engine/model/range~Range} range
+					 */
+					throw new CKEditorError(
+						'document-selection-wrong-position: Range from document selection starts or ends at incorrect position.',
+						{ range }
+					);
+				}
+			}
+		} );
 		this.listenTo( this._document, 'change', ( evt, type, changes, batch ) => {
 			// Whenever attribute operation is performed on document, update selection attributes.
 			// This is not the most efficient way to update selection attributes, but should be okay for now.

+ 42 - 0
packages/ckeditor5-engine/tests/model/documentselection.js

@@ -1152,4 +1152,46 @@ describe( 'DocumentSelection', () => {
 			} );
 		} );
 	} );
+
+	it( 'should throw if one of ranges starts or ends inside surrogate pair', () => {
+		root.removeChildren( 0, root.childCount );
+		root.appendChildren( '\uD83D\uDCA9' );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 0, root, 1 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 1, root, 2 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+	} );
+
+	it( 'should throw if one of ranges starts or ends between base character and combining mark', () => {
+		root.removeChildren( 0, root.childCount );
+		root.appendChildren( 'foo̻̐ͩbar' );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 3, root, 9 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 4, root, 9 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 5, root, 9 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 1, root, 3 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 1, root, 4 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+
+		expect( () => {
+			doc.selection.setRanges( [ Range.createFromParentsAndOffsets( root, 1, root, 5 ) ] );
+		} ).to.throw( CKEditorError, /document-selection-wrong-position/ );
+	} );
 } );