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

Merge pull request #82 from ckeditor/t/68

Fix: Merge cell horizontally should not be possible on overlapped cells. Closes #68.
Piotrek Koszuliński 7 лет назад
Родитель
Сommit
5547c575d7

+ 28 - 3
packages/ckeditor5-table/src/commands/mergecellcommand.js

@@ -12,6 +12,7 @@ import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 import TableWalker from '../tablewalker';
 import { updateNumericAttribute } from './utils';
+import TableUtils from '../tableutils';
 
 /**
  * The merge cell command.
@@ -130,8 +131,12 @@ export default class MergeCellCommand extends Command {
 			return;
 		}
 
+		const tableUtils = this.editor.plugins.get( TableUtils );
+
 		// First get the cell on proper direction.
-		const cellToMerge = this.isHorizontal ? getHorizontalCell( element, this.direction ) : getVerticalCell( element, this.direction );
+		const cellToMerge = this.isHorizontal ?
+			getHorizontalCell( element, this.direction, tableUtils ) :
+			getVerticalCell( element, this.direction );
 
 		if ( !cellToMerge ) {
 			return;
@@ -154,8 +159,28 @@ export default class MergeCellCommand extends Command {
 // @param {module:engine/model/element~Element} tableCell
 // @param {String} direction
 // @returns {module:engine/model/node~Node|null}
-function getHorizontalCell( tableCell, direction ) {
-	return direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;
+function getHorizontalCell( tableCell, direction, tableUtils ) {
+	const horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;
+
+	if ( !horizontalCell ) {
+		return;
+	}
+
+	// Sort cells:
+	const cellOnLeft = direction == 'right' ? tableCell : horizontalCell;
+	const cellOnRight = direction == 'right' ? horizontalCell : tableCell;
+
+	// Get their column indexes:
+	const { column: leftCellColumn } = tableUtils.getCellLocation( cellOnLeft );
+	const { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );
+
+	const leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) || 1 );
+
+	// The cell on the right must have index that is distant to the cell on the left by the left cell's width (colspan).
+	const cellsAreTouching = leftCellColumn + leftCellSpan === rightCellColumn;
+
+	// If the right cell's column index is different it means that there are rowspanned cells between them.
+	return cellsAreTouching ? horizontalCell : undefined;
 }
 
 // Returns the cell that can be merged vertically.

+ 41 - 39
packages/ckeditor5-table/tests/commands/insertcolumncommand.js

@@ -24,55 +24,57 @@ describe( 'InsertColumnCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {

+ 41 - 39
packages/ckeditor5-table/tests/commands/insertrowcommand.js

@@ -24,55 +24,57 @@ describe( 'InsertRowCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {

+ 42 - 40
packages/ckeditor5-table/tests/commands/inserttablecommand.js

@@ -25,56 +25,58 @@ describe( 'InsertTableCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-			command = new InsertTableCommand( editor );
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				command = new InsertTableCommand( editor );
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {

+ 41 - 1
packages/ckeditor5-table/tests/commands/mergecellcommand.js

@@ -18,12 +18,16 @@ import {
 } from '../../src/converters/downcast';
 import upcastTable from '../../src/converters/upcasttable';
 import { formatTable, formattedModelTable, modelTable } from '../_utils/utils';
+import TableUtils from '../../src/tableutils';
 
 describe( 'MergeCellCommand', () => {
 	let editor, model, command, root;
 
 	beforeEach( () => {
-		return ModelTestEditor.create()
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
 			.then( newEditor => {
 				editor = newEditor;
 				model = editor.model;
@@ -116,6 +120,24 @@ describe( 'MergeCellCommand', () => {
 				expect( command.isEnabled ).to.be.false;
 			} );
 
+			it( 'should be false when next cell is rowspanned', () => {
+				setData( model, modelTable( [
+					[ '00', { rowspan: 3, contents: '01' }, '02' ],
+					[ '10[]', '12' ],
+					[ '20', '22' ]
+				] ) );
+
+				expect( command.isEnabled ).to.be.false;
+			} );
+
+			it( 'should be true when current cell is colspanned', () => {
+				setData( model, modelTable( [
+					[ { colspan: 2, contents: '00[]' }, '02' ]
+				] ) );
+
+				expect( command.isEnabled ).to.be.true;
+			} );
+
 			it( 'should be false if not in a cell', () => {
 				setData( model, '<p>11[]</p>' );
 
@@ -216,6 +238,24 @@ describe( 'MergeCellCommand', () => {
 				expect( command.isEnabled ).to.be.false;
 			} );
 
+			it( 'should be false when next cell is rowspanned', () => {
+				setData( model, modelTable( [
+					[ '00', { rowspan: 3, contents: '01' }, '02' ],
+					[ '10', '12[]' ],
+					[ '20', '22' ]
+				] ) );
+
+				expect( command.isEnabled ).to.be.false;
+			} );
+
+			it( 'should be true when mergeable cell is colspanned', () => {
+				setData( model, modelTable( [
+					[ { colspan: 2, contents: '00' }, '02[]' ]
+				] ) );
+
+				expect( command.isEnabled ).to.be.true;
+			} );
+
 			it( 'should be false if not in a cell', () => {
 				setData( model, '<p>11[]</p>' );
 

+ 42 - 40
packages/ckeditor5-table/tests/commands/removecolumncommand.js

@@ -24,56 +24,58 @@ describe( 'RemoveColumnCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-			command = new RemoveColumnCommand( editor );
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows', 'headingColumns' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				command = new RemoveColumnCommand( editor );
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows', 'headingColumns' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {

+ 58 - 56
packages/ckeditor5-table/tests/commands/setheadercolumncommand.js

@@ -24,63 +24,65 @@ describe( 'HeaderColumnCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-			command = new SetHeaderColumnCommand( editor );
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isBlock: true,
-				isObject: true
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				command = new SetHeaderColumnCommand( editor );
+
+				const conversion = editor.conversion;
+				const schema = model.schema;
+
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isBlock: true,
+					isObject: true
+				} );
+
+				schema.register( 'tableRow', {
+					allowIn: 'table',
+					allowAttributes: [],
+					isBlock: true,
+					isLimit: true
+				} );
+
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isBlock: true,
+					isLimit: true
+				} );
+
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
+
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
+
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
+
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
+
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
+
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
 			} );
-
-			schema.register( 'tableRow', {
-				allowIn: 'table',
-				allowAttributes: [],
-				isBlock: true,
-				isLimit: true
-			} );
-
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isBlock: true,
-				isLimit: true
-			} );
-
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
-
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
-
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
-
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
-
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
-
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
-
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
-
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
 	} );
 
 	afterEach( () => {

+ 42 - 40
packages/ckeditor5-table/tests/commands/setheaderrowcommand.js

@@ -24,56 +24,58 @@ describe( 'HeaderRowCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-			command = new SetHeaderRowCommand( editor );
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				command = new SetHeaderRowCommand( editor );
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {

+ 42 - 40
packages/ckeditor5-table/tests/commands/splitcellcommand.js

@@ -24,56 +24,58 @@ describe( 'SplitCellCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create( {
-			plugins: [ TableUtils ]
-		} ).then( newEditor => {
-			editor = newEditor;
-			model = editor.model;
-			command = new SplitCellCommand( editor );
-
-			const conversion = editor.conversion;
-			const schema = model.schema;
-
-			schema.register( 'table', {
-				allowWhere: '$block',
-				allowAttributes: [ 'headingRows' ],
-				isObject: true
-			} );
+		return ModelTestEditor
+			.create( {
+				plugins: [ TableUtils ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+				command = new SplitCellCommand( editor );
 
-			schema.register( 'tableRow', { allowIn: 'table' } );
+				const conversion = editor.conversion;
+				const schema = model.schema;
 
-			schema.register( 'tableCell', {
-				allowIn: 'tableRow',
-				allowContentOf: '$block',
-				allowAttributes: [ 'colspan', 'rowspan' ],
-				isLimit: true
-			} );
+				schema.register( 'table', {
+					allowWhere: '$block',
+					allowAttributes: [ 'headingRows' ],
+					isObject: true
+				} );
 
-			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+				schema.register( 'tableRow', { allowIn: 'table' } );
 
-			// Table conversion.
-			conversion.for( 'upcast' ).add( upcastTable() );
-			conversion.for( 'downcast' ).add( downcastInsertTable() );
+				schema.register( 'tableCell', {
+					allowIn: 'tableRow',
+					allowContentOf: '$block',
+					allowAttributes: [ 'colspan', 'rowspan' ],
+					isLimit: true
+				} );
 
-			// Insert row conversion.
-			conversion.for( 'downcast' ).add( downcastInsertRow() );
+				model.schema.register( 'p', { inheritAllFrom: '$block' } );
 
-			// Remove row conversion.
-			conversion.for( 'downcast' ).add( downcastRemoveRow() );
+				// Table conversion.
+				conversion.for( 'upcast' ).add( upcastTable() );
+				conversion.for( 'downcast' ).add( downcastInsertTable() );
 
-			// Table cell conversion.
-			conversion.for( 'downcast' ).add( downcastInsertCell() );
+				// Insert row conversion.
+				conversion.for( 'downcast' ).add( downcastInsertRow() );
 
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+				// Remove row conversion.
+				conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
-			// Table attributes conversion.
-			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+				// Table cell conversion.
+				conversion.for( 'downcast' ).add( downcastInsertCell() );
 
-			conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
-			conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
-		} );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+				// Table attributes conversion.
+				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+
+				conversion.for( 'downcast' ).add( downcastTableHeadingColumnsChange() );
+				conversion.for( 'downcast' ).add( downcastTableHeadingRowsChange() );
+			} );
 	} );
 
 	afterEach( () => {