removerowcommand.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module table/commands/removerowcommand
  7. */
  8. import Command from '@ckeditor/ckeditor5-core/src/command';
  9. import { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';
  10. /**
  11. * The remove row command.
  12. *
  13. * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableRow'` editor command.
  14. *
  15. * To remove the row containing the selected cell, execute the command:
  16. *
  17. * editor.execute( 'removeTableRow' );
  18. *
  19. * @extends module:core/command~Command
  20. */
  21. export default class RemoveRowCommand extends Command {
  22. /**
  23. * @inheritDoc
  24. */
  25. refresh() {
  26. const selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
  27. const firstCell = selectedCells[ 0 ];
  28. if ( firstCell ) {
  29. const table = firstCell.findAncestor( 'table' );
  30. const tableRowCount = this.editor.plugins.get( 'TableUtils' ).getRows( table );
  31. const lastRowIndex = tableRowCount - 1;
  32. const selectedRowIndexes = getRowIndexes( selectedCells );
  33. const areAllRowsSelected = selectedRowIndexes.first === 0 && selectedRowIndexes.last === lastRowIndex;
  34. // Disallow selecting whole table -> delete whole table should be used instead.
  35. this.isEnabled = !areAllRowsSelected;
  36. } else {
  37. this.isEnabled = false;
  38. }
  39. }
  40. /**
  41. * @inheritDoc
  42. */
  43. execute() {
  44. const model = this.editor.model;
  45. const referenceCells = getSelectionAffectedTableCells( model.document.selection );
  46. const removedRowIndexes = getRowIndexes( referenceCells );
  47. const firstCell = referenceCells[ 0 ];
  48. const table = firstCell.findAncestor( 'table' );
  49. const columnIndexToFocus = this.editor.plugins.get( 'TableUtils' ).getCellLocation( firstCell ).column;
  50. model.change( writer => {
  51. const rowsToRemove = removedRowIndexes.last - removedRowIndexes.first + 1;
  52. this.editor.plugins.get( 'TableUtils' ).removeRows( table, {
  53. at: removedRowIndexes.first,
  54. rows: rowsToRemove
  55. } );
  56. const cellToFocus = getCellToFocus( table, removedRowIndexes.first, columnIndexToFocus );
  57. writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
  58. } );
  59. }
  60. }
  61. // Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
  62. // * If the row was not the last one, the cell to focus will be in the row that followed it (before removal).
  63. // * If the row was the last one, the cell to focus will be in the row that preceded it (before removal).
  64. function getCellToFocus( table, removedRowIndex, columnToFocus ) {
  65. const row = table.getChild( removedRowIndex ) || table.getChild( table.childCount - 1 );
  66. // Default to first table cell.
  67. let cellToFocus = row.getChild( 0 );
  68. let column = 0;
  69. for ( const tableCell of row.getChildren() ) {
  70. if ( column > columnToFocus ) {
  71. return cellToFocus;
  72. }
  73. cellToFocus = tableCell;
  74. column += parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
  75. }
  76. return cellToFocus;
  77. }