| 30 | function selectNextCellCommand( backward ) |
| 31 | { |
| 32 | return { |
| 33 | editorFocus : false, |
| 34 | canUndo : false, |
| 35 | modes : { wysiwyg : 1 }, |
| 36 | exec : function( editor ) |
| 37 | { |
| 38 | if ( editor.focusManager.hasFocus ) |
| 39 | { |
| 40 | var sel = editor.getSelection(), |
| 41 | ancestor = sel.getCommonAncestor(), |
| 42 | cell; |
| 43 | |
| 44 | if ( cell = ( ancestor.getAscendant( 'td', true ) || ancestor.getAscendant( 'th', true ) ) ) |
| 45 | { |
| 46 | var resultRange = new CKEDITOR.dom.range( editor.document ), |
| 47 | next = CKEDITOR.tools.tryThese( function() |
| 48 | { |
| 49 | var row = cell.getParent(), |
| 50 | next = row.$.cells[ cell.$.cellIndex + ( backward ? - 1 : 1 ) ]; |
| 51 | |
| 52 | // Invalid any empty value. |
| 53 | next.parentNode.parentNode; |
| 54 | return next; |
| 55 | }, |
| 56 | function() |
| 57 | { |
| 58 | var row = cell.getParent(), |
| 59 | table = row.getAscendant( 'table' ), |
| 60 | nextRow = table.$.rows[ row.$.rowIndex + ( backward ? - 1 : 1 ) ]; |
| 61 | |
| 62 | return nextRow.cells[ backward? nextRow.cells.length -1 : 0 ]; |
| 63 | }); |
| 64 | |
| 65 | // Clone one more row at the end of table and select the first newly established cell. |
| 66 | if ( ! ( next || backward ) ) |
| 67 | { |
| 68 | var table = cell.getAscendant( 'table' ).$, |
| 69 | cells = cell.getParent().$.cells; |
| 70 | |
| 71 | var newRow = new CKEDITOR.dom.element( table.insertRow( -1 ), editor.document ); |
| 72 | |
| 73 | for ( var i = 0, count = cells.length ; i < count; i++ ) |
| 74 | { |
| 75 | var newCell = newRow.append( new CKEDITOR.dom.element( |
| 76 | cells[ i ], editor.document ).clone( false, false ) ); |
| 77 | !CKEDITOR.env.ie && newCell.appendBogus(); |
| 78 | } |
| 79 | |
| 80 | resultRange.moveToElementEditStart( newRow ); |
| 81 | } |
| 82 | else if ( next ) |
| 83 | resultRange.moveToElementEditStart( new CKEDITOR.dom.element( next ) ); |
| 84 | else |
| 85 | return true; |
| 86 | |
| 87 | resultRange.select( true ); |
| 88 | return true; |
| 89 | } |
| 90 | } |
| 91 | return false; |
| 92 | } |
| 93 | }; |
| 94 | } |
| 95 | |
| 341 | |
| 342 | /** |
| 343 | * Allow context-sensitive tab key behaviors, including the following scenarios: |
| 344 | * <h5>When selection is anchored inside <b>table cells</b>:</h5> |
| 345 | * <ul> |
| 346 | * <li>If TAB is pressed, select the contents of the "next" cell. If in the last cell in the table, add a new row to it and focus its first cell.</li> |
| 347 | * <li>If SHIFT+TAB is pressed, select the contents of the "previous" cell. Do nothing when it's in the first cell.</li> |
| 348 | * </ul> |
| 349 | * @name CKEDITOR.config.enableTabKeyTools |
| 350 | * @type Boolean |
| 351 | * @default true |
| 352 | * @example |
| 353 | * config.enableTabKeyTools = false; |
| 354 | */ |