Browse Source

#396: Introduce DeltaFactory.

Maciej Gołaszewski 9 years ago
parent
commit
a819de8342

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/attributedelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import { register } from '../batch.js';
 import AttributeOperation from '../operation/attributeoperation.js';
 import RootAttributeOperation from '../operation/rootattributeoperation.js';

+ 3 - 42
packages/ckeditor5-engine/src/treemodel/delta/delta.js

@@ -6,10 +6,7 @@
 'use strict';
 
 import clone from '../../../utils/lib/lodash/clone.js';
-
-import CKEditorError from '../../../utils/ckeditorerror.js';
-
-import OperationFactory from '../operation/operationfactory.js';
+import { registerDeserializer } from './deltafactory.js';
 
 /**
  * Base class for all deltas.
@@ -141,7 +138,7 @@ export default class Delta {
 
 	/**
 	 * Delta class name. Used by {@link engine.treeModel.delta.Delta#toJSON} method for serialization and
-	 * {@link engine.treeModel.delta.Delta.fromJSON} during deserialization.
+	 * {@link engine.treeModel.delta.DeltaFactory.fromJSON} during deserialization.
 	 *
 	 * @type {String}
 	 * @readonly
@@ -161,42 +158,6 @@ export default class Delta {
 	static get _priority() {
 		return 0;
 	}
-
-	/**
-	 * Creates InsertDelta from deserialized object, i.e. from parsed JSON string.
-	 *
-	 * @param {Object} json
-	 * @param {engine.treeModel.Document} doc Document on which this delta will be applied.
-	 * @returns {engine.treeModel.delta.InsertDelta}
-	 */
-	static fromJSON( json, doc ) {
-		if ( !deserializers.has( json.__className ) ) {
-			/**
-			 * This delta has no defined deserializer.
-			 *
-			 * @error delta-fromjson-no-deserializer
-			 * @param {String} name
-			 */
-			throw new CKEditorError(
-				'delta-fromjson-no-deserializer: This delta has no defined deserializer',
-				{ name: json.__className }
-			);
-		}
-
-		let Constructor = deserializers.get( json.__className );
-
-		let delta = new Constructor();
-
-		if ( json.operations.length ) {
-			json.operations.forEach( ( operation ) => delta.addOperation( OperationFactory.fromJSON( operation, doc ) ) );
-		}
-
-		return delta;
-	}
 }
 
-const deserializers = new Map();
-
-export function registerDeserializer( className, constructor ) {
-	deserializers.set( className, constructor );
-}
+registerDeserializer( Delta.className, Delta );

+ 60 - 0
packages/ckeditor5-engine/src/treemodel/delta/deltafactory.js

@@ -0,0 +1,60 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import CKEditorError from '../../../utils/ckeditorerror.js';
+
+import OperationFactory from '../operation/operationfactory.js';
+
+/**
+ * A factory class for creating operations.
+ *
+ * Delta is a single, from the user action point of view, change in the editable document, like insert, split or
+ * rename element. Delta is composed of operations, which are unit changes needed to be done to execute user action.
+ *
+ * Multiple deltas are grouped into a single {@link engine.treeModel.Batch}.
+ *
+ * @memberOf engine.treeModel.delta
+ */
+export default class DeltaFactory {
+	/**
+	 * Creates InsertDelta from deserialized object, i.e. from parsed JSON string.
+	 *
+	 * @param {Object} json
+	 * @param {engine.treeModel.Document} doc Document on which this delta will be applied.
+	 * @returns {engine.treeModel.delta.InsertDelta}
+	 */
+	static fromJSON( json, doc ) {
+		if ( !deserializers.has( json.__className ) ) {
+			/**
+			 * This delta has no defined deserializer.
+			 *
+			 * @error delta-fromjson-no-deserializer
+			 * @param {String} name
+			 */
+			throw new CKEditorError(
+				'delta-fromjson-no-deserializer: This delta has no defined deserializer',
+				{ name: json.__className }
+			);
+		}
+
+		let Constructor = deserializers.get( json.__className );
+
+		let delta = new Constructor();
+
+		if ( json.operations.length ) {
+			json.operations.forEach( ( operation ) => delta.addOperation( OperationFactory.fromJSON( operation, doc ) ) );
+		}
+
+		return delta;
+	}
+}
+
+const deserializers = new Map();
+
+export function registerDeserializer( className, constructor ) {
+	deserializers.set( className, constructor );
+}

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/insertdelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import RemoveDelta from './removedelta.js';
 import { register } from '../batch.js';
 import InsertOperation from '../operation/insertoperation.js';

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/mergedelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import SplitDelta from './splitdelta.js';
 import { register } from '../batch.js';
 import Position from '../position.js';

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/movedelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import { register } from '../batch.js';
 import MoveOperation from '../operation/moveoperation.js';
 import Position from '../position.js';

+ 1 - 1
packages/ckeditor5-engine/src/treemodel/delta/removedelta.js

@@ -7,7 +7,7 @@
 
 import MoveDelta from './movedelta.js';
 import { register } from '../batch.js';
-import { registerDeserializer } from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import RemoveOperation from '../operation/removeoperation.js';
 import Position from '../position.js';
 import Range from '../range.js';

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/renamedelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import { register } from '../batch.js';
 import InsertOperation from '../operation/insertoperation.js';
 import RemoveOperation from '../operation/removeoperation.js';

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/splitdelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import { register } from '../batch.js';
 import Position from '../position.js';
 import Element from '../element.js';

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/unwrapdelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import WrapDelta from './wrapdelta.js';
 import { register } from '../batch.js';
 import Position from '../position.js';

+ 1 - 1
packages/ckeditor5-engine/src/treemodel/delta/weakinsertdelta.js

@@ -7,7 +7,7 @@
 
 import InsertDelta from './insertdelta.js';
 import { register } from '../batch.js';
-import { registerDeserializer } from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import InsertOperation from '../operation/insertoperation.js';
 import NodeList from '../nodelist.js';
 

+ 2 - 1
packages/ckeditor5-engine/src/treemodel/delta/wrapdelta.js

@@ -5,7 +5,8 @@
 
 'use strict';
 
-import { default as Delta, registerDeserializer } from './delta.js';
+import Delta from './delta.js';
+import { registerDeserializer } from './deltafactory.js';
 import UnwrapDelta from './unwrapdelta.js';
 import { register } from '../batch.js';
 import Position from '../position.js';

+ 0 - 126
packages/ckeditor5-engine/tests/treemodel/delta/delta.js

@@ -17,7 +17,6 @@ import NoOperation from '/ckeditor5/engine/treemodel/operation/nooperation.js';
 import ReinsertOperation from '/ckeditor5/engine/treemodel/operation/reinsertoperation.js';
 import RemoveOperation from '/ckeditor5/engine/treemodel/operation/removeoperation.js';
 import RootAttributeOperation from '/ckeditor5/engine/treemodel/operation/rootattributeoperation.js';
-import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
 import { registerDeserializer } from '/ckeditor5/engine/treemodel/delta/delta.js';
 import Document from '/ckeditor5/engine/treemodel/document.js';
 import Position from '/ckeditor5/engine/treemodel/position.js';
@@ -50,18 +49,6 @@ class FooDelta extends Delta {
 	}
 }
 
-class BarDelta extends Delta {
-	static get className() {
-		return 'tets.delta.bar';
-	}
-}
-
-class FooBarDelta extends Delta {
-	static get className() {
-		return 'tets.delta.foobar';
-	}
-}
-
 describe( 'Delta', () => {
 	describe( 'constructor', () => {
 		it( 'should create an delta with empty properties', () => {
@@ -264,117 +251,4 @@ describe( 'Delta', () => {
 			} );
 		} );
 	} );
-
-	describe( 'fromJSON', () => {
-		let delta, root, doc;
-
-		before( () => {
-			registerDeserializer( FooBarDelta.className, FooDelta );
-		} );
-
-		beforeEach( () => {
-			delta = new FooBarDelta();
-
-			doc = new Document();
-			root = doc.createRoot( 'root' );
-		} );
-
-		it( 'should throw error for unregistered delta', () => {
-			expect( () => {
-				Delta.fromJSON( jsonParseStringify( new BarDelta() ), {} );
-			} ).to.throw( CKEditorError, /^delta-fromjson-no-deserializer/ );
-		} );
-
-		it( 'should create delta with AttributeOperation', () => {
-			delta.addOperation( new AttributeOperation(
-				new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
-				'foo',
-				true,
-				null,
-				doc.version
-			) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with InsertOperation', () => {
-			delta.addOperation( new InsertOperation(
-				new Position( root, [ 0 ] ),
-				'x',
-				doc.version
-			) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with MoveOperation', () => {
-			delta.addOperation( new MoveOperation(
-				new Position( root, [ 0, 0 ] ),
-				1,
-				new Position( root, [ 1, 0 ] ),
-				doc.version
-			) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with NoOperation', () => {
-			delta.addOperation( new NoOperation( 0 ) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with ReinsertOperation', () => {
-			delta.addOperation( new ReinsertOperation(
-				new Position( doc.graveyard, [ 0 ] ),
-				2,
-				new Position( root, [ 0 ] ),
-				doc.version
-			) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with RemoveOperation', () => {
-			delta.addOperation( new RemoveOperation(
-				new Position( root, [ 2 ] ),
-				2,
-				doc.version
-			) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-
-		it( 'should create delta with RootAttributeOperation', () => {
-			delta.addOperation( new RootAttributeOperation( root, 'key', null, 'newValue', doc.version ) );
-
-			let deserialized = Delta.fromJSON( jsonParseStringify( delta ), doc );
-
-			expect( deserialized ).to.deep.equal( delta );
-		} );
-	} );
-
-	describe( 'registerDeserializer', () => {
-		it( 'should add delta deserializer', ( done ) => {
-			registerDeserializer( 'foo', deserializer );
-
-			Delta.fromJSON( { __className: 'foo', operations: [] } );
-
-			function deserializer() {
-				done();
-			}
-		} );
-	} );
 } );

+ 170 - 0
packages/ckeditor5-engine/tests/treemodel/delta/deltafactory.js

@@ -0,0 +1,170 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* bender-tags: treemodel, delta */
+
+'use strict';
+
+import Delta from '/ckeditor5/engine/treemodel/delta/delta.js';
+import InsertDelta from '/ckeditor5/engine/treemodel/delta/insertdelta.js';
+
+import AttributeOperation from '/ckeditor5/engine/treemodel/operation/attributeoperation.js';
+import InsertOperation from '/ckeditor5/engine/treemodel/operation/insertoperation.js';
+import MoveOperation from '/ckeditor5/engine/treemodel/operation/moveoperation.js';
+import NoOperation from '/ckeditor5/engine/treemodel/operation/nooperation.js';
+import ReinsertOperation from '/ckeditor5/engine/treemodel/operation/reinsertoperation.js';
+import RemoveOperation from '/ckeditor5/engine/treemodel/operation/removeoperation.js';
+import RootAttributeOperation from '/ckeditor5/engine/treemodel/operation/rootattributeoperation.js';
+
+import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
+
+import { default as DeltaFactory, registerDeserializer } from '/ckeditor5/engine/treemodel/delta/deltafactory.js';
+
+import Document from '/ckeditor5/engine/treemodel/document.js';
+import Position from '/ckeditor5/engine/treemodel/position.js';
+import Range from '/ckeditor5/engine/treemodel/range.js';
+import { jsonParseStringify } from '/tests/engine/treemodel/_utils/utils.js';
+
+class FooDelta extends Delta {
+	static get className() {
+		return 'tets.delta.foo';
+	}
+}
+
+class BarDelta extends Delta {
+	static get className() {
+		return 'tets.delta.bar';
+	}
+}
+
+class FooBarDelta extends Delta {
+	static get className() {
+		return 'tets.delta.foobar';
+	}
+}
+
+describe( 'DeltaFactory', () => {
+	describe( 'fromJSON', () => {
+		let delta, root, doc;
+
+		before( () => {
+			registerDeserializer( FooBarDelta.className, FooDelta );
+		} );
+
+		beforeEach( () => {
+			delta = new FooBarDelta();
+
+			doc = new Document();
+			root = doc.createRoot( 'root' );
+		} );
+
+		it( 'should throw error for unregistered delta', () => {
+			expect( () => {
+				DeltaFactory.fromJSON( jsonParseStringify( new BarDelta() ), {} );
+			} ).to.throw( CKEditorError, /^delta-fromjson-no-deserializer/ );
+		} );
+
+		it( 'should create delta with AttributeOperation', () => {
+			delta.addOperation( new AttributeOperation(
+				new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
+				'foo',
+				true,
+				null,
+				doc.version
+			) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with InsertOperation', () => {
+			delta.addOperation( new InsertOperation(
+				new Position( root, [ 0 ] ),
+				'x',
+				doc.version
+			) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with MoveOperation', () => {
+			delta.addOperation( new MoveOperation(
+				new Position( root, [ 0, 0 ] ),
+				1,
+				new Position( root, [ 1, 0 ] ),
+				doc.version
+			) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with NoOperation', () => {
+			delta.addOperation( new NoOperation( 0 ) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with ReinsertOperation', () => {
+			delta.addOperation( new ReinsertOperation(
+				new Position( doc.graveyard, [ 0 ] ),
+				2,
+				new Position( root, [ 0 ] ),
+				doc.version
+			) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with RemoveOperation', () => {
+			delta.addOperation( new RemoveOperation(
+				new Position( root, [ 2 ] ),
+				2,
+				doc.version
+			) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create delta with RootAttributeOperation', () => {
+			delta.addOperation( new RootAttributeOperation( root, 'key', null, 'newValue', doc.version ) );
+
+			let deserialized = DeltaFactory.fromJSON( jsonParseStringify( delta ), doc );
+
+			expect( deserialized ).to.deep.equal( delta );
+		} );
+
+		it( 'should create InsertDelta instance from serialized JSON object', () => {
+			let insertDelta = new InsertDelta();
+			let serialized = jsonParseStringify( insertDelta );
+			let deserialized = DeltaFactory.fromJSON( serialized, doc );
+
+			expect( deserialized ).to.be.instanceOf( InsertDelta );
+			expect( deserialized.operations ).to.have.length( 0 );
+		} );
+	} );
+
+	describe( 'registerDeserializer', () => {
+		it( 'should add delta deserializer', ( done ) => {
+			registerDeserializer( 'foo', deserializer );
+
+			DeltaFactory.fromJSON( { __className: 'foo', operations: [] } );
+
+			function deserializer() {
+				done();
+			}
+		} );
+	} );
+} );

+ 0 - 14
packages/ckeditor5-engine/tests/treemodel/delta/insertdelta.js

@@ -14,13 +14,9 @@ import Position from '/ckeditor5/engine/treemodel/position.js';
 import InsertOperation from '/ckeditor5/engine/treemodel/operation/insertoperation.js';
 import InsertDelta from '/ckeditor5/engine/treemodel/delta/insertdelta.js';
 
-import Delta from '/ckeditor5/engine/treemodel/delta/delta.js';
-
 import RemoveDelta from '/ckeditor5/engine/treemodel/delta/removedelta.js';
 import RemoveOperation from '/ckeditor5/engine/treemodel/operation/removeoperation.js';
 
-import { jsonParseStringify } from '/tests/engine/treemodel/_utils/utils.js';
-
 describe( 'Batch', () => {
 	let doc, root, batch, p, ul, chain;
 
@@ -127,16 +123,6 @@ describe( 'InsertDelta', () => {
 		} );
 	} );
 
-	describe( 'fromJSON', () => {
-		it( 'should create InsertDelta instance from serialized JSON object', () => {
-			let serialized = jsonParseStringify( insertDelta );
-			let deserialized = Delta.fromJSON( serialized, doc );
-
-			expect( deserialized ).to.be.instanceOf( InsertDelta );
-			expect( deserialized.operations ).to.have.length( 0 );
-		} );
-	} );
-
 	it( 'should provide proper className', () => {
 		expect( InsertDelta.className ).to.equal( 'engine.treeModel.delta.InsertDelta' );
 	} );