JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.0
[ckeditor.git] / _source / core / resourcemanager.js
diff --git a/_source/core/resourcemanager.js b/_source/core/resourcemanager.js
new file mode 100644 (file)
index 0000000..ebf6be3
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is\r
+ *             the base for resource managers, like plugins and themes.\r
+ */\r
+\r
+ /**\r
+ * Base class for resource managers, like plugins and themes. This class is not\r
+ * intended to be used out of the CKEditor core code.\r
+ * @param {String} basePath The path for the resources folder.\r
+ * @param {String} fileName The name used for resource files.\r
+ * @namespace\r
+ * @example\r
+ */\r
+CKEDITOR.resourceManager = function( basePath, fileName )\r
+{\r
+       /**\r
+        * The base directory containing all resources.\r
+        * @name CKEDITOR.resourceManager.prototype.basePath\r
+        * @type String\r
+        * @example\r
+        */\r
+       this.basePath = basePath;\r
+\r
+       /**\r
+        * The name used for resource files.\r
+        * @name CKEDITOR.resourceManager.prototype.fileName\r
+        * @type String\r
+        * @example\r
+        */\r
+       this.fileName = fileName;\r
+\r
+       /**\r
+        * Contains references to all resources that have already been registered\r
+        * with {@link #add}.\r
+        * @name CKEDITOR.resourceManager.prototype.registered\r
+        * @type Object\r
+        * @example\r
+        */\r
+       this.registered = {};\r
+\r
+       /**\r
+        * Contains references to all resources that have already been loaded\r
+        * with {@link #load}.\r
+        * @name CKEDITOR.resourceManager.prototype.loaded\r
+        * @type Object\r
+        * @example\r
+        */\r
+       this.loaded = {};\r
+\r
+       /**\r
+        * Contains references to all resources that have already been registered\r
+        * with {@link #addExternal}.\r
+        * @name CKEDITOR.resourceManager.prototype.externals\r
+        * @type Object\r
+        * @example\r
+        */\r
+       this.externals = {};\r
+\r
+       /**\r
+        * @private\r
+        */\r
+       this._ =\r
+       {\r
+               // List of callbacks waiting for plugins to be loaded.\r
+               waitingList : {}\r
+       };\r
+};\r
+\r
+CKEDITOR.resourceManager.prototype =\r
+{\r
+       /**\r
+        * Registers a resource.\r
+        * @param {String} name The resource name.\r
+        * @param {Object} [definition] The resource definition.\r
+        * @example\r
+        * CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );\r
+        * @see CKEDITOR.pluginDefinition\r
+        */\r
+       add : function( name, definition )\r
+       {\r
+               if ( this.registered[ name ] )\r
+                       throw '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.';\r
+\r
+               this.registered[ name ] = definition || {};\r
+       },\r
+\r
+       /**\r
+        * Gets the definition of a specific resource.\r
+        * @param {String} name The resource name.\r
+        * @type Object\r
+        * @example\r
+        * var definition = <b>CKEDITOR.plugins.get( 'sample' )</b>;\r
+        */\r
+       get : function( name )\r
+       {\r
+               return this.registered[ name ] || null;\r
+       },\r
+\r
+       /**\r
+        * Get the folder path for a specific loaded resource.\r
+        * @param {String} name The resource name.\r
+        * @type String\r
+        * @example\r
+        * alert( <b>CKEDITOR.plugins.getPath( 'sample' )</b> );  // "&lt;editor path&gt;/plugins/sample/"\r
+        */\r
+       getPath : function( name )\r
+       {\r
+               var external = this.externals[ name ];\r
+               return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );\r
+       },\r
+\r
+       /**\r
+        * Get the file path for a specific loaded resource.\r
+        * @param {String} name The resource name.\r
+        * @type String\r
+        * @example\r
+        * alert( <b>CKEDITOR.plugins.getFilePath( 'sample' )</b> );  // "&lt;editor path&gt;/plugins/sample/plugin.js"\r
+        */\r
+       getFilePath : function( name )\r
+       {\r
+               var external = this.externals[ name ];\r
+               return CKEDITOR.getUrl(\r
+                               this.getPath( name ) +\r
+                               ( ( external && external.file ) || ( this.fileName + '.js' ) ) );\r
+       },\r
+\r
+       /**\r
+        * Registers one or more resources to be loaded from an external path\r
+        * instead of the core base path.\r
+        * @param {String} names The resource names, separated by commas.\r
+        * @param {String} path The path of the folder containing the resource.\r
+        * @param {String} [fileName] The resource file name. If not provided, the\r
+        *              default name is used.\r
+        * @example\r
+        * // Loads a plugin from '/myplugin/samples/plugin.js'.\r
+        * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );\r
+        * @example\r
+        * // Loads a plugin from '/myplugin/samples/my_plugin.js'.\r
+        * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );\r
+        */\r
+       addExternal : function( names, path, fileName )\r
+       {\r
+               names = names.split( ',' );\r
+               for ( var i = 0 ; i < names.length ; i++ )\r
+               {\r
+                       var name = names[ i ];\r
+\r
+                       this.externals[ name ] =\r
+                       {\r
+                               dir : path,\r
+                               file : fileName\r
+                       };\r
+               }\r
+       },\r
+\r
+       /**\r
+        * Loads one or more resources.\r
+        * @param {String|Array} name The name of the resource to load. It may be a\r
+        *              string with a single resource name, or an array with several names.\r
+        * @param {Function} callback A function to be called when all resources\r
+        *              are loaded. The callback will receive an array containing all\r
+        *              loaded names.\r
+        * @param {Object} [scope] The scope object to be used for the callback\r
+        *              call.\r
+        * @example\r
+        * <b>CKEDITOR.plugins.load</b>( 'myplugin', function( plugins )\r
+        *     {\r
+        *         alert( plugins['myplugin'] );  // "object"\r
+        *     });\r
+        */\r
+       load : function( names, callback, scope )\r
+       {\r
+               // Ensure that we have an array of names.\r
+               if ( !CKEDITOR.tools.isArray( names ) )\r
+                       names = names ? [ names ] : [];\r
+\r
+               var loaded = this.loaded,\r
+                       registered = this.registered,\r
+                       urls = [],\r
+                       urlsNames = {},\r
+                       resources = {};\r
+\r
+               // Loop through all names.\r
+               for ( var i = 0 ; i < names.length ; i++ )\r
+               {\r
+                       var name = names[ i ];\r
+\r
+                       if ( !name )\r
+                               continue;\r
+\r
+                       // If not available yet.\r
+                       if ( !loaded[ name ] && !registered[ name ] )\r
+                       {\r
+                               var url = this.getFilePath( name );\r
+                               urls.push( url );\r
+                               if ( !( url in urlsNames ) )\r
+                                       urlsNames[ url ] = [];\r
+                               urlsNames[ url ].push( name );\r
+                       }\r
+                       else\r
+                               resources[ name ] = this.get( name );\r
+               }\r
+\r
+               CKEDITOR.scriptLoader.load( urls, function( completed, failed )\r
+                       {\r
+                               if ( failed.length )\r
+                               {\r
+                                       throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' )\r
+                                               + '" was not found at "' + failed[ 0 ] + '".';\r
+                               }\r
+\r
+                               for ( var i = 0 ; i < completed.length ; i++ )\r
+                               {\r
+                                       var nameList = urlsNames[ completed[ i ] ];\r
+                                       for ( var j = 0 ; j < nameList.length ; j++ )\r
+                                       {\r
+                                               var name = nameList[ j ];\r
+                                               resources[ name ] = this.get( name );\r
+\r
+                                               loaded[ name ] = 1;\r
+                                       }\r
+                               }\r
+\r
+                               callback.call( scope, resources );\r
+                       }\r
+                       , this);\r
+       }\r
+};\r