8
0
Просмотр исходного кода

Disallow merge cells command execution on selection extending from heading to body.

Maciej Gołaszewski 5 лет назад
Родитель
Сommit
ff5981c2b2

+ 15 - 1
packages/ckeditor5-table/src/commands/mergecellscommand.js

@@ -11,7 +11,7 @@ import Command from '@ckeditor/ckeditor5-core/src/command';
 import TableWalker from '../tablewalker';
 import { findAncestor, updateNumericAttribute } from './utils';
 import TableUtils from '../tableutils';
-import { getSelectionAffectedTableCells } from '../utils';
+import { getRowIndexes, getSelectionAffectedTableCells } from '../utils';
 
 /**
  * The merge cells command.
@@ -204,6 +204,10 @@ function canMergeCells( selection, tableUtils ) {
 
 	const selectedTableCells = getSelectionAffectedTableCells( selection );
 
+	if ( !areCellInTheSameTableSection( selectedTableCells, firstRangeTable ) ) {
+		return false;
+	}
+
 	// At this point selection contains ranges over table cells in the same table.
 	// The valid selection is a fully occupied rectangle composed of table cells.
 	// Below we calculate area of selected cells and the area of valid selection.
@@ -257,3 +261,13 @@ function getBiggestRectangleArea( rows, columns ) {
 
 	return ( lastRow - firstRow + 1 ) * ( lastColumn - firstColumn + 1 );
 }
+
+function areCellInTheSameTableSection( tableCells, table ) {
+	const rowIndexes = getRowIndexes( tableCells );
+	const headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );
+
+	const firstCellIsInBody = rowIndexes.first > headingRows - 1;
+	const lastCellIsInBody = rowIndexes.last > headingRows - 1;
+
+	return firstCellIsInBody === lastCellIsInBody;
+}

+ 1 - 11
packages/ckeditor5-table/src/commands/removerowcommand.js

@@ -11,7 +11,7 @@ import Command from '@ckeditor/ckeditor5-core/src/command';
 
 import TableWalker from '../tablewalker';
 import { findAncestor, updateNumericAttribute } from './utils';
-import { getSelectionAffectedTableCells } from '../utils';
+import { getRowIndexes, getSelectionAffectedTableCells } from '../utils';
 
 /**
  * The remove row command.
@@ -138,16 +138,6 @@ export default class RemoveRowCommand extends Command {
 	}
 }
 
-// Returns a helper object with first and last row index contained in given `referenceCells`.
-function getRowIndexes( referenceCells ) {
-	const allIndexesSorted = referenceCells.map( cell => cell.parent.index ).sort();
-
-	return {
-		first: allIndexesSorted[ 0 ],
-		last: allIndexesSorted[ allIndexesSorted.length - 1 ]
-	};
-}
-
 // Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
 // * If the row was not the last one, the cell to focus will be in the row that followed it (before removal).
 // * If the row was the last one, the cell to focus will be in the row that preceded it (before removal).

+ 10 - 0
packages/ckeditor5-table/src/utils.js

@@ -137,6 +137,16 @@ export function getSelectionAffectedTableCells( selection ) {
 	return getTableCellsContainingSelection( selection );
 }
 
+// Returns a helper object with first and last row index contained in given `referenceCells`.
+export function getRowIndexes( referenceCells ) {
+	const allIndexesSorted = referenceCells.map( cell => cell.parent.index ).sort();
+
+	return {
+		first: allIndexesSorted[ 0 ],
+		last: allIndexesSorted[ allIndexesSorted.length - 1 ]
+	};
+}
+
 function sortRanges( rangesIterator ) {
 	return Array.from( rangesIterator ).sort( compareRangeOrder );
 }

+ 19 - 1
packages/ckeditor5-table/tests/commands/mergecellscommand.js

@@ -10,6 +10,7 @@ import MergeCellsCommand from '../../src/commands/mergecellscommand';
 import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
 import TableUtils from '../../src/tableutils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
+import TableSelection from '../../src/tableselection';
 
 describe( 'MergeCellsCommand', () => {
 	let editor, model, command, root;
@@ -17,7 +18,7 @@ describe( 'MergeCellsCommand', () => {
 	beforeEach( () => {
 		return ModelTestEditor
 			.create( {
-				plugins: [ TableUtils ]
+				plugins: [ TableUtils, TableSelection ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
@@ -224,6 +225,23 @@ describe( 'MergeCellsCommand', () => {
 
 			expect( command.isEnabled ).to.be.false;
 		} );
+
+		it( 'should be false if selection has cells from header and body sections', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ],
+				[ '10', '11' ]
+			], { headingRows: 1 } ) );
+
+			const tableSelection = editor.plugins.get( TableSelection );
+			const modelRoot = model.document.getRoot();
+
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+			);
+
+			expect( command.isEnabled ).to.be.false;
+		} );
 	} );
 
 	describe( 'execute()', () => {