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

Merge remote-tracking branch 'up/master' into patch-1

Dmitri Pisarev 7 лет назад
Родитель
Сommit
6218a5c2ba

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/transform.js

@@ -1514,6 +1514,12 @@ setTransformation( RenameOperation, WrapOperation, ( a, b ) => {
 } );
 
 setTransformation( RenameOperation, UnwrapOperation, ( a, b ) => {
+	if ( a.position.isEqual( b.targetPosition ) ) {
+		a.position = Position.createFromPosition( b.graveyardPosition );
+
+		return [ a ];
+	}
+
 	a.position = a.position._getTransformedByUnwrapOperation( b );
 
 	return [ a ];

+ 7 - 3
packages/ckeditor5-engine/src/model/operation/wrapoperation.js

@@ -30,8 +30,8 @@ export default class WrapOperation extends Operation {
 	 * the first {@link module:engine/model/item~Item model item} to wrap.
 	 * @param {Number} howMany Offset size of wrapped range. Wrapped range will start at `position.offset` and end at
 	 * `position.offset + howMany`.
-	 * @param {module:engine/model/element~Element|module:engine/model/position~Position} elementOrPosition Element to
-	 * wrap with or position in graveyard before the element which should be used as a wrapper.
+	 * @param {module:engine/model/element~Element|module:engine/model/position~Position} elementOrPosition Wrapper
+	 * element or position in graveyard before the element which should be used as a wrapper.
 	 * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
 	 * can be applied or `null` if the operation operates on detached (non-document) tree.
 	 */
@@ -171,8 +171,12 @@ export default class WrapOperation extends Operation {
 
 		json.position = this.position.toJSON();
 
-		if ( json.graveyardPosition ) {
+		if ( this.element ) {
+			json.element = this.element.toJSON();
+			delete json.graveyardPosition;
+		} else {
 			json.graveyardPosition = this.graveyardPosition.toJSON();
+			delete json.element;
 		}
 
 		return json;

+ 1 - 1
packages/ckeditor5-engine/tests/model/operation/transform/attribute.js

@@ -331,7 +331,7 @@ describe( 'transform', () => {
 				john.setData( '<paragraph>F<$text bold="true" italic="true">o[]o</$text></paragraph>' );
 				kate.setData( '<paragraph>F<$text bold="true" italic="true">[oo]</$text></paragraph>' );
 
-				john.type( 'Bar' );
+				john.type( 'Bar', john.document.selection.getAttributes() );
 				kate.removeAttribute( 'bold' );
 
 				syncClients();

+ 4 - 0
packages/ckeditor5-engine/tests/model/operation/transform/remove.js

@@ -240,7 +240,11 @@ describe( 'transform', () => {
 				kate.unwrap();
 
 				syncClients();
+				expectClients( '<blockQuote></blockQuote>' );
+
+				john.undo();
 
+				syncClients();
 				expectClients( '<blockQuote>Foo</blockQuote>' );
 			} );
 

+ 1 - 1
packages/ckeditor5-engine/tests/model/operation/transform/rename.js

@@ -187,7 +187,7 @@ describe( 'transform', () => {
 			} );
 
 			it( 'text in same path', () => {
-				john.setData( '<blockQuote><paragraph>F[]oo</paragraph></blockQuote>' );
+				john.setData( '<blockQuote><paragraph>[]Foo</paragraph></blockQuote>' );
 				kate.setData( '<blockQuote><paragraph>[]Foo</paragraph></blockQuote>' );
 
 				john.rename( 'heading1' );

+ 1 - 4
packages/ckeditor5-engine/tests/model/operation/transform/split.js

@@ -130,10 +130,7 @@ describe( 'transform', () => {
 
 				syncClients();
 
-				expectClients(
-					'<blockQuote>F</blockQuote>' +
-					'<blockQuote>oo</blockQuote>'
-				);
+				expectClients( '<blockQuote>Foo</blockQuote>' );
 			} );
 
 			it( 'element in same position', () => {

+ 16 - 9
packages/ckeditor5-engine/tests/model/operation/transform/wrap.js

@@ -218,30 +218,33 @@ describe( 'transform', () => {
 
 			it( 'the same element', () => {
 				john.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
-				kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
+				kate.setData( '<blockQuote>[]<paragraph>Foo</paragraph></blockQuote>' );
 
-				john.wrap( 'blockQuote2' );
+				john.wrap( 'div' );
 				kate.unwrap();
 
 				syncClients();
 
-				expectClients( '<blockQuote2><paragraph>Foo</paragraph></blockQuote2>' );
+				expectClients( '<div><paragraph>Foo</paragraph></div>' );
 			} );
 
-			it( 'the same element, then undo', () => {
+			it.skip( 'the same element, then undo', () => {
+				// This is interesting scenario actually. Normally in wrap x wrap situation the stronger wrap just wins
+				// so we won't get incorrect model. But John was actually to make a wrap like this then he had
+				// <bq><div><p> structure for a while. So it should be possible to revert to it.
 				john.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
-				kate.setData( '<blockQuote>[<paragraph>Foo</paragraph>]</blockQuote>' );
+				kate.setData( '<blockQuote>[]<paragraph>Foo</paragraph></blockQuote>' );
 
-				john.wrap( 'blockQuote2' );
+				john.wrap( 'div' );
 				kate.unwrap();
 
 				syncClients();
+				expectClients( '<div><paragraph>Foo</paragraph></div>' );
 
 				kate.undo();
 
 				syncClients();
-
-				expectClients( '<blockQuote><paragraph>Foo</paragraph></blockQuote>' );
+				expectClients( '<blockQuote><div><paragraph>Foo</paragraph></div></blockQuote>' );
 			} );
 
 			it( 'the same text', () => {
@@ -256,7 +259,10 @@ describe( 'transform', () => {
 				expectClients( '<blockQuote><div>Foo</div></blockQuote>' );
 			} );
 
-			it( 'the same text, then undo', () => {
+			it.skip( 'the same text, then undo', () => {
+				// This is interesting scenario actually. Normally in wrap x wrap situation the stronger wrap just wins
+				// so we won't get incorrect model. But John was actually to make a wrap like this then he had
+				// <bq><p><div> structure for a while. So it should be possible to revert to it.
 				john.setData( '<blockQuote><paragraph>[Foo]</paragraph></blockQuote>' );
 				kate.setData( '<blockQuote><paragraph>[]Foo</paragraph></blockQuote>' );
 
@@ -264,6 +270,7 @@ describe( 'transform', () => {
 				kate.unwrap();
 
 				syncClients();
+				expectClients( '<blockQuote><div>Foo</div></blockQuote>' );
 
 				kate.undo();
 

+ 88 - 0
packages/ckeditor5-engine/tests/model/operation/wrapoperation.js

@@ -0,0 +1,88 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import Model from '../../../src/model/model';
+import Element from '../../../src/model/element';
+import WrapOperation from '../../../src/model/operation/wrapoperation';
+import Position from '../../../src/model/position';
+
+describe( 'WrapOperation', () => {
+	let model, doc, root;
+
+	beforeEach( () => {
+		model = new Model();
+		doc = model.document;
+		root = doc.createRoot();
+	} );
+
+	describe( 'type', () => {
+		it( 'should be wrap', () => {
+			const op = new WrapOperation(
+				new Position( root, [ 0 ] ),
+				1,
+				new Position( doc.graveyard, [ 0 ] ),
+				doc.version
+			);
+
+			expect( op.type ).to.equal( 'wrap' );
+		} );
+	} );
+
+	describe( 'toJSON', () => {
+		it( 'should create proper serialized object #1', () => {
+			const op = new WrapOperation(
+				new Position( root, [ 0 ] ),
+				1,
+				new Position( doc.graveyard, [ 0 ] ),
+				doc.version
+			);
+
+			const serialized = op.toJSON();
+
+			expect( serialized ).to.deep.equal( {
+				__className: 'engine.model.operation.WrapOperation',
+				baseVersion: 0,
+				position: op.position.toJSON(),
+				graveyardPosition: op.graveyardPosition.toJSON(),
+				howMany: 1
+			} );
+		} );
+
+		it( 'should create proper serialized object #2', () => {
+			const op = new WrapOperation(
+				new Position( root, [ 0 ] ),
+				1,
+				new Element( 'paragraph' ),
+				doc.version
+			);
+
+			const serialized = op.toJSON();
+
+			expect( serialized ).to.deep.equal( {
+				__className: 'engine.model.operation.WrapOperation',
+				baseVersion: 0,
+				position: op.position.toJSON(),
+				element: op.element.toJSON(),
+				howMany: 1
+			} );
+		} );
+	} );
+
+	describe( 'fromJSON', () => {
+		it( 'should create proper WrapOperation from json object', () => {
+			const op = new WrapOperation(
+				new Position( root, [ 0 ] ),
+				1,
+				new Position( doc.graveyard, [ 0 ] ),
+				doc.version
+			);
+
+			const serialized = op.toJSON();
+			const deserialized = WrapOperation.fromJSON( serialized, doc );
+
+			expect( deserialized ).to.deep.equal( op );
+		} );
+	} );
+} );