initial commit
[namibia] / public / scripts / ckeditor / _source / core / resourcemanager.js
1 /*
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
5
6 /**
7  * @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is
8  *              the base for resource managers, like plugins and themes.
9  */
10
11  /**
12  * Base class for resource managers, like plugins and themes. This class is not
13  * intended to be used out of the CKEditor core code.
14  * @param {String} basePath The path for the resources folder.
15  * @param {String} fileName The name used for resource files.
16  * @namespace
17  * @example
18  */
19 CKEDITOR.resourceManager = function( basePath, fileName )
20 {
21         /**
22          * The base directory containing all resources.
23          * @name CKEDITOR.resourceManager.prototype.basePath
24          * @type String
25          * @example
26          */
27         this.basePath = basePath;
28
29         /**
30          * The name used for resource files.
31          * @name CKEDITOR.resourceManager.prototype.fileName
32          * @type String
33          * @example
34          */
35         this.fileName = fileName;
36
37         /**
38          * Contains references to all resources that have already been registered
39          * with {@link #add}.
40          * @name CKEDITOR.resourceManager.prototype.registered
41          * @type Object
42          * @example
43          */
44         this.registered = {};
45
46         /**
47          * Contains references to all resources that have already been loaded
48          * with {@link #load}.
49          * @name CKEDITOR.resourceManager.prototype.loaded
50          * @type Object
51          * @example
52          */
53         this.loaded = {};
54
55         /**
56          * Contains references to all resources that have already been registered
57          * with {@link #addExternal}.
58          * @name CKEDITOR.resourceManager.prototype.externals
59          * @type Object
60          * @example
61          */
62         this.externals = {};
63
64         /**
65          * @private
66          */
67         this._ =
68         {
69                 // List of callbacks waiting for plugins to be loaded.
70                 waitingList : {}
71         };
72 };
73
74 CKEDITOR.resourceManager.prototype =
75 {
76         /**
77          * Registers a resource.
78          * @param {String} name The resource name.
79          * @param {Object} [definition] The resource definition.
80          * @example
81          * CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );
82          * @see CKEDITOR.pluginDefinition
83          */
84         add : function( name, definition )
85         {
86                 if ( this.registered[ name ] )
87                         throw '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.';
88
89                 CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready',
90                                 this.registered[ name ] = definition || {} );
91         },
92
93         /**
94          * Gets the definition of a specific resource.
95          * @param {String} name The resource name.
96          * @type Object
97          * @example
98          * var definition = <b>CKEDITOR.plugins.get( 'sample' )</b>;
99          */
100         get : function( name )
101         {
102                 return this.registered[ name ] || null;
103         },
104
105         /**
106          * Get the folder path for a specific loaded resource.
107          * @param {String} name The resource name.
108          * @type String
109          * @example
110          * alert( <b>CKEDITOR.plugins.getPath( 'sample' )</b> );  // "&lt;editor path&gt;/plugins/sample/"
111          */
112         getPath : function( name )
113         {
114                 var external = this.externals[ name ];
115                 return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );
116         },
117
118         /**
119          * Get the file path for a specific loaded resource.
120          * @param {String} name The resource name.
121          * @type String
122          * @example
123          * alert( <b>CKEDITOR.plugins.getFilePath( 'sample' )</b> );  // "&lt;editor path&gt;/plugins/sample/plugin.js"
124          */
125         getFilePath : function( name )
126         {
127                 var external = this.externals[ name ];
128                 return CKEDITOR.getUrl(
129                                 this.getPath( name ) +
130                                 ( ( external && ( typeof external.file == 'string' ) ) ? external.file : this.fileName + '.js' ) );
131         },
132
133         /**
134          * Registers one or more resources to be loaded from an external path
135          * instead of the core base path.
136          * @param {String} names The resource names, separated by commas.
137          * @param {String} path The path of the folder containing the resource.
138          * @param {String} [fileName] The resource file name. If not provided, the
139          *              default name is used; If provided with a empty string, will implicitly indicates that {@param path}
140          *              is already the full path.
141          * @example
142          * // Loads a plugin from '/myplugin/samples/plugin.js'.
143          * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );
144          * @example
145          * // Loads a plugin from '/myplugin/samples/my_plugin.js'.
146          * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );
147          * @example
148          * // Loads a plugin from '/myplugin/samples/my_plugin.js'.
149          * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' );
150          */
151         addExternal : function( names, path, fileName )
152         {
153                 names = names.split( ',' );
154                 for ( var i = 0 ; i < names.length ; i++ )
155                 {
156                         var name = names[ i ];
157
158                         this.externals[ name ] =
159                         {
160                                 dir : path,
161                                 file : fileName
162                         };
163                 }
164         },
165
166         /**
167          * Loads one or more resources.
168          * @param {String|Array} name The name of the resource to load. It may be a
169          *              string with a single resource name, or an array with several names.
170          * @param {Function} callback A function to be called when all resources
171          *              are loaded. The callback will receive an array containing all
172          *              loaded names.
173          * @param {Object} [scope] The scope object to be used for the callback
174          *              call.
175          * @example
176          * <b>CKEDITOR.plugins.load</b>( 'myplugin', function( plugins )
177          *     {
178          *         alert( plugins['myplugin'] );  // "object"
179          *     });
180          */
181         load : function( names, callback, scope )
182         {
183                 // Ensure that we have an array of names.
184                 if ( !CKEDITOR.tools.isArray( names ) )
185                         names = names ? [ names ] : [];
186
187                 var loaded = this.loaded,
188                         registered = this.registered,
189                         urls = [],
190                         urlsNames = {},
191                         resources = {};
192
193                 // Loop through all names.
194                 for ( var i = 0 ; i < names.length ; i++ )
195                 {
196                         var name = names[ i ];
197
198                         if ( !name )
199                                 continue;
200
201                         // If not available yet.
202                         if ( !loaded[ name ] && !registered[ name ] )
203                         {
204                                 var url = this.getFilePath( name );
205                                 urls.push( url );
206                                 if ( !( url in urlsNames ) )
207                                         urlsNames[ url ] = [];
208                                 urlsNames[ url ].push( name );
209                         }
210                         else
211                                 resources[ name ] = this.get( name );
212                 }
213
214                 CKEDITOR.scriptLoader.load( urls, function( completed, failed )
215                         {
216                                 if ( failed.length )
217                                 {
218                                         throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' )
219                                                 + '" was not found at "' + failed[ 0 ] + '".';
220                                 }
221
222                                 for ( var i = 0 ; i < completed.length ; i++ )
223                                 {
224                                         var nameList = urlsNames[ completed[ i ] ];
225                                         for ( var j = 0 ; j < nameList.length ; j++ )
226                                         {
227                                                 var name = nameList[ j ];
228                                                 resources[ name ] = this.get( name );
229
230                                                 loaded[ name ] = 1;
231                                         }
232                                 }
233
234                                 callback.call( scope, resources );
235                         }
236                         , this);
237         }
238 };