Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Added a possibility to insert column or row with multiple selected cells #258

Merged
merged 6 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/commands/insertcolumncommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import Command from '@ckeditor/ckeditor5-core/src/command';
import { findAncestor } from './utils';
import { getRangeContainedElement, findAncestor } from './utils';

/**
* The insert column command.
Expand Down Expand Up @@ -70,15 +70,16 @@ export default class InsertColumnCommand extends Command {
const editor = this.editor;
const selection = editor.model.document.selection;
const tableUtils = editor.plugins.get( 'TableUtils' );
const insertBefore = this.order === 'left';

const firstPosition = selection.getFirstPosition();
const referencePosition = insertBefore ? selection.getFirstPosition() : selection.getLastPosition();
const referenceRange = insertBefore ? selection.getFirstRange() : selection.getLastRange();

const tableCell = findAncestor( 'tableCell', firstPosition );
const tableCell = getRangeContainedElement( referenceRange ) || findAncestor( 'tableCell', referencePosition );
const table = tableCell.parent.parent;

const { column } = tableUtils.getCellLocation( tableCell );
const insertAt = this.order === 'right' ? column + 1 : column;

tableUtils.insertColumns( table, { columns: 1, at: insertAt } );
tableUtils.insertColumns( table, { columns: 1, at: insertBefore ? column : column + 1 } );
}
}
11 changes: 7 additions & 4 deletions src/commands/insertrowcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import Command from '@ckeditor/ckeditor5-core/src/command';
import { findAncestor } from './utils';
import { getRangeContainedElement, findAncestor } from './utils';

/**
* The insert row command.
Expand Down Expand Up @@ -69,14 +69,17 @@ export default class InsertRowCommand extends Command {
const editor = this.editor;
const selection = editor.model.document.selection;
const tableUtils = editor.plugins.get( 'TableUtils' );
const insertAbove = this.order === 'above';

const tableCell = findAncestor( 'tableCell', selection.getFirstPosition() );
const referencePosition = insertAbove ? selection.getFirstPosition() : selection.getLastPosition();
const referenceRange = insertAbove ? selection.getFirstRange() : selection.getLastRange();

const tableCell = getRangeContainedElement( referenceRange ) || findAncestor( 'tableCell', referencePosition );
const tableRow = tableCell.parent;
const table = tableRow.parent;

const row = table.getChildIndex( tableRow );
const insertAt = this.order === 'below' ? row + 1 : row;

tableUtils.insertRows( table, { rows: 1, at: insertAt } );
tableUtils.insertRows( table, { rows: 1, at: this.order === 'below' ? row + 1 : row } );
}
}
13 changes: 13 additions & 0 deletions src/commands/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ 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 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
*
Expand Down
57 changes: 54 additions & 3 deletions tests/commands/insertcolumncommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';

import InsertColumnCommand from '../../src/commands/insertcolumncommand';
import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
import TableSelection from '../../src/tableselection';
import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
import TableUtils from '../../src/tableutils';
import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';

Expand All @@ -17,7 +18,7 @@ describe( 'InsertColumnCommand', () => {
beforeEach( () => {
return ModelTestEditor
.create( {
plugins: [ TableUtils ]
plugins: [ TableUtils, TableSelection ]
} )
.then( newEditor => {
editor = newEditor;
Expand Down Expand Up @@ -76,7 +77,7 @@ describe( 'InsertColumnCommand', () => {
] ) );
} );

it( 'should insert columns at table end', () => {
it( 'should insert column at table end', () => {
setData( model, modelTable( [
[ '11', '12' ],
[ '21', '22[]' ]
Expand All @@ -90,6 +91,31 @@ describe( 'InsertColumnCommand', () => {
] ) );
} );

it( 'should insert column after a multi column selection', () => {
setData( model, modelTable( [
[ '11', '12', '13' ],
[ '21', '22', '23' ]
] ) );

const tableSelection = editor.plugins.get( TableSelection );
const modelRoot = model.document.getRoot();

tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 1, 1 ] ) );

command.execute();

assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
[ '11', '12', '', '13' ],
[ '21', '22', '', '23' ]
] ) );

assertSelectedCells( model, [
[ 1, 1, 0, 0 ],
[ 1, 1, 0, 0 ]
] );
} );

it( 'should update table heading columns attribute when inserting column in headings section', () => {
setData( model, modelTable( [
[ '11[]', '12' ],
Expand Down Expand Up @@ -214,6 +240,31 @@ describe( 'InsertColumnCommand', () => {
] ) );
} );

it( 'should insert column before a multi column selection', () => {
setData( model, modelTable( [
[ '11', '12', '13' ],
[ '21', '22', '23' ]
] ) );

const tableSelection = editor.plugins.get( TableSelection );
const modelRoot = model.document.getRoot();

tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 1, 1 ] ) );

command.execute();

assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
[ '', '11', '12', '13' ],
[ '', '21', '22', '23' ]
] ) );

assertSelectedCells( model, [
[ 0, 1, 1, 0 ],
[ 0, 1, 1, 0 ]
] );
} );

it( 'should update table heading columns attribute when inserting column in headings section', () => {
setData( model, modelTable( [
[ '11', '12[]' ],
Expand Down
65 changes: 63 additions & 2 deletions tests/commands/insertrowcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltestedit
import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';

import InsertRowCommand from '../../src/commands/insertrowcommand';
import { defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
import TableSelection from '../../src/tableselection';
import { assertSelectedCells, defaultConversion, defaultSchema, modelTable } from '../_utils/utils';
import TableUtils from '../../src/tableutils';
import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';

Expand All @@ -17,7 +18,7 @@ describe( 'InsertRowCommand', () => {
beforeEach( () => {
return ModelTestEditor
.create( {
plugins: [ TableUtils ]
plugins: [ TableUtils, TableSelection ]
} )
.then( newEditor => {
editor = newEditor;
Expand Down Expand Up @@ -181,6 +182,36 @@ describe( 'InsertRowCommand', () => {
[ '', '' ]
] ) );
} );

it( 'should insert a row when multiple rows are selected', () => {
setData( model, modelTable( [
[ '11', '12' ],
[ '21', '22' ],
[ '31', '32' ]
] ) );

const tableSelection = editor.plugins.get( TableSelection );
const modelRoot = model.document.getRoot();

tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 1, 1 ] ) );

command.execute();

assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
[ '11', '12' ],
[ '21', '22' ],
[ '', '' ],
[ '31', '32' ]
] ) );

assertSelectedCells( model, [
[ 1, 1 ],
[ 1, 1 ],
[ 0, 0 ],
[ 0, 0 ]
] );
} );
} );
} );

Expand Down Expand Up @@ -284,6 +315,36 @@ describe( 'InsertRowCommand', () => {
[ '20[]', '21' ]
], { headingRows: 2 } ) );
} );

it( 'should insert a row when multiple rows are selected', () => {
setData( model, modelTable( [
[ '11', '12' ],
[ '21', '22' ],
[ '31', '32' ]
] ) );

const tableSelection = editor.plugins.get( TableSelection );
const modelRoot = model.document.getRoot();

tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );
tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 1, 1 ] ) );

command.execute();

assertEqualMarkup( getData( model, { withoutSelection: true } ), modelTable( [
[ '', '' ],
[ '11', '12' ],
[ '21', '22' ],
[ '31', '32' ]
] ) );

assertSelectedCells( model, [
[ 0, 0 ],
[ 1, 1 ],
[ 1, 1 ],
[ 0, 0 ]
] );
} );
} );
} );
} );