1 /* 2 Copyright (c) 2003-2009, 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 this.registered[ name ] = definition || {}; 90 }, 91 92 /** 93 * Gets the definition of a specific resource. 94 * @param {String} name The resource name. 95 * @type Object 96 * @example 97 * var definition = <b>CKEDITOR.plugins.get( 'sample' )</b>; 98 */ 99 get : function( name ) 100 { 101 return this.registered[ name ] || null; 102 }, 103 104 /** 105 * Get the full path for a specific loaded resource. 106 * @param {String} name The resource name. 107 * @type String 108 * @example 109 * alert( <b>CKEDITOR.plugins.getPath( 'sample' )</b> ); // "<editor path>/plugins/sample/" 110 */ 111 getPath : function( name ) 112 { 113 return this.externals[ name ] || this.basePath + name + '/'; 114 }, 115 116 /** 117 * Registers a resource to be loaded from an external path instead of the core base path. 118 * @param {String} name The resource name. 119 * @param {String} path The resource external path. 120 * @example 121 * // Loads a plugin from '/myplugin/samples/plugin.js'. 122 * CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' ); 123 */ 124 addExternal : function( name, path ) 125 { 126 if ( this.registered[ name ] || this.externals[ name ] ) 127 throw '[CKEDITOR.resourceManager.import] The resource name "' + name + '" is already registered or imported.'; 128 129 this.externals[ name ] = path; 130 }, 131 132 /** 133 * Loads one or more resources. 134 * @param {String|Array} name The name of the resource to load. It may be a 135 * string with a single resource name, or an array with several names. 136 * @param {Function} callback A function to be called when all resources 137 * are loaded. The callback will receive an array containing all 138 * loaded names. 139 * @param {Object} [scope] The scope object to be used for the callback 140 * call. 141 * @example 142 * <b>CKEDITOR.plugins.load</b>( 'myplugin', function( plugins ) 143 * { 144 * alert( plugins['myplugin'] ); // "object" 145 * }); 146 */ 147 load : function( names, callback, scope ) 148 { 149 // Ensure that we have an array of names. 150 if ( !CKEDITOR.tools.isArray( names ) ) 151 names = names ? [ names ] : []; 152 153 var loaded = this.loaded, 154 registered = this.registered, 155 urls = [], 156 urlsNames = {}, 157 resources = {}; 158 159 // Loop through all names. 160 for ( var i = 0 ; i < names.length ; i++ ) 161 { 162 var name = names[ i ]; 163 164 if ( !name ) 165 continue; 166 167 // If not available yet. 168 if ( !loaded[ name ] && !registered[ name ] ) 169 { 170 var url = CKEDITOR.getUrl( this.getPath( name ) + this.fileName + '.js' ); 171 urls.push( url ); 172 urlsNames[ url ] = name; 173 } 174 else 175 resources[ name ] = this.get( name ); 176 } 177 178 CKEDITOR.scriptLoader.load( urls, function( completed, failed ) 179 { 180 if ( failed.length ) 181 throw '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ] + '" was not found at "' + failed[ 0 ] + '".'; 182 183 for ( var i = 0 ; i < completed.length ; i++ ) 184 { 185 var name = urlsNames[ completed[ i ] ]; 186 resources[ name ] = this.get( name ); 187 188 loaded[ name ] = 1; 189 } 190 191 callback.call( scope, resources ); 192 } 193 , this); 194 } 195 }; 196