]> git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/blame - sources/plugins/wysiwygarea/plugin.js
Update to 4.7.3
[perso/Immae/Projets/packagist/ludivine-ckeditor-component.git] / sources / plugins / wysiwygarea / plugin.js
CommitLineData
c63493c8
IB
1/**\r
2 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
3 * For licensing, see LICENSE.md or http://ckeditor.com/license\r
4 */\r
5\r
6/**\r
7 * @fileOverview The WYSIWYG Area plugin. It registers the "wysiwyg" editing\r
8 * mode, which handles the main editing area space.\r
9 */\r
10\r
11( function() {\r
12 var framedWysiwyg;\r
13\r
14 CKEDITOR.plugins.add( 'wysiwygarea', {\r
15 init: function( editor ) {\r
16 if ( editor.config.fullPage ) {\r
17 editor.addFeature( {\r
18 allowedContent: 'html head title; style [media,type]; body (*)[id]; meta link [*]',\r
19 requiredContent: 'body'\r
20 } );\r
21 }\r
22\r
23 editor.addMode( 'wysiwyg', function( callback ) {\r
24 var src = 'document.open();' +\r
25 // In IE, the document domain must be set any time we call document.open().\r
26 ( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) +\r
27 'document.close();';\r
28\r
29 // With IE, the custom domain has to be taken care at first,\r
30 // for other browers, the 'src' attribute should be left empty to\r
31 // trigger iframe's 'load' event.\r
1794320d 32 // Microsoft Edge throws "Permission Denied" if treated like an IE (http://dev.ckeditor.com/ticket/13441).\r
c63493c8
IB
33 if ( CKEDITOR.env.air ) {\r
34 src = 'javascript:void(0)'; // jshint ignore:line\r
35 } else if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {\r
36 src = 'javascript:void(function(){' + encodeURIComponent( src ) + '}())'; // jshint ignore:line\r
37 } else {\r
38 src = '';\r
39 }\r
40\r
41 var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="' + src + '" frameBorder="0"></iframe>' );\r
42 iframe.setStyles( { width: '100%', height: '100%' } );\r
43 iframe.addClass( 'cke_wysiwyg_frame' ).addClass( 'cke_reset' );\r
44\r
45 var contentSpace = editor.ui.space( 'contents' );\r
46 contentSpace.append( iframe );\r
47\r
48\r
49 // Asynchronous iframe loading is only required in IE>8 and Gecko (other reasons probably).\r
50 // Do not use it on WebKit as it'll break the browser-back navigation.\r
51 var useOnloadEvent = ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) || CKEDITOR.env.gecko;\r
52 if ( useOnloadEvent )\r
53 iframe.on( 'load', onLoad );\r
54\r
55 var frameLabel = editor.title,\r
56 helpLabel = editor.fire( 'ariaEditorHelpLabel', {} ).label;\r
57\r
58 if ( frameLabel ) {\r
59 if ( CKEDITOR.env.ie && helpLabel )\r
60 frameLabel += ', ' + helpLabel;\r
61\r
62 iframe.setAttribute( 'title', frameLabel );\r
63 }\r
64\r
65 if ( helpLabel ) {\r
66 var labelId = CKEDITOR.tools.getNextId(),\r
67 desc = CKEDITOR.dom.element.createFromHtml( '<span id="' + labelId + '" class="cke_voice_label">' + helpLabel + '</span>' );\r
68\r
69 contentSpace.append( desc, 1 );\r
70 iframe.setAttribute( 'aria-describedby', labelId );\r
71 }\r
72\r
73 // Remove the ARIA description.\r
74 editor.on( 'beforeModeUnload', function( evt ) {\r
75 evt.removeListener();\r
76 if ( desc )\r
77 desc.remove();\r
78 } );\r
79\r
80 iframe.setAttributes( {\r
81 tabIndex: editor.tabIndex,\r
82 allowTransparency: 'true'\r
83 } );\r
84\r
85 // Execute onLoad manually for all non IE||Gecko browsers.\r
86 !useOnloadEvent && onLoad();\r
87\r
88 editor.fire( 'ariaWidget', iframe );\r
89\r
90 function onLoad( evt ) {\r
91 evt && evt.removeListener();\r
92 editor.editable( new framedWysiwyg( editor, iframe.$.contentWindow.document.body ) );\r
93 editor.setData( editor.getData( 1 ), callback );\r
94 }\r
95 } );\r
96 }\r
97 } );\r
98\r
99 /**\r
100 * Adds the path to a stylesheet file to the exisiting {@link CKEDITOR.config#contentsCss} value.\r
101 *\r
102 * **Note:** This method is available only with the `wysiwygarea` plugin and only affects\r
103 * classic editors based on it (so it does not affect inline editors).\r
104 *\r
105 * editor.addContentsCss( 'assets/contents.css' );\r
106 *\r
107 * @since 4.4\r
108 * @param {String} cssPath The path to the stylesheet file which should be added.\r
109 * @member CKEDITOR.editor\r
110 */\r
111 CKEDITOR.editor.prototype.addContentsCss = function( cssPath ) {\r
112 var cfg = this.config,\r
113 curContentsCss = cfg.contentsCss;\r
114\r
115 // Convert current value into array.\r
116 if ( !CKEDITOR.tools.isArray( curContentsCss ) )\r
117 cfg.contentsCss = curContentsCss ? [ curContentsCss ] : [];\r
118\r
119 cfg.contentsCss.push( cssPath );\r
120 };\r
121\r
122 function onDomReady( win ) {\r
123 var editor = this.editor,\r
124 doc = win.document,\r
125 body = doc.body;\r
126\r
127 // Remove helper scripts from the DOM.\r
128 var script = doc.getElementById( 'cke_actscrpt' );\r
129 script && script.parentNode.removeChild( script );\r
130 script = doc.getElementById( 'cke_shimscrpt' );\r
131 script && script.parentNode.removeChild( script );\r
132 script = doc.getElementById( 'cke_basetagscrpt' );\r
133 script && script.parentNode.removeChild( script );\r
134\r
135 body.contentEditable = true;\r
136\r
137 if ( CKEDITOR.env.ie ) {\r
138 // Don't display the focus border.\r
139 body.hideFocus = true;\r
140\r
141 // Disable and re-enable the body to avoid IE from\r
1794320d 142 // taking the editing focus at startup. (http://dev.ckeditor.com/ticket/141 / http://dev.ckeditor.com/ticket/523)\r
c63493c8
IB
143 body.disabled = true;\r
144 body.removeAttribute( 'disabled' );\r
145 }\r
146\r
147 delete this._.isLoadingData;\r
148\r
149 // Play the magic to alter element reference to the reloaded one.\r
150 this.$ = body;\r
151\r
152 doc = new CKEDITOR.dom.document( doc );\r
153\r
154 this.setup();\r
155 this.fixInitialSelection();\r
156\r
157 var editable = this;\r
158\r
1794320d 159 // Without it IE8 has problem with removing selection in nested editable. (http://dev.ckeditor.com/ticket/13785)\r
c63493c8
IB
160 if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {\r
161 doc.getDocumentElement().addClass( doc.$.compatMode );\r
162 }\r
163\r
1794320d 164 // Prevent IE/Edge from leaving a new paragraph/div after deleting all contents in body. (http://dev.ckeditor.com/ticket/6966, http://dev.ckeditor.com/ticket/13142)\r
c63493c8
IB
165 if ( CKEDITOR.env.ie && !CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_P ) {\r
166 removeSuperfluousElement( 'p' );\r
167 } else if ( CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_DIV ) {\r
168 removeSuperfluousElement( 'div' );\r
169 }\r
170\r
1794320d 171 // Fix problem with cursor not appearing in Webkit and IE11+ when clicking below the body (http://dev.ckeditor.com/ticket/10945, http://dev.ckeditor.com/ticket/10906).\r
c63493c8
IB
172 // Fix for older IEs (8-10 and QM) is placed inside selection.js.\r
173 if ( CKEDITOR.env.webkit || ( CKEDITOR.env.ie && CKEDITOR.env.version > 10 ) ) {\r
174 doc.getDocumentElement().on( 'mousedown', function( evt ) {\r
175 if ( evt.data.getTarget().is( 'html' ) ) {\r
176 // IE needs this timeout. Webkit does not, but it does not cause problems too.\r
177 setTimeout( function() {\r
178 editor.editable().focus();\r
179 } );\r
180 }\r
181 } );\r
182 }\r
183\r
184 // Config props: disableObjectResizing and disableNativeTableHandles handler.\r
185 objectResizeDisabler( editor );\r
186\r
187 // Enable dragging of position:absolute elements in IE.\r
188 try {\r
189 editor.document.$.execCommand( '2D-position', false, true );\r
190 } catch ( e ) {}\r
191\r
192 if ( CKEDITOR.env.gecko || CKEDITOR.env.ie && editor.document.$.compatMode == 'CSS1Compat' ) {\r
193 this.attachListener( this, 'keydown', function( evt ) {\r
194 var keyCode = evt.data.getKeystroke();\r
195\r
196 // PageUp OR PageDown\r
197 if ( keyCode == 33 || keyCode == 34 ) {\r
198 // PageUp/PageDown scrolling is broken in document\r
1794320d 199 // with standard doctype, manually fix it. (http://dev.ckeditor.com/ticket/4736)\r
c63493c8
IB
200 if ( CKEDITOR.env.ie ) {\r
201 setTimeout( function() {\r
202 editor.getSelection().scrollIntoView();\r
203 }, 0 );\r
204 }\r
205 // Page up/down cause editor selection to leak\r
206 // outside of editable thus we try to intercept\r
207 // the behavior, while it affects only happen\r
1794320d 208 // when editor contents are not overflowed. (http://dev.ckeditor.com/ticket/7955)\r
c63493c8
IB
209 else if ( editor.window.$.innerHeight > this.$.offsetHeight ) {\r
210 var range = editor.createRange();\r
211 range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd' ]( this );\r
212 range.select();\r
213 evt.data.preventDefault();\r
214 }\r
215 }\r
216 } );\r
217 }\r
218\r
219 if ( CKEDITOR.env.ie ) {\r
220 // [IE] Iframe will still keep the selection when blurred, if\r
221 // focus is moved onto a non-editing host, e.g. link or button, but\r
222 // it becomes a problem for the object type selection, since the resizer\r
223 // handler attached on it will mark other part of the UI, especially\r
1794320d 224 // for the dialog. (http://dev.ckeditor.com/ticket/8157)\r
c63493c8 225 // [IE<8 & Opera] Even worse For old IEs, the cursor will not vanish even if\r
1794320d 226 // the selection has been moved to another text input in some cases. (http://dev.ckeditor.com/ticket/4716)\r
c63493c8
IB
227 //\r
228 // Now the range restore is disabled, so we simply force IE to clean\r
229 // up the selection before blur.\r
230 this.attachListener( doc, 'blur', function() {\r
1794320d 231 // Error proof when the editor is not visible. (http://dev.ckeditor.com/ticket/6375)\r
c63493c8
IB
232 try {\r
233 doc.$.selection.empty();\r
234 } catch ( er ) {}\r
235 } );\r
236 }\r
237\r
238 if ( CKEDITOR.env.iOS ) {\r
239 // [iOS] If touch is bound to any parent of the iframe blur happens on any touch\r
1794320d 240 // event and body becomes the focused element (http://dev.ckeditor.com/ticket/10714).\r
c63493c8
IB
241 this.attachListener( doc, 'touchend', function() {\r
242 win.focus();\r
243 } );\r
244 }\r
245\r
246 var title = editor.document.getElementsByTag( 'title' ).getItem( 0 );\r
1794320d 247 // document.title is malfunctioning on Chrome, so get value from the element (http://dev.ckeditor.com/ticket/12402).\r
c63493c8
IB
248 title.data( 'cke-title', title.getText() );\r
249\r
250 // [IE] JAWS will not recognize the aria label we used on the iframe\r
251 // unless the frame window title string is used as the voice label,\r
252 // backup the original one and restore it on output.\r
253 if ( CKEDITOR.env.ie )\r
254 editor.document.$.title = this._.docTitle;\r
255\r
256 CKEDITOR.tools.setTimeout( function() {\r
257 // Editable is ready after first setData.\r
258 if ( this.status == 'unloaded' )\r
259 this.status = 'ready';\r
260\r
261 editor.fire( 'contentDom' );\r
262\r
263 if ( this._.isPendingFocus ) {\r
264 editor.focus();\r
265 this._.isPendingFocus = false;\r
266 }\r
267\r
268 setTimeout( function() {\r
269 editor.fire( 'dataReady' );\r
270 }, 0 );\r
271 }, 0, this );\r
272\r
273 function removeSuperfluousElement( tagName ) {\r
274 var lockRetain = false;\r
275\r
276 // Superfluous elements appear after keydown\r
277 // and before keyup, so the procedure is as follows:\r
278 // 1. On first keydown mark all elements with\r
279 // a specified tag name as non-superfluous.\r
280 editable.attachListener( editable, 'keydown', function() {\r
281 var body = doc.getBody(),\r
282 retained = body.getElementsByTag( tagName );\r
283\r
284 if ( !lockRetain ) {\r
285 for ( var i = 0; i < retained.count(); i++ ) {\r
286 retained.getItem( i ).setCustomData( 'retain', true );\r
287 }\r
288 lockRetain = true;\r
289 }\r
290 }, null, null, 1 );\r
291\r
292 // 2. On keyup remove all elements that were not marked\r
293 // as non-superfluous (which means they must have had appeared in the meantime).\r
294 // Also we should preserve all temporary elements inserted by editor – otherwise we'd likely\r
1794320d 295 // leak fake selection's content into editable due to removing hidden selection container (http://dev.ckeditor.com/ticket/14831).\r
c63493c8
IB
296 editable.attachListener( editable, 'keyup', function() {\r
297 var elements = doc.getElementsByTag( tagName );\r
298 if ( lockRetain ) {\r
299 if ( elements.count() == 1 && !elements.getItem( 0 ).getCustomData( 'retain' ) &&\r
300 !elements.getItem( 0 ).hasAttribute( 'data-cke-temp' ) ) {\r
301 elements.getItem( 0 ).remove( 1 );\r
302 }\r
303 lockRetain = false;\r
304 }\r
305 } );\r
306 }\r
307 }\r
308\r
309 framedWysiwyg = CKEDITOR.tools.createClass( {\r
310 $: function() {\r
311 this.base.apply( this, arguments );\r
312\r
313 this._.frameLoadedHandler = CKEDITOR.tools.addFunction( function( win ) {\r
314 // Avoid opening design mode in a frame window thread,\r
1794320d 315 // which will cause host page scrolling.(http://dev.ckeditor.com/ticket/4397)\r
c63493c8
IB
316 CKEDITOR.tools.setTimeout( onDomReady, 0, this, win );\r
317 }, this );\r
318\r
319 this._.docTitle = this.getWindow().getFrame().getAttribute( 'title' );\r
320 },\r
321\r
322 base: CKEDITOR.editable,\r
323\r
324 proto: {\r
325 setData: function( data, isSnapshot ) {\r
326 var editor = this.editor;\r
327\r
328 if ( isSnapshot ) {\r
329 this.setHtml( data );\r
330 this.fixInitialSelection();\r
331\r
332 // Fire dataReady for the consistency with inline editors\r
1794320d 333 // and because it makes sense. (http://dev.ckeditor.com/ticket/10370)\r
c63493c8
IB
334 editor.fire( 'dataReady' );\r
335 }\r
336 else {\r
337 this._.isLoadingData = true;\r
338 editor._.dataStore = { id: 1 };\r
339\r
340 var config = editor.config,\r
341 fullPage = config.fullPage,\r
342 docType = config.docType;\r
343\r
344 // Build the additional stuff to be included into <head>.\r
345 var headExtra = CKEDITOR.tools.buildStyleHtml( iframeCssFixes() ).replace( /<style>/, '<style data-cke-temp="1">' );\r
346\r
347 if ( !fullPage )\r
348 headExtra += CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss );\r
349\r
350 var baseTag = config.baseHref ? '<base href="' + config.baseHref + '" data-cke-temp="1" />' : '';\r
351\r
352 if ( fullPage ) {\r
353 // Search and sweep out the doctype declaration.\r
354 data = data.replace( /<!DOCTYPE[^>]*>/i, function( match ) {\r
355 editor.docType = docType = match;\r
356 return '';\r
357 } ).replace( /<\?xml\s[^\?]*\?>/i, function( match ) {\r
358 editor.xmlDeclaration = match;\r
359 return '';\r
360 } );\r
361 }\r
362\r
363 // Get the HTML version of the data.\r
364 data = editor.dataProcessor.toHtml( data );\r
365\r
366 if ( fullPage ) {\r
367 // Check if the <body> tag is available.\r
368 if ( !( /<body[\s|>]/ ).test( data ) )\r
369 data = '<body>' + data;\r
370\r
371 // Check if the <html> tag is available.\r
372 if ( !( /<html[\s|>]/ ).test( data ) )\r
373 data = '<html>' + data + '</html>';\r
374\r
375 // Check if the <head> tag is available.\r
376 if ( !( /<head[\s|>]/ ).test( data ) )\r
377 data = data.replace( /<html[^>]*>/, '$&<head><title></title></head>' );\r
378 else if ( !( /<title[\s|>]/ ).test( data ) )\r
379 data = data.replace( /<head[^>]*>/, '$&<title></title>' );\r
380\r
381 // The base must be the first tag in the HEAD, e.g. to get relative\r
382 // links on styles.\r
383 baseTag && ( data = data.replace( /<head[^>]*?>/, '$&' + baseTag ) );\r
384\r
385 // Inject the extra stuff into <head>.\r
386 // Attention: do not change it before testing it well. (V2)\r
387 // This is tricky... if the head ends with <meta ... content type>,\r
388 // Firefox will break. But, it works if we place our extra stuff as\r
389 // the last elements in the HEAD.\r
390 data = data.replace( /<\/head\s*>/, headExtra + '$&' );\r
391\r
392 // Add the DOCTYPE back to it.\r
393 data = docType + data;\r
394 } else {\r
395 data = config.docType +\r
396 '<html dir="' + config.contentsLangDirection + '"' +\r
397 ' lang="' + ( config.contentsLanguage || editor.langCode ) + '">' +\r
398 '<head>' +\r
399 '<title>' + this._.docTitle + '</title>' +\r
400 baseTag +\r
401 headExtra +\r
402 '</head>' +\r
403 '<body' + ( config.bodyId ? ' id="' + config.bodyId + '"' : '' ) +\r
404 ( config.bodyClass ? ' class="' + config.bodyClass + '"' : '' ) +\r
405 '>' +\r
406 data +\r
407 '</body>' +\r
408 '</html>';\r
409 }\r
410\r
411 if ( CKEDITOR.env.gecko ) {\r
412 // Hack to make Fx put cursor at the start of doc on fresh focus.\r
413 data = data.replace( /<body/, '<body contenteditable="true" ' );\r
414\r
415 // Another hack which is used by onDomReady to remove a leading\r
416 // <br> which is inserted by Firefox 3.6 when document.write is called.\r
417 // This additional <br> is present because of contenteditable="true"\r
418 if ( CKEDITOR.env.version < 20000 )\r
419 data = data.replace( /<body[^>]*>/, '$&<!-- cke-content-start -->' );\r
420 }\r
421\r
422 // The script that launches the bootstrap logic on 'domReady', so the document\r
1794320d 423 // is fully editable even before the editing iframe is fully loaded (http://dev.ckeditor.com/ticket/4455).\r
c63493c8
IB
424 var bootstrapCode =\r
425 '<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' +\r
426 'var wasLoaded=0;' + // It must be always set to 0 as it remains as a window property.\r
427 'function onload(){' +\r
428 'if(!wasLoaded)' + // FF3.6 calls onload twice when editor.setData. Stop that.\r
429 'window.parent.CKEDITOR.tools.callFunction(' + this._.frameLoadedHandler + ',window);' +\r
430 'wasLoaded=1;' +\r
431 '}' +\r
432 ( CKEDITOR.env.ie ? 'onload();' : 'document.addEventListener("DOMContentLoaded", onload, false );' ) +\r
433 '</script>';\r
434\r
435 // For IE<9 add support for HTML5's elements.\r
436 // Note: this code must not be deferred.\r
437 if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {\r
438 bootstrapCode +=\r
439 '<script id="cke_shimscrpt">' +\r
440 'window.parent.CKEDITOR.tools.enableHtml5Elements(document)' +\r
441 '</script>';\r
442 }\r
443\r
444 // IE<10 needs this hack to properly enable <base href="...">.\r
1794320d 445 // See: http://stackoverflow.com/a/13373180/1485219 (http://dev.ckeditor.com/ticket/11910).\r
c63493c8
IB
446 if ( baseTag && CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {\r
447 bootstrapCode +=\r
448 '<script id="cke_basetagscrpt">' +\r
449 'var baseTag = document.querySelector( "base" );' +\r
450 'baseTag.href = baseTag.href;' +\r
451 '</script>';\r
452 }\r
453\r
454 data = data.replace( /(?=\s*<\/(:?head)>)/, bootstrapCode );\r
455\r
456 // Current DOM will be deconstructed by document.write, cleanup required.\r
457 this.clearCustomData();\r
458 this.clearListeners();\r
459\r
460 editor.fire( 'contentDomUnload' );\r
461\r
462 var doc = this.getDocument();\r
463\r
1794320d 464 // Work around Firefox bug - error prune when called from XUL (http://dev.ckeditor.com/ticket/320),\r
c63493c8
IB
465 // defer it thanks to the async nature of this method.\r
466 try {\r
467 doc.write( data );\r
468 } catch ( e ) {\r
469 setTimeout( function() {\r
470 doc.write( data );\r
471 }, 0 );\r
472 }\r
473 }\r
474 },\r
475\r
476 getData: function( isSnapshot ) {\r
477 if ( isSnapshot )\r
478 return this.getHtml();\r
479 else {\r
480 var editor = this.editor,\r
481 config = editor.config,\r
482 fullPage = config.fullPage,\r
483 docType = fullPage && editor.docType,\r
484 xmlDeclaration = fullPage && editor.xmlDeclaration,\r
485 doc = this.getDocument();\r
486\r
487 var data = fullPage ? doc.getDocumentElement().getOuterHtml() : doc.getBody().getHtml();\r
488\r
1794320d 489 // BR at the end of document is bogus node for Mozilla. (http://dev.ckeditor.com/ticket/5293).\r
c63493c8 490 // Prevent BRs from disappearing from the end of the content\r
1794320d 491 // while enterMode is ENTER_BR (http://dev.ckeditor.com/ticket/10146).\r
c63493c8
IB
492 if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR )\r
493 data = data.replace( /<br>(?=\s*(:?$|<\/body>))/, '' );\r
494\r
495 data = editor.dataProcessor.toDataFormat( data );\r
496\r
497 if ( xmlDeclaration )\r
498 data = xmlDeclaration + '\n' + data;\r
499 if ( docType )\r
500 data = docType + '\n' + data;\r
501\r
502 return data;\r
503 }\r
504 },\r
505\r
506 focus: function() {\r
507 if ( this._.isLoadingData )\r
508 this._.isPendingFocus = true;\r
509 else\r
510 framedWysiwyg.baseProto.focus.call( this );\r
511 },\r
512\r
513 detach: function() {\r
514 var editor = this.editor,\r
515 doc = editor.document,\r
516 iframe,\r
517 onResize;\r
518\r
519 // Trying to access window's frameElement property on Edge throws an exception\r
1794320d 520 // when frame was already removed from DOM. (http://dev.ckeditor.com/ticket/13850, http://dev.ckeditor.com/ticket/13790)\r
c63493c8
IB
521 try {\r
522 iframe = editor.window.getFrame();\r
523 } catch ( e ) {}\r
524\r
525 framedWysiwyg.baseProto.detach.call( this );\r
526\r
527 // Memory leak proof.\r
528 this.clearCustomData();\r
529 doc.getDocumentElement().clearCustomData();\r
530 CKEDITOR.tools.removeFunction( this._.frameLoadedHandler );\r
531\r
532 // On IE, iframe is returned even after remove() method is called on it.\r
1794320d 533 // Checking if parent is present fixes this issue. (http://dev.ckeditor.com/ticket/13850)\r
c63493c8
IB
534 if ( iframe && iframe.getParent() ) {\r
535 iframe.clearCustomData();\r
536 onResize = iframe.removeCustomData( 'onResize' );\r
537 onResize && onResize.removeListener();\r
538\r
539 // IE BUG: When destroying editor DOM with the selection remains inside\r
540 // editing area would break IE7/8's selection system, we have to put the editing\r
1794320d 541 // iframe offline first. (http://dev.ckeditor.com/ticket/3812 and http://dev.ckeditor.com/ticket/5441)\r
c63493c8
IB
542 iframe.remove();\r
543 } else {\r
544 CKEDITOR.warn( 'editor-destroy-iframe' );\r
545 }\r
546 }\r
547 }\r
548 } );\r
549\r
550 function objectResizeDisabler( editor ) {\r
551 if ( CKEDITOR.env.gecko ) {\r
552 // FF allows to change resizing preferences by calling execCommand.\r
553 try {\r
554 var doc = editor.document.$;\r
555 doc.execCommand( 'enableObjectResizing', false, !editor.config.disableObjectResizing );\r
556 doc.execCommand( 'enableInlineTableEditing', false, !editor.config.disableNativeTableHandles );\r
557 } catch ( e ) {}\r
558 } else if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && editor.config.disableObjectResizing ) {\r
559 // It's possible to prevent resizing up to IE10.\r
560 blockResizeStart( editor );\r
561 }\r
562\r
563 // Disables resizing by preventing default action on resizestart event.\r
564 function blockResizeStart() {\r
565 var lastListeningElement;\r
566\r
567 // We'll attach only one listener at a time, instead of adding it to every img, input, hr etc.\r
568 // Listener will be attached upon selectionChange, we'll also check if there was any element that\r
569 // got listener before (lastListeningElement) - if so we need to remove previous listener.\r
570 editor.editable().attachListener( editor, 'selectionChange', function() {\r
571 var selectedElement = editor.getSelection().getSelectedElement();\r
572\r
573 if ( selectedElement ) {\r
574 if ( lastListeningElement ) {\r
575 lastListeningElement.detachEvent( 'onresizestart', resizeStartListener );\r
576 lastListeningElement = null;\r
577 }\r
578\r
579 // IE requires using attachEvent, because it does not work using W3C compilant addEventListener,\r
580 // tested with IE10.\r
581 selectedElement.$.attachEvent( 'onresizestart', resizeStartListener );\r
582 lastListeningElement = selectedElement.$;\r
583 }\r
584 } );\r
585 }\r
586\r
587 function resizeStartListener( evt ) {\r
588 evt.returnValue = false;\r
589 }\r
590 }\r
591\r
592 function iframeCssFixes() {\r
593 var css = [];\r
594\r
595 // IE>=8 stricts mode doesn't have 'contentEditable' in effect\r
1794320d 596 // on element unless it has layout. (http://dev.ckeditor.com/ticket/5562)\r
c63493c8
IB
597 if ( CKEDITOR.document.$.documentMode >= 8 ) {\r
598 css.push( 'html.CSS1Compat [contenteditable=false]{min-height:0 !important}' );\r
599\r
600 var selectors = [];\r
601\r
602 for ( var tag in CKEDITOR.dtd.$removeEmpty )\r
603 selectors.push( 'html.CSS1Compat ' + tag + '[contenteditable=false]' );\r
604\r
605 css.push( selectors.join( ',' ) + '{display:inline-block}' );\r
606 }\r
1794320d 607 // Set the HTML style to 100% to have the text cursor in affect (http://dev.ckeditor.com/ticket/6341)\r
c63493c8
IB
608 else if ( CKEDITOR.env.gecko ) {\r
609 css.push( 'html{height:100% !important}' );\r
610 css.push( 'img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}' );\r
611 }\r
612\r
1794320d
IB
613 // http://dev.ckeditor.com/ticket/6341: The text cursor must be set on the editor area.\r
614 // http://dev.ckeditor.com/ticket/6632: Avoid having "text" shape of cursor in IE7 scrollbars.\r
c63493c8
IB
615 css.push( 'html{cursor:text;*cursor:auto}' );\r
616\r
617 // Use correct cursor for these elements\r
618 css.push( 'img,input,textarea{cursor:default}' );\r
619\r
620 return css.join( '\n' );\r
621 }\r
622} )();\r
623\r
624/**\r
625 * Disables the ability to resize objects (images and tables) in the editing area.\r
626 *\r
627 * config.disableObjectResizing = true;\r
628 *\r
629 * **Note:** Because of incomplete implementation of editing features in browsers\r
630 * this option does not work for inline editors (see ticket [#10197](http://dev.ckeditor.com/ticket/10197)),\r
631 * does not work in Internet Explorer 11+ (see [#9317](http://dev.ckeditor.com/ticket/9317#comment:16) and\r
632 * [IE11+ issue](https://connect.microsoft.com/IE/feedback/details/742593/please-respect-execcommand-enableobjectresizing-in-contenteditable-elements)).\r
633 * In Internet Explorer 8-10 this option only blocks resizing, but it is unable to hide the resize handles.\r
634 *\r
635 * @cfg\r
636 * @member CKEDITOR.config\r
637 */\r
638CKEDITOR.config.disableObjectResizing = false;\r
639\r
640/**\r
641 * Disables the "table tools" offered natively by the browser (currently\r
642 * Firefox only) to perform quick table editing operations, like adding or\r
643 * deleting rows and columns.\r
644 *\r
645 * config.disableNativeTableHandles = false;\r
646 *\r
647 * @cfg\r
648 * @member CKEDITOR.config\r
649 */\r
650CKEDITOR.config.disableNativeTableHandles = true;\r
651\r
652/**\r
653 * Disables the built-in spell checker if the browser provides one.\r
654 *\r
655 * **Note:** Although word suggestions provided natively by the browsers will\r
656 * not appear in CKEditor's default context menu,\r
657 * users can always reach the native context menu by holding the\r
658 * *Ctrl* key when right-clicking if {@link #browserContextMenuOnCtrl}\r
659 * is enabled or you are simply not using the\r
660 * [context menu](http://ckeditor.com/addon/contextmenu) plugin.\r
661 *\r
662 * config.disableNativeSpellChecker = false;\r
663 *\r
664 * @cfg\r
665 * @member CKEDITOR.config\r
666 */\r
667CKEDITOR.config.disableNativeSpellChecker = true;\r
668\r
669/**\r
670 * Language code of the writing language which is used to author the editor\r
671 * content. This option accepts one single entry value in the format defined in the\r
672 * [Tags for Identifying Languages (BCP47)](http://www.ietf.org/rfc/bcp/bcp47.txt)\r
673 * IETF document and is used in the `lang` attribute.\r
674 *\r
675 * config.contentsLanguage = 'fr';\r
676 *\r
677 * @cfg {String} [contentsLanguage=same value with editor's UI language]\r
678 * @member CKEDITOR.config\r
679 */\r
680\r
681/**\r
682 * The base href URL used to resolve relative and absolute URLs in the\r
683 * editor content.\r
684 *\r
685 * config.baseHref = 'http://www.example.com/path/';\r
686 *\r
687 * @cfg {String} [baseHref='']\r
688 * @member CKEDITOR.config\r
689 */\r
690\r
691/**\r
692 * Whether to automatically create wrapping blocks around inline content inside the document body.\r
693 * This helps to ensure the integrity of the block *Enter* mode.\r
694 *\r
695 * **Note:** This option is deprecated. Changing the default value might introduce unpredictable usability issues and is\r
696 * highly unrecommended.\r
697 *\r
698 * config.autoParagraph = false;\r
699 *\r
700 * @deprecated\r
701 * @since 3.6\r
702 * @cfg {Boolean} [autoParagraph=true]\r
703 * @member CKEDITOR.config\r
704 */\r
705\r
706/**\r
707 * Fired when some elements are added to the document.\r
708 *\r
709 * @event ariaWidget\r
710 * @member CKEDITOR.editor\r
711 * @param {CKEDITOR.editor} editor This editor instance.\r
712 * @param {CKEDITOR.dom.element} data The element being added.\r
713 */\r