Subversion Repositories Applications.papyrus

Rev

Rev 1925 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1925 Rev 2048
1
/*
1
/*
2
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
2
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3
 * Copyright (C) 2003-2008 Frederico Caldeira Knabben
3
 * Copyright (C) 2003-2009 Frederico Caldeira Knabben
4
 *
4
 *
5
 * == BEGIN LICENSE ==
5
 * == BEGIN LICENSE ==
6
 *
6
 *
7
 * Licensed under the terms of any of the following licenses at your
7
 * Licensed under the terms of any of the following licenses at your
8
 * choice:
8
 * choice:
9
 *
9
 *
10
 *  - GNU General Public License Version 2 or later (the "GPL")
10
 *  - GNU General Public License Version 2 or later (the "GPL")
11
 *    http://www.gnu.org/licenses/gpl.html
11
 *    http://www.gnu.org/licenses/gpl.html
12
 *
12
 *
13
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
13
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
14
 *    http://www.gnu.org/licenses/lgpl.html
14
 *    http://www.gnu.org/licenses/lgpl.html
15
 *
15
 *
16
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
16
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
17
 *    http://www.mozilla.org/MPL/MPL-1.1.html
17
 *    http://www.mozilla.org/MPL/MPL-1.1.html
18
 *
18
 *
19
 * == END LICENSE ==
19
 * == END LICENSE ==
20
 *
20
 *
21
 * This is the integration file for JavaScript.
21
 * This is the integration file for JavaScript.
22
 *
22
 *
23
 * It defines the FCKeditor class that can be used to create editor
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
24
 * instances in a HTML page in the client side. For server side
25
 * operations, use the specific integration system.
25
 * operations, use the specific integration system.
26
 */
26
 */
27
 
27
 
28
// FCKeditor Class
28
// FCKeditor Class
29
var FCKeditor = function( instanceName, width, height, toolbarSet, value )
29
var FCKeditor = function( instanceName, width, height, toolbarSet, value )
30
{
30
{
31
	// Properties
31
	// Properties
32
	this.InstanceName	= instanceName ;
32
	this.InstanceName	= instanceName ;
33
	this.Width			= width			|| '100%' ;
33
	this.Width			= width			|| '100%' ;
34
	this.Height			= height		|| '200' ;
34
	this.Height			= height		|| '200' ;
35
	this.ToolbarSet		= toolbarSet	|| 'Default' ;
35
	this.ToolbarSet		= toolbarSet	|| 'Default' ;
36
	this.Value			= value			|| '' ;
36
	this.Value			= value			|| '' ;
37
	this.BasePath		= FCKeditor.BasePath ;
37
	this.BasePath		= FCKeditor.BasePath ;
38
	this.CheckBrowser	= true ;
38
	this.CheckBrowser	= true ;
39
	this.DisplayErrors	= true ;
39
	this.DisplayErrors	= true ;
40
 
40
 
41
	this.Config			= new Object() ;
41
	this.Config			= new Object() ;
42
 
42
 
43
	// Events
43
	// Events
44
	this.OnError		= null ;	// function( source, errorNumber, errorDescription )
44
	this.OnError		= null ;	// function( source, errorNumber, errorDescription )
45
}
45
}
46
 
46
 
47
/**
47
/**
48
 * This is the default BasePath used by all editor instances.
48
 * This is the default BasePath used by all editor instances.
49
 */
49
 */
50
FCKeditor.BasePath = '/fckeditor/' ;
50
FCKeditor.BasePath = '/fckeditor/' ;
51
 
51
 
52
/**
52
/**
53
 * The minimum height used when replacing textareas.
53
 * The minimum height used when replacing textareas.
54
 */
54
 */
55
FCKeditor.MinHeight = 200 ;
55
FCKeditor.MinHeight = 200 ;
56
 
56
 
57
/**
57
/**
58
 * The minimum width used when replacing textareas.
58
 * The minimum width used when replacing textareas.
59
 */
59
 */
60
FCKeditor.MinWidth = 750 ;
60
FCKeditor.MinWidth = 750 ;
61
 
61
 
62
FCKeditor.prototype.Version			= '2.6.3' ;
62
FCKeditor.prototype.Version			= '2.6.4' ;
63
FCKeditor.prototype.VersionBuild	= '19836' ;
63
FCKeditor.prototype.VersionBuild	= '21629' ;
64
 
64
 
65
FCKeditor.prototype.Create = function()
65
FCKeditor.prototype.Create = function()
66
{
66
{
67
	document.write( this.CreateHtml() ) ;
67
	document.write( this.CreateHtml() ) ;
68
}
68
}
69
 
69
 
70
FCKeditor.prototype.CreateHtml = function()
70
FCKeditor.prototype.CreateHtml = function()
71
{
71
{
72
	// Check for errors
72
	// Check for errors
73
	if ( !this.InstanceName || this.InstanceName.length == 0 )
73
	if ( !this.InstanceName || this.InstanceName.length == 0 )
74
	{
74
	{
75
		this._ThrowError( 701, 'You must specify an instance name.' ) ;
75
		this._ThrowError( 701, 'You must specify an instance name.' ) ;
76
		return '' ;
76
		return '' ;
77
	}
77
	}
78
 
78
 
79
	var sHtml = '' ;
79
	var sHtml = '' ;
80
 
80
 
81
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
81
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
82
	{
82
	{
83
		sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
83
		sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" />' ;
84
		sHtml += this._GetConfigHtml() ;
84
		sHtml += this._GetConfigHtml() ;
85
		sHtml += this._GetIFrameHtml() ;
85
		sHtml += this._GetIFrameHtml() ;
86
	}
86
	}
87
	else
87
	else
88
	{
88
	{
89
		var sWidth  = this.Width.toString().indexOf('%')  > 0 ? this.Width  : this.Width  + 'px' ;
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' ;
90
		var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;
91
 
91
 
92
		sHtml += '<textarea name="' + this.InstanceName +
92
		sHtml += '<textarea name="' + this.InstanceName +
93
			'" rows="4" cols="40" style="width:' + sWidth +
93
			'" rows="4" cols="40" style="width:' + sWidth +
94
			';height:' + sHeight ;
94
			';height:' + sHeight ;
95
 
95
 
96
		if ( this.TabIndex )
96
		if ( this.TabIndex )
97
			sHtml += '" tabindex="' + this.TabIndex ;
97
			sHtml += '" tabindex="' + this.TabIndex ;
98
 
98
 
99
		sHtml += '">' +
99
		sHtml += '">' +
100
			this._HTMLEncode( this.Value ) +
100
			this._HTMLEncode( this.Value ) +
101
			'<\/textarea>' ;
101
			'<\/textarea>' ;
102
	}
102
	}
103
 
103
 
104
	return sHtml ;
104
	return sHtml ;
105
}
105
}
106
 
106
 
107
FCKeditor.prototype.ReplaceTextarea = function()
107
FCKeditor.prototype.ReplaceTextarea = function()
108
{
108
{
-
 
109
	if ( document.getElementById( this.InstanceName + '___Frame' ) )
-
 
110
		return ;
109
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
111
	if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
110
	{
112
	{
111
		// We must check the elements firstly using the Id and then the name.
113
		// We must check the elements firstly using the Id and then the name.
112
		var oTextarea = document.getElementById( this.InstanceName ) ;
114
		var oTextarea = document.getElementById( this.InstanceName ) ;
113
		var colElementsByName = document.getElementsByName( this.InstanceName ) ;
115
		var colElementsByName = document.getElementsByName( this.InstanceName ) ;
114
		var i = 0;
116
		var i = 0;
115
		while ( oTextarea || i == 0 )
117
		while ( oTextarea || i == 0 )
116
		{
118
		{
117
			if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
119
			if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
118
				break ;
120
				break ;
119
			oTextarea = colElementsByName[i++] ;
121
			oTextarea = colElementsByName[i++] ;
120
		}
122
		}
121
 
123
 
122
		if ( !oTextarea )
124
		if ( !oTextarea )
123
		{
125
		{
124
			alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
126
			alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
125
			return ;
127
			return ;
126
		}
128
		}
127
 
129
 
128
		oTextarea.style.display = 'none' ;
130
		oTextarea.style.display = 'none' ;
129
 
131
 
130
		if ( oTextarea.tabIndex )
132
		if ( oTextarea.tabIndex )
131
			this.TabIndex = oTextarea.tabIndex ;
133
			this.TabIndex = oTextarea.tabIndex ;
132
 
134
 
133
		this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
135
		this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
134
		this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
136
		this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
135
	}
137
	}
136
}
138
}
137
 
139
 
138
FCKeditor.prototype._InsertHtmlBefore = function( html, element )
140
FCKeditor.prototype._InsertHtmlBefore = function( html, element )
139
{
141
{
140
	if ( element.insertAdjacentHTML )	// IE
142
	if ( element.insertAdjacentHTML )	// IE
141
		element.insertAdjacentHTML( 'beforeBegin', html ) ;
143
		element.insertAdjacentHTML( 'beforeBegin', html ) ;
142
	else								// Gecko
144
	else								// Gecko
143
	{
145
	{
144
		var oRange = document.createRange() ;
146
		var oRange = document.createRange() ;
145
		oRange.setStartBefore( element ) ;
147
		oRange.setStartBefore( element ) ;
146
		var oFragment = oRange.createContextualFragment( html );
148
		var oFragment = oRange.createContextualFragment( html );
147
		element.parentNode.insertBefore( oFragment, element ) ;
149
		element.parentNode.insertBefore( oFragment, element ) ;
148
	}
150
	}
149
}
151
}
150
 
152
 
151
FCKeditor.prototype._GetConfigHtml = function()
153
FCKeditor.prototype._GetConfigHtml = function()
152
{
154
{
153
	var sConfig = '' ;
155
	var sConfig = '' ;
154
	for ( var o in this.Config )
156
	for ( var o in this.Config )
155
	{
157
	{
156
		if ( sConfig.length > 0 ) sConfig += '&amp;' ;
158
		if ( sConfig.length > 0 ) sConfig += '&amp;' ;
157
		sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
159
		sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
158
	}
160
	}
159
 
161
 
160
	return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
162
	return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" />' ;
161
}
163
}
162
 
164
 
163
FCKeditor.prototype._GetIFrameHtml = function()
165
FCKeditor.prototype._GetIFrameHtml = function()
164
{
166
{
165
	var sFile = 'fckeditor.html' ;
167
	var sFile = 'fckeditor.html' ;
166
 
168
 
167
	try
169
	try
168
	{
170
	{
169
		if ( (/fcksource=true/i).test( window.top.location.search ) )
171
		if ( (/fcksource=true/i).test( window.top.location.search ) )
170
			sFile = 'fckeditor.original.html' ;
172
			sFile = 'fckeditor.original.html' ;
171
	}
173
	}
172
	catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
174
	catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ }
173
 
175
 
174
	var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
176
	var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
175
	if (this.ToolbarSet)
177
	if (this.ToolbarSet)
176
		sLink += '&amp;Toolbar=' + this.ToolbarSet ;
178
		sLink += '&amp;Toolbar=' + this.ToolbarSet ;
177
 
179
 
178
	html = '<iframe id="' + this.InstanceName +
180
	var html = '<iframe id="' + this.InstanceName +
179
		'___Frame" src="' + sLink +
181
		'___Frame" src="' + sLink +
180
		'" width="' + this.Width +
182
		'" width="' + this.Width +
181
		'" height="' + this.Height ;
183
		'" height="' + this.Height ;
182
 
184
 
183
	if ( this.TabIndex )
185
	if ( this.TabIndex )
184
		html += '" tabindex="' + this.TabIndex ;
186
		html += '" tabindex="' + this.TabIndex ;
185
 
187
 
186
	html += '" frameborder="0" scrolling="no"></iframe>' ;
188
	html += '" frameborder="0" scrolling="no"></iframe>' ;
187
 
189
 
188
	return html ;
190
	return html ;
189
}
191
}
190
 
192
 
191
FCKeditor.prototype._IsCompatibleBrowser = function()
193
FCKeditor.prototype._IsCompatibleBrowser = function()
192
{
194
{
193
	return FCKeditor_IsCompatibleBrowser() ;
195
	return FCKeditor_IsCompatibleBrowser() ;
194
}
196
}
195
 
197
 
196
FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
198
FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
197
{
199
{
198
	this.ErrorNumber		= errorNumber ;
200
	this.ErrorNumber		= errorNumber ;
199
	this.ErrorDescription	= errorDescription ;
201
	this.ErrorDescription	= errorDescription ;
200
 
202
 
201
	if ( this.DisplayErrors )
203
	if ( this.DisplayErrors )
202
	{
204
	{
203
		document.write( '<div style="COLOR: #ff0000">' ) ;
205
		document.write( '<div style="COLOR: #ff0000">' ) ;
204
		document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
206
		document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
205
		document.write( '</div>' ) ;
207
		document.write( '</div>' ) ;
206
	}
208
	}
207
 
209
 
208
	if ( typeof( this.OnError ) == 'function' )
210
	if ( typeof( this.OnError ) == 'function' )
209
		this.OnError( this, errorNumber, errorDescription ) ;
211
		this.OnError( this, errorNumber, errorDescription ) ;
210
}
212
}
211
 
213
 
212
FCKeditor.prototype._HTMLEncode = function( text )
214
FCKeditor.prototype._HTMLEncode = function( text )
213
{
215
{
214
	if ( typeof( text ) != "string" )
216
	if ( typeof( text ) != "string" )
215
		text = text.toString() ;
217
		text = text.toString() ;
216
 
218
 
217
	text = text.replace(
219
	text = text.replace(
218
		/&/g, "&amp;").replace(
220
		/&/g, "&amp;").replace(
219
		/"/g, "&quot;").replace(
221
		/"/g, "&quot;").replace(
220
		/</g, "&lt;").replace(
222
		/</g, "&lt;").replace(
221
		/>/g, "&gt;") ;
223
		/>/g, "&gt;") ;
222
 
224
 
223
	return text ;
225
	return text ;
224
}
226
}
225
 
227
 
226
;(function()
228
;(function()
227
{
229
{
228
	var textareaToEditor = function( textarea )
230
	var textareaToEditor = function( textarea )
229
	{
231
	{
230
		var editor = new FCKeditor( textarea.name ) ;
232
		var editor = new FCKeditor( textarea.name ) ;
231
 
233
 
232
		editor.Width = Math.max( textarea.offsetWidth, FCKeditor.MinWidth ) ;
234
		editor.Width = Math.max( textarea.offsetWidth, FCKeditor.MinWidth ) ;
233
		editor.Height = Math.max( textarea.offsetHeight, FCKeditor.MinHeight ) ;
235
		editor.Height = Math.max( textarea.offsetHeight, FCKeditor.MinHeight ) ;
234
 
236
 
235
		return editor ;
237
		return editor ;
236
	}
238
	}
237
 
239
 
238
	/**
240
	/**
239
	 * Replace all <textarea> elements available in the document with FCKeditor
241
	 * Replace all <textarea> elements available in the document with FCKeditor
240
	 * instances.
242
	 * instances.
241
	 *
243
	 *
242
	 *	// Replace all <textarea> elements in the page.
244
	 *	// Replace all <textarea> elements in the page.
243
	 *	FCKeditor.ReplaceAllTextareas() ;
245
	 *	FCKeditor.ReplaceAllTextareas() ;
244
	 *
246
	 *
245
	 *	// Replace all <textarea class="myClassName"> elements in the page.
247
	 *	// Replace all <textarea class="myClassName"> elements in the page.
246
	 *	FCKeditor.ReplaceAllTextareas( 'myClassName' ) ;
248
	 *	FCKeditor.ReplaceAllTextareas( 'myClassName' ) ;
247
	 *
249
	 *
248
	 *	// Selectively replace <textarea> elements, based on custom assertions.
250
	 *	// Selectively replace <textarea> elements, based on custom assertions.
249
	 *	FCKeditor.ReplaceAllTextareas( function( textarea, editor )
251
	 *	FCKeditor.ReplaceAllTextareas( function( textarea, editor )
250
	 *		{
252
	 *		{
251
	 *			// Custom code to evaluate the replace, returning false if it
253
	 *			// Custom code to evaluate the replace, returning false if it
252
	 *			// must not be done.
254
	 *			// must not be done.
253
	 *			// It also passes the "editor" parameter, so the developer can
255
	 *			// It also passes the "editor" parameter, so the developer can
254
	 *			// customize the instance.
256
	 *			// customize the instance.
255
	 *		} ) ;
257
	 *		} ) ;
256
	 */
258
	 */
257
	FCKeditor.ReplaceAllTextareas = function()
259
	FCKeditor.ReplaceAllTextareas = function()
258
	{
260
	{
259
		var textareas = document.getElementsByTagName( 'textarea' ) ;
261
		var textareas = document.getElementsByTagName( 'textarea' ) ;
260
 
262
 
261
		for ( var i = 0 ; i < textareas.length ; i++ )
263
		for ( var i = 0 ; i < textareas.length ; i++ )
262
		{
264
		{
263
			var editor = null ;
265
			var editor = null ;
264
			var textarea = textareas[i] ;
266
			var textarea = textareas[i] ;
265
			var name = textarea.name ;
267
			var name = textarea.name ;
266
 
268
 
267
			// The "name" attribute must exist.
269
			// The "name" attribute must exist.
268
			if ( !name || name.length == 0 )
270
			if ( !name || name.length == 0 )
269
				continue ;
271
				continue ;
270
 
272
 
271
			if ( typeof arguments[0] == 'string' )
273
			if ( typeof arguments[0] == 'string' )
272
			{
274
			{
273
				// The textarea class name could be passed as the function
275
				// The textarea class name could be passed as the function
274
				// parameter.
276
				// parameter.
275
 
277
 
276
				var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' ) ;
278
				var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' ) ;
277
 
279
 
278
				if ( !classRegex.test( textarea.className ) )
280
				if ( !classRegex.test( textarea.className ) )
279
					continue ;
281
					continue ;
280
			}
282
			}
281
			else if ( typeof arguments[0] == 'function' )
283
			else if ( typeof arguments[0] == 'function' )
282
			{
284
			{
283
				// An assertion function could be passed as the function parameter.
285
				// An assertion function could be passed as the function parameter.
284
				// It must explicitly return "false" to ignore a specific <textarea>.
286
				// It must explicitly return "false" to ignore a specific <textarea>.
285
				editor = textareaToEditor( textarea ) ;
287
				editor = textareaToEditor( textarea ) ;
286
				if ( arguments[0]( textarea, editor ) === false )
288
				if ( arguments[0]( textarea, editor ) === false )
287
					continue ;
289
					continue ;
288
			}
290
			}
289
 
291
 
290
			if ( !editor )
292
			if ( !editor )
291
				editor = textareaToEditor( textarea ) ;
293
				editor = textareaToEditor( textarea ) ;
292
 
294
 
293
			editor.ReplaceTextarea() ;
295
			editor.ReplaceTextarea() ;
294
		}
296
		}
295
	}
297
	}
296
})() ;
298
})() ;
297
 
299
 
298
function FCKeditor_IsCompatibleBrowser()
300
function FCKeditor_IsCompatibleBrowser()
299
{
301
{
300
	var sAgent = navigator.userAgent.toLowerCase() ;
302
	var sAgent = navigator.userAgent.toLowerCase() ;
301
 
303
 
302
	// Internet Explorer 5.5+
304
	// Internet Explorer 5.5+
303
	if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 )
305
	if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 )
304
	{
306
	{
305
		var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
307
		var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
306
		return ( sBrowserVersion >= 5.5 ) ;
308
		return ( sBrowserVersion >= 5.5 ) ;
307
	}
309
	}
308
 
310
 
309
	// Gecko (Opera 9 tries to behave like Gecko at this point).
311
	// Gecko (Opera 9 tries to behave like Gecko at this point).
310
	if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
312
	if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
311
		return true ;
313
		return true ;
312
 
314
 
313
	// Opera 9.50+
315
	// Opera 9.50+
314
	if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
316
	if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
315
		return true ;
317
		return true ;
316
 
318
 
317
	// Adobe AIR
319
	// Adobe AIR
318
	// Checked before Safari because AIR have the WebKit rich text editor
320
	// Checked before Safari because AIR have the WebKit rich text editor
319
	// features from Safari 3.0.4, but the version reported is 420.
321
	// features from Safari 3.0.4, but the version reported is 420.
320
	if ( sAgent.indexOf( ' adobeair/' ) != -1 )
322
	if ( sAgent.indexOf( ' adobeair/' ) != -1 )
321
		return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ;	// Build must be at least v1
323
		return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ;	// Build must be at least v1
322
 
324
 
323
	// Safari 3+
325
	// Safari 3+
324
	if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
326
	if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
325
		return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ;	// Build must be at least 522 (v3)
327
		return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ;	// Build must be at least 522 (v3)
326
 
328
 
327
	return false ;
329
	return false ;
328
}
330
}