浏览代码

Improved filtering to handle disallowed attributes when merge.

Oskar Wróbel 8 年之前
父节点
当前提交
86a52d9314

+ 29 - 6
packages/ckeditor5-engine/src/controller/insertcontent.js

@@ -10,6 +10,7 @@
 import Position from '../model/position';
 import LivePosition from '../model/liveposition';
 import Element from '../model/element';
+import Text from '../model/text';
 import Range from '../model/range';
 import log from '@ckeditor/ckeditor5-utils/src/log';
 
@@ -286,6 +287,14 @@ class Insertion {
 		if ( mergeLeft ) {
 			const position = LivePosition.createFromPosition( this.position );
 
+			const children = Array.from( node.getChildren() );
+
+			// When Text is a direct child of node which is going to be merged
+			// we need to strip it from the disallowed attributes according to the new parent.
+			if ( children.some( child => child instanceof Text ) ) {
+				this._stripDisallowedAttributes( children, mergePosLeft.nodeBefore );
+			}
+
 			this.batch.merge( mergePosLeft );
 
 			this.position = Position.createFromPosition( position );
@@ -309,6 +318,14 @@ class Insertion {
 			// NOK: <p>xx[]</p> + <p>yy</p> => <p>xxyy[]</p> (when sticks to next)
 			const position = new LivePosition( this.position.root, this.position.path, 'sticksToPrevious' );
 
+			const children = Array.from( node.getChildren() );
+
+			// When Text is a direct child of node which is going to be merged
+			// we need to strip it from the disallowed attributes according to the new parent.
+			if ( children.some( child => child instanceof Text ) ) {
+				this._stripDisallowedAttributes( children, mergePosLeft.nodeAfter );
+			}
+
 			this.batch.merge( mergePosRight );
 
 			this.position = Position.createFromPosition( position );
@@ -431,16 +448,22 @@ class Insertion {
 	}
 
 	/**
-	 * Removes disallowed by schema attributes.
+	 * Removes disallowed by schema attributes from given nodes.
 	 *
 	 * @private
-	 * @param {module:engine/model/node~Node} node
+	 * @param {module:engine/model/node~Node|Array<module:engine/model/node~Node>} nodes
 	 * @param {module:engine/model/schema~SchemaPath} path
 	 */
-	_stripDisallowedAttributes( node, path = this.position ) {
-		for ( const attribute of node.getAttributeKeys() ) {
-			if ( !this.schema.check( { name: '$text', attributes: attribute, inside: path } ) ) {
-				node.removeAttribute( attribute );
+	_stripDisallowedAttributes( nodes, path = this.position ) {
+		if ( !Array.isArray( nodes ) ) {
+			nodes = [ nodes ];
+		}
+
+		for ( const node of nodes ) {
+			for ( const attribute of node.getAttributeKeys() ) {
+				if ( !this.schema.check( { name: '$text', attributes: attribute, inside: path } ) ) {
+					node.removeAttribute( attribute );
+				}
 			}
 		}
 	}

+ 24 - 0
packages/ckeditor5-engine/tests/controller/insertcontent.js

@@ -300,6 +300,12 @@ describe( 'DataController', () => {
 					expect( getData( doc ) ).to.equal( '<paragraph>xyz[]</paragraph>' );
 				} );
 
+				it( 'inserts one empty paragraph', () => {
+					setData( doc, '<paragraph>f[]oo</paragraph>' );
+					insertHelper( '<paragraph></paragraph>' );
+					expect( getData( doc ) ).to.equal( '<paragraph>f[]oo</paragraph>' );
+				} );
+
 				it( 'inserts one block into a fully selected content', () => {
 					setData( doc, '<heading1>[foo</heading1><paragraph>bar]</paragraph>' );
 					insertHelper( '<heading2>xyz</heading2>' );
@@ -625,6 +631,24 @@ describe( 'DataController', () => {
 				expect( getData( doc ) ).to.equal( '<paragraph>fx<$text b="1">x</$text>xyyy[]oo</paragraph>' );
 			} );
 
+			it( 'filters out disallowed attributes when merging #1', () => {
+				setData( doc, '<paragraph>[]foo</paragraph>' );
+				insertHelper( '<paragraph>x<$text a="1" b="1">x</$text>x</paragraph>' );
+				expect( getData( doc ) ).to.equal( '<paragraph>x<$text b="1">x</$text>x[]foo</paragraph>' );
+			} );
+
+			it( 'filters out disallowed attributes when merging #2', () => {
+				setData( doc, '<paragraph>f[]oo</paragraph>' );
+				insertHelper( '<paragraph>x<$text a="1" b="1">x</$text>x</paragraph>' );
+				expect( getData( doc ) ).to.equal( '<paragraph>fx<$text b="1">x</$text>x[]oo</paragraph>' );
+			} );
+
+			it( 'filters out disallowed attributes when merging #3', () => {
+				setData( doc, '<paragraph>foo[]</paragraph>' );
+				insertHelper( '<paragraph>x<$text a="1" b="1">x</$text>x</paragraph>' );
+				expect( getData( doc ) ).to.equal( '<paragraph>foox<$text b="1">x</$text>x[]</paragraph>' );
+			} );
+
 			it( 'filters out disallowed attributes when autoparagraphing', () => {
 				setData( doc, '<paragraph>f[]oo</paragraph>' );
 				insertHelper( '<paragraph>xxx</paragraph><$text a="1" b="1">yyy</$text>' );