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

Added attributes filtering when merging after delete.

Oskar Wróbel 8 лет назад
Родитель
Сommit
293db51931

+ 39 - 0
packages/ckeditor5-engine/src/controller/deletecontent.js

@@ -132,6 +132,13 @@ function mergeBranches( batch, startPos, endPos ) {
 		// To then become:
 		// <a><b>xy</b>[]</a><c>{}</c>
 		batch.merge( startPos );
+
+		// We need to check and strip disallowed attributes in direct children because after merge
+		// some attributes could end up in a parent where are disallowed.
+		//
+		// e.g. bold is disallowed for <H1>
+		// <h1>Fo{o</h1><p>b}a<b>r</b><p> -> <h1>Fo{}a<b>r</b><h1> -> <h1>Fo{}ar<h1>.
+		removeDisallowedAttributes( Array.from( startParent.getChildren() ), [ startParent ], batch.document.schema );
 	}
 
 	// Removes empty end ancestors:
@@ -210,3 +217,35 @@ function shouldEntireContentBeReplacedWithParagraph( schema, selection ) {
 
 	return schema.check( { name: 'paragraph', inside: limitElement.name } );
 }
+
+// Gets a name under which we should check this node in the schema.
+//
+// @private
+// @param {module:engine/model/node~Node} node The node.
+function getNodeSchemaName( node ) {
+	if ( node.is( 'text' ) ) {
+		return '$text';
+	}
+
+	return node.name;
+}
+
+// Removes disallowed by schema attributes from given text nodes.
+//
+// @private
+// @param {module:engine/model/node~Node|Array<module:engine/model/node~Node>} nodes
+// @param {module:engine/model/schema~SchemaPath} schemaPath
+// @param {module:engine/model/schema~Schema} schema
+function removeDisallowedAttributes( nodes, schemaPath, schema ) {
+	if ( !Array.isArray( nodes ) ) {
+		nodes = [ nodes ];
+	}
+
+	for ( const node of nodes ) {
+		for ( const attribute of node.getAttributeKeys() ) {
+			if ( !schema.check( { name: getNodeSchemaName( node ), attributes: attribute, inside: schemaPath } ) ) {
+				node.removeAttribute( attribute );
+			}
+		}
+	}
+}

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

@@ -167,6 +167,12 @@ describe( 'DataController', () => {
 				schema.allow( { name: '$text', inside: 'pparent' } );
 
 				schema.allow( { name: 'paragraph', attributes: [ 'align' ] } );
+				schema.allow( { name: '$text', attributes: 'a', inside: 'paragraph' } );
+				schema.allow( { name: '$text', attributes: 'b', inside: 'paragraph' } );
+				schema.allow( { name: '$text', attributes: 'c', inside: 'paragraph' } );
+				schema.allow( { name: '$text', attributes: 'b', inside: 'heading1' } );
+				schema.allow( { name: '$text', attributes: 'c', inside: 'pchild' } );
+				schema.allow( { name: '$text', attributes: 'd', inside: 'pchild' } );
 			} );
 
 			test(
@@ -263,6 +269,12 @@ describe( 'DataController', () => {
 				expect( spyMerge.called ).to.be.true;
 			} );
 
+			test(
+				'filters out disallowed attributes after merge',
+				'<heading1>fo[o</heading1><paragraph>b]a<$text a="true" b="true">r</$text></paragraph>',
+				'<heading1>fo[]a<$text b="true">r</$text></heading1>'
+			);
+
 			// Note: in all these cases we ignore the direction of merge.
 			// If https://github.com/ckeditor/ckeditor5-engine/issues/470 was fixed we could differently treat
 			// forward and backward delete.
@@ -400,6 +412,18 @@ describe( 'DataController', () => {
 					expect( getData( doc ) )
 						.to.equal( '<paragraph>fo[]</paragraph>' );
 				} );
+
+				test(
+					'filters out disallowed attributes after merge when left',
+					'<paragraph>x<pchild>fo[o</pchild></paragraph><paragraph>y]<$text b="true" c="true">z</$text></paragraph>',
+					'<paragraph>x<pchild>fo[]<$text c="true">z</$text></pchild></paragraph>'
+				);
+
+				test(
+					'filters out disallowed attributes after merge when right',
+					'<paragraph>fo[o</paragraph><paragraph><pchild>x<$text c="true" d="true">y]z</$text></pchild></paragraph>',
+					'<paragraph>fo[]<$text c="true">z</$text></paragraph>'
+				);
 			} );
 
 			describe( 'with object elements', () => {