~ubuntu-it-wiki/wiki-ubuntu-it/wiki-repo

« back to all changes in this revision

Viewing changes to applets/FCKeditor/editor/_source/internals/fcktools.js

  • Committer: Leo Iannacone
  • Date: 2011-06-02 15:05:37 UTC
  • Revision ID: l3on@ubuntu.com-20110602150537-ycrnf58qf67uf593
Added applets for gui editor

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 
3
 * Copyright (C) 2003-2010 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
 * Utility functions.
 
22
 */
 
23
 
 
24
var FCKTools = new Object() ;
 
25
 
 
26
FCKTools.CreateBogusBR = function( targetDocument )
 
27
{
 
28
        var eBR = targetDocument.createElement( 'br' ) ;
 
29
//      eBR.setAttribute( '_moz_editor_bogus_node', 'TRUE' ) ;
 
30
        eBR.setAttribute( 'type', '_moz' ) ;
 
31
        return eBR ;
 
32
}
 
33
 
 
34
/**
 
35
 * Fixes relative URL entries defined inside CSS styles by appending a prefix
 
36
 * to them.
 
37
 * @param (String) cssStyles The CSS styles definition possibly containing url()
 
38
 *              paths.
 
39
 * @param (String) urlFixPrefix The prefix to append to relative URLs.
 
40
 */
 
41
FCKTools.FixCssUrls = function( urlFixPrefix, cssStyles )
 
42
{
 
43
        if ( !urlFixPrefix || urlFixPrefix.length == 0 )
 
44
                return cssStyles ;
 
45
 
 
46
        return cssStyles.replace( /url\s*\(([\s'"]*)(.*?)([\s"']*)\)/g, function( match, opener, path, closer )
 
47
                {
 
48
                        if ( /^\/|^\w?:/.test( path ) )
 
49
                                return match ;
 
50
                        else
 
51
                                return 'url(' + opener + urlFixPrefix + path + closer + ')' ;
 
52
                } ) ;
 
53
}
 
54
 
 
55
FCKTools._GetUrlFixedCss = function( cssStyles, urlFixPrefix )
 
56
{
 
57
        var match = cssStyles.match( /^([^|]+)\|([\s\S]*)/ ) ;
 
58
 
 
59
        if ( match )
 
60
                return FCKTools.FixCssUrls( match[1], match[2] ) ;
 
61
        else
 
62
                return cssStyles ;
 
63
}
 
64
 
 
65
/**
 
66
 * Appends a <link css> or <style> element to the document.
 
67
 * @param (Object) documentElement The DOM document object to which append the
 
68
 *              stylesheet.
 
69
 * @param (Variant) cssFileOrDef A String pointing to the CSS file URL or an
 
70
 *              Array with many CSS file URLs or the CSS definitions for the <style>
 
71
 *              element.
 
72
 * @return {Array} An array containing all elements created in the target
 
73
 *              document. It may include <link> or <style> elements, depending on the
 
74
 *              value passed with cssFileOrDef.
 
75
 */
 
76
FCKTools.AppendStyleSheet = function( domDocument, cssFileOrArrayOrDef )
 
77
{
 
78
        if ( !cssFileOrArrayOrDef )
 
79
                return [] ;
 
80
 
 
81
        if ( typeof( cssFileOrArrayOrDef ) == 'string' )
 
82
        {
 
83
                // Test if the passed argument is an URL.
 
84
                if ( /[\\\/\.][^{}]*$/.test( cssFileOrArrayOrDef ) )
 
85
                {
 
86
                        // The string may have several URLs separated by comma.
 
87
                        return this.AppendStyleSheet( domDocument, cssFileOrArrayOrDef.split(',') ) ;
 
88
                }
 
89
                else
 
90
                        return [ this.AppendStyleString( domDocument, FCKTools._GetUrlFixedCss( cssFileOrArrayOrDef ) ) ] ;
 
91
        }
 
92
        else
 
93
        {
 
94
                var styles = [] ;
 
95
                for ( var i = 0 ; i < cssFileOrArrayOrDef.length ; i++ )
 
96
                        styles.push( this._AppendStyleSheet( domDocument, cssFileOrArrayOrDef[i] ) ) ;
 
97
                return styles ;
 
98
        }
 
99
}
 
100
 
 
101
FCKTools.GetStyleHtml = (function()
 
102
{
 
103
        var getStyle = function( styleDef, markTemp )
 
104
        {
 
105
                if ( styleDef.length == 0 )
 
106
                        return '' ;
 
107
 
 
108
                var temp = markTemp ? ' _fcktemp="true"' : '' ;
 
109
                return '<' + 'style type="text/css"' + temp + '>' + styleDef + '<' + '/style>' ;
 
110
        }
 
111
 
 
112
        var getLink = function( cssFileUrl, markTemp )
 
113
        {
 
114
                if ( cssFileUrl.length == 0 )
 
115
                        return '' ;
 
116
 
 
117
                var temp = markTemp ? ' _fcktemp="true"' : '' ;
 
118
                return '<' + 'link href="' + cssFileUrl + '" type="text/css" rel="stylesheet" ' + temp + '/>' ;
 
119
        }
 
120
 
 
121
        return function( cssFileOrArrayOrDef, markTemp )
 
122
        {
 
123
                if ( !cssFileOrArrayOrDef )
 
124
                        return '' ;
 
125
 
 
126
                if ( typeof( cssFileOrArrayOrDef ) == 'string' )
 
127
                {
 
128
                        // Test if the passed argument is an URL.
 
129
                        if ( /[\\\/\.][^{}]*$/.test( cssFileOrArrayOrDef ) )
 
130
                        {
 
131
                                // The string may have several URLs separated by comma.
 
132
                                return this.GetStyleHtml( cssFileOrArrayOrDef.split(','), markTemp ) ;
 
133
                        }
 
134
                        else
 
135
                                return getStyle( this._GetUrlFixedCss( cssFileOrArrayOrDef ), markTemp ) ;
 
136
                }
 
137
                else
 
138
                {
 
139
                        var html = '' ;
 
140
 
 
141
                        for ( var i = 0 ; i < cssFileOrArrayOrDef.length ; i++ )
 
142
                                html += getLink( cssFileOrArrayOrDef[i], markTemp ) ;
 
143
 
 
144
                        return html ;
 
145
                }
 
146
        }
 
147
})() ;
 
148
 
 
149
FCKTools.GetElementDocument = function ( element )
 
150
{
 
151
        return element.ownerDocument || element.document ;
 
152
}
 
153
 
 
154
// Get the window object where the element is placed in.
 
155
FCKTools.GetElementWindow = function( element )
 
156
{
 
157
        return this.GetDocumentWindow( this.GetElementDocument( element ) ) ;
 
158
}
 
159
 
 
160
FCKTools.GetDocumentWindow = function( document )
 
161
{
 
162
        // With Safari, there is not way to retrieve the window from the document, so we must fix it.
 
163
        if ( FCKBrowserInfo.IsSafari && !document.parentWindow )
 
164
                this.FixDocumentParentWindow( window.top ) ;
 
165
 
 
166
        return document.parentWindow || document.defaultView ;
 
167
}
 
168
 
 
169
/*
 
170
        This is a Safari specific function that fix the reference to the parent
 
171
        window from the document object.
 
172
*/
 
173
FCKTools.FixDocumentParentWindow = function( targetWindow )
 
174
{
 
175
        if ( targetWindow.document )
 
176
                targetWindow.document.parentWindow = targetWindow ;
 
177
 
 
178
        for ( var i = 0 ; i < targetWindow.frames.length ; i++ )
 
179
                FCKTools.FixDocumentParentWindow( targetWindow.frames[i] ) ;
 
180
}
 
181
 
 
182
FCKTools.HTMLEncode = function( text )
 
183
{
 
184
        if ( !text )
 
185
                return '' ;
 
186
 
 
187
        text = text.replace( /&/g, '&amp;' ) ;
 
188
        text = text.replace( /</g, '&lt;' ) ;
 
189
        text = text.replace( />/g, '&gt;' ) ;
 
190
 
 
191
        return text ;
 
192
}
 
193
 
 
194
FCKTools.HTMLDecode = function( text )
 
195
{
 
196
        if ( !text )
 
197
                return '' ;
 
198
 
 
199
        text = text.replace( /&gt;/g, '>' ) ;
 
200
        text = text.replace( /&lt;/g, '<' ) ;
 
201
        text = text.replace( /&amp;/g, '&' ) ;
 
202
 
 
203
        return text ;
 
204
}
 
205
 
 
206
FCKTools._ProcessLineBreaksForPMode = function( oEditor, text, liState, node, strArray )
 
207
{
 
208
        var closeState = 0 ;
 
209
        var blockStartTag = "<p>" ;
 
210
        var blockEndTag = "</p>" ;
 
211
        var lineBreakTag = "<br />" ;
 
212
        if ( liState )
 
213
        {
 
214
                blockStartTag = "<li>" ;
 
215
                blockEndTag = "</li>" ;
 
216
                closeState = 1 ;
 
217
        }
 
218
 
 
219
        // Are we currently inside a <p> tag now?
 
220
        // If yes, close it at the next double line break.
 
221
        while ( node && node != oEditor.FCK.EditorDocument.body )
 
222
        {
 
223
                if ( node.tagName.toLowerCase() == 'p' )
 
224
                {
 
225
                        closeState = 1 ;
 
226
                        break;
 
227
                }
 
228
                node = node.parentNode ;
 
229
        }
 
230
 
 
231
        for ( var i = 0 ; i < text.length ; i++ )
 
232
        {
 
233
                var c = text.charAt( i ) ;
 
234
                if ( c == '\r' )
 
235
                        continue ;
 
236
 
 
237
                if ( c != '\n' )
 
238
                {
 
239
                        strArray.push( c ) ;
 
240
                        continue ;
 
241
                }
 
242
 
 
243
                // Now we have encountered a line break.
 
244
                // Check if the next character is also a line break.
 
245
                var n = text.charAt( i + 1 ) ;
 
246
                if ( n == '\r' )
 
247
                {
 
248
                        i++ ;
 
249
                        n = text.charAt( i + 1 ) ;
 
250
                }
 
251
                if ( n == '\n' )
 
252
                {
 
253
                        i++ ;   // ignore next character - we have already processed it.
 
254
                        if ( closeState )
 
255
                                strArray.push( blockEndTag ) ;
 
256
                        strArray.push( blockStartTag ) ;
 
257
                        closeState = 1 ;
 
258
                }
 
259
                else
 
260
                        strArray.push( lineBreakTag ) ;
 
261
        }
 
262
}
 
263
 
 
264
FCKTools._ProcessLineBreaksForDivMode = function( oEditor, text, liState, node, strArray )
 
265
{
 
266
        var closeState = 0 ;
 
267
        var blockStartTag = "<div>" ;
 
268
        var blockEndTag = "</div>" ;
 
269
        if ( liState )
 
270
        {
 
271
                blockStartTag = "<li>" ;
 
272
                blockEndTag = "</li>" ;
 
273
                closeState = 1 ;
 
274
        }
 
275
 
 
276
        // Are we currently inside a <div> tag now?
 
277
        // If yes, close it at the next double line break.
 
278
        while ( node && node != oEditor.FCK.EditorDocument.body )
 
279
        {
 
280
                if ( node.tagName.toLowerCase() == 'div' )
 
281
                {
 
282
                        closeState = 1 ;
 
283
                        break ;
 
284
                }
 
285
                node = node.parentNode ;
 
286
        }
 
287
 
 
288
        for ( var i = 0 ; i < text.length ; i++ )
 
289
        {
 
290
                var c = text.charAt( i ) ;
 
291
                if ( c == '\r' )
 
292
                        continue ;
 
293
 
 
294
                if ( c != '\n' )
 
295
                {
 
296
                        strArray.push( c ) ;
 
297
                        continue ;
 
298
                }
 
299
 
 
300
                if ( closeState )
 
301
                {
 
302
                        if ( strArray[ strArray.length - 1 ] == blockStartTag )
 
303
                        {
 
304
                                // A div tag must have some contents inside for it to be visible.
 
305
                                strArray.push( "&nbsp;" ) ;
 
306
                        }
 
307
                        strArray.push( blockEndTag ) ;
 
308
                }
 
309
                strArray.push( blockStartTag ) ;
 
310
                closeState = 1 ;
 
311
        }
 
312
        if ( closeState )
 
313
                strArray.push( blockEndTag ) ;
 
314
}
 
315
 
 
316
FCKTools._ProcessLineBreaksForBrMode = function( oEditor, text, liState, node, strArray )
 
317
{
 
318
        var closeState = 0 ;
 
319
        var blockStartTag = "<br />" ;
 
320
        var blockEndTag = "" ;
 
321
        if ( liState )
 
322
        {
 
323
                blockStartTag = "<li>" ;
 
324
                blockEndTag = "</li>" ;
 
325
                closeState = 1 ;
 
326
        }
 
327
 
 
328
        for ( var i = 0 ; i < text.length ; i++ )
 
329
        {
 
330
                var c = text.charAt( i ) ;
 
331
                if ( c == '\r' )
 
332
                        continue ;
 
333
 
 
334
                if ( c != '\n' )
 
335
                {
 
336
                        strArray.push( c ) ;
 
337
                        continue ;
 
338
                }
 
339
 
 
340
                if ( closeState && blockEndTag.length )
 
341
                        strArray.push ( blockEndTag ) ;
 
342
                strArray.push( blockStartTag ) ;
 
343
                closeState = 1 ;
 
344
        }
 
345
}
 
346
 
 
347
FCKTools.ProcessLineBreaks = function( oEditor, oConfig, text )
 
348
{
 
349
        var enterMode = oConfig.EnterMode.toLowerCase() ;
 
350
        var strArray = [] ;
 
351
 
 
352
        // Is the caret or selection inside an <li> tag now?
 
353
        var liState = 0 ;
 
354
        var range = new oEditor.FCKDomRange( oEditor.FCK.EditorWindow ) ;
 
355
        range.MoveToSelection() ;
 
356
        var node = range._Range.startContainer ;
 
357
        while ( node && node.nodeType != 1 )
 
358
                node = node.parentNode ;
 
359
        if ( node && node.tagName.toLowerCase() == 'li' )
 
360
                liState = 1 ;
 
361
 
 
362
        if ( enterMode == 'p' )
 
363
                this._ProcessLineBreaksForPMode( oEditor, text, liState, node, strArray ) ;
 
364
        else if ( enterMode == 'div' )
 
365
                this._ProcessLineBreaksForDivMode( oEditor, text, liState, node, strArray ) ;
 
366
        else if ( enterMode == 'br' )
 
367
                this._ProcessLineBreaksForBrMode( oEditor, text, liState, node, strArray ) ;
 
368
        return strArray.join( "" ) ;
 
369
}
 
370
 
 
371
/**
 
372
 * Adds an option to a SELECT element.
 
373
 */
 
374
FCKTools.AddSelectOption = function( selectElement, optionText, optionValue )
 
375
{
 
376
        var oOption = FCKTools.GetElementDocument( selectElement ).createElement( "OPTION" ) ;
 
377
 
 
378
        oOption.text    = optionText ;
 
379
        oOption.value   = optionValue ;
 
380
 
 
381
        selectElement.options.add(oOption) ;
 
382
 
 
383
        return oOption ;
 
384
}
 
385
 
 
386
FCKTools.RunFunction = function( func, thisObject, paramsArray, timerWindow )
 
387
{
 
388
        if ( func )
 
389
                this.SetTimeout( func, 0, thisObject, paramsArray, timerWindow ) ;
 
390
}
 
391
 
 
392
FCKTools.SetTimeout = function( func, milliseconds, thisObject, paramsArray, timerWindow )
 
393
{
 
394
        return ( timerWindow || window ).setTimeout(
 
395
                function()
 
396
                {
 
397
                        if ( paramsArray )
 
398
                                func.apply( thisObject, [].concat( paramsArray ) ) ;
 
399
                        else
 
400
                                func.apply( thisObject ) ;
 
401
                },
 
402
                milliseconds ) ;
 
403
}
 
404
 
 
405
FCKTools.SetInterval = function( func, milliseconds, thisObject, paramsArray, timerWindow )
 
406
{
 
407
        return ( timerWindow || window ).setInterval(
 
408
                function()
 
409
                {
 
410
                        func.apply( thisObject, paramsArray || [] ) ;
 
411
                },
 
412
                milliseconds ) ;
 
413
}
 
414
 
 
415
FCKTools.ConvertStyleSizeToHtml = function( size )
 
416
{
 
417
        return size.EndsWith( '%' ) ? size : parseInt( size, 10 ) ;
 
418
}
 
419
 
 
420
FCKTools.ConvertHtmlSizeToStyle = function( size )
 
421
{
 
422
        return size.EndsWith( '%' ) ? size : ( size + 'px' ) ;
 
423
}
 
424
 
 
425
// START iCM MODIFICATIONS
 
426
// Amended to accept a list of one or more ascensor tag names
 
427
// Amended to check the element itself before working back up through the parent hierarchy
 
428
FCKTools.GetElementAscensor = function( element, ascensorTagNames )
 
429
{
 
430
//      var e = element.parentNode ;
 
431
        var e = element ;
 
432
        var lstTags = "," + ascensorTagNames.toUpperCase() + "," ;
 
433
 
 
434
        while ( e )
 
435
        {
 
436
                if ( lstTags.indexOf( "," + e.nodeName.toUpperCase() + "," ) != -1 )
 
437
                        return e ;
 
438
 
 
439
                e = e.parentNode ;
 
440
        }
 
441
        return null ;
 
442
}
 
443
// END iCM MODIFICATIONS
 
444
 
 
445
FCKTools.CreateEventListener = function( func, params )
 
446
{
 
447
        var f = function()
 
448
        {
 
449
                var aAllParams = [] ;
 
450
 
 
451
                for ( var i = 0 ; i < arguments.length ; i++ )
 
452
                        aAllParams.push( arguments[i] ) ;
 
453
 
 
454
                func.apply( this, aAllParams.concat( params ) ) ;
 
455
        }
 
456
 
 
457
        return f ;
 
458
}
 
459
 
 
460
FCKTools.IsStrictMode = function( document )
 
461
{
 
462
        // There is no compatMode in Safari, but it seams that it always behave as
 
463
        // CSS1Compat, so let's assume it as the default for that browser.
 
464
        return ( 'CSS1Compat' == ( document.compatMode || ( FCKBrowserInfo.IsSafari ? 'CSS1Compat' : null ) ) ) ;
 
465
}
 
466
 
 
467
// Transforms a "arguments" object to an array.
 
468
FCKTools.ArgumentsToArray = function( args, startIndex, maxLength )
 
469
{
 
470
        startIndex = startIndex || 0 ;
 
471
        maxLength = maxLength || args.length ;
 
472
 
 
473
        var argsArray = new Array() ;
 
474
 
 
475
        for ( var i = startIndex ; i < startIndex + maxLength && i < args.length ; i++ )
 
476
                argsArray.push( args[i] ) ;
 
477
 
 
478
        return argsArray ;
 
479
}
 
480
 
 
481
FCKTools.CloneObject = function( sourceObject )
 
482
{
 
483
        var fCloneCreator = function() {} ;
 
484
        fCloneCreator.prototype = sourceObject ;
 
485
        return new fCloneCreator ;
 
486
}
 
487
 
 
488
// Appends a bogus <br> at the end of the element, if not yet available.
 
489
FCKTools.AppendBogusBr = function( element )
 
490
{
 
491
        if ( !element )
 
492
                return ;
 
493
 
 
494
        var eLastChild = this.GetLastItem( element.getElementsByTagName('br') ) ;
 
495
 
 
496
        if ( !eLastChild || ( eLastChild.getAttribute( 'type', 2 ) != '_moz' && eLastChild.getAttribute( '_moz_dirty' ) == null ) )
 
497
        {
 
498
                var doc = this.GetElementDocument( element ) ;
 
499
 
 
500
                if ( FCKBrowserInfo.IsOpera )
 
501
                        element.appendChild( doc.createTextNode('') ) ;
 
502
                else
 
503
                        element.appendChild( this.CreateBogusBR( doc ) ) ;
 
504
        }
 
505
}
 
506
 
 
507
FCKTools.GetLastItem = function( list )
 
508
{
 
509
        if ( list.length > 0 )
 
510
                return list[ list.length - 1 ] ;
 
511
 
 
512
        return null ;
 
513
}
 
514
 
 
515
FCKTools.GetDocumentPosition = function( w, node )
 
516
{
 
517
        var x = 0 ;
 
518
        var y = 0 ;
 
519
        var curNode = node ;
 
520
        var prevNode = null ;
 
521
        var curWindow = FCKTools.GetElementWindow( curNode ) ;
 
522
        while ( curNode && !( curWindow == w && ( curNode == w.document.body || curNode == w.document.documentElement ) ) )
 
523
        {
 
524
                x += curNode.offsetLeft - curNode.scrollLeft ;
 
525
                y += curNode.offsetTop - curNode.scrollTop ;
 
526
 
 
527
                if ( ! FCKBrowserInfo.IsOpera )
 
528
                {
 
529
                        var scrollNode = prevNode ;
 
530
                        while ( scrollNode && scrollNode != curNode )
 
531
                        {
 
532
                                x -= scrollNode.scrollLeft ;
 
533
                                y -= scrollNode.scrollTop ;
 
534
                                scrollNode = scrollNode.parentNode ;
 
535
                        }
 
536
                }
 
537
 
 
538
                prevNode = curNode ;
 
539
                if ( curNode.offsetParent )
 
540
                        curNode = curNode.offsetParent ;
 
541
                else
 
542
                {
 
543
                        if ( curWindow != w )
 
544
                        {
 
545
                                curNode = curWindow.frameElement ;
 
546
                                prevNode = null ;
 
547
                                if ( curNode )
 
548
                                        curWindow = curNode.contentWindow.parent ;
 
549
                        }
 
550
                        else
 
551
                                curNode = null ;
 
552
                }
 
553
        }
 
554
 
 
555
        // document.body is a special case when it comes to offsetTop and offsetLeft values.
 
556
        // 1. It matters if document.body itself is a positioned element;
 
557
        // 2. It matters is when we're in IE and the element has no positioned ancestor.
 
558
        // Otherwise the values should be ignored.
 
559
        if ( FCKDomTools.GetCurrentElementStyle( w.document.body, 'position') != 'static'
 
560
                        || ( FCKBrowserInfo.IsIE && FCKDomTools.GetPositionedAncestor( node ) == null ) )
 
561
        {
 
562
                x += w.document.body.offsetLeft ;
 
563
                y += w.document.body.offsetTop ;
 
564
        }
 
565
 
 
566
        return { "x" : x, "y" : y } ;
 
567
}
 
568
 
 
569
FCKTools.GetWindowPosition = function( w, node )
 
570
{
 
571
        var pos = this.GetDocumentPosition( w, node ) ;
 
572
        var scroll = FCKTools.GetScrollPosition( w ) ;
 
573
        pos.x -= scroll.X ;
 
574
        pos.y -= scroll.Y ;
 
575
        return pos ;
 
576
}
 
577
 
 
578
FCKTools.ProtectFormStyles = function( formNode )
 
579
{
 
580
        if ( !formNode || formNode.nodeType != 1 || formNode.tagName.toLowerCase() != 'form' )
 
581
                return [] ;
 
582
        var hijackRecord = [] ;
 
583
        var hijackNames = [ 'style', 'className' ] ;
 
584
        for ( var i = 0 ; i < hijackNames.length ; i++ )
 
585
        {
 
586
                var name = hijackNames[i] ;
 
587
                if ( formNode.elements.namedItem( name ) )
 
588
                {
 
589
                        var hijackNode = formNode.elements.namedItem( name ) ;
 
590
                        hijackRecord.push( [ hijackNode, hijackNode.nextSibling ] ) ;
 
591
                        formNode.removeChild( hijackNode ) ;
 
592
                }
 
593
        }
 
594
        return hijackRecord ;
 
595
}
 
596
 
 
597
FCKTools.RestoreFormStyles = function( formNode, hijackRecord )
 
598
{
 
599
        if ( !formNode || formNode.nodeType != 1 || formNode.tagName.toLowerCase() != 'form' )
 
600
                return ;
 
601
        if ( hijackRecord.length > 0 )
 
602
        {
 
603
                for ( var i = hijackRecord.length - 1 ; i >= 0 ; i-- )
 
604
                {
 
605
                        var node = hijackRecord[i][0] ;
 
606
                        var sibling = hijackRecord[i][1] ;
 
607
                        if ( sibling )
 
608
                                formNode.insertBefore( node, sibling ) ;
 
609
                        else
 
610
                                formNode.appendChild( node ) ;
 
611
                }
 
612
        }
 
613
}
 
614
 
 
615
// Perform a one-step DFS walk.
 
616
FCKTools.GetNextNode = function( node, limitNode )
 
617
{
 
618
        if ( node.firstChild )
 
619
                return node.firstChild ;
 
620
        else if ( node.nextSibling )
 
621
                return node.nextSibling ;
 
622
        else
 
623
        {
 
624
                var ancestor = node.parentNode ;
 
625
                while ( ancestor )
 
626
                {
 
627
                        if ( ancestor == limitNode )
 
628
                                return null ;
 
629
                        if ( ancestor.nextSibling )
 
630
                                return ancestor.nextSibling ;
 
631
                        else
 
632
                                ancestor = ancestor.parentNode ;
 
633
                }
 
634
        }
 
635
        return null ;
 
636
}
 
637
 
 
638
FCKTools.GetNextTextNode = function( textnode, limitNode, checkStop )
 
639
{
 
640
        node = this.GetNextNode( textnode, limitNode ) ;
 
641
        if ( checkStop && node && checkStop( node ) )
 
642
                return null ;
 
643
        while ( node && node.nodeType != 3 )
 
644
        {
 
645
                node = this.GetNextNode( node, limitNode ) ;
 
646
                if ( checkStop && node && checkStop( node ) )
 
647
                        return null ;
 
648
        }
 
649
        return node ;
 
650
}
 
651
 
 
652
/**
 
653
 * Merge all objects passed by argument into a single object.
 
654
 */
 
655
FCKTools.Merge = function()
 
656
{
 
657
        var args = arguments ;
 
658
        var o = args[0] ;
 
659
 
 
660
        for ( var i = 1 ; i < args.length ; i++ )
 
661
        {
 
662
                var arg = args[i] ;
 
663
                for ( var p in arg )
 
664
                        o[p] = arg[p] ;
 
665
        }
 
666
 
 
667
        return o ;
 
668
}
 
669
 
 
670
/**
 
671
 * Check if the passed argument is a real Array. It may not working when
 
672
 * calling it cross windows.
 
673
 */
 
674
FCKTools.IsArray = function( it )
 
675
{
 
676
        return ( it instanceof Array ) ;
 
677
}
 
678
 
 
679
/**
 
680
 * Appends a "length" property to an object, containing the number of
 
681
 * properties available on it, excluded the append property itself.
 
682
 */
 
683
FCKTools.AppendLengthProperty = function( targetObject, propertyName )
 
684
{
 
685
        var counter = 0 ;
 
686
 
 
687
        for ( var n in targetObject )
 
688
                counter++ ;
 
689
 
 
690
        return targetObject[ propertyName || 'length' ] = counter ;
 
691
}
 
692
 
 
693
/**
 
694
 * Gets the browser parsed version of a css text (style attribute value). On
 
695
 * some cases, the browser makes changes to the css text, returning a different
 
696
 * value. For example, hexadecimal colors get transformed to rgb().
 
697
 */
 
698
FCKTools.NormalizeCssText = function( unparsedCssText )
 
699
{
 
700
        // Injects the style in a temporary span object, so the browser parses it,
 
701
        // retrieving its final format.
 
702
        var tempSpan = document.createElement( 'span' ) ;
 
703
        tempSpan.style.cssText = unparsedCssText ;
 
704
        return tempSpan.style.cssText ;
 
705
}
 
706
 
 
707
/**
 
708
 * Binding the "this" reference to an object for a function.
 
709
 */
 
710
FCKTools.Bind = function( subject, func )
 
711
{
 
712
  return function(){ return func.apply( subject, arguments ) ; } ;
 
713
}
 
714
 
 
715
/**
 
716
 * Retrieve the correct "empty iframe" URL for the current browser, which
 
717
 * causes the minimum fuzz (e.g. security warnings in HTTPS, DNS error in
 
718
 * IE5.5, etc.) for that browser, making the iframe ready to DOM use whithout
 
719
 * having to loading an external file.
 
720
 */
 
721
FCKTools.GetVoidUrl = function()
 
722
{
 
723
        if ( FCK_IS_CUSTOM_DOMAIN )
 
724
                return "javascript: void( function(){" +
 
725
                        "document.open();" +
 
726
                        "document.write('<html><head><title></title></head><body></body></html>');" +
 
727
                        "document.domain = '" + FCK_RUNTIME_DOMAIN + "';" +
 
728
                        "document.close();" +
 
729
                        "}() ) ;";
 
730
 
 
731
        if ( FCKBrowserInfo.IsIE )
 
732
        {
 
733
                if ( FCKBrowserInfo.IsIE7 || !FCKBrowserInfo.IsIE6 )
 
734
                        return "" ;                                     // IE7+ / IE5.5
 
735
                else
 
736
                        return "javascript: '';" ;      // IE6+
 
737
        }
 
738
 
 
739
        return "javascript: void(0);" ;         // All other browsers.
 
740
}
 
741
 
 
742
FCKTools.ResetStyles = function( element )
 
743
{
 
744
        element.style.cssText = 'margin:0;' +
 
745
                'padding:0;' +
 
746
                'border:0;' +
 
747
                'background-color:transparent;' +
 
748
                'background-image:none;' ;
 
749
}