Ticket #5479: 5479_16.patch
File 5479_16.patch, 9.8 KB (added by , 13 years ago) |
---|
-
_source/plugins/selection/plugin.js
99 99 canUndo : false 100 100 }; 101 101 102 function createFillingChar( doc)102 function createFillingChar( range ) 103 103 { 104 var doc = range.document; 104 105 removeFillingChar( doc ); 105 106 107 // Append a zero-width space so WebKit will not try to 108 // move the selection by itself (#1272). 106 109 var fillingChar = doc.createText( '\u200B' ); 107 110 doc.setCustomData( 'cke-fillingChar', fillingChar ); 108 111 109 return fillingChar; 110 } 112 range.insertNode( fillingChar ); 113 114 var next = fillingChar.getNext(); 115 116 // If the filling char is followed by a <br>, whithout 117 // having something before it, it'll not blink. 118 // Let's remove it in this case. 119 if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' ) 120 { 121 removeFillingChar( this.document ); 122 range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START ); 123 } 124 else 125 range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END ); 126 } 111 127 112 128 function getFillingChar( doc ) 113 129 { … … 148 164 { 149 165 // On WebKit only, we need a special "filling" char on some situations 150 166 // (#1272). Here we set the events that should invalidate that char. 151 if ( CKEDITOR.env.webkit)167 editor.on( 'selectionChange', function() 152 168 { 153 editor.on( 'selectionChange', function() { checkFillingChar( editor.document ); } ); 154 editor.on( 'beforeSetMode', function() { removeFillingChar( editor.document ); } ); 155 editor.on( 'key', function( e ) 156 { 157 // Remove the filling char before some keys get 158 // executed, so they'll not get blocked by it. 159 switch ( e.data.keyCode ) 160 { 161 case 37 : // LEFT-ARROW 162 case 39 : // RIGHT-ARROW 163 case 8 : // BACKSPACE 164 removeFillingChar( editor.document ); 165 } 166 }); 169 checkFillingChar( editor.document ); 170 } ); 171 editor.on( 'beforeSetMode', function() 172 { 173 removeFillingChar( editor.document ); 174 } ); 175 editor.on( 'key', function( e ) 176 { 177 // Remove the filling char before some keys get 178 // executed, so they'll not get blocked by it. 179 switch ( e.data.keyCode ) 180 { 181 case 37 : // LEFT-ARROW 182 case 39 : // RIGHT-ARROW 183 case 8 : // BACKSPACE 184 removeFillingChar( editor.document ); 185 } 186 } ); 167 187 168 169 170 171 172 188 var fillingCharBefore; 189 function beforeData() 190 { 191 var fillingChar = getFillingChar( editor.document ); 192 fillingCharBefore = fillingChar && fillingChar.getText(); 173 193 fillingCharBefore && fillingChar.setText( fillingCharBefore.replace( /\u200B/g, '' ) ); 174 } 175 function afterData() 176 { 177 var fillingChar = getFillingChar( editor.document ); 178 fillingChar && fillingChar.setText( fillingCharBefore ); 179 } 180 editor.on( 'beforeUndoImage', beforeData ); 181 editor.on( 'afterUndoImage', afterData ); 182 editor.on( 'beforeGetData', beforeData, null, null, 0 ); 183 editor.on( 'getData', afterData ); 184 } 194 } 195 function afterData() 196 { 197 var fillingChar = getFillingChar( editor.document ); 198 fillingChar && fillingChar.setText( fillingCharBefore ); 199 } 200 editor.on( 'beforeUndoImage', beforeData ); 201 editor.on( 'afterUndoImage', afterData ); 202 editor.on( 'beforeGetData', beforeData, null, null, 0 ); 203 editor.on( 'getData', afterData ); 185 204 186 205 editor.on( 'contentDom', function() 187 206 { … … 1194 1213 * by clearing up the original selection. 1195 1214 * @param {CKEDITOR.dom.range} ranges 1196 1215 */ 1197 selectRanges : function( ranges )1216 selectRanges : function( ranges, forceExpand ) 1198 1217 { 1199 1218 if ( this.isLocked ) 1200 1219 { … … 1217 1236 } 1218 1237 1219 1238 if ( ranges[ 0 ] ) 1220 ranges[ 0 ].select( );1239 ranges[ 0 ].select( forceExpand ); 1221 1240 1222 1241 this.reset(); 1223 1242 } … … 1233 1252 { 1234 1253 sel.removeAllRanges(); 1235 1254 // Remove any existing filling char first. 1236 CKEDITOR.env.webkit &&removeFillingChar( this.document );1255 removeFillingChar( this.document ); 1237 1256 } 1238 1257 1239 1258 for ( var i = 0 ; i < ranges.length ; i++ ) … … 1284 1303 startContainer.appendText( '' ); 1285 1304 } 1286 1305 1287 if ( range.collapsed && CKEDITOR.env.webkit ) 1288 { 1289 // Append a zero-width space so WebKit will not try to 1290 // move the selection by itself (#1272). 1291 var fillingChar = createFillingChar( this.document ); 1292 range.insertNode( fillingChar ) ; 1306 if ( range.collapsed && ( forceExpand || CKEDITOR.env.webkit ) ) 1307 createFillingChar( range ); 1293 1308 1294 var next = fillingChar.getNext();1295 1296 // If the filling char is followed by a <br>, whithout1297 // having something before it, it'll not blink.1298 // Let's remove it in this case.1299 if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' )1300 {1301 removeFillingChar( this.document );1302 range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );1303 }1304 else1305 range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );1306 }1307 1308 1309 nativeRange.setStart( range.startContainer.$, range.startOffset ); 1309 1310 1310 1311 try … … 1394 1395 start.scrollIntoView(); 1395 1396 } 1396 1397 }; 1397 })();1398 1398 1399 ( function()1400 {1401 1399 var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ), 1402 1400 fillerTextRegex = /\ufeff|\u00a0/, 1403 1401 nonCells = { table:1,tbody:1,tr:1 }; … … 1411 1409 var isStartMarkerAlone; 1412 1410 var dummySpan; 1413 1411 1412 forceExpand && createFillingChar( this ); 1413 1414 1414 // IE doesn't support selecting the entire table row/cell, move the selection into cells, e.g. 1415 1415 // <table><tbody><tr>[<td>cell</b></td>... => <table><tbody><tr><td>[cell</td>... 1416 1416 if ( this.startContainer.type == CKEDITOR.NODE_ELEMENT && this.startContainer.getName() in nonCells … … 1508 1508 this.document.fire( 'selectionchange' ); 1509 1509 } 1510 1510 : 1511 function( )1511 function( forceExpand ) 1512 1512 { 1513 this.document.getSelection().selectRanges( [ this ] );1513 this.document.getSelection().selectRanges( [ this ], forceExpand ); 1514 1514 }; 1515 } )(); 1515 1516 })(); -
_source/plugins/wysiwygarea/plugin.js
430 430 editor.selectionChange(); 431 431 } 432 432 } 433 434 // All browsers are incapable to moving cursor out of certain non-exitable 435 // blocks (e.g. table, list, pre) at the end of document, make this happen by 436 // place a bogus node there, which would be later removed by dataprocessor. 437 var walkerRange = new CKEDITOR.dom.range( editor.document ), 438 walker = new CKEDITOR.dom.walker( walkerRange ); 439 walkerRange.selectNodeContents( body ); 440 walker.evaluator = function( node ) 441 { 442 return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames ); 443 }; 444 walker.guard = function( node, isMoveout ) 445 { 446 return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout ); 447 }; 448 449 if ( walker.previous() ) 450 { 451 editor.fire( 'updateSnapshot' ); 452 restoreDirty( editor ); 453 CKEDITOR.env.ie && restoreSelection( selection ); 454 455 var paddingBlock; 456 if ( enterMode != CKEDITOR.ENTER_BR ) 457 paddingBlock = body.append( new CKEDITOR.dom.element( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ); 458 else 459 paddingBlock = body; 460 461 if ( !CKEDITOR.env.ie ) 462 paddingBlock.appendBogus(); 463 } 464 } 433 } 465 434 466 435 CKEDITOR.plugins.add( 'wysiwygarea', 467 436 { … … 1216 1185 } 1217 1186 }); 1218 1187 1219 } 1220 }); 1188 // All browsers are incapable to moving cursor out of certain non-exitable 1189 // blocks (e.g. table, list, pre) at the end of document, enable this when 1190 // user clicks on the padding bottom area of body. 1191 if ( !CKEDITOR.env.ie || CKEDITOR.document.$.documentMode > 7 ) 1192 { 1193 editor.addCss( 'body{padding-bottom: 20px;}'); 1194 editor.on( 'contentDom', function () 1195 { 1196 var doc = editor.document, 1197 body = doc.getBody(); 1198 1199 body.on( 'click', function ( evt ) 1200 { 1201 evt = evt.data; 1202 1203 // All browsers are incapable to moving cursor out of certain non-exitable 1204 // blocks (e.g. table, list, pre) at the end of document, make this happen by 1205 // place a bogus node there, which would be later removed by dataprocessor. 1206 if ( ( evt.$.offsetY || evt.$.layerY || evt.$.y ) > body.$.clientHeight - parseInt( body.getComputedStyle( 'padding-bottom' ) ) ) 1207 { 1208 var walkerRange = new CKEDITOR.dom.range( editor.document ), 1209 walker = new CKEDITOR.dom.walker( walkerRange ); 1210 walkerRange.selectNodeContents( body ); 1211 walker.evaluator = function( node ) 1212 { 1213 return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames ); 1214 }; 1215 walker.guard = function( node, isMoveout ) 1216 { 1217 return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout ); 1218 }; 1219 1220 if ( walker.previous() ) 1221 { 1222 var range = new CKEDITOR.dom.range( doc ); 1223 range.moveToPosition( body, CKEDITOR.POSITION_BEFORE_END ); 1224 range.select( 1 ); 1225 evt.preventDefault(); 1226 } 1227 } 1228 }); 1229 }); 1230 } 1231 } 1232 }); 1221 1233 1222 1234 // Fixing Firefox 'Back-Forward Cache' break design mode. (#4514) 1223 1235 if ( CKEDITOR.env.gecko )