~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckxhtml.js

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20080622211713-inlv5k4eifxckelr
ImportĀ upstreamĀ versionĀ 1.7.0

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: fckxhtml.js
 
14
 *      Defines the FCKXHtml object, responsible for the XHTML operations.
 
15
 * 
 
16
 * File Authors:
 
17
 *              Frederico Caldeira Knabben (fredck@fckeditor.net)
 
18
 */
 
19
 
 
20
var FCKXHtml = new Object() ;
 
21
 
 
22
FCKXHtml.CurrentJobNum = 0 ;
 
23
 
 
24
FCKXHtml.GetXHTML = function( node, includeNode, format )
 
25
{
 
26
        // Special blocks are blocks of content that remain untouched during the
 
27
        // process. It is used for SCRIPTs and STYLEs.
 
28
        FCKXHtml.SpecialBlocks = new Array() ;
 
29
 
 
30
        // Create the XML DOMDocument object.
 
31
        this.XML = FCKTools.CreateXmlObject( 'DOMDocument' ) ;
 
32
 
 
33
        // Add a root element that holds all child nodes.
 
34
        this.MainNode = this.XML.appendChild( this.XML.createElement( 'xhtml' ) ) ;
 
35
 
 
36
        FCKXHtml.CurrentJobNum++ ;
 
37
 
 
38
        if ( includeNode )
 
39
                this._AppendNode( this.MainNode, node ) ;
 
40
        else
 
41
                this._AppendChildNodes( this.MainNode, node, false ) ;
 
42
 
 
43
        // Get the resulting XHTML as a string.
 
44
        var sXHTML = this._GetMainXmlString() ;
 
45
 
 
46
        // Strip the "XHTML" root node.
 
47
        sXHTML = sXHTML.substr( 7, sXHTML.length - 15 ).trim() ;
 
48
        
 
49
        // Remove the trailing <br> added by Gecko.
 
50
        if ( FCKBrowserInfo.IsGecko )
 
51
                sXHTML = sXHTML.replace( /<br\/>$/, '' ) ;
 
52
 
 
53
        // Add a space in the tags with no closing tags, like <br/> -> <br />
 
54
        sXHTML = sXHTML.replace( FCKRegexLib.SpaceNoClose, ' />');
 
55
 
 
56
        if ( FCKConfig.ForceSimpleAmpersand )
 
57
                sXHTML = sXHTML.replace( FCKRegexLib.ForceSimpleAmpersand, '&' ) ;
 
58
 
 
59
        if ( format )
 
60
                sXHTML = FCKCodeFormatter.Format( sXHTML ) ;
 
61
 
 
62
        // Now we put back the SpecialBlocks contents.
 
63
        for ( var i = 0 ; i < FCKXHtml.SpecialBlocks.length ; i++ )
 
64
        {
 
65
                var oRegex = new RegExp( '___FCKsi___' + i ) ;
 
66
                sXHTML = sXHTML.replace( oRegex, FCKXHtml.SpecialBlocks[i] ) ;
 
67
        }
 
68
 
 
69
        this.XML = null ;
 
70
 
 
71
        return sXHTML
 
72
}
 
73
 
 
74
FCKXHtml._AppendAttribute = function( xmlNode, attributeName, attributeValue )
 
75
{
 
76
        try
 
77
        {
 
78
                // Create the attribute.
 
79
                var oXmlAtt = this.XML.createAttribute( attributeName ) ;
 
80
 
 
81
                oXmlAtt.value = attributeValue ? attributeValue : '' ;
 
82
 
 
83
                // Set the attribute in the node.
 
84
                xmlNode.attributes.setNamedItem( oXmlAtt ) ;
 
85
        }
 
86
        catch (e)
 
87
        {}
 
88
}
 
89
 
 
90
FCKXHtml._AppendChildNodes = function( xmlNode, htmlNode, isBlockElement )
 
91
{
 
92
        var iCount = 0 ;
 
93
        
 
94
        var oNode = htmlNode.firstChild ;
 
95
 
 
96
        while ( oNode )
 
97
        {
 
98
                if ( this._AppendNode( xmlNode, oNode ) )
 
99
                        iCount++ ;
 
100
 
 
101
                oNode = oNode.nextSibling ;
 
102
        }
 
103
        
 
104
        if ( iCount == 0 )
 
105
        {
 
106
                if ( isBlockElement && FCKConfig.FillEmptyBlocks )
 
107
                {
 
108
                        this._AppendEntity( xmlNode, 'nbsp' ) ;
 
109
                        return ;
 
110
                }
 
111
 
 
112
                // We can't use short representation of empty elements that are not marked
 
113
                // as empty in th XHTML DTD.
 
114
                if ( !FCKRegexLib.EmptyElements.test( htmlNode.nodeName ) )
 
115
                        xmlNode.appendChild( this.XML.createTextNode('') ) ;
 
116
        }
 
117
}
 
118
 
 
119
FCKXHtml._AppendNode = function( xmlNode, htmlNode )
 
120
{
 
121
        if ( !htmlNode )
 
122
                return ;
 
123
 
 
124
        switch ( htmlNode.nodeType )
 
125
        {
 
126
                // Element Node.
 
127
                case 1 :
 
128
                        if ( htmlNode.getAttribute('_fckfakelement') )
 
129
                                return FCKXHtml._AppendNode( xmlNode, FCK.GetRealElement( htmlNode ) ) ;
 
130
                
 
131
                        // Mozilla insert custom nodes in the DOM.
 
132
                        if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') )
 
133
                                return false ;
 
134
                        
 
135
                        if ( htmlNode.getAttribute('_fckdelete') )
 
136
                                return false ;
 
137
 
 
138
                        // Get the element name.
 
139
                        var sNodeName = htmlNode.nodeName ;
 
140
                        
 
141
                        //Add namespace:
 
142
                        if ( FCKBrowserInfo.IsIE && htmlNode.scopeName && htmlNode.scopeName != 'HTML' )
 
143
                                sNodeName = htmlNode.scopeName + ':' + sNodeName ;
 
144
 
 
145
                        // Check if the node name is valid, otherwise ignore this tag.
 
146
                        // If the nodeName starts with a slash, it is a orphan closing tag.
 
147
                        // On some strange cases, the nodeName is empty, even if the node exists.
 
148
                        if ( !FCKRegexLib.ElementName.test( sNodeName ) )
 
149
                                return false ;
 
150
 
 
151
                        sNodeName = sNodeName.toLowerCase() ;
 
152
 
 
153
                        if ( FCKBrowserInfo.IsGecko && sNodeName == 'br' && htmlNode.hasAttribute('type') && htmlNode.getAttribute( 'type', 2 ) == '_moz' )
 
154
                                return false ;
 
155
 
 
156
                        // The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML).
 
157
                        // So here, the "mark" is checked... if the element is Ok, then mark it.
 
158
                        if ( htmlNode._fckxhtmljob && htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum )
 
159
                                return false ;
 
160
 
 
161
                        var oNode = this._CreateNode( sNodeName ) ;
 
162
                        
 
163
                        // Add all attributes.
 
164
                        FCKXHtml._AppendAttributes( xmlNode, htmlNode, oNode, sNodeName ) ;
 
165
                        
 
166
                        htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ;
 
167
 
 
168
                        // Tag specific processing.
 
169
                        var oTagProcessor = FCKXHtml.TagProcessors[ sNodeName ] ;
 
170
 
 
171
                        if ( oTagProcessor )
 
172
                        {
 
173
                                oNode = oTagProcessor( oNode, htmlNode ) ;
 
174
                                if ( !oNode ) break ;
 
175
                        }
 
176
                        else
 
177
                                this._AppendChildNodes( oNode, htmlNode, FCKRegexLib.BlockElements.test( sNodeName ) ) ;
 
178
 
 
179
                        xmlNode.appendChild( oNode ) ;
 
180
 
 
181
                        break ;
 
182
 
 
183
                // Text Node.
 
184
                case 3 :
 
185
                        this._AppendTextNode( xmlNode, htmlNode.nodeValue.replaceNewLineChars(' ') ) ;
 
186
                        break ;
 
187
 
 
188
                // Comment
 
189
                case 8 :
 
190
                        try { xmlNode.appendChild( this.XML.createComment( htmlNode.nodeValue ) ) ; }
 
191
                        catch (e) { /* Do nothing... probably this is a wrong format comment. */ }
 
192
                        break ;
 
193
 
 
194
                // Unknown Node type.
 
195
                default :
 
196
                        xmlNode.appendChild( this.XML.createComment( "Element not supported - Type: " + htmlNode.nodeType + " Name: " + htmlNode.nodeName ) ) ;
 
197
                        break ;
 
198
        }
 
199
        return true ;
 
200
}
 
201
 
 
202
if ( FCKConfig.ForceStrongEm )
 
203
{
 
204
        FCKXHtml._CreateNode = function( nodeName )
 
205
        {
 
206
                switch ( nodeName )
 
207
                {
 
208
                        case 'b' :
 
209
                                nodeName = 'strong' ;
 
210
                                break ;
 
211
                        case 'i' :
 
212
                                nodeName = 'em' ;
 
213
                                break ;
 
214
                }
 
215
                return this.XML.createElement( nodeName ) ;
 
216
        }
 
217
}
 
218
else
 
219
{
 
220
        FCKXHtml._CreateNode = function( nodeName )
 
221
        {
 
222
                return this.XML.createElement( nodeName ) ;
 
223
        }
 
224
}
 
225
 
 
226
// Append an item to the SpecialBlocks array and returns the tag to be used.
 
227
FCKXHtml._AppendSpecialItem = function( item )
 
228
{
 
229
        return '___FCKsi___' + FCKXHtml.SpecialBlocks.addItem( item ) ;
 
230
}
 
231
 
 
232
//if ( FCKConfig.ProcessHTMLEntities )
 
233
//{
 
234
        FCKXHtml._AppendTextNode = function( targetNode, textValue )
 
235
        {
 
236
                // We can't just replace the special chars with entities and create a
 
237
                // text node with it. We must split the text isolating the special chars
 
238
                // and add each piece a time.
 
239
                var asPieces = textValue.match( FCKXHtmlEntities.EntitiesRegex ) ;
 
240
 
 
241
                if ( asPieces )
 
242
                {
 
243
                        for ( var i = 0 ; i < asPieces.length ; i++ )
 
244
                        {
 
245
                                if ( asPieces[i].length == 1 )
 
246
                                {
 
247
                                        var sEntity = FCKXHtmlEntities.Entities[ asPieces[i] ] ;
 
248
                                        if ( sEntity != null )
 
249
                                        {
 
250
                                                this._AppendEntity( targetNode, sEntity ) ;
 
251
                                                continue ;
 
252
                                        }
 
253
                                }
 
254
                                targetNode.appendChild( this.XML.createTextNode( asPieces[i] ) ) ;
 
255
                        }
 
256
                }
 
257
        }
 
258
//}
 
259
//else
 
260
//{
 
261
//      FCKXHtml._AppendTextNode = function( targetNode, textValue )
 
262
//      {
 
263
//              targetNode.appendChild( this.XML.createTextNode( textValue ) ) ;
 
264
//      }
 
265
//}
 
266
 
 
267
// An object that hold tag specific operations.
 
268
FCKXHtml.TagProcessors = new Object() ;
 
269
 
 
270
FCKXHtml.TagProcessors['img'] = function( node, htmlNode )
 
271
{
 
272
        // The "ALT" attribute is required in XHTML.
 
273
        if ( ! node.attributes.getNamedItem( 'alt' ) )
 
274
                FCKXHtml._AppendAttribute( node, 'alt', '' ) ;
 
275
 
 
276
        var sSavedUrl = htmlNode.getAttribute( '_fcksavedurl' ) ;
 
277
        if ( sSavedUrl && sSavedUrl.length > 0 )
 
278
                FCKXHtml._AppendAttribute( node, 'src', sSavedUrl ) ;
 
279
 
 
280
        return node ;
 
281
}
 
282
 
 
283
FCKXHtml.TagProcessors['a'] = function( node, htmlNode )
 
284
{
 
285
        var sSavedUrl = htmlNode.getAttribute( '_fcksavedurl' ) ;
 
286
        if ( sSavedUrl && sSavedUrl.length > 0 )
 
287
                FCKXHtml._AppendAttribute( node, 'href', sSavedUrl ) ;
 
288
 
 
289
        FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
 
290
 
 
291
        return node ;
 
292
}
 
293
 
 
294
FCKXHtml.TagProcessors['script'] = function( node, htmlNode )
 
295
{
 
296
        // The "TYPE" attribute is required in XHTML.
 
297
        if ( ! node.attributes.getNamedItem( 'type' ) )
 
298
                FCKXHtml._AppendAttribute( node, 'type', 'text/javascript' ) ;
 
299
 
 
300
        node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.text ) ) ) ;
 
301
 
 
302
        return node ;
 
303
}
 
304
 
 
305
FCKXHtml.TagProcessors['style'] = function( node, htmlNode )
 
306
{
 
307
        // The "_fcktemp" attribute is used to mark the <STYLE> used by the editor
 
308
        // to set some behaviors.
 
309
        if ( htmlNode.getAttribute( '_fcktemp' ) )
 
310
                return null ;
 
311
 
 
312
        // The "TYPE" attribute is required in XHTML.
 
313
        if ( ! node.attributes.getNamedItem( 'type' ) )
 
314
                FCKXHtml._AppendAttribute( node, 'type', 'text/css' ) ;
 
315
 
 
316
        node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.innerHTML ) ) ) ;
 
317
 
 
318
        return node ;
 
319
}
 
320
 
 
321
FCKXHtml.TagProcessors['title'] = function( node, htmlNode )
 
322
{
 
323
        node.appendChild( FCKXHtml.XML.createTextNode( FCK.EditorDocument.title ) ) ;
 
324
 
 
325
        return node ;
 
326
}
 
327
 
 
328
FCKXHtml.TagProcessors['base'] = function( node, htmlNode )
 
329
{
 
330
        // The "_fcktemp" attribute is used to mark the <BASE> tag when the editor
 
331
        // automatically sets it using the FCKConfig.BaseHref configuration.
 
332
        if ( htmlNode.getAttribute( '_fcktemp' ) )
 
333
                return null ;
 
334
 
 
335
        // IE duplicates the BODY inside the <BASE /> tag (don't ask me why!).
 
336
        // This tag processor does nothing... in this way, no child nodes are added
 
337
        // (also because the BASE tag must be empty).
 
338
        return node ;
 
339
}
 
340
 
 
341
FCKXHtml.TagProcessors['link'] = function( node, htmlNode )
 
342
{
 
343
        // The "_fcktemp" attribute is used to mark the fck_internal.css <LINK>
 
344
        // reference.
 
345
        if ( htmlNode.getAttribute( '_fcktemp' ) )
 
346
                return null ;
 
347
 
 
348
        return node ;
 
349
}
 
350
 
 
351
FCKXHtml.TagProcessors['table'] = function( node, htmlNode )
 
352
{
 
353
        // There is a trick to show table borders when border=0. We add to the
 
354
        // table class the FCK__ShowTableBorders rule. So now we must remove it.
 
355
 
 
356
        var oClassAtt = node.attributes.getNamedItem( 'class' ) ;
 
357
 
 
358
        if ( oClassAtt && FCKRegexLib.TableBorderClass.test( oClassAtt.nodeValue ) )
 
359
        {
 
360
                var sClass = oClassAtt.nodeValue.replace( FCKRegexLib.TableBorderClass, '' ) ;
 
361
 
 
362
                if ( sClass.length == 0 )
 
363
                        node.attributes.removeNamedItem( 'class' ) ;
 
364
                else
 
365
                        FCKXHtml._AppendAttribute( node, 'class', sClass ) ;
 
366
        }
 
367
 
 
368
        FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
 
369
 
 
370
        return node ;
 
371
}
 
 
b'\\ No newline at end of file'