浏览代码

Changed: AttributeOperation should do nothing and return undefined if it's oldValue and newValue are same.

Szymon Cofalik 9 年之前
父节点
当前提交
9b00f7e4c2

+ 9 - 0
packages/ckeditor5-engine/src/model/operation/attributeoperation.js

@@ -7,6 +7,7 @@ import Operation from './operation.js';
 import Range from '../range.js';
 import CKEditorError from '../../../utils/ckeditorerror.js';
 import writer from '../writer.js';
+import isEqual from '../../../utils/lib/lodash/isEqual.js';
 
 /**
  * Operation to change nodes' attribute.
@@ -133,6 +134,14 @@ export default class AttributeOperation extends Operation {
 					{ node: item, key: this.key }
 				);
 			}
+
+			// If value to set is same as old value, don't do anything.
+			// By not returning `undefined`, this operation will be seen as `NoOperation` - that means
+			// that it won't generate any events, etc. `AttributeOperation` with such parameters may be
+			// a result of Operational Transformation.
+			if ( isEqual( this.oldValue, this.newValue ) ) {
+				return;
+			}
 		}
 
 		// Execution.

+ 16 - 0
packages/ckeditor5-engine/tests/model/operation/attributeoperation.js

@@ -355,6 +355,22 @@ describe( 'AttributeOperation', () => {
 		expect( root.getChild( 1 ).data ).to.equal( 'bcxyz' );
 	} );
 
+	it( 'should return undefined upon execution if new value is same as old value', () => {
+		root.insertChildren( 0, new Text( 'bar', { foo: true } ) );
+
+		let operation = new AttributeOperation(
+			new Range( new Position( root, [ 0 ] ), new Position( root, [ 3 ] ) ),
+			'foo',
+			true,
+			true,
+			doc.version
+		);
+
+		const result = operation._execute();
+
+		expect( result ).to.be.undefined;
+	} );
+
 	describe( 'toJSON', () => {
 		it( 'should create proper serialized object', () => {
 			const range = new Range( new Position( root, [ 0 ] ), new Position( root, [ 2 ] ) );