Project

General

Profile

1
/*
2
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3
 * Copyright (C) 2003-2009 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
 * This is the integration file for JavaScript.
22
 *
23
 * It defines the FCKeditor class that can be used to create editor
24
 * instances in a HTML page in the client side. For server side
25
 * operations, use the specific integration system.
26
 */
27

    
28
// FCKeditor Class
29
var FCKeditor = function( instanceName, width, height, toolbarSet, value )
30
{
31
	// Properties
32
	this.InstanceName	= instanceName ;
33
	this.Width			= width			|| '100%' ;
34
	this.Height			= height		|| '200' ;
35
	this.ToolbarSet		= toolbarSet	|| 'Default' ;
36
	this.Value			= value			|| '' ;
37
	this.BasePath		= FCKeditor.BasePath ;
38
	this.CheckBrowser	= true ;
39
	this.DisplayErrors	= true ;
40

    
41
	this.Config			= new Object() ;
42

    
43
	// Events
44
	this.OnError		= null ;	// function( source, errorNumber, errorDescription )
45
}
46

    
47
/**
48
 * This is the default BasePath used by all editor instances.
49
 */
50
FCKeditor.BasePath = '/fckeditor/' ;
51

    
52
/**
53
 * The minimum height used when replacing textareas.
54
 */
55
FCKeditor.MinHeight = 200 ;
56

    
57
/**
58
 * The minimum width used when replacing textareas.
59
 */
60
FCKeditor.MinWidth = 750 ;
61

    
62
FCKeditor.prototype.Version			= '2.6.4.1' ;
63
FCKeditor.prototype.VersionBuild	= '23187' ;
64

    
65
FCKeditor.prototype.Create = function()
66
{
67
	document.write( this.CreateHtml() ) ;
68
}
69

    
70
FCKeditor.prototype.CreateHtml = function()
71
{
72
	// Check for errors
73
	if ( !this.InstanceName || this.InstanceName.length == 0 )
74
	{
75
		this._ThrowError( 701, 'You must specify an instance name.' ) ;
76
		return '' ;
77
	}
78

    
79
	var sHtml = '' ;
80

    
81
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
82
	{
83
		sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
84
		sHtml += this._GetConfigHtml() ;
85
		sHtml += this._GetIFrameHtml() ;
86
	}
87
	else
88
	{
89
		var sWidth  = this.Width.toString().indexOf('%')  > 0 ? this.Width  : this.Width  + 'px' ;
90
		var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;
91

    
92
		sHtml += '<textarea name="' + this.InstanceName +
93
			'" rows="4" cols="40" style="width:' + sWidth +
94
			';height:' + sHeight ;
95

    
96
		if ( this.TabIndex )
97
			sHtml += '" tabindex="' + this.TabIndex ;
98

    
99
		sHtml += '">' +
100
			this._HTMLEncode( this.Value ) +
101
			'<\/textarea>' ;
102
	}
103

    
104
	return sHtml ;
105
}
106

    
107
FCKeditor.prototype.ReplaceTextarea = function()
108
{
109
	if ( document.getElementById( this.InstanceName + '___Frame' ) )
110
		return ;
111
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
112
	{
113
		// We must check the elements firstly using the Id and then the name.
114
		var oTextarea = document.getElementById( this.InstanceName ) ;
115
		var colElementsByName = document.getElementsByName( this.InstanceName ) ;
116
		var i = 0;
117
		while ( oTextarea || i == 0 )
118
		{
119
			if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
120
				break ;
121
			oTextarea = colElementsByName[i++] ;
122
		}
123

    
124
		if ( !oTextarea )
125
		{
126
			alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
127
			return ;
128
		}
129

    
130
		oTextarea.style.display = 'none' ;
131

    
132
		if ( oTextarea.tabIndex )
133
			this.TabIndex = oTextarea.tabIndex ;
134

    
135
		this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
136
		this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
137
	}
138
}
139

    
140
FCKeditor.prototype._InsertHtmlBefore = function( html, element )
141
{
142
	if ( element.insertAdjacentHTML )	// IE
143
		element.insertAdjacentHTML( 'beforeBegin', html ) ;
144
	else								// Gecko
145
	{
146
		var oRange = document.createRange() ;
147
		oRange.setStartBefore( element ) ;
148
		var oFragment = oRange.createContextualFragment( html );
149
		element.parentNode.insertBefore( oFragment, element ) ;
150
	}
151
}
152

    
153
FCKeditor.prototype._GetConfigHtml = function()
154
{
155
	var sConfig = '' ;
156
	for ( var o in this.Config )
157
	{
158
		if ( sConfig.length > 0 ) sConfig += '&amp;' ;
159
		sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
160
	}
161

    
162
	return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
163
}
164

    
165
FCKeditor.prototype._GetIFrameHtml = function()
166
{
167
	var sFile = 'fckeditor.html' ;
168

    
169
	try
170
	{
171
		if ( (/fcksource=true/i).test( window.top.location.search ) )
172
			sFile = 'fckeditor.original.html' ;
173
	}
174
	catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
175

    
176
	var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
177
	if (this.ToolbarSet)
178
		sLink += '&amp;Toolbar=' + this.ToolbarSet ;
179

    
180
	var html = '<iframe id="' + this.InstanceName +
181
		'___Frame" src="' + sLink +
182
		'" width="' + this.Width +
183
		'" height="' + this.Height ;
184

    
185
	if ( this.TabIndex )
186
		html += '" tabindex="' + this.TabIndex ;
187

    
188
	html += '" frameborder="0" scrolling="no"></iframe>' ;
189

    
190
	return html ;
191
}
192

    
193
FCKeditor.prototype._IsCompatibleBrowser = function()
194
{
195
	return FCKeditor_IsCompatibleBrowser() ;
196
}
197

    
198
FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
199
{
200
	this.ErrorNumber		= errorNumber ;
201
	this.ErrorDescription	= errorDescription ;
202

    
203
	if ( this.DisplayErrors )
204
	{
205
		document.write( '<div style="COLOR: #ff0000">' ) ;
206
		document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
207
		document.write( '</div>' ) ;
208
	}
209

    
210
	if ( typeof( this.OnError ) == 'function' )
211
		this.OnError( this, errorNumber, errorDescription ) ;
212
}
213

    
214
FCKeditor.prototype._HTMLEncode = function( text )
215
{
216
	if ( typeof( text ) != "string" )
217
		text = text.toString() ;
218

    
219
	text = text.replace(
220
		/&/g, "&amp;").replace(
221
		/"/g, "&quot;").replace(
222
		/</g, "&lt;").replace(
223
		/>/g, "&gt;") ;
224

    
225
	return text ;
226
}
227

    
228
;(function()
229
{
230
	var textareaToEditor = function( textarea )
231
	{
232
		var editor = new FCKeditor( textarea.name ) ;
233

    
234
		editor.Width = Math.max( textarea.offsetWidth, FCKeditor.MinWidth ) ;
235
		editor.Height = Math.max( textarea.offsetHeight, FCKeditor.MinHeight ) ;
236

    
237
		return editor ;
238
	}
239

    
240
	/**
241
	 * Replace all <textarea> elements available in the document with FCKeditor
242
	 * instances.
243
	 *
244
	 *	// Replace all <textarea> elements in the page.
245
	 *	FCKeditor.ReplaceAllTextareas() ;
246
	 *
247
	 *	// Replace all <textarea class="myClassName"> elements in the page.
248
	 *	FCKeditor.ReplaceAllTextareas( 'myClassName' ) ;
249
	 *
250
	 *	// Selectively replace <textarea> elements, based on custom assertions.
251
	 *	FCKeditor.ReplaceAllTextareas( function( textarea, editor )
252
	 *		{
253
	 *			// Custom code to evaluate the replace, returning false if it
254
	 *			// must not be done.
255
	 *			// It also passes the "editor" parameter, so the developer can
256
	 *			// customize the instance.
257
	 *		} ) ;
258
	 */
259
	FCKeditor.ReplaceAllTextareas = function()
260
	{
261
		var textareas = document.getElementsByTagName( 'textarea' ) ;
262

    
263
		for ( var i = 0 ; i < textareas.length ; i++ )
264
		{
265
			var editor = null ;
266
			var textarea = textareas[i] ;
267
			var name = textarea.name ;
268

    
269
			// The "name" attribute must exist.
270
			if ( !name || name.length == 0 )
271
				continue ;
272

    
273
			if ( typeof arguments[0] == 'string' )
274
			{
275
				// The textarea class name could be passed as the function
276
				// parameter.
277

    
278
				var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' ) ;
279

    
280
				if ( !classRegex.test( textarea.className ) )
281
					continue ;
282
			}
283
			else if ( typeof arguments[0] == 'function' )
284
			{
285
				// An assertion function could be passed as the function parameter.
286
				// It must explicitly return "false" to ignore a specific <textarea>.
287
				editor = textareaToEditor( textarea ) ;
288
				if ( arguments[0]( textarea, editor ) === false )
289
					continue ;
290
			}
291

    
292
			if ( !editor )
293
				editor = textareaToEditor( textarea ) ;
294

    
295
			editor.ReplaceTextarea() ;
296
		}
297
	}
298
})() ;
299

    
300
function FCKeditor_IsCompatibleBrowser()
301
{
302
	var sAgent = navigator.userAgent.toLowerCase() ;
303

    
304
	// Internet Explorer 5.5+
305
	if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 )
306
	{
307
		var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
308
		return ( sBrowserVersion >= 5.5 ) ;
309
	}
310

    
311
	// Gecko (Opera 9 tries to behave like Gecko at this point).
312
	if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
313
		return true ;
314

    
315
	// Opera 9.50+
316
	if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
317
		return true ;
318

    
319
	// Adobe AIR
320
	// Checked before Safari because AIR have the WebKit rich text editor
321
	// features from Safari 3.0.4, but the version reported is 420.
322
	if ( sAgent.indexOf( ' adobeair/' ) != -1 )
323
		return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ;	// Build must be at least v1
324

    
325
	// Safari 3+
326
	if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
327
		return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ;	// Build must be at least 522 (v3)
328

    
329
	return false ;
330
}
(2-2/10)