diff options
Diffstat (limited to 'sources/plugins/wysiwygarea/plugin.js')
-rw-r--r-- | sources/plugins/wysiwygarea/plugin.js | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/sources/plugins/wysiwygarea/plugin.js b/sources/plugins/wysiwygarea/plugin.js index a1ec9e6..1358129 100644 --- a/sources/plugins/wysiwygarea/plugin.js +++ b/sources/plugins/wysiwygarea/plugin.js | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. | 2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | 3 | * For licensing, see LICENSE.md or http://ckeditor.com/license |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -9,6 +9,8 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | ( function() { | 11 | ( function() { |
12 | var framedWysiwyg; | ||
13 | |||
12 | CKEDITOR.plugins.add( 'wysiwygarea', { | 14 | CKEDITOR.plugins.add( 'wysiwygarea', { |
13 | init: function( editor ) { | 15 | init: function( editor ) { |
14 | if ( editor.config.fullPage ) { | 16 | if ( editor.config.fullPage ) { |
@@ -27,7 +29,7 @@ | |||
27 | // With IE, the custom domain has to be taken care at first, | 29 | // With IE, the custom domain has to be taken care at first, |
28 | // for other browers, the 'src' attribute should be left empty to | 30 | // for other browers, the 'src' attribute should be left empty to |
29 | // trigger iframe's 'load' event. | 31 | // trigger iframe's 'load' event. |
30 | // Microsoft Edge throws "Permission Denied" if treated like an IE (#13441). | 32 | // Microsoft Edge throws "Permission Denied" if treated like an IE (http://dev.ckeditor.com/ticket/13441). |
31 | if ( CKEDITOR.env.air ) { | 33 | if ( CKEDITOR.env.air ) { |
32 | src = 'javascript:void(0)'; // jshint ignore:line | 34 | src = 'javascript:void(0)'; // jshint ignore:line |
33 | } else if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { | 35 | } else if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { |
@@ -137,7 +139,7 @@ | |||
137 | body.hideFocus = true; | 139 | body.hideFocus = true; |
138 | 140 | ||
139 | // Disable and re-enable the body to avoid IE from | 141 | // Disable and re-enable the body to avoid IE from |
140 | // taking the editing focus at startup. (#141 / #523) | 142 | // taking the editing focus at startup. (http://dev.ckeditor.com/ticket/141 / http://dev.ckeditor.com/ticket/523) |
141 | body.disabled = true; | 143 | body.disabled = true; |
142 | body.removeAttribute( 'disabled' ); | 144 | body.removeAttribute( 'disabled' ); |
143 | } | 145 | } |
@@ -154,19 +156,19 @@ | |||
154 | 156 | ||
155 | var editable = this; | 157 | var editable = this; |
156 | 158 | ||
157 | // Without it IE8 has problem with removing selection in nested editable. (#13785) | 159 | // Without it IE8 has problem with removing selection in nested editable. (http://dev.ckeditor.com/ticket/13785) |
158 | if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { | 160 | if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { |
159 | doc.getDocumentElement().addClass( doc.$.compatMode ); | 161 | doc.getDocumentElement().addClass( doc.$.compatMode ); |
160 | } | 162 | } |
161 | 163 | ||
162 | // Prevent IE/Edge from leaving a new paragraph/div after deleting all contents in body. (#6966, #13142) | 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) |
163 | if ( CKEDITOR.env.ie && !CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_P ) { | 165 | if ( CKEDITOR.env.ie && !CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_P ) { |
164 | removeSuperfluousElement( 'p' ); | 166 | removeSuperfluousElement( 'p' ); |
165 | } else if ( CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_DIV ) { | 167 | } else if ( CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_DIV ) { |
166 | removeSuperfluousElement( 'div' ); | 168 | removeSuperfluousElement( 'div' ); |
167 | } | 169 | } |
168 | 170 | ||
169 | // Fix problem with cursor not appearing in Webkit and IE11+ when clicking below the body (#10945, #10906). | 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). |
170 | // Fix for older IEs (8-10 and QM) is placed inside selection.js. | 172 | // Fix for older IEs (8-10 and QM) is placed inside selection.js. |
171 | if ( CKEDITOR.env.webkit || ( CKEDITOR.env.ie && CKEDITOR.env.version > 10 ) ) { | 173 | if ( CKEDITOR.env.webkit || ( CKEDITOR.env.ie && CKEDITOR.env.version > 10 ) ) { |
172 | doc.getDocumentElement().on( 'mousedown', function( evt ) { | 174 | doc.getDocumentElement().on( 'mousedown', function( evt ) { |
@@ -194,7 +196,7 @@ | |||
194 | // PageUp OR PageDown | 196 | // PageUp OR PageDown |
195 | if ( keyCode == 33 || keyCode == 34 ) { | 197 | if ( keyCode == 33 || keyCode == 34 ) { |
196 | // PageUp/PageDown scrolling is broken in document | 198 | // PageUp/PageDown scrolling is broken in document |
197 | // with standard doctype, manually fix it. (#4736) | 199 | // with standard doctype, manually fix it. (http://dev.ckeditor.com/ticket/4736) |
198 | if ( CKEDITOR.env.ie ) { | 200 | if ( CKEDITOR.env.ie ) { |
199 | setTimeout( function() { | 201 | setTimeout( function() { |
200 | editor.getSelection().scrollIntoView(); | 202 | editor.getSelection().scrollIntoView(); |
@@ -203,7 +205,7 @@ | |||
203 | // Page up/down cause editor selection to leak | 205 | // Page up/down cause editor selection to leak |
204 | // outside of editable thus we try to intercept | 206 | // outside of editable thus we try to intercept |
205 | // the behavior, while it affects only happen | 207 | // the behavior, while it affects only happen |
206 | // when editor contents are not overflowed. (#7955) | 208 | // when editor contents are not overflowed. (http://dev.ckeditor.com/ticket/7955) |
207 | else if ( editor.window.$.innerHeight > this.$.offsetHeight ) { | 209 | else if ( editor.window.$.innerHeight > this.$.offsetHeight ) { |
208 | var range = editor.createRange(); | 210 | var range = editor.createRange(); |
209 | range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd' ]( this ); | 211 | range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd' ]( this ); |
@@ -219,14 +221,14 @@ | |||
219 | // focus is moved onto a non-editing host, e.g. link or button, but | 221 | // focus is moved onto a non-editing host, e.g. link or button, but |
220 | // it becomes a problem for the object type selection, since the resizer | 222 | // it becomes a problem for the object type selection, since the resizer |
221 | // handler attached on it will mark other part of the UI, especially | 223 | // handler attached on it will mark other part of the UI, especially |
222 | // for the dialog. (#8157) | 224 | // for the dialog. (http://dev.ckeditor.com/ticket/8157) |
223 | // [IE<8 & Opera] Even worse For old IEs, the cursor will not vanish even if | 225 | // [IE<8 & Opera] Even worse For old IEs, the cursor will not vanish even if |
224 | // the selection has been moved to another text input in some cases. (#4716) | 226 | // the selection has been moved to another text input in some cases. (http://dev.ckeditor.com/ticket/4716) |
225 | // | 227 | // |
226 | // Now the range restore is disabled, so we simply force IE to clean | 228 | // Now the range restore is disabled, so we simply force IE to clean |
227 | // up the selection before blur. | 229 | // up the selection before blur. |
228 | this.attachListener( doc, 'blur', function() { | 230 | this.attachListener( doc, 'blur', function() { |
229 | // Error proof when the editor is not visible. (#6375) | 231 | // Error proof when the editor is not visible. (http://dev.ckeditor.com/ticket/6375) |
230 | try { | 232 | try { |
231 | doc.$.selection.empty(); | 233 | doc.$.selection.empty(); |
232 | } catch ( er ) {} | 234 | } catch ( er ) {} |
@@ -235,14 +237,14 @@ | |||
235 | 237 | ||
236 | if ( CKEDITOR.env.iOS ) { | 238 | if ( CKEDITOR.env.iOS ) { |
237 | // [iOS] If touch is bound to any parent of the iframe blur happens on any touch | 239 | // [iOS] If touch is bound to any parent of the iframe blur happens on any touch |
238 | // event and body becomes the focused element (#10714). | 240 | // event and body becomes the focused element (http://dev.ckeditor.com/ticket/10714). |
239 | this.attachListener( doc, 'touchend', function() { | 241 | this.attachListener( doc, 'touchend', function() { |
240 | win.focus(); | 242 | win.focus(); |
241 | } ); | 243 | } ); |
242 | } | 244 | } |
243 | 245 | ||
244 | var title = editor.document.getElementsByTag( 'title' ).getItem( 0 ); | 246 | var title = editor.document.getElementsByTag( 'title' ).getItem( 0 ); |
245 | // document.title is malfunctioning on Chrome, so get value from the element (#12402). | 247 | // document.title is malfunctioning on Chrome, so get value from the element (http://dev.ckeditor.com/ticket/12402). |
246 | title.data( 'cke-title', title.getText() ); | 248 | title.data( 'cke-title', title.getText() ); |
247 | 249 | ||
248 | // [IE] JAWS will not recognize the aria label we used on the iframe | 250 | // [IE] JAWS will not recognize the aria label we used on the iframe |
@@ -289,10 +291,13 @@ | |||
289 | 291 | ||
290 | // 2. On keyup remove all elements that were not marked | 292 | // 2. On keyup remove all elements that were not marked |
291 | // as non-superfluous (which means they must have had appeared in the meantime). | 293 | // as non-superfluous (which means they must have had appeared in the meantime). |
294 | // Also we should preserve all temporary elements inserted by editor – otherwise we'd likely | ||
295 | // leak fake selection's content into editable due to removing hidden selection container (http://dev.ckeditor.com/ticket/14831). | ||
292 | editable.attachListener( editable, 'keyup', function() { | 296 | editable.attachListener( editable, 'keyup', function() { |
293 | var elements = doc.getElementsByTag( tagName ); | 297 | var elements = doc.getElementsByTag( tagName ); |
294 | if ( lockRetain ) { | 298 | if ( lockRetain ) { |
295 | if ( elements.count() == 1 && !elements.getItem( 0 ).getCustomData( 'retain' ) ) { | 299 | if ( elements.count() == 1 && !elements.getItem( 0 ).getCustomData( 'retain' ) && |
300 | !elements.getItem( 0 ).hasAttribute( 'data-cke-temp' ) ) { | ||
296 | elements.getItem( 0 ).remove( 1 ); | 301 | elements.getItem( 0 ).remove( 1 ); |
297 | } | 302 | } |
298 | lockRetain = false; | 303 | lockRetain = false; |
@@ -301,13 +306,13 @@ | |||
301 | } | 306 | } |
302 | } | 307 | } |
303 | 308 | ||
304 | var framedWysiwyg = CKEDITOR.tools.createClass( { | 309 | framedWysiwyg = CKEDITOR.tools.createClass( { |
305 | $: function() { | 310 | $: function() { |
306 | this.base.apply( this, arguments ); | 311 | this.base.apply( this, arguments ); |
307 | 312 | ||
308 | this._.frameLoadedHandler = CKEDITOR.tools.addFunction( function( win ) { | 313 | this._.frameLoadedHandler = CKEDITOR.tools.addFunction( function( win ) { |
309 | // Avoid opening design mode in a frame window thread, | 314 | // Avoid opening design mode in a frame window thread, |
310 | // which will cause host page scrolling.(#4397) | 315 | // which will cause host page scrolling.(http://dev.ckeditor.com/ticket/4397) |
311 | CKEDITOR.tools.setTimeout( onDomReady, 0, this, win ); | 316 | CKEDITOR.tools.setTimeout( onDomReady, 0, this, win ); |
312 | }, this ); | 317 | }, this ); |
313 | 318 | ||
@@ -325,7 +330,7 @@ | |||
325 | this.fixInitialSelection(); | 330 | this.fixInitialSelection(); |
326 | 331 | ||
327 | // Fire dataReady for the consistency with inline editors | 332 | // Fire dataReady for the consistency with inline editors |
328 | // and because it makes sense. (#10370) | 333 | // and because it makes sense. (http://dev.ckeditor.com/ticket/10370) |
329 | editor.fire( 'dataReady' ); | 334 | editor.fire( 'dataReady' ); |
330 | } | 335 | } |
331 | else { | 336 | else { |
@@ -415,7 +420,7 @@ | |||
415 | } | 420 | } |
416 | 421 | ||
417 | // The script that launches the bootstrap logic on 'domReady', so the document | 422 | // The script that launches the bootstrap logic on 'domReady', so the document |
418 | // is fully editable even before the editing iframe is fully loaded (#4455). | 423 | // is fully editable even before the editing iframe is fully loaded (http://dev.ckeditor.com/ticket/4455). |
419 | var bootstrapCode = | 424 | var bootstrapCode = |
420 | '<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' + | 425 | '<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' + |
421 | 'var wasLoaded=0;' + // It must be always set to 0 as it remains as a window property. | 426 | 'var wasLoaded=0;' + // It must be always set to 0 as it remains as a window property. |
@@ -437,7 +442,7 @@ | |||
437 | } | 442 | } |
438 | 443 | ||
439 | // IE<10 needs this hack to properly enable <base href="...">. | 444 | // IE<10 needs this hack to properly enable <base href="...">. |
440 | // See: http://stackoverflow.com/a/13373180/1485219 (#11910). | 445 | // See: http://stackoverflow.com/a/13373180/1485219 (http://dev.ckeditor.com/ticket/11910). |
441 | if ( baseTag && CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) { | 446 | if ( baseTag && CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) { |
442 | bootstrapCode += | 447 | bootstrapCode += |
443 | '<script id="cke_basetagscrpt">' + | 448 | '<script id="cke_basetagscrpt">' + |
@@ -456,7 +461,7 @@ | |||
456 | 461 | ||
457 | var doc = this.getDocument(); | 462 | var doc = this.getDocument(); |
458 | 463 | ||
459 | // Work around Firefox bug - error prune when called from XUL (#320), | 464 | // Work around Firefox bug - error prune when called from XUL (http://dev.ckeditor.com/ticket/320), |
460 | // defer it thanks to the async nature of this method. | 465 | // defer it thanks to the async nature of this method. |
461 | try { | 466 | try { |
462 | doc.write( data ); | 467 | doc.write( data ); |
@@ -481,9 +486,9 @@ | |||
481 | 486 | ||
482 | var data = fullPage ? doc.getDocumentElement().getOuterHtml() : doc.getBody().getHtml(); | 487 | var data = fullPage ? doc.getDocumentElement().getOuterHtml() : doc.getBody().getHtml(); |
483 | 488 | ||
484 | // BR at the end of document is bogus node for Mozilla. (#5293). | 489 | // BR at the end of document is bogus node for Mozilla. (http://dev.ckeditor.com/ticket/5293). |
485 | // Prevent BRs from disappearing from the end of the content | 490 | // Prevent BRs from disappearing from the end of the content |
486 | // while enterMode is ENTER_BR (#10146). | 491 | // while enterMode is ENTER_BR (http://dev.ckeditor.com/ticket/10146). |
487 | if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR ) | 492 | if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR ) |
488 | data = data.replace( /<br>(?=\s*(:?$|<\/body>))/, '' ); | 493 | data = data.replace( /<br>(?=\s*(:?$|<\/body>))/, '' ); |
489 | 494 | ||
@@ -512,7 +517,7 @@ | |||
512 | onResize; | 517 | onResize; |
513 | 518 | ||
514 | // Trying to access window's frameElement property on Edge throws an exception | 519 | // Trying to access window's frameElement property on Edge throws an exception |
515 | // when frame was already removed from DOM. (#13850, #13790) | 520 | // when frame was already removed from DOM. (http://dev.ckeditor.com/ticket/13850, http://dev.ckeditor.com/ticket/13790) |
516 | try { | 521 | try { |
517 | iframe = editor.window.getFrame(); | 522 | iframe = editor.window.getFrame(); |
518 | } catch ( e ) {} | 523 | } catch ( e ) {} |
@@ -525,7 +530,7 @@ | |||
525 | CKEDITOR.tools.removeFunction( this._.frameLoadedHandler ); | 530 | CKEDITOR.tools.removeFunction( this._.frameLoadedHandler ); |
526 | 531 | ||
527 | // On IE, iframe is returned even after remove() method is called on it. | 532 | // On IE, iframe is returned even after remove() method is called on it. |
528 | // Checking if parent is present fixes this issue. (#13850) | 533 | // Checking if parent is present fixes this issue. (http://dev.ckeditor.com/ticket/13850) |
529 | if ( iframe && iframe.getParent() ) { | 534 | if ( iframe && iframe.getParent() ) { |
530 | iframe.clearCustomData(); | 535 | iframe.clearCustomData(); |
531 | onResize = iframe.removeCustomData( 'onResize' ); | 536 | onResize = iframe.removeCustomData( 'onResize' ); |
@@ -533,7 +538,7 @@ | |||
533 | 538 | ||
534 | // IE BUG: When destroying editor DOM with the selection remains inside | 539 | // IE BUG: When destroying editor DOM with the selection remains inside |
535 | // editing area would break IE7/8's selection system, we have to put the editing | 540 | // editing area would break IE7/8's selection system, we have to put the editing |
536 | // iframe offline first. (#3812 and #5441) | 541 | // iframe offline first. (http://dev.ckeditor.com/ticket/3812 and http://dev.ckeditor.com/ticket/5441) |
537 | iframe.remove(); | 542 | iframe.remove(); |
538 | } else { | 543 | } else { |
539 | CKEDITOR.warn( 'editor-destroy-iframe' ); | 544 | CKEDITOR.warn( 'editor-destroy-iframe' ); |
@@ -588,7 +593,7 @@ | |||
588 | var css = []; | 593 | var css = []; |
589 | 594 | ||
590 | // IE>=8 stricts mode doesn't have 'contentEditable' in effect | 595 | // IE>=8 stricts mode doesn't have 'contentEditable' in effect |
591 | // on element unless it has layout. (#5562) | 596 | // on element unless it has layout. (http://dev.ckeditor.com/ticket/5562) |
592 | if ( CKEDITOR.document.$.documentMode >= 8 ) { | 597 | if ( CKEDITOR.document.$.documentMode >= 8 ) { |
593 | css.push( 'html.CSS1Compat [contenteditable=false]{min-height:0 !important}' ); | 598 | css.push( 'html.CSS1Compat [contenteditable=false]{min-height:0 !important}' ); |
594 | 599 | ||
@@ -599,14 +604,14 @@ | |||
599 | 604 | ||
600 | css.push( selectors.join( ',' ) + '{display:inline-block}' ); | 605 | css.push( selectors.join( ',' ) + '{display:inline-block}' ); |
601 | } | 606 | } |
602 | // Set the HTML style to 100% to have the text cursor in affect (#6341) | 607 | // Set the HTML style to 100% to have the text cursor in affect (http://dev.ckeditor.com/ticket/6341) |
603 | else if ( CKEDITOR.env.gecko ) { | 608 | else if ( CKEDITOR.env.gecko ) { |
604 | css.push( 'html{height:100% !important}' ); | 609 | css.push( 'html{height:100% !important}' ); |
605 | css.push( 'img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}' ); | 610 | css.push( 'img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}' ); |
606 | } | 611 | } |
607 | 612 | ||
608 | // #6341: The text cursor must be set on the editor area. | 613 | // http://dev.ckeditor.com/ticket/6341: The text cursor must be set on the editor area. |
609 | // #6632: Avoid having "text" shape of cursor in IE7 scrollbars. | 614 | // http://dev.ckeditor.com/ticket/6632: Avoid having "text" shape of cursor in IE7 scrollbars. |
610 | css.push( 'html{cursor:text;*cursor:auto}' ); | 615 | css.push( 'html{cursor:text;*cursor:auto}' ); |
611 | 616 | ||
612 | // Use correct cursor for these elements | 617 | // Use correct cursor for these elements |