浏览代码

Removing non-exitent attributes from DocumentSelection prevents from adding them during attribute auto-update.

Szymon Kupś 7 年之前
父节点
当前提交
9bd4101fdb

+ 6 - 3
packages/ckeditor5-engine/src/model/documentselection.js

@@ -801,6 +801,9 @@ class LiveSelection extends Selection {
 	// Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`
 	// parameter).
 	//
+	// NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will
+	// be changed according to `directChange` parameter.
+	//
 	// @private
 	// @param {String} key Attribute key.
 	// @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change
@@ -815,6 +818,9 @@ class LiveSelection extends Selection {
 			return false;
 		}
 
+		// Update priorities map.
+		this._attributePriority.set( key, priority );
+
 		// Don't do anything if value has not changed.
 		if ( !super.hasAttribute( key ) ) {
 			return false;
@@ -822,9 +828,6 @@ class LiveSelection extends Selection {
 
 		this._attrs.delete( key );
 
-		// Update priorities map.
-		this._attributePriority.set( key, priority );
-
 		return true;
 	}
 

+ 27 - 4
packages/ckeditor5-engine/tests/model/documentselection.js

@@ -439,6 +439,21 @@ describe( 'DocumentSelection', () => {
 
 				expect( selection.getAttribute( 'foo' ) ).to.be.undefined;
 			} );
+
+			it( 'should prevent auto update of the attribute even if attribute is not preset yet', () => {
+				selection._setTo( new Position( root, [ 0, 1 ] ) );
+
+				// Remove "foo" attribute that is not present in selection yet.
+				expect( selection.hasAttribute( 'foo' ) ).to.be.false;
+				selection._removeAttribute( 'foo' );
+
+				// Trigger selecton auto update on document change. It should not get attribute from surrounding text;
+				model.change( writer => {
+					writer.setAttribute( 'foo', 'bar', Range.createIn( fullP ) );
+				} );
+
+				expect( selection.getAttribute( 'foo' ) ).to.be.undefined;
+			} );
 		} );
 
 		describe( '_getStoredAttributes()', () => {
@@ -1056,10 +1071,18 @@ describe( 'DocumentSelection', () => {
 					expect( data.attributeKeys ).to.deep.equal( [ 'foo' ] );
 				} );
 
-				model.change( writer => {
-					const range = new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 5 ] ) );
-					writer.setAttribute( 'foo', 'bar', range );
-				} );
+				model.applyOperation( wrapInDelta(
+					new AttributeOperation(
+						new Range( new Position( root, [ 0, 1 ] ), new Position( root, [ 0, 5 ] ) ),
+						'foo',
+						null,
+						'bar',
+						doc.version
+					)
+				) );
+
+				// Attributes are auto updated on document change.
+				model.change( () => {} );
 
 				expect( selection.getAttribute( 'foo' ) ).to.equal( 'bar' );
 				expect( spyAttribute.calledOnce ).to.be.true;