import rt 3.8.7
[freeside.git] / rt / share / html / NoAuth / RichText / FCKeditor / editor / _source / internals / fckdocumentprocessor.js
1 /*\r
2  * FCKeditor - The text editor for Internet - http://www.fckeditor.net\r
3  * Copyright (C) 2003-2009 Frederico Caldeira Knabben\r
4  *\r
5  * == BEGIN LICENSE ==\r
6  *\r
7  * Licensed under the terms of any of the following licenses at your\r
8  * choice:\r
9  *\r
10  *  - GNU General Public License Version 2 or later (the "GPL")\r
11  *    http://www.gnu.org/licenses/gpl.html\r
12  *\r
13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
14  *    http://www.gnu.org/licenses/lgpl.html\r
15  *\r
16  *  - Mozilla Public License Version 1.1 or later (the "MPL")\r
17  *    http://www.mozilla.org/MPL/MPL-1.1.html\r
18  *\r
19  * == END LICENSE ==\r
20  *\r
21  * Advanced document processors.\r
22  */\r
23 \r
24 var FCKDocumentProcessor = new Object() ;\r
25 FCKDocumentProcessor._Items = new Array() ;\r
26 \r
27 FCKDocumentProcessor.AppendNew = function()\r
28 {\r
29         var oNewItem = new Object() ;\r
30         this._Items.push( oNewItem ) ;\r
31         return oNewItem ;\r
32 }\r
33 \r
34 FCKDocumentProcessor.Process = function( document )\r
35 {\r
36         var bIsDirty = FCK.IsDirty() ;\r
37         var oProcessor, i = 0 ;\r
38         while( ( oProcessor = this._Items[i++] ) )\r
39                 oProcessor.ProcessDocument( document ) ;\r
40         if ( !bIsDirty )\r
41                 FCK.ResetIsDirty() ;\r
42 }\r
43 \r
44 var FCKDocumentProcessor_CreateFakeImage = function( fakeClass, realElement )\r
45 {\r
46         var oImg = FCKTools.GetElementDocument( realElement ).createElement( 'IMG' ) ;\r
47         oImg.className = fakeClass ;\r
48         oImg.src = FCKConfig.BasePath + 'images/spacer.gif' ;\r
49         oImg.setAttribute( '_fckfakelement', 'true', 0 ) ;\r
50         oImg.setAttribute( '_fckrealelement', FCKTempBin.AddElement( realElement ), 0 ) ;\r
51         return oImg ;\r
52 }\r
53 \r
54 // Link Anchors\r
55 if ( FCKBrowserInfo.IsIE || FCKBrowserInfo.IsOpera )\r
56 {\r
57         var FCKAnchorsProcessor = FCKDocumentProcessor.AppendNew() ;\r
58         FCKAnchorsProcessor.ProcessDocument = function( document )\r
59         {\r
60                 var aLinks = document.getElementsByTagName( 'A' ) ;\r
61 \r
62                 var oLink ;\r
63                 var i = aLinks.length - 1 ;\r
64                 while ( i >= 0 && ( oLink = aLinks[i--] ) )\r
65                 {\r
66                         // If it is anchor. Doesn't matter if it's also a link (even better: we show that it's both a link and an anchor)\r
67                         if ( oLink.name.length > 0 )\r
68                         {\r
69                                 //if the anchor has some content then we just add a temporary class\r
70                                 if ( oLink.innerHTML !== '' )\r
71                                 {\r
72                                         if ( FCKBrowserInfo.IsIE )\r
73                                                 oLink.className += ' FCK__AnchorC' ;\r
74                                 }\r
75                                 else\r
76                                 {\r
77                                         var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__Anchor', oLink.cloneNode(true) ) ;\r
78                                         oImg.setAttribute( '_fckanchor', 'true', 0 ) ;\r
79 \r
80                                         oLink.parentNode.insertBefore( oImg, oLink ) ;\r
81                                         oLink.parentNode.removeChild( oLink ) ;\r
82                                 }\r
83                         }\r
84                 }\r
85         }\r
86 }\r
87 \r
88 // Page Breaks\r
89 var FCKPageBreaksProcessor = FCKDocumentProcessor.AppendNew() ;\r
90 FCKPageBreaksProcessor.ProcessDocument = function( document )\r
91 {\r
92         var aDIVs = document.getElementsByTagName( 'DIV' ) ;\r
93 \r
94         var eDIV ;\r
95         var i = aDIVs.length - 1 ;\r
96         while ( i >= 0 && ( eDIV = aDIVs[i--] ) )\r
97         {\r
98                 if ( eDIV.style.pageBreakAfter == 'always' && eDIV.childNodes.length == 1 && eDIV.childNodes[0].style && eDIV.childNodes[0].style.display == 'none' )\r
99                 {\r
100                         var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', eDIV.cloneNode(true) ) ;\r
101 \r
102                         eDIV.parentNode.insertBefore( oFakeImage, eDIV ) ;\r
103                         eDIV.parentNode.removeChild( eDIV ) ;\r
104                 }\r
105         }\r
106 /*\r
107         var aCenters = document.getElementsByTagName( 'CENTER' ) ;\r
108 \r
109         var oCenter ;\r
110         var i = aCenters.length - 1 ;\r
111         while ( i >= 0 && ( oCenter = aCenters[i--] ) )\r
112         {\r
113                 if ( oCenter.style.pageBreakAfter == 'always' && oCenter.innerHTML.Trim().length == 0 )\r
114                 {\r
115                         var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', oCenter.cloneNode(true) ) ;\r
116 \r
117                         oCenter.parentNode.insertBefore( oFakeImage, oCenter ) ;\r
118                         oCenter.parentNode.removeChild( oCenter ) ;\r
119                 }\r
120         }\r
121 */\r
122 }\r
123 \r
124 // EMBED and OBJECT tags.\r
125 var FCKEmbedAndObjectProcessor = (function()\r
126 {\r
127         var customProcessors = [] ;\r
128 \r
129         var processElement = function( el )\r
130         {\r
131                 var clone = el.cloneNode( true ) ;\r
132                 var replaceElement ;\r
133                 var fakeImg = replaceElement = FCKDocumentProcessor_CreateFakeImage( 'FCK__UnknownObject', clone ) ;\r
134                 FCKEmbedAndObjectProcessor.RefreshView( fakeImg, el ) ;\r
135 \r
136                 for ( var i = 0 ; i < customProcessors.length ; i++ )\r
137                         replaceElement = customProcessors[i]( el, replaceElement ) || replaceElement ;\r
138 \r
139                 if ( replaceElement != fakeImg )\r
140                         FCKTempBin.RemoveElement( fakeImg.getAttribute( '_fckrealelement' ) ) ;\r
141 \r
142                 el.parentNode.replaceChild( replaceElement, el ) ;\r
143         }\r
144 \r
145         var processElementsByName = function( elementName, doc )\r
146         {\r
147                 var aObjects = doc.getElementsByTagName( elementName );\r
148                 for ( var i = aObjects.length - 1 ; i >= 0 ; i-- )\r
149                         processElement( aObjects[i] ) ;\r
150         }\r
151 \r
152         var processObjectAndEmbed = function( doc )\r
153         {\r
154                 processElementsByName( 'object', doc );\r
155                 processElementsByName( 'embed', doc );\r
156         }\r
157 \r
158         return FCKTools.Merge( FCKDocumentProcessor.AppendNew(),\r
159                        {\r
160                                 ProcessDocument : function( doc )\r
161                                 {\r
162                                         // Firefox 3 would sometimes throw an unknown exception while accessing EMBEDs and OBJECTs\r
163                                         // without the setTimeout().\r
164                                         if ( FCKBrowserInfo.IsGecko )\r
165                                                 FCKTools.RunFunction( processObjectAndEmbed, this, [ doc ] ) ;\r
166                                         else\r
167                                                 processObjectAndEmbed( doc ) ;\r
168                                 },\r
169 \r
170                                 RefreshView : function( placeHolder, original )\r
171                                 {\r
172                                         if ( original.getAttribute( 'width' ) > 0 )\r
173                                                 placeHolder.style.width = FCKTools.ConvertHtmlSizeToStyle( original.getAttribute( 'width' ) ) ;\r
174 \r
175                                         if ( original.getAttribute( 'height' ) > 0 )\r
176                                                 placeHolder.style.height = FCKTools.ConvertHtmlSizeToStyle( original.getAttribute( 'height' ) ) ;\r
177                                 },\r
178 \r
179                                 AddCustomHandler : function( func )\r
180                                 {\r
181                                         customProcessors.push( func ) ;\r
182                                 }\r
183                         } ) ;\r
184 } )() ;\r
185 \r
186 FCK.GetRealElement = function( fakeElement )\r
187 {\r
188         var e = FCKTempBin.Elements[ fakeElement.getAttribute('_fckrealelement') ] ;\r
189 \r
190         if ( fakeElement.getAttribute('_fckflash') )\r
191         {\r
192                 if ( fakeElement.style.width.length > 0 )\r
193                                 e.width = FCKTools.ConvertStyleSizeToHtml( fakeElement.style.width ) ;\r
194 \r
195                 if ( fakeElement.style.height.length > 0 )\r
196                                 e.height = FCKTools.ConvertStyleSizeToHtml( fakeElement.style.height ) ;\r
197         }\r
198 \r
199         return e ;\r
200 }\r
201 \r
202 // HR Processor.\r
203 // This is a IE only (tricky) thing. We protect all HR tags before loading them\r
204 // (see FCK.ProtectTags). Here we put the HRs back.\r
205 if ( FCKBrowserInfo.IsIE )\r
206 {\r
207         FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )\r
208         {\r
209                 var aHRs = document.getElementsByTagName( 'HR' ) ;\r
210 \r
211                 var eHR ;\r
212                 var i = aHRs.length - 1 ;\r
213                 while ( i >= 0 && ( eHR = aHRs[i--] ) )\r
214                 {\r
215                         // Create the replacement HR.\r
216                         var newHR = document.createElement( 'hr' ) ;\r
217                         newHR.mergeAttributes( eHR, true ) ;\r
218 \r
219                         // We must insert the new one after it. insertBefore will not work in all cases.\r
220                         FCKDomTools.InsertAfterNode( eHR, newHR ) ;\r
221 \r
222                         eHR.parentNode.removeChild( eHR ) ;\r
223                 }\r
224         }\r
225 }\r
226 \r
227 // INPUT:hidden Processor.\r
228 FCKDocumentProcessor.AppendNew().ProcessDocument = function( document )\r
229 {\r
230         var aInputs = document.getElementsByTagName( 'INPUT' ) ;\r
231 \r
232         var oInput ;\r
233         var i = aInputs.length - 1 ;\r
234         while ( i >= 0 && ( oInput = aInputs[i--] ) )\r
235         {\r
236                 if ( oInput.type == 'hidden' )\r
237                 {\r
238                         var oImg = FCKDocumentProcessor_CreateFakeImage( 'FCK__InputHidden', oInput.cloneNode(true) ) ;\r
239                         oImg.setAttribute( '_fckinputhidden', 'true', 0 ) ;\r
240 \r
241                         oInput.parentNode.insertBefore( oImg, oInput ) ;\r
242                         oInput.parentNode.removeChild( oInput ) ;\r
243                 }\r
244         }\r
245 }\r
246 \r
247 // Flash handler.\r
248 FCKEmbedAndObjectProcessor.AddCustomHandler( function( el, fakeImg )\r
249         {\r
250                 if ( ! ( el.nodeName.IEquals( 'embed' ) && ( el.type == 'application/x-shockwave-flash' || /\.swf($|#|\?)/i.test( el.src ) ) ) )\r
251                         return ;\r
252                 fakeImg.className = 'FCK__Flash' ;\r
253                 fakeImg.setAttribute( '_fckflash', 'true', 0 );\r
254         } ) ;\r
255 \r
256 // Buggy <span class="Apple-style-span"> tags added by Safari.\r
257 if ( FCKBrowserInfo.IsSafari )\r
258 {\r
259         FCKDocumentProcessor.AppendNew().ProcessDocument = function( doc )\r
260         {\r
261                 var spans = doc.getElementsByClassName ?\r
262                         doc.getElementsByClassName( 'Apple-style-span' ) :\r
263                         Array.prototype.filter.call(\r
264                                         doc.getElementsByTagName( 'span' ),\r
265                                         function( item ){ return item.className == 'Apple-style-span' ; }\r
266                                         ) ;\r
267                 for ( var i = spans.length - 1 ; i >= 0 ; i-- )\r
268                         FCKDomTools.RemoveNode( spans[i], true ) ;\r
269         }\r
270 }\r