source: sandbox/filemanager/tp/fckeditor/editor/_source/classes/fckeditingarea.js @ 1575

Revision 1575, 11.6 KB checked in by amuller, 14 years ago (diff)

Ticket #597 - Implentação, melhorias do modulo gerenciador de arquivos

  • Property svn:executable set to *
Line 
1/*
2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
3 * Copyright (C) 2003-2009 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 * FCKEditingArea Class: renders an editable area.
22 */
23
24/**
25 * @constructor
26 * @param {String} targetElement The element that will hold the editing area. Any child element present in the target will be deleted.
27 */
28var FCKEditingArea = function( targetElement )
29{
30        this.TargetElement = targetElement ;
31        this.Mode = FCK_EDITMODE_WYSIWYG ;
32
33        if ( FCK.IECleanup )
34                FCK.IECleanup.AddItem( this, FCKEditingArea_Cleanup ) ;
35}
36
37
38/**
39 * @param {String} html The complete HTML for the page, including DOCTYPE and the <html> tag.
40 */
41FCKEditingArea.prototype.Start = function( html, secondCall )
42{
43        var eTargetElement      = this.TargetElement ;
44        var oTargetDocument     = FCKTools.GetElementDocument( eTargetElement ) ;
45
46        // Remove all child nodes from the target.
47        while( eTargetElement.firstChild )
48                eTargetElement.removeChild( eTargetElement.firstChild ) ;
49
50        if ( this.Mode == FCK_EDITMODE_WYSIWYG )
51        {
52                // For FF, document.domain must be set only when different, otherwhise
53                // we'll strangely have "Permission denied" issues.
54                if ( FCK_IS_CUSTOM_DOMAIN )
55                        html = '<script>document.domain="' + FCK_RUNTIME_DOMAIN + '";</script>' + html ;
56
57                // IE has a bug with the <base> tag... it must have a </base> closer,
58                // otherwise the all successive tags will be set as children nodes of the <base>.
59                if ( FCKBrowserInfo.IsIE )
60                        html = html.replace( /(<base[^>]*?)\s*\/?>(?!\s*<\/base>)/gi, '$1></base>' ) ;
61                else if ( !secondCall )
62                {
63                        // Gecko moves some tags out of the body to the head, so we must use
64                        // innerHTML to set the body contents (SF BUG 1526154).
65
66                        // Extract the BODY contents from the html.
67                        var oMatchBefore = html.match( FCKRegexLib.BeforeBody ) ;
68                        var oMatchAfter = html.match( FCKRegexLib.AfterBody ) ;
69
70                        if ( oMatchBefore && oMatchAfter )
71                        {
72                                var sBody = html.substr( oMatchBefore[1].length,
73                                               html.length - oMatchBefore[1].length - oMatchAfter[1].length ) ; // This is the BODY tag contents.
74
75                                html =
76                                        oMatchBefore[1] +                       // This is the HTML until the <body...> tag, inclusive.
77                                        '&nbsp;' +
78                                        oMatchAfter[1] ;                        // This is the HTML from the </body> tag, inclusive.
79
80                                // If nothing in the body, place a BOGUS tag so the cursor will appear.
81                                if ( FCKBrowserInfo.IsGecko && ( sBody.length == 0 || FCKRegexLib.EmptyParagraph.test( sBody ) ) )
82                                        sBody = '<br type="_moz">' ;
83
84                                this._BodyHTML = sBody ;
85
86                        }
87                        else
88                                this._BodyHTML = html ;                 // Invalid HTML input.
89                }
90
91                // Create the editing area IFRAME.
92                var oIFrame = this.IFrame = oTargetDocument.createElement( 'iframe' ) ;
93
94                // IE: Avoid JavaScript errors thrown by the editing are source (like tags events).
95                // See #1055.
96                var sOverrideError = '<script type="text/javascript" _fcktemp="true">window.onerror=function(){return true;};</script>' ;
97
98                oIFrame.frameBorder = 0 ;
99                oIFrame.style.width = oIFrame.style.height = '100%' ;
100
101                if ( FCK_IS_CUSTOM_DOMAIN && FCKBrowserInfo.IsIE )
102                {
103                        window._FCKHtmlToLoad = html.replace( /<head>/i, '<head>' + sOverrideError ) ;
104                        oIFrame.src = 'javascript:void( (function(){' +
105                                'document.open() ;' +
106                                'document.domain="' + document.domain + '" ;' +
107                                'document.write( window.parent._FCKHtmlToLoad );' +
108                                'document.close() ;' +
109                                'window.parent._FCKHtmlToLoad = null ;' +
110                                '})() )' ;
111                }
112                else if ( !FCKBrowserInfo.IsGecko )
113                {
114                        // Firefox will render the tables inside the body in Quirks mode if the
115                        // source of the iframe is set to javascript. see #515
116                        oIFrame.src = 'javascript:void(0)' ;
117                }
118
119                // Append the new IFRAME to the target. For IE, it must be done after
120                // setting the "src", to avoid the "secure/unsecure" message under HTTPS.
121                eTargetElement.appendChild( oIFrame ) ;
122
123                // Get the window and document objects used to interact with the newly created IFRAME.
124                this.Window = oIFrame.contentWindow ;
125
126                // IE: Avoid JavaScript errors thrown by the editing are source (like tags events).
127                // TODO: This error handler is not being fired.
128                // this.Window.onerror = function() { alert( 'Error!' ) ; return true ; }
129
130                if ( !FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE )
131                {
132                        var oDoc = this.Window.document ;
133
134                        oDoc.open() ;
135                        oDoc.write( html.replace( /<head>/i, '<head>' + sOverrideError ) ) ;
136                        oDoc.close() ;
137                }
138
139                if ( FCKBrowserInfo.IsAIR )
140                        FCKAdobeAIR.EditingArea_Start( oDoc, html ) ;
141
142                // Firefox 1.0.x is buggy... ohh yes... so let's do it two times and it
143                // will magically work.
144                if ( FCKBrowserInfo.IsGecko10 && !secondCall )
145                {
146                        this.Start( html, true ) ;
147                        return ;
148                }
149
150                if ( oIFrame.readyState && oIFrame.readyState != 'completed' )
151                {
152                        var editArea = this ;
153
154                        // Using a IE alternative for DOMContentLoaded, similar to the
155                        // solution proposed at http://javascript.nwbox.com/IEContentLoaded/
156                        setTimeout( function()
157                                        {
158                                                try
159                                                {
160                                                        editArea.Window.document.documentElement.doScroll("left") ;
161                                                }
162                                                catch(e)
163                                                {
164                                                        setTimeout( arguments.callee, 0 ) ;
165                                                        return ;
166                                                }
167                                                editArea.Window._FCKEditingArea = editArea ;
168                                                FCKEditingArea_CompleteStart.call( editArea.Window ) ;
169                                        }, 0 ) ;
170                }
171                else
172                {
173                        this.Window._FCKEditingArea = this ;
174
175                        // FF 1.0.x is buggy... we must wait a lot to enable editing because
176                        // sometimes the content simply disappears, for example when pasting
177                        // "bla1!<img src='some_url'>!bla2" in the source and then switching
178                        // back to design.
179                        if ( FCKBrowserInfo.IsGecko10 )
180                                this.Window.setTimeout( FCKEditingArea_CompleteStart, 500 ) ;
181                        else
182                                FCKEditingArea_CompleteStart.call( this.Window ) ;
183                }
184        }
185        else
186        {
187                var eTextarea = this.Textarea = oTargetDocument.createElement( 'textarea' ) ;
188                eTextarea.className = 'SourceField' ;
189                eTextarea.dir = 'ltr' ;
190                FCKDomTools.SetElementStyles( eTextarea,
191                        {
192                                width   : '100%',
193                                height  : '100%',
194                                border  : 'none',
195                                resize  : 'none',
196                                outline : 'none'
197                        } ) ;
198                eTargetElement.appendChild( eTextarea ) ;
199
200                eTextarea.value = html  ;
201
202                // Fire the "OnLoad" event.
203                FCKTools.RunFunction( this.OnLoad ) ;
204        }
205}
206
207// "this" here is FCKEditingArea.Window
208function FCKEditingArea_CompleteStart()
209{
210        // On Firefox, the DOM takes a little to become available. So we must wait for it in a loop.
211        if ( !this.document.body )
212        {
213                this.setTimeout( FCKEditingArea_CompleteStart, 50 ) ;
214                return ;
215        }
216
217        var oEditorArea = this._FCKEditingArea ;
218
219        // Save this reference to be re-used later.
220        oEditorArea.Document = oEditorArea.Window.document ;
221
222        oEditorArea.MakeEditable() ;
223
224        // Fire the "OnLoad" event.
225        FCKTools.RunFunction( oEditorArea.OnLoad ) ;
226}
227
228FCKEditingArea.prototype.MakeEditable = function()
229{
230        var oDoc = this.Document ;
231
232        if ( FCKBrowserInfo.IsIE )
233        {
234                // Kludge for #141 and #523
235                oDoc.body.disabled = true ;
236                oDoc.body.contentEditable = true ;
237                oDoc.body.removeAttribute( "disabled" ) ;
238
239                /* The following commands don't throw errors, but have no effect.
240                oDoc.execCommand( 'AutoDetect', false, false ) ;
241                oDoc.execCommand( 'KeepSelection', false, true ) ;
242                */
243        }
244        else
245        {
246                try
247                {
248                        // Disable Firefox 2 Spell Checker.
249                        oDoc.body.spellcheck = ( this.FFSpellChecker !== false ) ;
250
251                        if ( this._BodyHTML )
252                        {
253                                oDoc.body.innerHTML = this._BodyHTML ;
254                                oDoc.body.offsetLeft ;          // Don't remove, this is a hack to fix Opera 9.50, see #2264.
255                                this._BodyHTML = null ;
256                        }
257
258                        oDoc.designMode = 'on' ;
259
260                        // Tell Gecko (Firefox 1.5+) to enable or not live resizing of objects (by Alfonso Martinez)
261                        oDoc.execCommand( 'enableObjectResizing', false, !FCKConfig.DisableObjectResizing ) ;
262
263                        // Disable the standard table editing features of Firefox.
264                        oDoc.execCommand( 'enableInlineTableEditing', false, !FCKConfig.DisableFFTableHandles ) ;
265                }
266                catch (e)
267                {
268                        // In Firefox if the iframe is initially hidden it can't be set to designMode and it raises an exception
269                        // So we set up a DOM Mutation event Listener on the HTML, as it will raise several events when the document is  visible again
270                        FCKTools.AddEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ;
271                }
272
273        }
274}
275
276// This function processes the notifications of the DOM Mutation event on the document
277// We use it to know that the document will be ready to be editable again (or we hope so)
278function FCKEditingArea_Document_AttributeNodeModified( evt )
279{
280        var editingArea = evt.currentTarget.contentWindow._FCKEditingArea ;
281
282        // We want to run our function after the events no longer fire, so we can know that it's a stable situation
283        if ( editingArea._timer )
284                window.clearTimeout( editingArea._timer ) ;
285
286        editingArea._timer = FCKTools.SetTimeout( FCKEditingArea_MakeEditableByMutation, 1000, editingArea ) ;
287}
288
289// This function ideally should be called after the document is visible, it does clean up of the
290// mutation tracking and tries again to make the area editable.
291function FCKEditingArea_MakeEditableByMutation()
292{
293        // Clean up
294        delete this._timer ;
295        // Now we don't want to keep on getting this event
296        FCKTools.RemoveEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ;
297        // Let's try now to set the editing area editable
298        // If it fails it will set up the Mutation Listener again automatically
299        this.MakeEditable() ;
300}
301
302FCKEditingArea.prototype.Focus = function()
303{
304        try
305        {
306                if ( this.Mode == FCK_EDITMODE_WYSIWYG )
307                {
308                        if ( FCKBrowserInfo.IsIE )
309                                this._FocusIE() ;
310                        else
311                                this.Window.focus() ;
312                }
313                else
314                {
315                        var oDoc = FCKTools.GetElementDocument( this.Textarea ) ;
316                        if ( (!oDoc.hasFocus || oDoc.hasFocus() ) && oDoc.activeElement == this.Textarea )
317                                return ;
318
319                        this.Textarea.focus() ;
320                }
321        }
322        catch(e) {}
323}
324
325FCKEditingArea.prototype._FocusIE = function()
326{
327        // In IE it can happen that the document is in theory focused but the
328        // active element is outside of it.
329        this.Document.body.setActive() ;
330
331        this.Window.focus() ;
332
333        // Kludge for #141... yet more code to workaround IE bugs
334        var range = this.Document.selection.createRange() ;
335
336        var parentNode = range.parentElement() ;
337        var parentTag = parentNode.nodeName.toLowerCase() ;
338
339        // Only apply the fix when in a block, and the block is empty.
340        if ( parentNode.childNodes.length > 0 ||
341                 !( FCKListsLib.BlockElements[parentTag] ||
342                    FCKListsLib.NonEmptyBlockElements[parentTag] ) )
343        {
344                return ;
345        }
346
347        // Force the selection to happen, in this way we guarantee the focus will
348        // be there.
349        range = new FCKDomRange( this.Window ) ;
350        range.MoveToElementEditStart( parentNode ) ;
351        range.Select() ;
352}
353
354function FCKEditingArea_Cleanup()
355{
356        if ( this.Document )
357        {
358                // Avoid IE crash if an object is selected on unload #2201
359                this.Document.selection.empty() ;
360                this.Document.body.innerHTML = "" ;
361        }
362        this.TargetElement = null ;
363        this.IFrame = null ;
364        this.Document = null ;
365        this.Textarea = null ;
366
367        if ( this.Window )
368        {
369                this.Window._FCKEditingArea = null ;
370                this.Window = null ;
371        }
372}
Note: See TracBrowser for help on using the repository browser.