浏览代码

Changed: The insertContent() should accept position & range.

Maciej Gołaszewski 7 年之前
父节点
当前提交
29cdfeaec2

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

@@ -300,11 +300,13 @@ export default class Model {
 	 *
 	 * @fires insertContent
 	 * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.
-	 * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
-	 * Selection into which the content should be inserted.
+	 * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection|
+	 * module:engine/model/position~Position|module:engine/model/element~Element|
+	 * Iterable.<module:engine/model/range~Range>|module:engine/model/range~Range|null} [selectable]
+	 * Selection into which the content should be inserted. If not provided the current model document selection will be used.
 	 */
-	insertContent( content, selection ) {
-		insertContent( this, content, selection );
+	insertContent( content, selectable ) {
+		insertContent( this, content, selectable );
 	}
 
 	/**

+ 15 - 2
packages/ckeditor5-engine/src/model/utils/insertcontent.js

@@ -13,6 +13,7 @@ import Element from '../element';
 import Range from '../range';
 import log from '@ckeditor/ckeditor5-utils/src/log';
 import DocumentSelection from '../documentselection';
+import Selection from '../selection';
 
 /**
  * Inserts content into the editor (specified selection) as one would expect the paste
@@ -26,11 +27,23 @@ import DocumentSelection from '../documentselection';
  * @param {module:engine/model/model~Model} model The model in context of which the insertion
  * should be performed.
  * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
+ * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection|
+ * module:engine/model/position~Position|module:engine/model/element~Element|
+ * Iterable.<module:engine/model/range~Range>|module:engine/model/range~Range|null} [selectable]
  * Selection into which the content should be inserted.
  */
-export default function insertContent( model, content, selection ) {
+export default function insertContent( model, content, selectable ) {
 	model.change( writer => {
+		let selection;
+
+		if ( !selectable ) {
+			selection = model.document.selection;
+		} else if ( selectable instanceof DocumentSelection ) {
+			selection = selectable;
+		} else {
+			selection = new Selection( selectable );
+		}
+
 		if ( !selection.isCollapsed ) {
 			model.deleteContent( selection );
 		}

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

@@ -372,6 +372,16 @@ describe( 'Model', () => {
 			expect( getData( model ) ).to.equal( '<paragraph>foob[]ar</paragraph>' );
 		} );
 
+		it( 'should use current model selection if no selectable passed', () => {
+			schema.register( 'paragraph', { inheritAllFrom: '$block' } );
+
+			setData( model, '<paragraph>fo[]ar</paragraph>' );
+
+			model.insertContent( new ModelText( 'ob' ) );
+
+			expect( getData( model ) ).to.equal( '<paragraph>foob[]ar</paragraph>' );
+		} );
+
 		it( 'should use parent batch', () => {
 			schema.register( 'paragraph', { inheritAllFrom: '$block' } );
 			setData( model, '<paragraph>[]</paragraph>' );

+ 47 - 0
packages/ckeditor5-engine/tests/model/utils/insertcontent.js

@@ -12,6 +12,7 @@ import Selection from '../../../src/model/selection';
 import Position from '../../../src/model/position';
 
 import { setData, getData, parse } from '../../../src/dev-utils/model';
+import Range from '../../../src/model/range';
 
 describe( 'DataController utils', () => {
 	let model, doc;
@@ -47,6 +48,52 @@ describe( 'DataController utils', () => {
 			} );
 		} );
 
+		it( 'should be able to insert content at custom position', () => {
+			model = new Model();
+			doc = model.document;
+			doc.createRoot();
+
+			model.schema.extend( '$text', { allowIn: '$root' } );
+			setData( model, 'a[]bc' );
+
+			const position = new Position( doc.getRoot(), [ 2 ] );
+
+			model.change( () => {
+				insertContent( model, new Text( 'x' ), position );
+				expect( getData( model ) ).to.equal( 'a[]bxc' );
+			} );
+		} );
+
+		it( 'should be able to insert content at custom range', () => {
+			model = new Model();
+			doc = model.document;
+			doc.createRoot();
+
+			model.schema.extend( '$text', { allowIn: '$root' } );
+			setData( model, 'a[]bc' );
+
+			const range = new Range( new Position( doc.getRoot(), [ 2 ] ), new Position( doc.getRoot(), [ 3 ] ) );
+
+			model.change( () => {
+				insertContent( model, new Text( 'x' ), range );
+				expect( getData( model ) ).to.equal( 'a[]bx' );
+			} );
+		} );
+
+		it( 'should be able to insert content at model selection if none passed', () => {
+			model = new Model();
+			doc = model.document;
+			doc.createRoot();
+
+			model.schema.extend( '$text', { allowIn: '$root' } );
+			setData( model, 'a[]bc' );
+
+			model.change( () => {
+				insertContent( model, new Text( 'x' ) );
+				expect( getData( model ) ).to.equal( 'ax[]bc' );
+			} );
+		} );
+
 		it( 'accepts DocumentFragment', () => {
 			model = new Model();
 			doc = model.document;