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

Merge branch 'master' into t/847

Piotrek Koszuliński 8 лет назад
Родитель
Сommit
71a65b9911

+ 41 - 2
packages/ckeditor5-engine/src/dev-utils/enableenginedebug.js

@@ -12,6 +12,7 @@
 import ModelPosition from '../model/position';
 import ModelPosition from '../model/position';
 import ModelRange from '../model/range';
 import ModelRange from '../model/range';
 import ModelText from '../model/text';
 import ModelText from '../model/text';
+import ModelTextProxy from '../model/textproxy';
 import ModelElement from '../model/element';
 import ModelElement from '../model/element';
 import Operation from '../model/operation/operation';
 import Operation from '../model/operation/operation';
 import AttributeOperation from '../model/operation/attributeoperation';
 import AttributeOperation from '../model/operation/attributeoperation';
@@ -38,6 +39,8 @@ import ModelRootElement from '../model/rootelement';
 
 
 import ViewDocument from '../view/document';
 import ViewDocument from '../view/document';
 import ViewElement from '../view/element';
 import ViewElement from '../view/element';
+import ViewText from '../view/text';
+import ViewTextProxy from '../view/textproxy';
 import ViewDocumentFragment from '../view/documentfragment';
 import ViewDocumentFragment from '../view/documentfragment';
 
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
@@ -128,13 +131,25 @@ function enableLoggingTools() {
 	};
 	};
 
 
 	ModelText.prototype.logExtended = function() {
 	ModelText.prototype.logExtended = function() {
-		log( `ModelText: ${ this }, attrs: ${ mapString( this._attrs ) }` );
+		log( `ModelText: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
 	};
 	};
 
 
 	ModelText.prototype.log = function() {
 	ModelText.prototype.log = function() {
 		log( 'ModelText: ' + this );
 		log( 'ModelText: ' + this );
 	};
 	};
 
 
+	ModelTextProxy.prototype.toString = function() {
+		return `#${ this.data }`;
+	};
+
+	ModelTextProxy.prototype.logExtended = function() {
+		log( `ModelTextProxy: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
+	};
+
+	ModelTextProxy.prototype.log = function() {
+		log( 'ModelTextProxy: ' + this );
+	};
+
 	ModelElement.prototype.toString = function() {
 	ModelElement.prototype.toString = function() {
 		return `<${ this.rootName || this.name }>`;
 		return `<${ this.rootName || this.name }>`;
 	};
 	};
@@ -144,7 +159,7 @@ function enableLoggingTools() {
 	};
 	};
 
 
 	ModelElement.prototype.logExtended = function() {
 	ModelElement.prototype.logExtended = function() {
-		log( `ModelElement: ${ this }, ${ this.childCount } children, attrs: ${ mapString( this._attrs ) }` );
+		log( `ModelElement: ${ this }, ${ this.childCount } children, attrs: ${ mapString( this.getAttributes() ) }` );
 	};
 	};
 
 
 	ModelElement.prototype.logAll = function() {
 	ModelElement.prototype.logAll = function() {
@@ -362,6 +377,30 @@ function enableLoggingTools() {
 			`${ this.range } -> ${ wrapElement }`;
 			`${ this.range } -> ${ wrapElement }`;
 	};
 	};
 
 
+	ViewText.prototype.toString = function() {
+		return `#${ this.data }`;
+	};
+
+	ViewText.prototype.logExtended = function() {
+		log( 'ViewText: ' + this );
+	};
+
+	ViewText.prototype.log = function() {
+		log( 'ViewText: ' + this );
+	};
+
+	ViewTextProxy.prototype.toString = function() {
+		return `#${ this.data }`;
+	};
+
+	ViewTextProxy.prototype.logExtended = function() {
+		log( 'ViewTextProxy: ' + this );
+	};
+
+	ViewTextProxy.prototype.log = function() {
+		log( 'ViewTextProxy: ' + this );
+	};
+
 	ViewElement.prototype.printTree = function( level = 0 ) {
 	ViewElement.prototype.printTree = function( level = 0 ) {
 		let string = '';
 		let string = '';
 
 

+ 7 - 2
packages/ckeditor5-engine/src/model/delta/attributedelta.js

@@ -165,9 +165,10 @@ function changeItem( batch, doc, key, value, item ) {
 	let range, operation;
 	let range, operation;
 
 
 	const delta = item.is( 'rootElement' ) ? new RootAttributeDelta() : new AttributeDelta();
 	const delta = item.is( 'rootElement' ) ? new RootAttributeDelta() : new AttributeDelta();
-	batch.addDelta( delta );
 
 
 	if ( previousValue != value ) {
 	if ( previousValue != value ) {
+		batch.addDelta( delta );
+
 		if ( item.is( 'rootElement' ) ) {
 		if ( item.is( 'rootElement' ) ) {
 			// If we change attributes of root element, we have to use `RootAttributeOperation`.
 			// If we change attributes of root element, we have to use `RootAttributeOperation`.
 			operation = new RootAttributeOperation( item, key, previousValue, value, doc.version );
 			operation = new RootAttributeOperation( item, key, previousValue, value, doc.version );
@@ -195,7 +196,6 @@ function changeItem( batch, doc, key, value, item ) {
 // into smaller parts.
 // into smaller parts.
 function changeRange( batch, doc, attributeKey, attributeValue, range ) {
 function changeRange( batch, doc, attributeKey, attributeValue, range ) {
 	const delta = new AttributeDelta();
 	const delta = new AttributeDelta();
-	batch.addDelta( delta );
 
 
 	// Position of the last split, the beginning of the new range.
 	// Position of the last split, the beginning of the new range.
 	let lastSplitPosition = range.start;
 	let lastSplitPosition = range.start;
@@ -233,6 +233,11 @@ function changeRange( batch, doc, attributeKey, attributeValue, range ) {
 	}
 	}
 
 
 	function addOperation() {
 	function addOperation() {
+		// Add delta to the batch only if there is at least operation in the delta. Add delta only once.
+		if ( delta.operations.length === 0 ) {
+			batch.addDelta( delta );
+		}
+
 		let range = new Range( lastSplitPosition, position );
 		let range = new Range( lastSplitPosition, position );
 		const operation = new AttributeOperation( range, attributeKey, attributeValueBefore, attributeValue, doc.version );
 		const operation = new AttributeOperation( range, attributeKey, attributeValueBefore, attributeValue, doc.version );
 
 

+ 40 - 0
packages/ckeditor5-engine/tests/dev-utils/enableenginedebug.js

@@ -10,6 +10,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import ModelPosition from '../../src/model/position';
 import ModelPosition from '../../src/model/position';
 import ModelRange from '../../src/model/range';
 import ModelRange from '../../src/model/range';
 import ModelText from '../../src/model/text';
 import ModelText from '../../src/model/text';
+import ModelTextProxy from '../../src/model/textproxy';
 import ModelElement from '../../src/model/element';
 import ModelElement from '../../src/model/element';
 import AttributeOperation from '../../src/model/operation/attributeoperation';
 import AttributeOperation from '../../src/model/operation/attributeoperation';
 import InsertOperation from '../../src/model/operation/insertoperation';
 import InsertOperation from '../../src/model/operation/insertoperation';
@@ -37,6 +38,7 @@ import ViewDocument from '../../src/view/document';
 import ViewAttributeElement from '../../src/view/attributeelement';
 import ViewAttributeElement from '../../src/view/attributeelement';
 import ViewContainerElement from '../../src/view/containerelement';
 import ViewContainerElement from '../../src/view/containerelement';
 import ViewText from '../../src/view/text';
 import ViewText from '../../src/view/text';
+import ViewTextProxy from '../../src/view/textproxy';
 import ViewDocumentFragment from '../../src/view/documentfragment';
 import ViewDocumentFragment from '../../src/view/documentfragment';
 
 
 /* global document */
 /* global document */
@@ -100,6 +102,19 @@ describe( 'debug tools', () => {
 			expect( log.calledWithExactly( 'ModelText: #foo, attrs: {"foo":"bar"}' ) ).to.be.true;
 			expect( log.calledWithExactly( 'ModelText: #foo, attrs: {"foo":"bar"}' ) ).to.be.true;
 		} );
 		} );
 
 
+		it( 'for ModelTextProxy', () => {
+			const foo = new ModelText( 'foo', { foo: 'bar' } );
+			const proxy = new ModelTextProxy( foo, 1, 1 );
+
+			expect( proxy.toString() ).to.equal( '#o' );
+
+			proxy.log();
+			expect( log.calledWithExactly( 'ModelTextProxy: #o' ) ).to.be.true;
+
+			proxy.logExtended();
+			expect( log.calledWithExactly( 'ModelTextProxy: #o, attrs: {"foo":"bar"}' ) ).to.be.true;
+		} );
+
 		it( 'for ModelElement', () => {
 		it( 'for ModelElement', () => {
 			const paragraph = new ModelElement( 'paragraph', { foo: 'bar' }, new ModelText( 'foo' ) );
 			const paragraph = new ModelElement( 'paragraph', { foo: 'bar' }, new ModelText( 'foo' ) );
 
 
@@ -153,6 +168,31 @@ describe( 'debug tools', () => {
 			expectLog( 'ModelRange: main [ 0 ] - [ 0 ]' );
 			expectLog( 'ModelRange: main [ 0 ] - [ 0 ]' );
 		} );
 		} );
 
 
+		it( 'for ViewText', () => {
+			const foo = new ViewText( 'foo' );
+
+			expect( foo.toString() ).to.equal( '#foo' );
+
+			foo.log();
+			expect( log.calledWithExactly( 'ViewText: #foo' ) ).to.be.true;
+
+			foo.logExtended();
+			expect( log.calledWithExactly( 'ViewText: #foo' ) ).to.be.true;
+		} );
+
+		it( 'for ViewTextProxy', () => {
+			const foo = new ViewText( 'foo', { foo: 'bar' } );
+			const proxy = new ViewTextProxy( foo, 1, 1 );
+
+			expect( proxy.toString() ).to.equal( '#o' );
+
+			proxy.log();
+			expect( log.calledWithExactly( 'ViewTextProxy: #o' ) ).to.be.true;
+
+			proxy.logExtended();
+			expect( log.calledWithExactly( 'ViewTextProxy: #o' ) ).to.be.true;
+		} );
+
 		describe( 'for operations', () => {
 		describe( 'for operations', () => {
 			beforeEach( () => {
 			beforeEach( () => {
 				modelRoot.appendChildren( [ new ModelText( 'foobar' ) ] );
 				modelRoot.appendChildren( [ new ModelText( 'foobar' ) ] );

+ 14 - 0
packages/ckeditor5-engine/tests/model/delta/attributedelta.js

@@ -393,6 +393,20 @@ describe( 'Batch', () => {
 			} );
 			} );
 		} );
 		} );
 	} );
 	} );
+
+	it( 'should not add empty delta to the batch', () => {
+		let nodeA = new Element( 'p', { a: 1 } );
+		let nodeB = new Element( 'p', { b: 2 } );
+		root.insertChildren( 0, [ nodeA, nodeB ] );
+
+		batch.setAttribute( nodeA, 'a', 1 );
+
+		expect( batch.deltas.length ).to.equal( 0 );
+
+		batch.removeAttribute( Range.createIn( root ), 'x' );
+
+		expect( batch.deltas.length ).to.equal( 0 );
+	} );
 } );
 } );
 
 
 describe( 'AttributeDelta', () => {
 describe( 'AttributeDelta', () => {