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