UNPKG

3.41 kBJavaScriptView Raw
1/**
2 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. 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 */
8import { Command } from 'ckeditor5/src/core';
9/**
10 * The remove row command.
11 *
12 * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableRow'` editor command.
13 *
14 * To remove the row containing the selected cell, execute the command:
15 *
16 * ```ts
17 * editor.execute( 'removeTableRow' );
18 * ```
19 */
20export default class RemoveRowCommand extends Command {
21 /**
22 * @inheritDoc
23 */
24 refresh() {
25 const tableUtils = this.editor.plugins.get('TableUtils');
26 const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);
27 const firstCell = selectedCells[0];
28 if (firstCell) {
29 const table = firstCell.findAncestor('table');
30 const tableRowCount = tableUtils.getRows(table);
31 const lastRowIndex = tableRowCount - 1;
32 const selectedRowIndexes = tableUtils.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 }
37 else {
38 this.isEnabled = false;
39 }
40 }
41 /**
42 * @inheritDoc
43 */
44 execute() {
45 const model = this.editor.model;
46 const tableUtils = this.editor.plugins.get('TableUtils');
47 const referenceCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);
48 const removedRowIndexes = tableUtils.getRowIndexes(referenceCells);
49 const firstCell = referenceCells[0];
50 const table = firstCell.findAncestor('table');
51 const columnIndexToFocus = tableUtils.getCellLocation(firstCell).column;
52 model.change(writer => {
53 const rowsToRemove = removedRowIndexes.last - removedRowIndexes.first + 1;
54 tableUtils.removeRows(table, {
55 at: removedRowIndexes.first,
56 rows: rowsToRemove
57 });
58 const cellToFocus = getCellToFocus(table, removedRowIndexes.first, columnIndexToFocus, tableUtils.getRows(table));
59 writer.setSelection(writer.createPositionAt(cellToFocus, 0));
60 });
61 }
62}
63/**
64 * Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
65 * - If the row was not the last one, the cell to focus will be in the row that followed it (before removal).
66 * - If the row was the last one, the cell to focus will be in the row that preceded it (before removal).
67 */
68function getCellToFocus(table, removedRowIndex, columnToFocus, tableRowCount) {
69 // Don't go beyond last row's index.
70 const row = table.getChild(Math.min(removedRowIndex, tableRowCount - 1));
71 // Default to first table cell.
72 let cellToFocus = row.getChild(0);
73 let column = 0;
74 for (const tableCell of row.getChildren()) {
75 if (column > columnToFocus) {
76 return cellToFocus;
77 }
78 cellToFocus = tableCell;
79 column += parseInt(tableCell.getAttribute('colspan') || '1');
80 }
81 return cellToFocus;
82}