Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master' into i/6128

~ Conflicts:
~	src/tableselection/utils.js
Marek Lewandowski 5 anni fa
parent
commit
90c9b37d3c

+ 1 - 0
packages/ckeditor5-table/package.json

@@ -21,6 +21,7 @@
     "@ckeditor/ckeditor5-clipboard": "^17.0.0",
     "@ckeditor/ckeditor5-editor-classic": "^17.0.0",
     "@ckeditor/ckeditor5-engine": "^17.0.0",
+    "@ckeditor/ckeditor5-horizontal-line": "^17.0.0",
     "@ckeditor/ckeditor5-image": "^17.0.0",
     "@ckeditor/ckeditor5-indent": "^17.0.0",
     "@ckeditor/ckeditor5-list": "^17.0.0",

+ 2 - 2
packages/ckeditor5-table/src/commands/insertcolumncommand.js

@@ -8,7 +8,7 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import { getRangeContainedElement, findAncestor } from './utils';
+import { findAncestor } from './utils';
 
 /**
  * The insert column command.
@@ -75,7 +75,7 @@ export default class InsertColumnCommand extends Command {
 		const referencePosition = insertBefore ? selection.getFirstPosition() : selection.getLastPosition();
 		const referenceRange = insertBefore ? selection.getFirstRange() : selection.getLastRange();
 
-		const tableCell = getRangeContainedElement( referenceRange ) || findAncestor( 'tableCell', referencePosition );
+		const tableCell = referenceRange.getContainedElement() || findAncestor( 'tableCell', referencePosition );
 		const table = tableCell.parent.parent;
 
 		const { column } = tableUtils.getCellLocation( tableCell );

+ 2 - 2
packages/ckeditor5-table/src/commands/insertrowcommand.js

@@ -8,7 +8,7 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import { getRangeContainedElement, findAncestor } from './utils';
+import { findAncestor } from './utils';
 
 /**
  * The insert row command.
@@ -74,7 +74,7 @@ export default class InsertRowCommand extends Command {
 		const referencePosition = insertAbove ? selection.getFirstPosition() : selection.getLastPosition();
 		const referenceRange = insertAbove ? selection.getFirstRange() : selection.getLastRange();
 
-		const tableCell = getRangeContainedElement( referenceRange ) || findAncestor( 'tableCell', referencePosition );
+		const tableCell = referenceRange.getContainedElement() || findAncestor( 'tableCell', referencePosition );
 		const tableRow = tableCell.parent;
 		const table = tableRow.parent;
 

+ 0 - 13
packages/ckeditor5-table/src/commands/utils.js

@@ -30,19 +30,6 @@ export function findAncestor( parentName, positionOrElement ) {
 }
 
 /**
- * Returns an element contained by a range, if it's the only one element contained by the range and if it's fully contained.
- *
- * @param {module:engine/model/range~Range} range
- * @returns {module:engine/model/element~Element|null}
- */
-export function getRangeContainedElement( range ) {
-	const nodeAfterStart = range.start.nodeAfter;
-	const nodeBeforeEnd = range.end.nodeBefore;
-
-	return ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart == nodeBeforeEnd ) ? nodeAfterStart : null;
-}
-
-/**
  * A common method to update the numeric value. If a value is the default one, it will be unset.
  *
  * @param {String} key An attribute key.

+ 8 - 6
packages/ckeditor5-table/src/tableselection.js

@@ -304,12 +304,14 @@ export default class TableSelection extends Plugin {
 
 			clearTableCellsContents( model, selectedTableCells );
 
-			// The insertContent() helper passes the actual DocumentSelection,
-			// while the deleteContent() helper always operates on the abstract clones.
-			if ( selection.is( 'documentSelection' ) ) {
-				writer.setSelection( tableCellToSelect, 'in' );
-			} else {
-				selection.setTo( tableCellToSelect, 'in' );
+			const rangeToSelect = model.schema.getNearestSelectionRange( writer.createPositionAt( tableCellToSelect, 0 ) );
+
+			if ( rangeToSelect ) {
+				if ( selection.is( 'documentSelection' ) ) {
+					writer.setSelection( rangeToSelect );
+				} else {
+					selection.setTo( rangeToSelect );
+				}
 			}
 		} );
 	}

+ 2 - 2
packages/ckeditor5-table/src/tableselection/utils.js

@@ -7,7 +7,7 @@
  * @module table/tableselection/utils
  */
 
-import { getRangeContainedElement, findAncestor } from '../commands/utils';
+import { findAncestor } from '../commands/utils';
 
 /**
  * Clears contents of the passed table cells.
@@ -41,7 +41,7 @@ export function getTableCellsInSelection( selection, expandSelection = false ) {
 	const cells = [];
 
 	for ( const range of selection.getRanges() ) {
-		const element = getRangeContainedElement( range );
+		const element = range.getContainedElement();
 
 		if ( element && element.is( 'tableCell' ) ) {
 			cells.push( element );

+ 229 - 167
packages/ckeditor5-table/tests/tableselection-integration.js

@@ -5,207 +5,269 @@
 
 /* globals document */
 
+import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
+
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
-import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import Delete from '@ckeditor/ckeditor5-typing/src/delete';
+import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
+import HorizontalLine from '@ckeditor/ckeditor5-horizontal-line/src/horizontalline';
 
 import TableEditing from '../src/tableediting';
 import TableSelection from '../src/tableselection';
+import TableClipboard from '../src/tableclipboard';
+
+import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+
 import { modelTable } from './_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata';
-import Delete from '@ckeditor/ckeditor5-typing/src/delete';
-import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
 import { getCode } from '@ckeditor/ckeditor5-utils/src/keyboard';
 import Input from '@ckeditor/ckeditor5-typing/src/input';
 import ViewText from '@ckeditor/ckeditor5-engine/src/view/text';
 
-describe( 'table selection', () => {
+describe( 'TableSelection - integration', () => {
 	let editor, model, tableSelection, modelRoot, element, viewDocument;
 
-	describe( 'TableSelection - input integration', () => {
-		afterEach( async () => {
-			element.remove();
-			await editor.destroy();
+	afterEach( async () => {
+		element.remove();
+		await editor.destroy();
+	} );
+
+	describe( 'on delete', () => {
+		beforeEach( async () => {
+			await setupEditor( [ Delete ] );
 		} );
 
-		describe( 'on delete', () => {
-			beforeEach( async () => {
-				await setupEditor( [ Delete ] );
+		it( 'should clear contents of the selected table cells and put selection in last cell on backward delete', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			const domEventData = new DomEventData( viewDocument, {
+				preventDefault: sinon.spy()
+			}, {
+				direction: 'backward',
+				unit: 'character',
+				sequence: 1
 			} );
+			viewDocument.fire( 'delete', domEventData );
 
-			it( 'should clear contents of the selected table cells and put selection in last cell on backward delete', () => {
-				tableSelection._setCellSelection(
-					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
-					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
-				);
-
-				const domEventData = new DomEventData( viewDocument, {
-					preventDefault: sinon.spy()
-				}, {
-					direction: 'backward',
-					unit: 'character',
-					sequence: 1
-				} );
-				viewDocument.fire( 'delete', domEventData );
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '', '', '13' ],
+				[ '', '[]', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
 
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '', '', '13' ],
-					[ '', '[]', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
+		it( 'should clear contents of the selected table cells and put selection in last cell on forward delete', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			const domEventData = new DomEventData( viewDocument, {
+				preventDefault: sinon.spy()
+			}, {
+				direction: 'forward',
+				unit: 'character',
+				sequence: 1
 			} );
+			viewDocument.fire( 'delete', domEventData );
 
-			it( 'should clear contents of the selected table cells and put selection in last cell on forward delete', () => {
-				tableSelection._setCellSelection(
-					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
-					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
-				);
-
-				const domEventData = new DomEventData( viewDocument, {
-					preventDefault: sinon.spy()
-				}, {
-					direction: 'forward',
-					unit: 'character',
-					sequence: 1
-				} );
-				viewDocument.fire( 'delete', domEventData );
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '[]', '', '13' ],
+				[ '', '', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
 
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '[]', '', '13' ],
-					[ '', '', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
+		it( 'should not interfere with default key handler if no table selection', () => {
+			setModelData( model, modelTable( [
+				[ '11[]', '12', '13' ],
+				[ '21', '22', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+
+			const domEventData = new DomEventData( viewDocument, {
+				preventDefault: sinon.spy()
+			}, {
+				direction: 'backward',
+				unit: 'character',
+				sequence: 1
 			} );
+			viewDocument.fire( 'delete', domEventData );
 
-			it( 'should not interfere with default key handler if no table selection', () => {
-				setModelData( model, modelTable( [
-					[ '11[]', '12', '13' ],
-					[ '21', '22', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
-
-				const domEventData = new DomEventData( viewDocument, {
-					preventDefault: sinon.spy()
-				}, {
-					direction: 'backward',
-					unit: 'character',
-					sequence: 1
-				} );
-				viewDocument.fire( 'delete', domEventData );
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '1[]', '12', '13' ],
+				[ '21', '22', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
 
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '1[]', '12', '13' ],
-					[ '21', '22', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
+		it( 'should work with any arbitrary selection passed to Model#deleteContent() (delete backwards)', () => {
+			const selection = model.createSelection( [
+				model.createRange(
+					model.createPositionFromPath( modelRoot, [ 0, 0, 0 ] ),
+					model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] )
+				),
+				model.createRange(
+					model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] ),
+					model.createPositionFromPath( modelRoot, [ 0, 0, 2 ] )
+				)
+			] );
+
+			model.change( writer => {
+				model.deleteContent( selection );
+				writer.setSelection( selection );
 			} );
 
-			it( 'should work with any arbitrary selection passed to Model#deleteContent() (delete backwards)', () => {
-				const selection = model.createSelection( [
-					model.createRange(
-						model.createPositionFromPath( modelRoot, [ 0, 0, 0 ] ),
-						model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] )
-					),
-					model.createRange(
-						model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] ),
-						model.createPositionFromPath( modelRoot, [ 0, 0, 2 ] )
-					)
-				] );
-
-				model.change( writer => {
-					model.deleteContent( selection );
-					writer.setSelection( selection );
-				} );
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '', '[]', '13' ],
+				[ '21', '22', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
 
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '', '[]', '13' ],
-					[ '21', '22', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
+		it( 'should work with any arbitrary selection passed to Model#deleteContent() (delete forwards)', () => {
+			const selection = model.createSelection( [
+				model.createRange(
+					model.createPositionFromPath( modelRoot, [ 0, 0, 0 ] ),
+					model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] )
+				),
+				model.createRange(
+					model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] ),
+					model.createPositionFromPath( modelRoot, [ 0, 0, 2 ] )
+				)
+			] );
+
+			model.change( writer => {
+				model.deleteContent( selection, {
+					direction: 'forward'
+				} );
+				writer.setSelection( selection );
 			} );
 
-			it( 'should work with any arbitrary selection passed to Model#deleteContent() (delete forwards)', () => {
-				const selection = model.createSelection( [
-					model.createRange(
-						model.createPositionFromPath( modelRoot, [ 0, 0, 0 ] ),
-						model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] )
-					),
-					model.createRange(
-						model.createPositionFromPath( modelRoot, [ 0, 0, 1 ] ),
-						model.createPositionFromPath( modelRoot, [ 0, 0, 2 ] )
-					)
-				] );
-
-				model.change( writer => {
-					model.deleteContent( selection, {
-						direction: 'forward'
-					} );
-					writer.setSelection( selection );
-				} );
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '[]', '', '13' ],
+				[ '21', '22', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
+	} );
 
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '[]', '', '13' ],
-					[ '21', '22', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
-			} );
+	describe( 'on user input', () => {
+		beforeEach( async () => {
+			await setupEditor( [ Input ] );
 		} );
 
-		describe( 'on user input', () => {
-			beforeEach( async () => {
-				await setupEditor( [ Input ] );
-			} );
+		it( 'should clear contents of the selected table cells and put selection in last cell on user input', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			viewDocument.fire( 'keydown', { keyCode: getCode( 'x' ) } );
+
+			// Mutate at the place where the document selection was put; it's more realistic
+			// than mutating at some arbitrary position.
+			const placeOfMutation = viewDocument.selection.getFirstRange().start.parent;
+
+			viewDocument.fire( 'mutations', [
+				{
+					type: 'children',
+					oldChildren: [],
+					newChildren: [ new ViewText( viewDocument, 'x' ) ],
+					node: placeOfMutation
+				}
+			] );
+
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ '', '', '13' ],
+				[ '', 'x[]', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
 
-			it( 'should clear contents of the selected table cells and put selection in last cell on user input', () => {
-				tableSelection._setCellSelection(
-					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
-					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
-				);
-
-				viewDocument.fire( 'keydown', { keyCode: getCode( 'x' ) } );
-
-				// Mutate at the place where the document selection was put; it's more realistic
-				// than mutating at some arbitrary position.
-				const placeOfMutation = viewDocument.selection.getFirstRange().start.parent;
-
-				viewDocument.fire( 'mutations', [
-					{
-						type: 'children',
-						oldChildren: [],
-						newChildren: [ new ViewText( viewDocument, 'x' ) ],
-						node: placeOfMutation
-					}
-				] );
-
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ '', '', '13' ],
-					[ '', 'x[]', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
-			} );
+		it( 'should not interfere with default key handler if no table selection', () => {
+			viewDocument.fire( 'keydown', { keyCode: getCode( 'x' ) } );
+
+			// Mutate at the place where the document selection was put; it's more realistic
+			// than mutating at some arbitrary position.
+			const placeOfMutation = viewDocument.selection.getFirstRange().start.parent;
+
+			viewDocument.fire( 'mutations', [
+				{
+					type: 'children',
+					oldChildren: [],
+					newChildren: [ new ViewText( viewDocument, 'x' ) ],
+					node: placeOfMutation
+				}
+			] );
+
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ 'x[]11', '12', '13' ],
+				[ '21', '22', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
+	} );
+
+	describe( 'with other features', () => {
+		beforeEach( async () => {
+			await setupEditor( [ Clipboard, HorizontalLine ] );
+		} );
+
+		it( 'allows pasting over multi-cell selection', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
 
-			it( 'should not interfere with default key handler if no table selection', () => {
-				viewDocument.fire( 'keydown', { keyCode: getCode( 'x' ) } );
-
-				// Mutate at the place where the document selection was put; it's more realistic
-				// than mutating at some arbitrary position.
-				const placeOfMutation = viewDocument.selection.getFirstRange().start.parent;
-
-				viewDocument.fire( 'mutations', [
-					{
-						type: 'children',
-						oldChildren: [],
-						newChildren: [ new ViewText( viewDocument, 'x' ) ],
-						node: placeOfMutation
-					}
-				] );
-
-				assertEqualMarkup( getModelData( model ), modelTable( [
-					[ 'x[]11', '12', '13' ],
-					[ '21', '22', '23' ],
-					[ '31', '32', '33' ]
-				] ) );
+			const dataTransferMock = {
+				getData: sinon.stub().withArgs( 'text/plain' ).returns( 'foo' )
+			};
+
+			editor.editing.view.document.fire( 'clipboardInput', {
+				dataTransfer: dataTransferMock,
+				stop: sinon.spy()
 			} );
+
+			assertEqualMarkup( getModelData( model ), modelTable( [
+				[ 'foo[]', '', '13' ],
+				[ '', '', '23' ],
+				[ '31', '32', '33' ]
+			] ) );
+		} );
+
+		it( 'allows inserting a horizontal line over a multi-range selection', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			editor.execute( 'horizontalLine' );
+
+			assertEqualMarkup(
+				getModelData( model ),
+				'<table>' +
+					'<tableRow>' +
+						'<tableCell><horizontalLine></horizontalLine><paragraph>[]</paragraph></tableCell>' +
+						'<tableCell><paragraph></paragraph></tableCell>' +
+						'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'</tableRow>' +
+					'<tableRow>' +
+						'<tableCell><paragraph></paragraph></tableCell>' +
+						'<tableCell><paragraph></paragraph></tableCell>' +
+						'<tableCell><paragraph>23</paragraph></tableCell>' +
+					'</tableRow>' +
+					'<tableRow>' +
+						'<tableCell><paragraph>31</paragraph></tableCell>' +
+						'<tableCell><paragraph>32</paragraph></tableCell>' +
+						'<tableCell><paragraph>33</paragraph></tableCell>' +
+					'</tableRow>' +
+				'</table>'
+			);
 		} );
 	} );
 
@@ -214,7 +276,7 @@ describe( 'table selection', () => {
 		document.body.appendChild( element );
 
 		editor = await ClassicTestEditor.create( element, {
-			plugins: [ TableEditing, TableSelection, Paragraph, ...plugins ]
+			plugins: [ TableEditing, TableSelection, TableClipboard, Paragraph, ...plugins ]
 		} );
 
 		model = editor.model;

+ 88 - 91
packages/ckeditor5-table/tests/tableselection.js

@@ -37,110 +37,107 @@ describe( 'table selection', () => {
 	afterEach( async () => {
 		await editor.destroy();
 	} );
+	describe( 'selection by shift+click', () => {
+		it( 'should...', () => {
+			// tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
+			// tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 0, 1 ] ) );
+
+			// tableSelection.stopSelection();
+
+			// assertSelectedCells( model, [
+			// 	[ 1, 1, 0 ],
+			// 	[ 0, 0, 0 ],
+			// 	[ 0, 0, 0 ]
+			// ] );
+		} );
+	} );
+
+	describe( 'selection by mouse drag', () => {
+		it( 'should...', () => {
+			// tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
+			// tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 0, 1 ] ) );
 
-	describe( 'TableSelection', () => {
-		describe( 'selection by shift+click', () => {
-			it( 'should...', () => {
-				// tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
-				// tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 0, 1 ] ) );
+			// tableSelection.stopSelection();
 
-				// tableSelection.stopSelection();
+			// assertSelectedCells( model, [
+			// 	[ 1, 1, 0 ],
+			// 	[ 0, 0, 0 ],
+			// 	[ 0, 0, 0 ]
+			// ] );
+		} );
+	} );
 
-				// assertSelectedCells( model, [
-				// 	[ 1, 1, 0 ],
-				// 	[ 0, 0, 0 ],
-				// 	[ 0, 0, 0 ]
-				// ] );
-			} );
+	describe( 'getSelectedTableCells()', () => {
+		it( 'should return nothing if selection is not started', () => {
+			expect( tableSelection.getSelectedTableCells() ).to.be.null;
 		} );
 
-		describe( 'selection by mouse drag', () => {
-			it( 'should...', () => {
-				// tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
-				// tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 0, 1 ] ) );
+		it( 'should return two table cells', () => {
+			const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
+			const lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
 
-				// tableSelection.stopSelection();
+			tableSelection._setCellSelection(
+				firstCell,
+				lastCell
+			);
 
-				// assertSelectedCells( model, [
-				// 	[ 1, 1, 0 ],
-				// 	[ 0, 0, 0 ],
-				// 	[ 0, 0, 0 ]
-				// ] );
-			} );
+			expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
+				firstCell, lastCell
+			] );
 		} );
 
-		describe( 'getSelectedTableCells()', () => {
-			it( 'should return nothing if selection is not started', () => {
-				expect( tableSelection.getSelectedTableCells() ).to.be.null;
-			} );
-
-			it( 'should return two table cells', () => {
-				const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
-				const lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
-
-				tableSelection._setCellSelection(
-					firstCell,
-					lastCell
-				);
-
-				expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
-					firstCell, lastCell
-				] );
-			} );
-
-			it( 'should return four table cells for diagonal selection', () => {
-				const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
-				const lastCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] );
-
-				tableSelection._setCellSelection(
-					firstCell,
-					lastCell
-				);
-
-				expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
-					firstCell, modelRoot.getNodeByPath( [ 0, 0, 1 ] ), modelRoot.getNodeByPath( [ 0, 1, 0 ] ), lastCell
-				] );
-			} );
-
-			it( 'should return row table cells', () => {
-				const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
-				const lastCell = modelRoot.getNodeByPath( [ 0, 0, 2 ] );
-
-				tableSelection._setCellSelection(
-					firstCell,
-					lastCell
-				);
-
-				expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
-					firstCell, modelRoot.getNodeByPath( [ 0, 0, 1 ] ), lastCell
-				] );
-			} );
-
-			it( 'should return column table cells', () => {
-				const firstCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
-				const lastCell = modelRoot.getNodeByPath( [ 0, 2, 1 ] );
-
-				tableSelection._setCellSelection( firstCell, lastCell );
-
-				expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
-					firstCell, modelRoot.getNodeByPath( [ 0, 1, 1 ] ), lastCell
-				] );
-			} );
+		it( 'should return four table cells for diagonal selection', () => {
+			const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
+			const lastCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] );
+
+			tableSelection._setCellSelection(
+				firstCell,
+				lastCell
+			);
+
+			expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
+				firstCell, modelRoot.getNodeByPath( [ 0, 0, 1 ] ), modelRoot.getNodeByPath( [ 0, 1, 0 ] ), lastCell
+			] );
 		} );
 
-		describe( 'getSelectionAsFragment()', () => {
-			it( 'should return undefined if no table cells are selected', () => {
-				expect( tableSelection.getSelectionAsFragment() ).to.be.null;
-			} );
+		it( 'should return row table cells', () => {
+			const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
+			const lastCell = modelRoot.getNodeByPath( [ 0, 0, 2 ] );
+
+			tableSelection._setCellSelection(
+				firstCell,
+				lastCell
+			);
+
+			expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
+				firstCell, modelRoot.getNodeByPath( [ 0, 0, 1 ] ), lastCell
+			] );
+		} );
+
+		it( 'should return column table cells', () => {
+			const firstCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
+			const lastCell = modelRoot.getNodeByPath( [ 0, 2, 1 ] );
+
+			tableSelection._setCellSelection( firstCell, lastCell );
+
+			expect( Array.from( tableSelection.getSelectedTableCells() ) ).to.deep.equal( [
+				firstCell, modelRoot.getNodeByPath( [ 0, 1, 1 ] ), lastCell
+			] );
+		} );
+	} );
+
+	describe( 'getSelectionAsFragment()', () => {
+		it( 'should return undefined if no table cells are selected', () => {
+			expect( tableSelection.getSelectionAsFragment() ).to.be.null;
+		} );
 
-			it( 'should return document fragment for selected table cells', () => {
-				tableSelection._setCellSelection(
-					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
-					modelRoot.getNodeByPath( [ 0, 1, 1 ] )
-				);
+		it( 'should return document fragment for selected table cells', () => {
+			tableSelection._setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
 
-				expect( tableSelection.getSelectionAsFragment() ).to.be.instanceOf( DocumentFragment );
-			} );
+			expect( tableSelection.getSelectionAsFragment() ).to.be.instanceOf( DocumentFragment );
 		} );
 	} );
 } );