Bläddra i källkod

Made it possible to retrieve plugins by name.

fredck 10 år sedan
förälder
incheckning
4b22904655

+ 42 - 1
packages/ckeditor5-engine/src/plugincollection.js

@@ -24,6 +24,9 @@ CKEDITOR.define( [ 'mvc/collection', 'promise' ], function( Collection, Promise
 			Collection.apply( this );
 
 			this._editor = editor;
+
+			// The hash table used to store pointers to loaded plugins by name.
+			this._names = {};
 		},
 
 		/**
@@ -46,8 +49,11 @@ CKEDITOR.define( [ 'mvc/collection', 'promise' ], function( Collection, Promise
 					CKEDITOR.require( [ 'plugin!' + plugin ],
 						// Success callback.
 						function( LoadedPlugin ) {
+							var loadedPlugin = new LoadedPlugin( that._editor );
+							loadedPlugin.name = plugin;
+
 							// Adds a new instance of the loaded plugin to the collection.
-							that.add( new LoadedPlugin( that._editor ) );
+							that.add( loadedPlugin );
 
 							// Done! Resolve this promise.
 							resolve();
@@ -61,6 +67,41 @@ CKEDITOR.define( [ 'mvc/collection', 'promise' ], function( Collection, Promise
 					);
 				} );
 			}
+		},
+
+		/**
+		 * Adds a plugin to the collection.
+		 *
+		 * The `name` property must be set to the plugin object before passing it to this function. Adding plugins
+		 * with the same name has no effect and silently fails.
+		 *
+		 * @param {Plugin} plugin The plugin to be added.
+		 */
+		add: function( plugin ) {
+			// Do nothing if the plugin is already loaded.
+			if ( this._names[ plugin.name ] ) {
+				return;
+			}
+
+			// Save a pointer to the plugin by its name.
+			this._names[ plugin.name ] = plugin;
+
+			// Call the original implementation.
+			Collection.prototype.add.apply( this, arguments );
+		},
+
+		/**
+		 * Gets a plugin from the collection.
+		 *
+		 * @param {String} name The plugin name.
+		 * @returns {Plugin} The requested plugin, if available in the collection.
+		 */
+		get: function( name ) {
+			if ( typeof name != 'string' ) {
+				return Collection.prototype.get.apply( this, arguments );
+			}
+
+			return this._names[ name ];
 		}
 	} );
 

+ 68 - 0
packages/ckeditor5-engine/tests/plugincollection/plugincollection.js

@@ -80,3 +80,71 @@ describe( 'load', function() {
 			} );
 	} );
 } );
+
+describe( 'add', function() {
+	it( 'should add plugins to the collection', function() {
+		var PluginCollection = modules.plugincollection;
+
+		var plugins = new PluginCollection( editor );
+
+		var pluginA = new PluginA();
+		var pluginB = new PluginB();
+
+		// `add()` requires the `name` property to the defined.
+		pluginA.name = 'A';
+		pluginB.name = 'B';
+
+		plugins.add( pluginA );
+		plugins.add( pluginB );
+
+		expect( plugins.length ).to.equal( 2 );
+
+		expect( plugins.get( 0 ) ).to.be.an.instanceof( PluginA );
+		expect( plugins.get( 1 ) ).to.be.an.instanceof( PluginB );
+	} );
+
+	it( 'should do nothing if the plugin is already loaded', function() {
+		var PluginCollection = modules.plugincollection;
+
+		var plugins = new PluginCollection( editor );
+
+		return plugins.load( 'A,B' )
+			.then( function() {
+				// Check length before `add()`.
+				expect( plugins.length ).to.equal( 2 );
+
+				var pluginA = new PluginA();
+				pluginA.name = 'A';
+
+				plugins.add( pluginA );
+
+				// Length should not change after `add()`.
+				expect( plugins.length ).to.equal( 2 );
+			} );
+	} );
+} );
+
+describe( 'get', function() {
+	it( 'should get plugin by name', function() {
+		var PluginCollection = modules.plugincollection;
+
+		var plugins = new PluginCollection( editor );
+
+		return plugins.load( 'A,B' )
+			.then( function() {
+				expect( plugins.get( 'A' ) ).to.be.an.instanceof( PluginA );
+				expect( plugins.get( 'B' ) ).to.be.an.instanceof( PluginB );
+			} );
+	} );
+
+	it( 'should return undefined for non existing plugin', function() {
+		var PluginCollection = modules.plugincollection;
+
+		var plugins = new PluginCollection( editor );
+
+		return plugins.load( 'A,B' )
+			.then( function() {
+				expect( plugins.get( 'C' ) ).to.be.an( 'undefined' );
+			} );
+	} );
+} );