1 /*
  2  * CKEditor - The text editor for Internet - http://ckeditor.com
  3  * Copyright (C) 2003-2008 Frederico Caldeira Knabben
  4  *
  5  * == BEGIN LICENSE ==
  6  *
  7  * Licensed under the terms of any of the following licenses at your
  8  * choice:
  9  *
 10  *  - GNU General Public License Version 2 or later (the "GPL")
 11  *    http://www.gnu.org/licenses/gpl.html
 12  *
 13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14  *    http://www.gnu.org/licenses/lgpl.html
 15  *
 16  *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17  *    http://www.mozilla.org/MPL/MPL-1.1.html
 18  *
 19  * == END LICENSE ==
 20  */
 21 
 22  /**
 23  * Represents an editor instance.
 24  * @constructor
 25  * @param {CKEDITOR.dom.element} element The original element replaced by this
 26  *		editor instance.
 27  */
 28 CKEDITOR.editor = ( function()
 29 {
 30 	// The counter for automatic instance names.
 31 	var nameCounter = 0;
 32 
 33 	var getNewName = function()
 34 	{
 35 		var name = 'editor' + nameCounter++;
 36 		return CKEDITOR.instances[ name ] ? getNewName() : name;
 37 	};
 38 	
 39 	// ##### START: Config Privates
 40 
 41 	// These function loads custom configuration files and cache the
 42 	// CKEDITOR.editorConfig functions defined on them, so there is no need to
 43 	// download them more than once for several instances.
 44 	var loadConfigLoaded = {};
 45 	var loadConfig = function( editor )
 46 	{
 47 		var customConfig = editor.config.customConfig;
 48 
 49 		// Check if there is a custom config to load.
 50 		if ( !customConfig )
 51 			return false;
 52 
 53 		var loadedConfig = loadConfigLoaded[ customConfig ] || ( loadConfigLoaded[ customConfig ] = { editors : [] } );
 54 
 55 		// If the custom config has already been downloaded, reuse it.
 56 		if ( loadedConfig.fn )
 57 		{
 58 			// Call the cached CKEDITOR.editorConfig defined in the custom
 59 			// config file for the editor instance depending on it.
 60 			loadedConfig.fn.call( editor, editor );
 61 
 62 			// If there is no other customConfig in the chain, fire the
 63 			// "configloaded" event.
 64 			if ( editor.config.customConfig == customConfig || !loadConfig( editor ) )
 65 				editor.fireOnce( 'customconfigloaded' );
 66 		}
 67 		else
 68 		{
 69 			// Add the editor to the list of editors waiting for this config.
 70 			loadedConfig.editors.push( editor );
 71 
 72 			// Load the custom configuration file.
 73 			CKEDITOR.scriptLoader.load( customConfig, function()
 74 				{
 75 					// If the CKEDITOR.editorConfig function has been properly
 76 					// defined in the custom configuration file, cache it.
 77 					if ( CKEDITOR.editorConfig )
 78 						loadedConfig.fn = CKEDITOR.editorConfig;
 79 					else
 80 						loadedConfig.fn = function(){};
 81 
 82 					delete CKEDITOR.editorConfig;
 83 
 84 					CKEDITOR.tools.each( loadedConfig.editors, function( editor )
 85 						{
 86 							// Call the load config again. This time the custom
 87 							// config is already cached and so it will get loaded.
 88 							loadConfig( editor );
 89 						});
 90 
 91 					delete loadedConfig.editors;
 92 				} );
 93 		}
 94 
 95 		return true;
 96 	};
 97 
 98 	var initConfig = function( editor, instanceConfig )
 99 	{
100 		// Setup the lister for the "customconfigloaded" event.
101 		editor.on( 'customconfigloaded', function()
102 			{
103 				// Overwrite the settings from the in-page config.
104 				if ( instanceConfig )
105 					CKEDITOR.tools.extend( editor.config, instanceConfig, true );
106 
107 				// Fire the "configloaded" event.
108 				editor.fireOnce( 'configloaded' );
109 				
110 				// Start loading the plugins.
111 				loadPlugins( editor );
112 			});
113 
114 		// The instance config may override the customConfig setting to avoid
115 		// loading the default ~/config.js file.
116 		if ( instanceConfig && instanceConfig.customConfig != undefined )
117 			editor.config.customConfig = instanceConfig.customConfig;
118 
119 		// Load configs from the custom configuration files.
120 		if ( !loadConfig( editor ) )
121 			editor.fireOnce( 'customconfigloaded' );
122 	};
123 
124 	// Basic config class to inherit the default settings from CKEDITOR.config.
125 	var config = function()
126 	{}
127 	config.prototype = CKEDITOR.config;
128 
129 	// ##### END: Config Privates
130 
131 	var loadPlugins = function( editor )
132 	{
133 		// Load all plugins defined in the "plugins" setting.
134 		CKEDITOR.plugins.load( editor.config.plugins.split( ',' ), function( plugins )
135 			{
136 				// Cache the loaded plugin names.
137 				editor.plugins = plugins;
138 				
139 				// Initialize all plugins that have the "init" method defined.
140 				for ( var i = 0 ; i < plugins.length ; i++ )
141 				{
142 					var pluginName = plugins[ i ];
143 					var plugin = CKEDITOR.plugins.get( pluginName );
144 					if ( plugin && plugin.init )
145 						plugin.init( editor, CKEDITOR.plugins.getPath( pluginName ) );
146 					
147 					// Load the editor theme.
148 					loadTheme( editor );
149 				}
150 			});
151 	};
152 	
153 	var loadTheme = function( editor )
154 	{
155 		var theme = editor.config.theme;
156 		CKEDITOR.themes.load( theme, function()
157 			{
158 				CKEDITOR.themes.get( theme ).build( editor, CKEDITOR.themes.getPath( theme ) );
159 			});
160 	};
161 
162 	return function( element, instanceConfig )
163 	{
164 		// Call the base constructor.
165 		CKEDITOR.event.call( this );
166 
167 		this.element = element;
168 		this.name = element.getId() || element.getNameAtt() || getNewName();
169 
170 		// Get the default settings.
171 		this.config = new config();
172 
173 		// Call initConfig using events, to be sure that instancecreated is
174 		// fired first.
175 		this.on( 'instancecreated', function()
176 			{
177 				initConfig( this, instanceConfig );
178 			});
179 	};
180 }());
181 
182 CKEDITOR.editor.prototype =
183 {
184 	// The CKEDITOR.editor.fire will always pass itself as the "editor"
185 	// param in CKEDITOR.event.fire. So, we override it to do that
186 	// automaticaly.
187 	fire : function( eventName, data )
188 	{
189 		return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
190 	},
191 
192 	fireOnce : function( eventName, data )
193 	{
194 		return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
195 	}
196 };
197 
198 // "Inherit" (copy actually) from CKEDITOR.event.
199 CKEDITOR.tools.extend( CKEDITOR.editor.prototype, CKEDITOR.event.prototype );
200