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  * @fileOverview Contains the second part of the {@link CKEDITOR} object
 24  *		definition, which defines the basic editor features to be available in
 25  *		the root ckeditor_basic.js file.
 26  */
 27
 28 CKEDITOR.event.implementOn( CKEDITOR );
 29
 30 /**
 31  * Forces the full CKEditor core code, in the case only the basic code has been
 32  * loaded (ckeditor_basic.js). This method self-destroys (becomes undefined) in
 33  * the first call or as soon as the full code is available.
 34  * @type undefined
 35  * @example
 36  * // Check if the full core code has been loaded and load it.
 37  * if ( CKEDITOR.loadFullCore )
 38  *     <b>CKEDITOR.loadFullCore()</b>;
 39  */
 40 CKEDITOR.loadFullCore = function()
 41 {
 42 	delete CKEDITOR.loadFullCore;
 43
 44 	CKEDITOR.loadFullCore._loaded = true;
 45
 46 	var script = document.createElement( 'script' );
 47 	script.type = 'text/javascript';
 48 	script.src = CKEDITOR.basePath + 'ckeditor.js';
 49
 50 	document.getElementsByTagName( 'head' )[0].appendChild( script );
 51 };
 52
 53 /**
 54  * The class name used to identify <textarea> elements to be replace
 55  * by CKEditor instances.
 56  * @type string
 57  * @default 'ckeditor'
 58  * @example
 59  * <b>CKEDITOR.replaceClass</b> = 'rich_editor';
 60  */
 61 CKEDITOR.replaceClass = 'ckeditor';
 62
 63 /**
 64  * Enables the replacement of all textareas with class name matching
 65  * {@link CKEDITOR.replaceClass}.
 66  * @type Boolean
 67  * @default true
 68  * @example
 69  * // Disable the auto-replace feature.
 70  * <b>CKEDITOR.replaceByClassEnabled</b> = false;
 71  */
 72 CKEDITOR.replaceByClassEnabled = true;
 73
 74 /**
 75  * Replaces a specific <textarea> with a CKEditor instance.
 76  * @param {object|string} elementOrIdOrName The DOM element (textarea), its
 77  *		ID or name.
 78  * @param {Object} [config] The specific configurations to apply to this
 79  *		editor instance. Configurations set here will override global CKEditor
 80  *		settings.
 81  * @type undefined
 82  * @example
 83  * <textarea id="myfield" name="myfield"><:/textarea>
 84  * ...
 85  * <b>CKEDITOR.replace( 'myfield' )</b>;
 86  * @example
 87  * var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
 88  * <b>CKEDITOR.replace( textarea )</b>;
 89  */
 90 CKEDITOR.replace = function( elementOrIdOrName, config )
 91 {
 92 	if ( CKEDITOR.env.isCompatible )
 93 	{
 94 		var textarea = elementOrIdOrName;
 95
 96 		if ( typeof textarea != 'object' )
 97 		{
 98 			// First look for the element id, then the name.
 99 			var i = 0;
100 			var textareasByName	= document.getElementsByName( elementOrIdOrName );
101 			textarea = document.getElementById( elementOrIdOrName ) || textareasByName[ i++ ];
102
103 			while ( textarea )
104 			{
105 				if ( textarea.tagName.toLowerCase() == 'textarea' )
106 					break;
107 				textarea = textareasByName[ i++ ];
108 			}
109
110 			if ( !textarea )
111 				throw '[CKEDITOR.replace] The <textarea> with id or name "' + elementOrIdOrName + '" was not found.';
112 		}
113
114 		CKEDITOR.replace._replaceElement( textarea, config );
115 	}
116 };
117
118 // This function will be overwritten by the full core code implementation.
119 CKEDITOR.replace._replaceElement = function( textarea, config )
120 {
121 	// Do not replace the textarea right now, just hide it. the
122 	// effective replacement will be done by the full core code.
123 	textarea.style.visibility = 'hidden';
124
125 	// Push the textarea in the array of pending replacements.
126 	var pending = CKEDITOR.replace._pending || ( CKEDITOR.replace._pending = [] );
127 	pending.push( [ textarea, config ] );
128
129 	// Check if it is time to load the full core code.
130 	if ( CKEDITOR.loadFullCore && CKEDITOR.status == 'basic_ready' )
131 		CKEDITOR.loadFullCore();
132 };
133
134 /**
135  * Replace all <textarea> elements available in the document with
136  * editor instances.
137  * @type undefined
138  * @example
139  * // Replace all <textarea> elements in the page.
140  * CKEDITOR.replaceAll();
141  * @example
142  * // Replace all <textarea class="myClassName"> elements in the page.
143  * CKEDITOR.replaceAll( 'myClassName' );
144  * @example
145  * // Selectively replace <textarea> elements, based on custom assertions.
146  * CKEDITOR.replaceAll( function( textarea, config )
147  *     {
148  *         // Custom code to evaluate the replace, returning false
149  *         // if it must not be done.
150  *         // It also passes the "config" parameter, so the
151  *         // developer can customize the instance.
152  *     } );
153  */
154 CKEDITOR.replaceAll = function()
155 {
156 	var textareas = document.getElementsByTagName( 'textarea' );
157
158 	for ( var i = 0 ; i < textareas.length ; i++ )
159 	{
160 		var config = null;
161 		var textarea = textareas[i];
162 		var name = textarea.name;
163
164 		// The "name" and/or "id" attribute must exist.
165 		if ( !textarea.name && !textarea.id )
166 			continue;
167
168 		if ( typeof arguments[0] == 'string' )
169 		{
170 			// The textarea class name could be passed as the function
171 			// parameter.
172
173 			var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' );
174
175 			if ( !classRegex.test( textarea.className ) )
176 				continue;
177 		}
178 		else if ( typeof arguments[0] == 'function' )
179 		{
180 			// An assertion function could be passed as the function parameter.
181 			// It must explicitly return "false" to ignore a specific <textarea>.
182 			config = {};
183 			if ( arguments[0]( textarea, config ) === false )
184 				continue;
185 		}
186
187 		this.replace( textarea, config );
188 	}
189 };
190
191 if ( CKEDITOR.status == 'unloaded' )
192 {
193 	(function()
194 	{
195 		var onload = function()
196 		{
197 			// Replace all textareas with the default class name.
198 			if ( CKEDITOR.replaceByClassEnabled )
199 				CKEDITOR.replaceAll( CKEDITOR.replaceClass );
200
201 			if ( CKEDITOR.replace._pending && CKEDITOR.status == 'basic_loaded' && CKEDITOR.loadFullCore )
202 				CKEDITOR.loadFullCore();
203
204 			CKEDITOR.status = 'basic_ready';
205 		};
206
207 		if ( window.addEventListener )
208 			window.addEventListener( 'load', onload, false );
209 		else if ( window.attachEvent )
210 			window.attachEvent( 'onload', onload );
211 	})();
212 }
213
214 CKEDITOR.status = 'basic_loaded';
215