diff options
Diffstat (limited to 'sources/core/editable.js')
-rw-r--r-- | sources/core/editable.js | 121 |
1 files changed, 71 insertions, 50 deletions
diff --git a/sources/core/editable.js b/sources/core/editable.js index c50ec7f..6b3fa9f 100644 --- a/sources/core/editable.js +++ b/sources/core/editable.js | |||
@@ -76,7 +76,7 @@ | |||
76 | 76 | ||
77 | // [Edge] Starting from EdgeHTML 14.14393, it does not support `setActive`. We need to use focus which | 77 | // [Edge] Starting from EdgeHTML 14.14393, it does not support `setActive`. We need to use focus which |
78 | // causes unexpected scroll. Store scrollTop value so it can be restored after focusing editor. | 78 | // causes unexpected scroll. Store scrollTop value so it can be restored after focusing editor. |
79 | // Scroll only happens if the editor is focused for the first time. (#14825) | 79 | // Scroll only happens if the editor is focused for the first time. (http://dev.ckeditor.com/ticket/14825) |
80 | if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 && !this.hasFocus && this.getDocument().equals( CKEDITOR.document ) ) { | 80 | if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 && !this.hasFocus && this.getDocument().equals( CKEDITOR.document ) ) { |
81 | this.editor._.previousScrollTop = this.$.scrollTop; | 81 | this.editor._.previousScrollTop = this.$.scrollTop; |
82 | } | 82 | } |
@@ -87,7 +87,15 @@ | |||
87 | if ( CKEDITOR.env.ie && !( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) && this.getDocument().equals( CKEDITOR.document ) ) { | 87 | if ( CKEDITOR.env.ie && !( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) && this.getDocument().equals( CKEDITOR.document ) ) { |
88 | this.$.setActive(); | 88 | this.$.setActive(); |
89 | } else { | 89 | } else { |
90 | this.$.focus(); | 90 | // We have no control over exactly what happens when the native `focus` method is called, |
91 | // so save the scroll position and restore it later. | ||
92 | if ( CKEDITOR.env.chrome ) { | ||
93 | var scrollPos = this.$.scrollTop; | ||
94 | this.$.focus(); | ||
95 | this.$.scrollTop = scrollPos; | ||
96 | } else { | ||
97 | this.$.focus(); | ||
98 | } | ||
91 | } | 99 | } |
92 | } catch ( e ) { | 100 | } catch ( e ) { |
93 | // IE throws unspecified error when focusing editable after closing dialog opened on nested editable. | 101 | // IE throws unspecified error when focusing editable after closing dialog opened on nested editable. |
@@ -95,7 +103,7 @@ | |||
95 | throw e; | 103 | throw e; |
96 | } | 104 | } |
97 | 105 | ||
98 | // Remedy if Safari doens't applies focus properly. (#279) | 106 | // Remedy if Safari doens't applies focus properly. (http://dev.ckeditor.com/ticket/279) |
99 | if ( CKEDITOR.env.safari && !this.isInline() ) { | 107 | if ( CKEDITOR.env.safari && !this.isInline() ) { |
100 | active = CKEDITOR.document.getActive(); | 108 | active = CKEDITOR.document.getActive(); |
101 | if ( !active.equals( this.getWindow().getFrame() ) ) | 109 | if ( !active.equals( this.getWindow().getFrame() ) ) |
@@ -117,7 +125,7 @@ | |||
117 | 125 | ||
118 | // The "focusin/focusout" events bubbled, e.g. If there are elements with layout | 126 | // The "focusin/focusout" events bubbled, e.g. If there are elements with layout |
119 | // they fire this event when clicking in to edit them but it must be ignored | 127 | // they fire this event when clicking in to edit them but it must be ignored |
120 | // to allow edit their contents. (#4682) | 128 | // to allow edit their contents. (http://dev.ckeditor.com/ticket/4682) |
121 | fn = isNotBubbling( fn, this ); | 129 | fn = isNotBubbling( fn, this ); |
122 | args[ 0 ] = name; | 130 | args[ 0 ] = name; |
123 | args[ 1 ] = fn; | 131 | args[ 1 ] = fn; |
@@ -252,7 +260,7 @@ | |||
252 | * @param {String} text | 260 | * @param {String} text |
253 | */ | 261 | */ |
254 | insertText: function( text ) { | 262 | insertText: function( text ) { |
255 | // Focus the editor before calling transformPlainTextToHtml. (#12726) | 263 | // Focus the editor before calling transformPlainTextToHtml. (http://dev.ckeditor.com/ticket/12726) |
256 | this.editor.focus(); | 264 | this.editor.focus(); |
257 | this.insertHtml( this.transformPlainTextToHtml( text ), 'text' ); | 265 | this.insertHtml( this.transformPlainTextToHtml( text ), 'text' ); |
258 | }, | 266 | }, |
@@ -350,7 +358,7 @@ | |||
350 | insertElement: function( element, range ) { | 358 | insertElement: function( element, range ) { |
351 | var editor = this.editor; | 359 | var editor = this.editor; |
352 | 360 | ||
353 | // Prepare for the insertion. For example - focus editor (#11848). | 361 | // Prepare for the insertion. For example - focus editor (http://dev.ckeditor.com/ticket/11848). |
354 | editor.focus(); | 362 | editor.focus(); |
355 | editor.fire( 'saveSnapshot' ); | 363 | editor.fire( 'saveSnapshot' ); |
356 | 364 | ||
@@ -363,12 +371,12 @@ | |||
363 | range = selection.getRanges()[ 0 ]; | 371 | range = selection.getRanges()[ 0 ]; |
364 | } | 372 | } |
365 | 373 | ||
366 | // Insert element into first range only and ignore the rest (#11183). | 374 | // Insert element into first range only and ignore the rest (http://dev.ckeditor.com/ticket/11183). |
367 | if ( this.insertElementIntoRange( element, range ) ) { | 375 | if ( this.insertElementIntoRange( element, range ) ) { |
368 | range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END ); | 376 | range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END ); |
369 | 377 | ||
370 | // If we're inserting a block element, the new cursor position must be | 378 | // If we're inserting a block element, the new cursor position must be |
371 | // optimized. (#3100,#5436,#8950) | 379 | // optimized. (http://dev.ckeditor.com/ticket/3100,http://dev.ckeditor.com/ticket/5436,http://dev.ckeditor.com/ticket/8950) |
372 | if ( isBlock ) { | 380 | if ( isBlock ) { |
373 | // Find next, meaningful element. | 381 | // Find next, meaningful element. |
374 | var next = element.getNext( function( node ) { | 382 | var next = element.getNext( function( node ) { |
@@ -456,7 +464,7 @@ | |||
456 | range.splitElement( current ); | 464 | range.splitElement( current ); |
457 | 465 | ||
458 | // If we're in an empty block which indicate a new paragraph, | 466 | // If we're in an empty block which indicate a new paragraph, |
459 | // simply replace it with the inserting block.(#3664) | 467 | // simply replace it with the inserting block.(http://dev.ckeditor.com/ticket/3664) |
460 | else if ( range.checkStartOfBlock() && range.checkEndOfBlock() ) { | 468 | else if ( range.checkStartOfBlock() && range.checkEndOfBlock() ) { |
461 | range.setStartBefore( current ); | 469 | range.setStartBefore( current ); |
462 | range.collapse( true ); | 470 | range.collapse( true ); |
@@ -770,7 +778,7 @@ | |||
770 | range.checkEndOfBlock() && | 778 | range.checkEndOfBlock() && |
771 | path.block && | 779 | path.block && |
772 | !range.root.equals( path.block ) && | 780 | !range.root.equals( path.block ) && |
773 | // Do not remove a block with bookmarks. (#13465) | 781 | // Do not remove a block with bookmarks. (http://dev.ckeditor.com/ticket/13465) |
774 | !hasBookmarks( path.block ) ) { | 782 | !hasBookmarks( path.block ) ) { |
775 | range.moveToPosition( path.block, CKEDITOR.POSITION_BEFORE_START ); | 783 | range.moveToPosition( path.block, CKEDITOR.POSITION_BEFORE_START ); |
776 | path.block.remove(); | 784 | path.block.remove(); |
@@ -832,7 +840,7 @@ | |||
832 | 840 | ||
833 | // IE considers control-type element as separate | 841 | // IE considers control-type element as separate |
834 | // focus host when selected, avoid destroying the | 842 | // focus host when selected, avoid destroying the |
835 | // selection in such case. (#5812) (#8949) | 843 | // selection in such case. (http://dev.ckeditor.com/ticket/5812) (http://dev.ckeditor.com/ticket/8949) |
836 | if ( ieSel && ieSel.type == 'Control' ) | 844 | if ( ieSel && ieSel.type == 'Control' ) |
837 | return; | 845 | return; |
838 | 846 | ||
@@ -884,14 +892,14 @@ | |||
884 | }, null, null, -1 ); | 892 | }, null, null, -1 ); |
885 | 893 | ||
886 | if ( CKEDITOR.env.webkit ) { | 894 | if ( CKEDITOR.env.webkit ) { |
887 | // [WebKit] Save scrollTop value so it can be used when restoring locked selection. (#14659) | 895 | // [WebKit] Save scrollTop value so it can be used when restoring locked selection. (http://dev.ckeditor.com/ticket/14659) |
888 | this.on( 'scroll', function() { | 896 | this.on( 'scroll', function() { |
889 | editor._.previousScrollTop = editor.editable().$.scrollTop; | 897 | editor._.previousScrollTop = editor.editable().$.scrollTop; |
890 | }, null, null, -1 ); | 898 | }, null, null, -1 ); |
891 | } | 899 | } |
892 | 900 | ||
893 | // [Edge] This is the other part of the workaround for Edge which restores saved | 901 | // [Edge] This is the other part of the workaround for Edge which restores saved |
894 | // scrollTop value and removes listener which is not needed anymore. (#14825) | 902 | // scrollTop value and removes listener which is not needed anymore. (http://dev.ckeditor.com/ticket/14825) |
895 | if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) { | 903 | if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) { |
896 | 904 | ||
897 | var fixScrollOnFocus = function() { | 905 | var fixScrollOnFocus = function() { |
@@ -967,7 +975,7 @@ | |||
967 | // Pass this configuration to styles system. | 975 | // Pass this configuration to styles system. |
968 | this.setCustomData( 'cke_includeReadonly', !editor.config.disableReadonlyStyling ); | 976 | this.setCustomData( 'cke_includeReadonly', !editor.config.disableReadonlyStyling ); |
969 | 977 | ||
970 | // Prevent the browser opening read-only links. (#6032 & #10912) | 978 | // Prevent the browser opening read-only links. (http://dev.ckeditor.com/ticket/6032 & http://dev.ckeditor.com/ticket/10912) |
971 | this.attachListener( this, 'click', function( evt ) { | 979 | this.attachListener( this, 'click', function( evt ) { |
972 | evt = evt.data; | 980 | evt = evt.data; |
973 | 981 | ||
@@ -980,7 +988,7 @@ | |||
980 | var backspaceOrDelete = { 8: 1, 46: 1 }; | 988 | var backspaceOrDelete = { 8: 1, 46: 1 }; |
981 | 989 | ||
982 | // Override keystrokes which should have deletion behavior | 990 | // Override keystrokes which should have deletion behavior |
983 | // on fully selected element . (#4047) (#7645) | 991 | // on fully selected element . (http://dev.ckeditor.com/ticket/4047) (http://dev.ckeditor.com/ticket/7645) |
984 | this.attachListener( editor, 'key', function( evt ) { | 992 | this.attachListener( editor, 'key', function( evt ) { |
985 | if ( editor.readOnly ) | 993 | if ( editor.readOnly ) |
986 | return true; | 994 | return true; |
@@ -990,10 +998,15 @@ | |||
990 | var keyCode = evt.data.domEvent.getKey(), | 998 | var keyCode = evt.data.domEvent.getKey(), |
991 | isHandled; | 999 | isHandled; |
992 | 1000 | ||
1001 | // Prevent of reading path of empty range (http://dev.ckeditor.com/ticket/13096, #457). | ||
1002 | var sel = editor.getSelection(); | ||
1003 | if ( sel.getRanges().length === 0 ) { | ||
1004 | return; | ||
1005 | } | ||
1006 | |||
993 | // Backspace OR Delete. | 1007 | // Backspace OR Delete. |
994 | if ( keyCode in backspaceOrDelete ) { | 1008 | if ( keyCode in backspaceOrDelete ) { |
995 | var sel = editor.getSelection(), | 1009 | var selected, |
996 | selected, | ||
997 | range = sel.getRanges()[ 0 ], | 1010 | range = sel.getRanges()[ 0 ], |
998 | path = range.startPath(), | 1011 | path = range.startPath(), |
999 | block, | 1012 | block, |
@@ -1001,16 +1014,17 @@ | |||
1001 | next, | 1014 | next, |
1002 | rtl = keyCode == 8; | 1015 | rtl = keyCode == 8; |
1003 | 1016 | ||
1017 | |||
1004 | if ( | 1018 | if ( |
1005 | // [IE<11] Remove selected image/anchor/etc here to avoid going back in history. (#10055) | 1019 | // [IE<11] Remove selected image/anchor/etc here to avoid going back in history. (http://dev.ckeditor.com/ticket/10055) |
1006 | ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && ( selected = sel.getSelectedElement() ) ) || | 1020 | ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && ( selected = sel.getSelectedElement() ) ) || |
1007 | // Remove the entire list/table on fully selected content. (#7645) | 1021 | // Remove the entire list/table on fully selected content. (http://dev.ckeditor.com/ticket/7645) |
1008 | ( selected = getSelectedTableList( sel ) ) ) { | 1022 | ( selected = getSelectedTableList( sel ) ) ) { |
1009 | // Make undo snapshot. | 1023 | // Make undo snapshot. |
1010 | editor.fire( 'saveSnapshot' ); | 1024 | editor.fire( 'saveSnapshot' ); |
1011 | 1025 | ||
1012 | // Delete any element that 'hasLayout' (e.g. hr,table) in IE8 will | 1026 | // Delete any element that 'hasLayout' (e.g. hr,table) in IE8 will |
1013 | // break up the selection, safely manage it here. (#4795) | 1027 | // break up the selection, safely manage it here. (http://dev.ckeditor.com/ticket/4795) |
1014 | range.moveToPosition( selected, CKEDITOR.POSITION_BEFORE_START ); | 1028 | range.moveToPosition( selected, CKEDITOR.POSITION_BEFORE_START ); |
1015 | // Remove the control manually. | 1029 | // Remove the control manually. |
1016 | selected.remove(); | 1030 | selected.remove(); |
@@ -1020,7 +1034,7 @@ | |||
1020 | 1034 | ||
1021 | isHandled = 1; | 1035 | isHandled = 1; |
1022 | } else if ( range.collapsed ) { | 1036 | } else if ( range.collapsed ) { |
1023 | // Handle the following special cases: (#6217) | 1037 | // Handle the following special cases: (http://dev.ckeditor.com/ticket/6217) |
1024 | // 1. Del/Backspace key before/after table; | 1038 | // 1. Del/Backspace key before/after table; |
1025 | // 2. Backspace Key after start of table. | 1039 | // 2. Backspace Key after start of table. |
1026 | if ( ( block = path.block ) && | 1040 | if ( ( block = path.block ) && |
@@ -1095,28 +1109,28 @@ | |||
1095 | editor.fire( 'doubleclick', data ); | 1109 | editor.fire( 'doubleclick', data ); |
1096 | } ); | 1110 | } ); |
1097 | 1111 | ||
1098 | // Prevent automatic submission in IE #6336 | 1112 | // Prevent automatic submission in IE http://dev.ckeditor.com/ticket/6336 |
1099 | CKEDITOR.env.ie && this.attachListener( this, 'click', blockInputClick ); | 1113 | CKEDITOR.env.ie && this.attachListener( this, 'click', blockInputClick ); |
1100 | 1114 | ||
1101 | // Gecko/Webkit need some help when selecting control type elements. (#3448) | 1115 | // Gecko/Webkit need some help when selecting control type elements. (http://dev.ckeditor.com/ticket/3448) |
1102 | // We apply same behavior for IE Edge. (#13386) | 1116 | // We apply same behavior for IE Edge. (http://dev.ckeditor.com/ticket/13386) |
1103 | if ( !CKEDITOR.env.ie || CKEDITOR.env.edge ) { | 1117 | if ( !CKEDITOR.env.ie || CKEDITOR.env.edge ) { |
1104 | this.attachListener( this, 'mousedown', function( ev ) { | 1118 | this.attachListener( this, 'mousedown', function( ev ) { |
1105 | var control = ev.data.getTarget(); | 1119 | var control = ev.data.getTarget(); |
1106 | // #11727. Note: htmlDP assures that input/textarea/select have contenteditable=false | 1120 | // http://dev.ckeditor.com/ticket/11727. Note: htmlDP assures that input/textarea/select have contenteditable=false |
1107 | // attributes. However, they also have data-cke-editable attribute, so isReadOnly() returns false, | 1121 | // attributes. However, they also have data-cke-editable attribute, so isReadOnly() returns false, |
1108 | // and therefore those elements are correctly selected by this code. | 1122 | // and therefore those elements are correctly selected by this code. |
1109 | if ( control.is( 'img', 'hr', 'input', 'textarea', 'select' ) && !control.isReadOnly() ) { | 1123 | if ( control.is( 'img', 'hr', 'input', 'textarea', 'select' ) && !control.isReadOnly() ) { |
1110 | editor.getSelection().selectElement( control ); | 1124 | editor.getSelection().selectElement( control ); |
1111 | 1125 | ||
1112 | // Prevent focus from stealing from the editable. (#9515) | 1126 | // Prevent focus from stealing from the editable. (http://dev.ckeditor.com/ticket/9515) |
1113 | if ( control.is( 'input', 'textarea', 'select' ) ) | 1127 | if ( control.is( 'input', 'textarea', 'select' ) ) |
1114 | ev.data.preventDefault(); | 1128 | ev.data.preventDefault(); |
1115 | } | 1129 | } |
1116 | } ); | 1130 | } ); |
1117 | } | 1131 | } |
1118 | 1132 | ||
1119 | // For some reason, after click event is done, IE Edge loses focus on the selected element. (#13386) | 1133 | // For some reason, after click event is done, IE Edge loses focus on the selected element. (http://dev.ckeditor.com/ticket/13386) |
1120 | if ( CKEDITOR.env.edge ) { | 1134 | if ( CKEDITOR.env.edge ) { |
1121 | this.attachListener( this, 'mouseup', function( ev ) { | 1135 | this.attachListener( this, 'mouseup', function( ev ) { |
1122 | var selectedElement = ev.data.getTarget(); | 1136 | var selectedElement = ev.data.getTarget(); |
@@ -1127,7 +1141,7 @@ | |||
1127 | } | 1141 | } |
1128 | 1142 | ||
1129 | // Prevent right click from selecting an empty block even | 1143 | // Prevent right click from selecting an empty block even |
1130 | // when selection is anchored inside it. (#5845) | 1144 | // when selection is anchored inside it. (http://dev.ckeditor.com/ticket/5845) |
1131 | if ( CKEDITOR.env.gecko ) { | 1145 | if ( CKEDITOR.env.gecko ) { |
1132 | this.attachListener( this, 'mouseup', function( ev ) { | 1146 | this.attachListener( this, 'mouseup', function( ev ) { |
1133 | if ( ev.data.$.button == 2 ) { | 1147 | if ( ev.data.$.button == 2 ) { |
@@ -1158,7 +1172,7 @@ | |||
1158 | } | 1172 | } |
1159 | 1173 | ||
1160 | // Prevent Webkit/Blink from going rogue when joining | 1174 | // Prevent Webkit/Blink from going rogue when joining |
1161 | // blocks on BACKSPACE/DEL (#11861,#9998). | 1175 | // blocks on BACKSPACE/DEL (http://dev.ckeditor.com/ticket/11861,http://dev.ckeditor.com/ticket/9998). |
1162 | if ( CKEDITOR.env.webkit ) { | 1176 | if ( CKEDITOR.env.webkit ) { |
1163 | this.attachListener( editor, 'key', function( evt ) { | 1177 | this.attachListener( editor, 'key', function( evt ) { |
1164 | if ( editor.readOnly ) { | 1178 | if ( editor.readOnly ) { |
@@ -1172,8 +1186,14 @@ | |||
1172 | if ( !( key in backspaceOrDelete ) ) | 1186 | if ( !( key in backspaceOrDelete ) ) |
1173 | return; | 1187 | return; |
1174 | 1188 | ||
1189 | // Prevent of reading path of empty range (http://dev.ckeditor.com/ticket/13096, #457). | ||
1190 | var sel = editor.getSelection(); | ||
1191 | if ( sel.getRanges().length === 0 ) { | ||
1192 | return; | ||
1193 | } | ||
1194 | |||
1175 | var backspace = key == 8, | 1195 | var backspace = key == 8, |
1176 | range = editor.getSelection().getRanges()[ 0 ], | 1196 | range = sel.getRanges()[ 0 ], |
1177 | startPath = range.startPath(); | 1197 | startPath = range.startPath(); |
1178 | 1198 | ||
1179 | if ( range.collapsed ) { | 1199 | if ( range.collapsed ) { |
@@ -1184,7 +1204,7 @@ | |||
1184 | return; | 1204 | return; |
1185 | } | 1205 | } |
1186 | 1206 | ||
1187 | // Scroll to the new position of the caret (#11960). | 1207 | // Scroll to the new position of the caret (http://dev.ckeditor.com/ticket/11960). |
1188 | editor.getSelection().scrollIntoView(); | 1208 | editor.getSelection().scrollIntoView(); |
1189 | editor.fire( 'saveSnapshot' ); | 1209 | editor.fire( 'saveSnapshot' ); |
1190 | 1210 | ||
@@ -1241,6 +1261,7 @@ | |||
1241 | * @member CKEDITOR.editor | 1261 | * @member CKEDITOR.editor |
1242 | * @param {CKEDITOR.dom.element/CKEDITOR.editable} [elementOrEditable] The | 1262 | * @param {CKEDITOR.dom.element/CKEDITOR.editable} [elementOrEditable] The |
1243 | * DOM element to become the editable or a {@link CKEDITOR.editable} object. | 1263 | * DOM element to become the editable or a {@link CKEDITOR.editable} object. |
1264 | * @returns {CKEDITOR.dom.element/null} The editor's editable element, or `null` if not available. | ||
1244 | */ | 1265 | */ |
1245 | CKEDITOR.editor.prototype.editable = function( element ) { | 1266 | CKEDITOR.editor.prototype.editable = function( element ) { |
1246 | var editable = this._.editable; | 1267 | var editable = this._.editable; |
@@ -1263,7 +1284,7 @@ | |||
1263 | CKEDITOR.on( 'instanceLoaded', function( evt ) { | 1284 | CKEDITOR.on( 'instanceLoaded', function( evt ) { |
1264 | var editor = evt.editor; | 1285 | var editor = evt.editor; |
1265 | 1286 | ||
1266 | // and flag that the element was locked by our code so it'll be editable by the editor functions (#6046). | 1287 | // and flag that the element was locked by our code so it'll be editable by the editor functions (http://dev.ckeditor.com/ticket/6046). |
1267 | editor.on( 'insertElement', function( evt ) { | 1288 | editor.on( 'insertElement', function( evt ) { |
1268 | var element = evt.data; | 1289 | var element = evt.data; |
1269 | if ( element.type == CKEDITOR.NODE_ELEMENT && ( element.is( 'input' ) || element.is( 'textarea' ) ) ) { | 1290 | if ( element.type == CKEDITOR.NODE_ELEMENT && ( element.is( 'input' ) || element.is( 'textarea' ) ) ) { |
@@ -1278,9 +1299,9 @@ | |||
1278 | if ( editor.readOnly ) | 1299 | if ( editor.readOnly ) |
1279 | return; | 1300 | return; |
1280 | 1301 | ||
1281 | // Auto fixing on some document structure weakness to enhance usabilities. (#3190 and #3189) | 1302 | // Auto fixing on some document structure weakness to enhance usabilities. (http://dev.ckeditor.com/ticket/3190 and http://dev.ckeditor.com/ticket/3189) |
1282 | var sel = editor.getSelection(); | 1303 | var sel = editor.getSelection(); |
1283 | // Do it only when selection is not locked. (#8222) | 1304 | // Do it only when selection is not locked. (http://dev.ckeditor.com/ticket/8222) |
1284 | if ( sel && !sel.isLocked ) { | 1305 | if ( sel && !sel.isLocked ) { |
1285 | var isDirty = editor.checkDirty(); | 1306 | var isDirty = editor.checkDirty(); |
1286 | 1307 | ||
@@ -1330,7 +1351,7 @@ | |||
1330 | } ); | 1351 | } ); |
1331 | } ); | 1352 | } ); |
1332 | 1353 | ||
1333 | // #9222: Show text cursor in Gecko. | 1354 | // http://dev.ckeditor.com/ticket/9222: Show text cursor in Gecko. |
1334 | // Show default cursor over control elements on all non-IEs. | 1355 | // Show default cursor over control elements on all non-IEs. |
1335 | CKEDITOR.addCss( '.cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}' ); | 1356 | CKEDITOR.addCss( '.cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}' ); |
1336 | 1357 | ||
@@ -1347,8 +1368,8 @@ | |||
1347 | // Matching an empty paragraph at the end of document. | 1368 | // Matching an empty paragraph at the end of document. |
1348 | emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi; | 1369 | emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi; |
1349 | 1370 | ||
1350 | // Auto-fixing block-less content by wrapping paragraph (#3190), prevent | 1371 | // Auto-fixing block-less content by wrapping paragraph (http://dev.ckeditor.com/ticket/3190), prevent |
1351 | // non-exitable-block by padding extra br.(#3189) | 1372 | // non-exitable-block by padding extra br.(http://dev.ckeditor.com/ticket/3189) |
1352 | // Returns truly value when dom was changed, falsy otherwise. | 1373 | // Returns truly value when dom was changed, falsy otherwise. |
1353 | function fixDom( evt ) { | 1374 | function fixDom( evt ) { |
1354 | var editor = evt.editor, | 1375 | var editor = evt.editor, |
@@ -1369,7 +1390,7 @@ | |||
1369 | } | 1390 | } |
1370 | 1391 | ||
1371 | // When we're in block enter mode, a new paragraph will be established | 1392 | // When we're in block enter mode, a new paragraph will be established |
1372 | // to encapsulate inline contents inside editable. (#3657) | 1393 | // to encapsulate inline contents inside editable. (http://dev.ckeditor.com/ticket/3657) |
1373 | // Don't autoparagraph if browser (namely - IE) incorrectly anchored selection | 1394 | // Don't autoparagraph if browser (namely - IE) incorrectly anchored selection |
1374 | // inside non-editable content. This happens e.g. if non-editable block is the only | 1395 | // inside non-editable content. This happens e.g. if non-editable block is the only |
1375 | // content of editable. | 1396 | // content of editable. |
@@ -1397,7 +1418,7 @@ | |||
1397 | 1418 | ||
1398 | selectionUpdateNeeded = 1; | 1419 | selectionUpdateNeeded = 1; |
1399 | 1420 | ||
1400 | // Cancel this selection change in favor of the next (correct). (#6811) | 1421 | // Cancel this selection change in favor of the next (correct). (http://dev.ckeditor.com/ticket/6811) |
1401 | evt.cancel(); | 1422 | evt.cancel(); |
1402 | } | 1423 | } |
1403 | } | 1424 | } |
@@ -1413,13 +1434,13 @@ | |||
1413 | if ( selection.isFake ) | 1434 | if ( selection.isFake ) |
1414 | return 0; | 1435 | return 0; |
1415 | 1436 | ||
1416 | // Ensure bogus br could help to move cursor (out of styles) to the end of block. (#7041) | 1437 | // Ensure bogus br could help to move cursor (out of styles) to the end of block. (http://dev.ckeditor.com/ticket/7041) |
1417 | var pathBlock = path.block || path.blockLimit, | 1438 | var pathBlock = path.block || path.blockLimit, |
1418 | lastNode = pathBlock && pathBlock.getLast( isNotEmpty ); | 1439 | lastNode = pathBlock && pathBlock.getLast( isNotEmpty ); |
1419 | 1440 | ||
1420 | // Check some specialities of the current path block: | 1441 | // Check some specialities of the current path block: |
1421 | // 1. It is really displayed as block; (#7221) | 1442 | // 1. It is really displayed as block; (http://dev.ckeditor.com/ticket/7221) |
1422 | // 2. It doesn't end with one inner block; (#7467) | 1443 | // 2. It doesn't end with one inner block; (http://dev.ckeditor.com/ticket/7467) |
1423 | // 3. It doesn't have bogus br yet. | 1444 | // 3. It doesn't have bogus br yet. |
1424 | if ( | 1445 | if ( |
1425 | pathBlock && pathBlock.isBlockBoundary() && | 1446 | pathBlock && pathBlock.isBlockBoundary() && |
@@ -1556,7 +1577,7 @@ | |||
1556 | // Whether in given context (pathBlock, pathBlockLimit and editor settings) | 1577 | // Whether in given context (pathBlock, pathBlockLimit and editor settings) |
1557 | // editor should automatically wrap inline contents with blocks. | 1578 | // editor should automatically wrap inline contents with blocks. |
1558 | function shouldAutoParagraph( editor, pathBlock, pathBlockLimit ) { | 1579 | function shouldAutoParagraph( editor, pathBlock, pathBlockLimit ) { |
1559 | // Check whether pathBlock equals pathBlockLimit to support nested editable (#12162). | 1580 | // Check whether pathBlock equals pathBlockLimit to support nested editable (http://dev.ckeditor.com/ticket/12162). |
1560 | return editor.config.autoParagraph !== false && | 1581 | return editor.config.autoParagraph !== false && |
1561 | editor.activeEnterMode != CKEDITOR.ENTER_BR && | 1582 | editor.activeEnterMode != CKEDITOR.ENTER_BR && |
1562 | ( | 1583 | ( |
@@ -1623,7 +1644,7 @@ | |||
1623 | 1644 | ||
1624 | // Select range and stop execution. | 1645 | // Select range and stop execution. |
1625 | // If data has been totally emptied after the filtering, | 1646 | // If data has been totally emptied after the filtering, |
1626 | // any insertion is pointless (#10339). | 1647 | // any insertion is pointless (http://dev.ckeditor.com/ticket/10339). |
1627 | if ( data && processDataForInsertion( that, data ) ) { | 1648 | if ( data && processDataForInsertion( that, data ) ) { |
1628 | // DATA INSERTION | 1649 | // DATA INSERTION |
1629 | insertDataIntoRange( that ); | 1650 | insertDataIntoRange( that ); |
@@ -2008,7 +2029,7 @@ | |||
2008 | nodeName = node.getName(); | 2029 | nodeName = node.getName(); |
2009 | 2030 | ||
2010 | // Extract only the list items, when insertion happens | 2031 | // Extract only the list items, when insertion happens |
2011 | // inside of a list, reads as rearrange list items. (#7957) | 2032 | // inside of a list, reads as rearrange list items. (http://dev.ckeditor.com/ticket/7957) |
2012 | if ( insideOfList && nodeName in CKEDITOR.dtd.$list ) { | 2033 | if ( insideOfList && nodeName in CKEDITOR.dtd.$list ) { |
2013 | nodesData = nodesData.concat( extractNodesData( node, that ) ); | 2034 | nodesData = nodesData.concat( extractNodesData( node, that ) ); |
2014 | continue; | 2035 | continue; |
@@ -2256,7 +2277,7 @@ | |||
2256 | } | 2277 | } |
2257 | 2278 | ||
2258 | // Don't use String.replace because it fails in IE7 if special replacement | 2279 | // Don't use String.replace because it fails in IE7 if special replacement |
2259 | // characters ($$, $&, etc.) are in data (#10367). | 2280 | // characters ($$, $&, etc.) are in data (http://dev.ckeditor.com/ticket/10367). |
2260 | return wrapper.getOuterHtml().split( '{cke-peak}' ).join( data ); | 2281 | return wrapper.getOuterHtml().split( '{cke-peak}' ).join( data ); |
2261 | } | 2282 | } |
2262 | 2283 | ||
@@ -2517,7 +2538,7 @@ | |||
2517 | if ( ( bogus = startBlock.getBogus() ) ) | 2538 | if ( ( bogus = startBlock.getBogus() ) ) |
2518 | bogus.remove(); | 2539 | bogus.remove(); |
2519 | 2540 | ||
2520 | // Changing end container to element from text node (#12503). | 2541 | // Changing end container to element from text node (http://dev.ckeditor.com/ticket/12503). |
2521 | range.enlarge( CKEDITOR.ENLARGE_INLINE ); | 2542 | range.enlarge( CKEDITOR.ENLARGE_INLINE ); |
2522 | 2543 | ||
2523 | // Delete range contents. Do NOT merge. Merging is weird. | 2544 | // Delete range contents. Do NOT merge. Merging is weird. |
@@ -2540,7 +2561,7 @@ | |||
2540 | range = editor.getSelection().getRanges()[ 0 ]; | 2561 | range = editor.getSelection().getRanges()[ 0 ]; |
2541 | range.collapse( 1 ); | 2562 | range.collapse( 1 ); |
2542 | 2563 | ||
2543 | // Optimizing range containers from text nodes to elements (#12503). | 2564 | // Optimizing range containers from text nodes to elements (http://dev.ckeditor.com/ticket/12503). |
2544 | range.optimize(); | 2565 | range.optimize(); |
2545 | if ( range.startContainer.getHtml() === '' ) { | 2566 | if ( range.startContainer.getHtml() === '' ) { |
2546 | range.startContainer.appendBogus(); | 2567 | range.startContainer.appendBogus(); |
@@ -2762,7 +2783,7 @@ | |||
2762 | while ( ( next = endBookmark.getNext() ) ) { | 2783 | while ( ( next = endBookmark.getNext() ) ) { |
2763 | next.insertAfter( startBookmark ); | 2784 | next.insertAfter( startBookmark ); |
2764 | 2785 | ||
2765 | // Update startBookmark after insertion to avoid the reversal of nodes (#13449). | 2786 | // Update startBookmark after insertion to avoid the reversal of nodes (http://dev.ckeditor.com/ticket/13449). |
2766 | startBookmark = next; | 2787 | startBookmark = next; |
2767 | } | 2788 | } |
2768 | 2789 | ||
@@ -2913,7 +2934,7 @@ | |||
2913 | 2934 | ||
2914 | walker.guard = function( node, leaving ) { | 2935 | walker.guard = function( node, leaving ) { |
2915 | // Guard may be executed on some node boundaries multiple times, | 2936 | // Guard may be executed on some node boundaries multiple times, |
2916 | // what results in creating more than one range for each selected cell. (#12964) | 2937 | // what results in creating more than one range for each selected cell. (http://dev.ckeditor.com/ticket/12964) |
2917 | if ( node.type == CKEDITOR.NODE_ELEMENT ) { | 2938 | if ( node.type == CKEDITOR.NODE_ELEMENT ) { |
2918 | var key = 'visited_' + ( leaving ? 'out' : 'in' ); | 2939 | var key = 'visited_' + ( leaving ? 'out' : 'in' ); |
2919 | if ( node.getCustomData( key ) ) { | 2940 | if ( node.getCustomData( key ) ) { |