Importation initiale du code de CKEditor 3.6.1.
[ckeditor.git] / _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 };