PluginProbe
Wp-Insert / 1.7.2
Wp-Insert v1.7.2
trunk 1.0 1.1 1.2 1.2.1 1.2.2 1.3.0 1.3.1 1.3.3 1.4 1.5.0 1.5.1 1.5.2 1.5.3 1.6.0 1.6.1 1.6.2 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 2.0 All 63 releases
wp-insert / fckeditor / editor / _source / classes / fckeditingarea.js

fckeditingarea.js in Wp-Insert 1.7.2, at fckeditor/editor/_source/classes/fckeditingarea.js

369 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 */
28 var 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 */
41 FCKEditingArea.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
208 function 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
228 FCKEditingArea.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)
278 function 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.
291 function 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
302 FCKEditingArea.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
325 FCKEditingArea.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
354 function FCKEditingArea_Cleanup()
355 {
356 if ( this.Document )
357 this.Document.body.innerHTML = "" ;
358 this.TargetElement = null ;
359 this.IFrame = null ;
360 this.Document = null ;
361 this.Textarea = null ;
362
363 if ( this.Window )
364 {
365 this.Window._FCKEditingArea = null ;
366 this.Window = null ;
367 }
368 }
369