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
148 				// Load the editor theme.
149 				loadTheme( editor );
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 		this._ = {};
165
166 		// Call the base constructor.
167 		CKEDITOR.event.call( this );
168
169 		this.element = element;
170 		this.name = element.getId() || element.getNameAtt() || getNewName();
171
172 		// Get the default settings.
173 		this.config = new config();
174
175 		// Call initConfig using events, to be sure that instancecreated is
176 		// fired first.
177 		this.on( 'instancecreated', function()
178 			{
179 				initConfig( this, instanceConfig );
180 			});
181 	};
182 }());
183
184 CKEDITOR.editor.prototype =
185 {
186 	// The CKEDITOR.editor.fire will always pass itself as the "editor"
187 	// param in CKEDITOR.event.fire. So, we override it to do that
188 	// automaticaly.
189 	fire : function( eventName, data )
190 	{
191 		return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
192 	},
193
194 	fireOnce : function( eventName, data )
195 	{
196 		return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
197 	}
198 };
199
200 // "Inherit" (copy actually) from CKEDITOR.event.
201 CKEDITOR.tools.extend( CKEDITOR.editor.prototype, CKEDITOR.event.prototype );
202