~pablocapeluto/cds-php/devel-3.1

« back to all changes in this revision

Viewing changes to FCKeditor/editor/_source/internals/fcktools_gecko.js

  • Committer: pcapeluto at gmail
  • Date: 2010-08-20 17:51:08 UTC
  • Revision ID: pcapeluto@gmail.com-20100820175108-jyi8dbyj15uy9p4i
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * FCKeditor - The text editor for internet
 
3
 * Copyright (C) 2003-2005 Frederico Caldeira Knabben
 
4
 * 
 
5
 * Licensed under the terms of the GNU Lesser General Public License:
 
6
 *              http://www.opensource.org/licenses/lgpl-license.php
 
7
 * 
 
8
 * For further information visit:
 
9
 *              http://www.fckeditor.net/
 
10
 * 
 
11
 * "Support Open Source software. What about a donation today?"
 
12
 * 
 
13
 * File Name: fcktools_gecko.js
 
14
 *      Utility functions. (Gecko version).
 
15
 * 
 
16
 * File Authors:
 
17
 *              Frederico Caldeira Knabben (fredck@fckeditor.net)
 
18
 */
 
19
 
 
20
// Constant for the Gecko Bogus Node.
 
21
var GECKO_BOGUS = '<br _moz_editor_bogus_node="TRUE">' ;
 
22
 
 
23
// Appends a CSS file to a document.
 
24
FCKTools.AppendStyleSheet = function( documentElement, cssFileUrl )
 
25
{
 
26
        var e = documentElement.createElement( 'LINK' ) ;
 
27
        e.rel   = 'stylesheet' ;
 
28
        e.type  = 'text/css' ;
 
29
        e.href  = cssFileUrl ;
 
30
        documentElement.getElementsByTagName("HEAD")[0].appendChild( e ) ;
 
31
        return e ;
 
32
}
 
33
 
 
34
// Removes all attributes and values from the element.
 
35
FCKTools.ClearElementAttributes = function( element )
 
36
{
 
37
        // Loop throw all attributes in the element
 
38
        for ( var i = 0 ; i < element.attributes.length ; i++ )
 
39
        {
 
40
                // Remove the element by name.
 
41
                element.removeAttribute( element.attributes[i].name, 0 ) ;      // 0 : Case Insensitive
 
42
        }
 
43
}
 
44
 
 
45
// Returns an Array of strings with all defined in the elements inside another element.
 
46
FCKTools.GetAllChildrenIds = function( parentElement )
 
47
{
 
48
        // Create the array that will hold all Ids.
 
49
        var aIds = new Array() ;
 
50
        
 
51
        // Define a recursive function that search for the Ids.
 
52
        var fGetIds = function( parent )
 
53
        {
 
54
                for ( var i = 0 ; i < parent.childNodes.length ; i++ )
 
55
                {
 
56
                        var sId = parent.childNodes[i].id ;
 
57
                        
 
58
                        // Check if the Id is defined for the element.
 
59
                        if ( sId && sId.length > 0 ) aIds[ aIds.length ] = sId ;
 
60
                        
 
61
                        // Recursive call.
 
62
                        fGetIds( parent.childNodes[i] ) ;
 
63
                }
 
64
        }
 
65
        
 
66
        // Start the recursive calls.
 
67
        fGetIds( parentElement ) ;
 
68
 
 
69
        return aIds ;
 
70
}
 
71
 
 
72
FCKTools.RemoveOuterTags = function( e )
 
73
{
 
74
        var oFragment = e.ownerDocument.createDocumentFragment() ;
 
75
                        
 
76
        for ( var i = 0 ; i < e.childNodes.length ; i++ )
 
77
                oFragment.appendChild( e.childNodes[i] ) ;
 
78
                        
 
79
        e.parentNode.replaceChild( oFragment, e ) ;
 
80
}
 
81
 
 
82
FCKTools.CreateXmlObject = function( object )
 
83
{
 
84
        switch ( object )
 
85
        {
 
86
                case 'XmlHttp' :
 
87
                        return new XMLHttpRequest() ;
 
88
                case 'DOMDocument' :
 
89
                        return document.implementation.createDocument( '', '', null ) ;
 
90
        }
 
91
        return null ;
 
92
}
 
93
 
 
94
FCKTools.DisableSelection = function( element )
 
95
{
 
96
        element.style.MozUserSelect     = 'none' ;      // Gecko only.
 
97
        // element.style.userSelect     = 'none' ;      // CSS3 (not supported yet).
 
98
}
 
99
 
 
100
// START iCM Modifications
 
101
/*
 
102
// Starting at the specified node, find the first inline node of the sequence
 
103
// For example, assume we have the following elements : <p>Some text <span>some more text</span> and <a href="href">some link</a> yet some more text</p>
 
104
// If the "some link" text node is the one specified, then the "Some text" text node will be the first inline node returned.
 
105
FCKTools.GetFirstInlineNode = function( oNode )
 
106
{
 
107
        if ( FCKRegexLib.BlockElements.test( oNode.nodeName ) )
 
108
                return oNode ;
 
109
        else if ( oNode.previousSibling && !FCKRegexLib.BlockElements.test( oNode.previousSibling.nodeName ) )
 
110
                return FCKTools.GetFirstInlineNode( oNode.previousSibling ) ;
 
111
        else if ( oNode.parentNode && !FCKRegexLib.BlockElements.test( oNode.parentNode.nodeName ) && oNode.parentNode.nodeName.toUpperCase() != "BODY" )
 
112
                return FCKTools.GetFirstInlineNode( oNode.parentNode ) ;
 
113
        else 
 
114
                return oNode ;
 
115
}
 
116
 
 
117
// Starting at the specified node, find the last inline node of the sequence
 
118
// For example, assume we have the following elements : <p>Some text <span>some more text</span> and <a href="href">some link</a> yet some more text</p>
 
119
// If the "some link" text node is the one specified, then the " yet some more text" text node will be the last inline node returned.
 
120
FCKTools.GetLastInlineNode = function( oNode )
 
121
{
 
122
        if ( FCKRegexLib.BlockElements.test( oNode.nodeName ) )
 
123
                return oNode ;
 
124
        else if ( oNode.nextSibling && !FCKRegexLib.BlockElements.test( oNode.nextSibling.nodeName ) )
 
125
                return FCKTools.GetLastInlineNode( oNode.nextSibling ) ;
 
126
        else if ( oNode.parentNode && !FCKRegexLib.BlockElements.test( oNode.parentNode.nodeName ) && oNode.parentNode.nodeName.toUpperCase() != "BODY" )
 
127
                return FCKTools.GetLastInlineNode( oNode.parentNode ) ;
 
128
        else
 
129
                return oNode ;
 
130
}
 
131
 
 
132
 
 
133
// Split the supplied parent at the specified child and (optionally) offset.
 
134
// Ensure that enclosing block elements are created where missing but that existing 
 
135
// block elements (table for example) don't get incorrectly nested. 
 
136
FCKTools.SplitNode = function( oParentBlockNode, oChildNode, nOffset )
 
137
{
 
138
        if ( typeof nOffset == "undefined" ) nOffset = 0 ;
 
139
 
 
140
        var oFragment = FCK.EditorDocument.createDocumentFragment() ;
 
141
        var oRange = FCK.EditorDocument.createRange() ;
 
142
 
 
143
        if ( FCKRegexLib.ListElements.test( oParentBlockNode.nodeName ) )
 
144
        {
 
145
                // Treat OL/UL parents differently as want to split at the specified
 
146
                // child LI node to create to OL/UL lists.
 
147
                oStartNode = oParentBlockNode.firstChild ;
 
148
                oEndNode = oParentBlockNode.lastChild ;
 
149
        }
 
150
        else
 
151
        {
 
152
                // Locate the inline nodes adjacent to the specified child node so that these can
 
153
                // be kept together.
 
154
                oStartNode = FCKTools.GetFirstInlineNode( oChildNode ) ;
 
155
                oEndNode = FCKTools.GetLastInlineNode( oChildNode ) ;
 
156
        }
 
157
 
 
158
        // Create a new tag which holds the content of the affected node(s) located before (but not including) the child node and offset
 
159
        if ( FCKRegexLib.BlockElements.test( oStartNode.nodeName ) && !FCKRegexLib.ListElements.test( oParentBlockNode.nodeName ) )
 
160
        {
 
161
                // First element of the bunch is already a block element so we don't want to wrap it with a new block element.
 
162
                // Just use this first node provided it is not the same as the last node (to prevent duplication), otherwise
 
163
                // create a new empty P element.
 
164
                if ( oStartNode != oEndNode )
 
165
                {
 
166
                        oBlockNode1 = oStartNode.cloneNode( true ) ;
 
167
                }
 
168
                else
 
169
                {
 
170
                        oBlockNode1 = FCK.EditorDocument.createElement( "P" ) ;
 
171
                        oBlockNode1.innerHTML = GECKO_BOGUS ;
 
172
                        
 
173
                        if ( !FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) )
 
174
                                FCKTools.SetElementAttributes( oBlockNode1, oParentBlockNode.attributes ) ;  // Transfer across any class attributes, etc
 
175
                }
 
176
        }
 
177
        else
 
178
        {
 
179
                // First element of the bunch is not a block element (or it is a LI element which is a special case).
 
180
                // So ensure all of the inline nodes before the selection are wrapped with a suitable block element.
 
181
                var oBlockNode1 = FCK.EditorDocument.createElement( FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) ? "P" : oParentBlockNode.tagName ) ;
 
182
                oRange.setStartBefore( oStartNode ) ;
 
183
                if ( nOffset == 0 )
 
184
                        oRange.setEndBefore( oChildNode ) ;
 
185
                else
 
186
                        oRange.setEnd( oChildNode, nOffset ) ;
 
187
                oBlockNode1.appendChild( oRange.cloneContents() ) ;
 
188
                oBlockNode1.innerHTML = oBlockNode1.innerHTML.replace(/[\x00-\x1F]/g, "") ; // Prevent any control characters returned within the innerHTML from causing problems
 
189
                if ( FCKTools.NodeIsEmpty( oBlockNode1 ) )
 
190
                        oBlockNode1.innerHTML = GECKO_BOGUS ;           // Ensure it has some content, required for Gecko
 
191
                else
 
192
                        oBlockNode1.innerHTML = oBlockNode1.innerHTML.replace( FCKRegexLib.EmptyElement, "" ) ; // Strip out any empty tags that may have been generated by the split
 
193
                if ( !FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) )
 
194
                        FCKTools.SetElementAttributes( oBlockNode1, oParentBlockNode.attributes ) ;     // Transfer across any class attributes, etc
 
195
        }
 
196
 
 
197
        // Create a new tag which holds the content of the affected node(s) located after (and including) the child node
 
198
        if ( FCKRegexLib.BlockElements.test( oEndNode.nodeName ) && !FCKRegexLib.ListElements.test( oParentBlockNode.nodeName ) )
 
199
        {
 
200
                // Last element of the bunch is already a block element so we don't want to wrap it with a new block element.
 
201
                oBlockNode2 = oEndNode.cloneNode( true ) ;
 
202
        }
 
203
        else
 
204
        {
 
205
                // Last element of the bunch is not a block element (or it is a LI element which is a special case).
 
206
                // So ensure all of the inline nodes after and including the child/offset are wrapped with a suitable block element.
 
207
                var oBlockNode2 = FCK.EditorDocument.createElement( FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) ? "P" : oParentBlockNode.tagName );
 
208
                oRange.setEndAfter( oEndNode );
 
209
                if ( nOffset == 0 )
 
210
                        oRange.setStartBefore( oChildNode ) ;
 
211
                else
 
212
                        oRange.setStart( oChildNode, nOffset );
 
213
                oBlockNode2.appendChild( oRange.cloneContents() ) ;
 
214
                oBlockNode2.innerHTML = oBlockNode2.innerHTML.replace(/[\x00-\x1F]/g, "") ;  // Prevent any control characters returned within the innerHTML from causing problems
 
215
                if ( FCKTools.NodeIsEmpty( oBlockNode2 ) ) 
 
216
                        oBlockNode2.innerHTML = GECKO_BOGUS ;                   // Ensure it has some content, required for Gecko
 
217
                else
 
218
                        oBlockNode2.innerHTML = oBlockNode2.innerHTML.replace( FCKRegexLib.EmptyElement, "" ) ; // Strip out any empty tags that may have been generated by the split
 
219
                if ( !FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) )
 
220
                        FCKTools.SetElementAttributes( oBlockNode2, oParentBlockNode.attributes ) ;     // Transfer across any class attributes, etc
 
221
        }
 
222
        
 
223
        // Insert the resulting nodes into a document fragment
 
224
        oFragment.appendChild( oBlockNode1 );
 
225
        oFragment.appendChild( oBlockNode2 );
 
226
        
 
227
        // Replace the affected nodes with the new nodes (fragment)
 
228
        FCKTools.ReplaceNodes( oParentBlockNode, oStartNode, oEndNode, oFragment ) ;    
 
229
        
 
230
        // Return the second node so it can be used for setting cursor position, etc
 
231
        return oBlockNode2 ;
 
232
}
 
233
 
 
234
// Function that replaces the specified range of nodes (inclusive) within the supplied parent
 
235
// with the nodes stored in the supplied document fragment.
 
236
FCKTools.ReplaceNodes = function( oParentBlockNode, oStartNode, oEndNode, oFragment )
 
237
{
 
238
        var oRange = FCK.EditorDocument.createRange() ;
 
239
        
 
240
        // Delete the affected node(s)
 
241
        if ( !FCKRegexLib.SpecialBlockElements.test( oParentBlockNode.nodeName ) && (oParentBlockNode.firstChild == oStartNode) && (oParentBlockNode.lastChild == oEndNode) )
 
242
        {
 
243
                // Entire parent block node is to be replaced so insert the two new block elements before it 
 
244
                // and then remove the old node
 
245
                oRange.selectNode ( oParentBlockNode );
 
246
        }
 
247
        else
 
248
        {
 
249
                // Only part of the parent block node is to be replaced so insert the two new block elements
 
250
                // before the first inline node of the affected content and then remove the old nodes
 
251
                oRange.setEndAfter( oEndNode ) ;
 
252
                oRange.setStartBefore( oStartNode ) ;
 
253
        }
 
254
        
 
255
        // Insert the replacement nodes
 
256
        oRange.deleteContents() ;
 
257
        oRange.insertNode( oFragment ) ;
 
258
}
 
259
*/
 
260
// END iCM Modifications
 
261