浏览代码

Removed model utils and refactored removing disallowed attributes.

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

+ 26 - 2
packages/ckeditor5-engine/src/controller/deletecontent.js

@@ -11,7 +11,6 @@ import LivePosition from '../model/liveposition';
 import Position from '../model/position';
 import Range from '../model/range';
 import Element from '../model/element';
-import { removeDisallowedAttributes } from '../model/utils';
 
 /**
  * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.
@@ -139,7 +138,7 @@ function mergeBranches( batch, startPos, endPos ) {
 		//
 		// 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 );
+		removeDisallowedAttributes( batch, Array.from( startParent.getChildren() ), [ startParent ] );
 	}
 
 	// Removes empty end ancestors:
@@ -218,3 +217,28 @@ 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.
+//
+// @param {module:engine/model/node~Node} node The node.
+// @returns {String} node name.
+function getNodeSchemaName( node ) {
+	return node.is( 'text' ) ? '$text' : node.name;
+}
+
+// Adds deltas with `removeAttributes` operation for disallowed by schema attributes on given nodes.
+//
+// @param {module:engine/model/batch~Batch} batch Batch to which the deltas will be added.
+// @param {module:engine/model/node~Node|Array<module:engine/model/node~Node>} nodes List of nodes or a single node to filter.
+// @param {module:engine/model/schema~SchemaPath} schemaPath
+function removeDisallowedAttributes( batch, nodes, schemaPath ) {
+	const schema = batch.document.schema;
+
+	for ( const node of nodes ) {
+		for ( const attribute of node.getAttributeKeys() ) {
+			if ( !schema.check( { name: getNodeSchemaName( node ), attributes: attribute, inside: schemaPath } ) ) {
+				batch.removeAttribute( node, attribute );
+			}
+		}
+	}
+}

+ 34 - 8
packages/ckeditor5-engine/src/controller/insertcontent.js

@@ -12,7 +12,6 @@ import LivePosition from '../model/liveposition';
 import Element from '../model/element';
 import Range from '../model/range';
 import log from '@ckeditor/ckeditor5-utils/src/log';
-import { getNodeSchemaName, removeDisallowedAttributes } from '../model/utils';
 
 /**
  * Inserts content into the editor (specified selection) as one would expect the paste
@@ -227,10 +226,10 @@ class Insertion {
 		if ( node.is( 'element' ) ) {
 			this.handleNodes( node.getChildren(), context );
 		}
-		// When disallowed node is a text but text is allowed in current parent it means that our node
+		// When disallowed node is a text but text is allowed in current position it means that our node
 		// contains disallowed attributes and we have to remove them.
 		else if ( node.is( 'text' ) && this.schema.check( { name: '$text', inside: this.position } ) ) {
-			removeDisallowedAttributes( node, this.position, this.schema );
+			removeDisallowedAttributes( this.schema, node, this.position );
 			this._handleNode( node, context );
 		}
 		// Try autoparagraphing.
@@ -287,9 +286,9 @@ class Insertion {
 		if ( mergeLeft ) {
 			const position = LivePosition.createFromPosition( this.position );
 
-			// When need to check a direct child of node that is going to be merged
+			// When need to check a children of node that is going to be merged
 			// and strip it from the disallowed attributes according to the new parent.
-			removeDisallowedAttributes( Array.from( node.getChildren() ), [ mergePosLeft.nodeBefore ], this.schema );
+			removeDisallowedAttributes( this.schema, Array.from( node.getChildren() ), [ mergePosLeft.nodeBefore ] );
 
 			this.batch.merge( mergePosLeft );
 
@@ -314,9 +313,9 @@ 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' );
 
-			// When need to check a direct child of node that is going to be merged
+			// When need to check a children of node that is going to be merged
 			// and strip it from the disallowed attributes according to the new parent.
-			removeDisallowedAttributes( Array.from( node.getChildren() ), [ mergePosLeft.nodeAfter ], this.schema );
+			removeDisallowedAttributes( this.schema, Array.from( node.getChildren() ), [ mergePosRight.nodeAfter ] );
 
 			this.batch.merge( mergePosRight );
 
@@ -344,7 +343,7 @@ class Insertion {
 			// When node is a text and is disallowed by schema it means that contains disallowed attributes
 			// and we need to remove them.
 			if ( node.is( 'text' ) && !this._checkIsAllowed( node, [ paragraph ] ) ) {
-				removeDisallowedAttributes( node, [ paragraph ], this.schema );
+				removeDisallowedAttributes( this.schema, node, [ paragraph ] );
 			}
 
 			if ( this._checkIsAllowed( node, [ paragraph ] ) ) {
@@ -439,3 +438,30 @@ class Insertion {
 		return this.schema.objects.has( getNodeSchemaName( node ) );
 	}
 }
+
+// Gets a name under which we should check this node in the schema.
+//
+// @param {module:engine/model/node~Node} node The node.
+// @returns {String} node name.
+function getNodeSchemaName( node ) {
+	return node.is( 'text' ) ? '$text' : node.name;
+}
+
+// Removes disallowed by schema attributes from given nodes.
+//
+// @param {module:engine/model/schema~Schema} schema
+// @param {module:engine/model/node~Node|Array<module:engine/model/node~Node>} nodes List of nodes or a single node to filter.
+// @param {module:engine/model/schema~SchemaPath} schemaPath
+export function removeDisallowedAttributes( schema, nodes, schemaPath ) {
+	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 );
+			}
+		}
+	}
+}

+ 0 - 43
packages/ckeditor5-engine/src/model/utils.js

@@ -1,43 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module engine/model/utils
- */
-
-/**
- * Gets a name under which we should check this node in the schema.
- *
- * @param {module:engine/model/node~Node} node The node.
- * @returns {String} node name.
- */
-export function getNodeSchemaName( node ) {
-	if ( node.is( 'text' ) ) {
-		return '$text';
-	}
-
-	return node.name;
-}
-
-/**
- * Removes disallowed by schema attributes from given nodes.
- *
- * @param {module:engine/model/node~Node|Array<module:engine/model/node~Node>} nodes List of nodes or a single node to filter.
- * @param {module:engine/model/schema~SchemaPath} schemaPath
- * @param {module:engine/model/schema~Schema} schema
- */
-export 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 );
-			}
-		}
-	}
-}

+ 10 - 11
packages/ckeditor5-engine/tests/controller/deletecontent.js

@@ -155,9 +155,9 @@ describe( 'DataController', () => {
 
 				schema.registerItem( 'paragraph', '$block' );
 				schema.registerItem( 'heading1', '$block' );
+				schema.registerItem( 'image', '$inline' );
 				schema.registerItem( 'pchild' );
 				schema.registerItem( 'pparent' );
-				schema.registerItem( 'image', '$inline' );
 
 				schema.allow( { name: 'pchild', inside: 'paragraph' } );
 				schema.allow( { name: '$text', inside: 'pchild' } );
@@ -167,12 +167,11 @@ 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' } );
+				schema.allow( { name: 'image', attributes: [ 'a', 'b' ], inside: 'paragraph' } );
+				schema.allow( { name: 'image', attributes: [ 'b' ], inside: 'heading1' } );
+				schema.allow( { name: '$text', attributes: [ 'a', 'b', 'c' ], inside: 'paragraph' } );
+				schema.allow( { name: '$text', attributes: [ 'b' ], inside: 'heading1' } );
+				schema.allow( { name: '$text', attributes: [ 'c', 'd' ], inside: 'pchild' } );
 			} );
 
 			test(
@@ -271,8 +270,8 @@ describe( 'DataController', () => {
 
 			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>'
+				'<heading1>fo[o</heading1><paragraph>b]a<$text a="1" b="1">r</$text><image a="1" b="1"></image></paragraph>',
+				'<heading1>fo[]a<$text b="1">r</$text><image b="1"></image></heading1>'
 			);
 
 			// Note: in all these cases we ignore the direction of merge.
@@ -414,13 +413,13 @@ describe( 'DataController', () => {
 				} );
 
 				test(
-					'filters out disallowed attributes after merge when left',
+					'filters out disallowed attributes after left merge',
 					'<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',
+					'filters out disallowed attributes after right merge',
 					'<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>'
 				);

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

@@ -593,6 +593,7 @@ describe( 'DataController', () => {
 				const schema = doc.schema;
 
 				schema.registerItem( 'paragraph', '$block' );
+				schema.registerItem( 'heading1', '$block' );
 
 				// Let's use table as an example of content which needs to be filtered out.
 				schema.registerItem( 'table' );

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

@@ -1,68 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import { getNodeSchemaName, removeDisallowedAttributes } from '../../src/model/utils';
-import Element from '../../src/model/element';
-import Text from '../../src/model/text';
-import Document from '../../src/model/document';
-import { stringify } from '../../src/dev-utils/model';
-
-describe( 'model utils', () => {
-	describe( 'getNodeSchemaName()', () => {
-		it( 'should return schema name for a given Element', () => {
-			const element = new Element( 'paragraph' );
-
-			expect( getNodeSchemaName( element ) ).to.equal( 'paragraph' );
-		} );
-
-		it( 'should return schema name for a Text', () => {
-			const element = new Text();
-
-			expect( getNodeSchemaName( element ) ).to.equal( '$text' );
-		} );
-	} );
-
-	describe( 'removeDisallowedAttributes()', () => {
-		let doc;
-
-		beforeEach( () => {
-			doc = new Document();
-			doc.createRoot();
-
-			const schema = doc.schema;
-
-			schema.registerItem( 'paragraph', '$block' );
-			schema.registerItem( 'el', '$inline' );
-
-			schema.allow( { name: '$text', attributes: 'a', inside: 'paragraph' } );
-			schema.allow( { name: '$text', attributes: 'c', inside: 'paragraph' } );
-			schema.allow( { name: 'el', attributes: 'b' } );
-		} );
-
-		it( 'should remove disallowed by schema attributes from list of nodes', () => {
-			const paragraph = new Element( 'paragraph' );
-			const el = new Element( 'el', { a: 1, b: 1, c: 1 } );
-			const foo = new Text( 'foo', { a: 1, b: 1 } );
-			const bar = new Text( 'bar' );
-			const biz = new Text( 'biz', { b: 1, c: 1 } );
-
-			paragraph.appendChildren( [ el, foo, bar, biz ] );
-
-			removeDisallowedAttributes( Array.from( paragraph.getChildren() ), [ paragraph ], doc.schema );
-
-			expect( stringify( paragraph ) )
-				.to.equal( '<paragraph><el b="1"></el><$text a="1">foo</$text>bar<$text c="1">biz</$text></paragraph>' );
-		} );
-
-		it( 'should remove disallowed by schema attributes from a single node', () => {
-			const paragraph = new Element( 'paragraph' );
-			const foo = new Text( 'foo', { a: 1, b: 1 } );
-
-			removeDisallowedAttributes( foo, [ paragraph ], doc.schema );
-
-			expect( stringify( foo ) ).to.equal( '<$text a="1">foo</$text>' );
-		} );
-	} );
-} );