Selaa lähdekoodia

Introduced the BasicClass, moving extend() from utils.

fredck 10 vuotta sitten
vanhempi
commit
ca00390ec3

+ 58 - 0
packages/ckeditor5-utils/src/basicclass.js

@@ -0,0 +1,58 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+/**
+ * A class implementing basic features useful for other classes.
+ *
+ * @class BasicClass
+ * @mixins Emitter
+ */
+
+CKEDITOR.define( [ 'emitter', 'utils' ], function( EmitterMixin, utils ) {
+	function BasicClass() {
+	}
+
+	// Injects the events API.
+	utils.extend( BasicClass.prototype, EmitterMixin );
+
+	/**
+	 * Creates a subclass constructor based on this class.
+	 *
+	 * @abstract
+	 * @static
+	 * @inheritable
+	 *
+	 * @param {Object} [proto] Extensions to be added to the subclass prototype.
+	 * @param {Object} [statics] Extension to be added as static members of the subclass constructor.
+	 * @returns {Object} The subclass constructor.
+	 */
+	BasicClass.extend = function( proto, statics ) {
+		var that = this;
+		var child = ( proto && proto.hasOwnProperty( 'constructor' ) ) ?
+			proto.constructor :
+			function() {
+				that.apply( this, arguments );
+			};
+
+		// Copy the statics.
+		utils.extend( child, this, statics );
+
+		// Use the same prototype.
+		child.prototype = Object.create( this.prototype );
+
+		// Add the new prototype stuff.
+		if ( proto ) {
+			proto = utils.clone( proto );
+			delete proto.constructor;
+			utils.extend( child.prototype, proto );
+		}
+
+		return child;
+	};
+
+	return BasicClass;
+} );

+ 27 - 26
packages/ckeditor5-utils/src/mvc/collection.js

@@ -9,38 +9,28 @@
  * Collections are ordered sets of models.
  *
  * @class Collection
+ * @extends BasicClass
  */
 
-CKEDITOR.define( [ 'emitter', 'utils' ], function( EmitterMixin, utils ) {
-	function Collection() {
+CKEDITOR.define( [ 'basicclass' ], function( BasicClass ) {
+	var Collection = BasicClass.extend( {
 		/**
-		 * The internal list of models in the collection.
+		 * Creates a new Collection instance.
 		 *
-		 * @property _models
-		 * @private
+		 * @constructor
 		 */
-		Object.defineProperty( this, '_models', {
-			value: []
-		} );
-	}
-
-	/**
-	 * @inheritdoc utils#extend
-	 */
-	Collection.extend = utils.extendMixin;
-
-	/**
-	 * The number of items available in the collection.
-	 *
-	 * @property length
-	 */
-	Object.defineProperty( Collection.prototype, 'length', {
-		get: function() {
-			return this._models.length;
-		}
-	} );
+		constructor: function Collection() {
+			/**
+			 * The internal list of models in the collection.
+			 *
+			 * @property _models
+			 * @private
+			 */
+			Object.defineProperty( this, '_models', {
+				value: []
+			} );
+		},
 
-	utils.extend( Collection.prototype, EmitterMixin, {
 		/**
 		 * Adds an item into the collection.
 		 *
@@ -99,6 +89,17 @@ CKEDITOR.define( [ 'emitter', 'utils' ], function( EmitterMixin, utils ) {
 		}
 	} );
 
+	/**
+	 * The number of items available in the collection.
+	 *
+	 * @property length
+	 */
+	Object.defineProperty( Collection.prototype, 'length', {
+		get: function() {
+			return this._models.length;
+		}
+	} );
+
 	return Collection;
 } );
 

+ 26 - 31
packages/ckeditor5-utils/src/mvc/model.js

@@ -9,45 +9,40 @@
  * The base MVC model class.
  *
  * @class Model
- * @mixins Emitter
+ * @extends BasicClass
  */
 
-CKEDITOR.define( [ 'emitter', 'utils' ], function( EmitterMixin, utils ) {
-	/**
-	 * Creates a new Model instance.
-	 *
-	 * @param {Object} [attributes] The model state attributes to be set during the instance creation.
-	 * @param {Object} [properties] The properties to be appended to the instance during creation.
-	 * @method constructor
-	 */
-	function Model( attributes, properties ) {
+CKEDITOR.define( [ 'basicclass', 'utils' ], function( BasicClass, utils ) {
+	var Model = BasicClass.extend( {
 		/**
-		 * The internal hash containing the model's state.
+		 * Creates a new Model instance.
 		 *
-		 * @property _attributes
-		 * @private
+		 * @param {Object} [attributes] The model state attributes to be set during the instance creation.
+		 * @param {Object} [properties] The properties to be appended to the instance during creation.
+		 * @method constructor
 		 */
-		Object.defineProperty( this, '_attributes', {
-			value: {}
-		} );
-
-		// Extend this instance with the additional (out of state) properties.
-		if ( properties ) {
-			utils.extend( this, properties );
-		}
+		constructor: function Model( attributes, properties ) {
+			/**
+			 * The internal hash containing the model's state.
+			 *
+			 * @property _attributes
+			 * @private
+			 */
+			Object.defineProperty( this, '_attributes', {
+				value: {}
+			} );
 
-		// Initialize the attributes.
-		if ( attributes ) {
-			this.set( attributes );
-		}
-	}
+			// Extend this instance with the additional (out of state) properties.
+			if ( properties ) {
+				utils.extend( this, properties );
+			}
 
-	/**
-	 * @inheritdoc utils#extend
-	 */
-	Model.extend = utils.extendMixin;
+			// Initialize the attributes.
+			if ( attributes ) {
+				this.set( attributes );
+			}
+		},
 
-	utils.extend( Model.prototype, EmitterMixin, {
 		/**
 		 * Creates and sets the value of a model attribute of this object. This attribute will be part of the model
 		 * state and will be observable.

+ 0 - 46
packages/ckeditor5-utils/src/utils.js

@@ -15,38 +15,6 @@
 CKEDITOR.define( [ 'utils-lodash', 'lib/lodash/lodash-ckeditor' ], function( lodashIncludes, lodash ) {
 	var utils = {
 		/**
-		 * A mixin function to be used to implement the static `extend()` method in classes. It allows for easy creation
-		 * of subclasses.
-		 *
-		 * @param {Object} [proto] Extensions to be added to the subclass prototype.
-		 * @param {Object} [statics] Additional static properties to be added to the subclass constructor.
-		 * @returns {Object} When executed as a static method of a class, it returns the new subclass constructor.
-		 */
-		extendMixin: function( proto, statics ) {
-			var that = this;
-			var child = ( proto && proto.hasOwnProperty( 'constructor' ) ) ?
-					proto.constructor :
-					function() {
-						that.apply( this, arguments );
-					};
-
-			// Copy the statics.
-			utils.extend( child, this, statics );
-
-			// Use the same prototype.
-			child.prototype = Object.create( this.prototype );
-
-			// Add the new prototype stuff.
-			if ( proto ) {
-				proto = utils.clone( proto );
-				delete proto.constructor;
-				utils.extend( child.prototype, proto );
-			}
-
-			return child;
-		},
-
-		/**
 		 * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.
 		 *
 		 * The following are the present features:
@@ -85,17 +53,3 @@ CKEDITOR.define( [ 'utils-lodash', 'lib/lodash/lodash-ckeditor' ], function( lod
 
 	return utils;
 } );
-
-/**
- * Creates a subclass constructor based on this class.
- *
- * @member utils
- * @method extend
- * @abstract
- * @static
- * @inheritable
- *
- * @param {Object} [proto] Extensions to be added to the subclass prototype.
- * @param {Object} [statics] Extension to be added as static members of the subclass constructor.
- * @returns {Object} The subclass constructor.
- */

+ 83 - 0
packages/ckeditor5-utils/tests/basicclass/basicclass.js

@@ -0,0 +1,83 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals describe, it, expect, bender */
+
+'use strict';
+
+var modules = bender.amd.require( 'basicclass' );
+
+describe( 'extend', function() {
+	it( 'should extend classes', function() {
+		var BasicClass = modules.basicclass;
+
+		var Truck = BasicClass.extend( {
+			loadContainers: function() {}
+		} );
+
+		var volvoTruck = new Truck();
+
+		expect( volvoTruck ).to.be.an.instanceof( Truck );
+		expect( volvoTruck ).to.be.an.instanceof( BasicClass );
+		expect( volvoTruck ).to.have.property( 'loadContainers' ).to.be.a( 'function' );
+
+		var Spacecraft = Truck.extend( {
+			jumpToHyperspace: function() {}
+		} );
+
+		var falcon = new Spacecraft();
+		expect( falcon ).to.be.an.instanceof( Spacecraft );
+		expect( falcon ).to.be.an.instanceof( Truck );
+		expect( falcon ).to.be.an.instanceof( BasicClass );
+		expect( falcon ).to.have.property( 'loadContainers' ).to.be.a( 'function' );
+		expect( falcon ).to.have.property( 'jumpToHyperspace' ).to.be.a( 'function' );
+	} );
+
+	it( 'should extend the prototype and add statics', function() {
+		var BasicClass = modules.basicclass;
+
+		var Truck = BasicClass.extend( {
+			property1: 1,
+			property2: function() {}
+		}, {
+			static1: 1,
+			static2: function() {}
+		} );
+
+		expect( Truck ).to.have.property( 'static1' ).to.equals( 1 );
+		expect( Truck ).to.have.property( 'static2' ).to.be.a( 'function' );
+
+		var truck = new Truck();
+
+		expect( truck ).to.have.property( 'property1' ).to.equals( 1 );
+		expect( truck ).to.have.property( 'property2' ).to.be.a( 'function' );
+	} );
+
+	it( 'should use a custom constructor', function() {
+		var BasicClass = modules.basicclass;
+
+		function customConstructor() {}
+
+		var Truck = BasicClass.extend( {
+			constructor: customConstructor
+		} );
+
+		expect( Truck ).to.equals( customConstructor );
+		expect( Truck.prototype ).to.not.have.ownProperty( 'constructor' );
+
+		expect( new Truck() ).to.be.an.instanceof( Truck );
+		expect( new Truck() ).to.be.an.instanceof( BasicClass );
+	} );
+} );
+
+describe( 'BasicClass', function() {
+	it( 'should be an event emitter', function() {
+		var BasicClass = modules.basicclass;
+
+		var basic = new BasicClass();
+
+		expect( basic ).to.have.property( 'fire' ).to.be.a( 'function' );
+	} );
+} );

+ 0 - 83
packages/ckeditor5-utils/tests/utils/utils.js

@@ -39,89 +39,6 @@ describe( 'extend()', function() {
 	} );
 } );
 
-describe( 'extendMixin', function() {
-	it( 'should extend classes', function() {
-		var utils = modules.utils;
-
-		function Car( name ) {
-			this.name = name;
-		}
-
-		Car.prototype.addGas = function() {};
-
-		Car.extend = utils.extendMixin;
-
-		var Truck = Car.extend( {
-			loadContainers: function() {}
-		} );
-
-		var volvoTruck = new Truck( 'Volvo' );
-
-		expect( volvoTruck ).to.be.an.instanceof( Truck );
-		expect( volvoTruck ).to.be.an.instanceof( Car );
-		expect( volvoTruck ).to.have.property( 'name' ).to.equals( 'Volvo' );
-		expect( volvoTruck ).to.have.property( 'addGas' ).to.be.a( 'function' );
-		expect( volvoTruck ).to.have.property( 'loadContainers' ).to.be.a( 'function' );
-
-		var Spacecraft = Truck.extend( {
-			jumpToHyperspace: function() {}
-		} );
-
-		var falcon = new Spacecraft( 'Millennium Falcon' );
-		expect( falcon ).to.be.an.instanceof( Spacecraft );
-		expect( falcon ).to.be.an.instanceof( Truck );
-		expect( falcon ).to.be.an.instanceof( Car );
-		expect( falcon ).to.have.property( 'name' ).to.equals( 'Millennium Falcon' );
-		expect( falcon ).to.have.property( 'addGas' ).to.be.a( 'function' );
-		expect( falcon ).to.have.property( 'loadContainers' ).to.be.a( 'function' );
-		expect( falcon ).to.have.property( 'jumpToHyperspace' ).to.be.a( 'function' );
-	} );
-
-	it( 'should extend the prototype and add statics', function() {
-		var utils = modules.utils;
-
-		function Car() {}
-
-		Car.extend = utils.extendMixin;
-
-		var Truck = Car.extend( {
-			property1: 1,
-			property2: function() {}
-		}, {
-			static1: 1,
-			static2: function() {}
-		} );
-
-		expect( Truck ).to.have.property( 'static1' ).to.equals( 1 );
-		expect( Truck ).to.have.property( 'static2' ).to.be.a( 'function' );
-
-		var truck = new Truck();
-
-		expect( truck ).to.have.property( 'property1' ).to.equals( 1 );
-		expect( truck ).to.have.property( 'property2' ).to.be.a( 'function' );
-	} );
-
-	it( 'should use a custom constructor', function() {
-		var utils = modules.utils;
-
-		function customConstructor() {}
-
-		function Car() {}
-
-		Car.extend = utils.extendMixin;
-
-		var Truck = Car.extend( {
-			constructor: customConstructor
-		} );
-
-		expect( Truck ).to.equals( customConstructor );
-		expect( Truck.prototype ).to.not.have.ownProperty( 'constructor' );
-
-		expect( new Truck() ).to.be.an.instanceof( Truck );
-		expect( new Truck() ).to.be.an.instanceof( Car );
-	} );
-} );
-
 describe( 'spy', function() {
 	it( 'should not have `called` after creation', function() {
 		var utils = modules.utils;