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

I/6113: Base table selection plugin #230

Merged
merged 118 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
6f5947a
Added: Fake table selection POC.
jodator Aug 2, 2018
9f56ac6
Changed: Make stopSelection work when mouse move outside the table.
jodator Aug 2, 2018
4a5e8f7
Changed: Do not change tables in table selection mode.
jodator Aug 2, 2018
631c6ba
Changed: Extract TableSelection class.
jodator Aug 2, 2018
b46b9c7
Changed: Remove superfluous selection modes from TableSelection.
jodator Aug 2, 2018
fc6401e
Changed. Make TableSelection a plugin.
jodator Aug 2, 2018
7d1aaa9
Tests: Stub TableSelection tests.
jodator Aug 3, 2018
cb97f1a
Fix missing method reference.
jodator Aug 3, 2018
ead7f98
Add some tests for TableSelection.
jodator Aug 3, 2018
8cc27ce
Add tests for TableSelection class methods.
jodator Aug 3, 2018
17086a1
Add tests for TableSelection view selection.
jodator Aug 3, 2018
922bfa2
Add MergeCellsCommand.
jodator Aug 13, 2018
843eb92
Tests: Fix table test dependencies.
jodator Aug 13, 2018
aa398a9
Tests: Simplify table manual test data and add model output.
jodator Aug 13, 2018
c4572a9
Make tableCell an object.
jodator Aug 13, 2018
33ef296
MergeCellCommand should update selection before removing table cells.
jodator Aug 13, 2018
967c136
Remove directional merge cell command.
jodator Aug 14, 2018
2042317
Update merge cell command to support ranges not table selection plugin.
jodator Sep 6, 2018
41ae8f5
Fix table commands after changes in selection mode.
jodator Sep 12, 2018
15b3a8e
Test: Add table selection tests in table editing.
jodator Sep 12, 2018
263a53a
Revert "Tests: Simplify table manual test data and add model output."
jodator Sep 14, 2018
3f2dc7f
Tests: Add manual test for table selection.
jodator Sep 14, 2018
8fe81c2
WiP: Refactor TableSelection to an Observer.
jodator Sep 18, 2018
43104d3
Merge branch 'master' into t/63
jodator Nov 26, 2018
6a7bbea
Update code to the latest engine API.
jodator Nov 26, 2018
6b53ca3
Merge branch 'master' into t/63
jodator Jun 7, 2019
72adea1
Fix table selection manual test.
jodator Jun 7, 2019
fe04ea0
Merge branch 'master' into t/63
jodator Oct 14, 2019
bbc3cdf
Merge branch 'master' into i/3202
jodator Nov 4, 2019
b320675
Update manual tests data.
jodator Nov 5, 2019
9f91cf7
Merge branch 'master' into i/3202
jodator Jan 21, 2020
844cc27
Make TableSelection an editor plugin.
jodator Jan 23, 2020
d7bcb46
Reset RemoveRowCommand to latest master version.
jodator Jan 24, 2020
520ce16
Reset RemoveColumnCommand to latest master version.
jodator Jan 24, 2020
8e8fe76
Revert changes in tab handling.
jodator Jan 24, 2020
d23e7d3
Restore merge cell up/down/right/bottom commands.
jodator Jan 24, 2020
50f07b9
Revert "Reset RemoveRowCommand to latest master version."
jodator Jan 24, 2020
59322af
Revert "Reset RemoveColumnCommand to latest master version."
jodator Jan 24, 2020
4de73c4
Update license header.
jodator Jan 27, 2020
837391b
Use fake selection to render table selection.
jodator Jan 27, 2020
a323834
Merge branch 'master' into i/3202
jodator Jan 27, 2020
8318c30
Add MouseSelectionObserver.
jodator Jan 28, 2020
16a3d30
Fix tests.
jodator Jan 28, 2020
31f9ce3
Fix test name.
jodator Jan 28, 2020
8cf18bd
Move table selection tests to own file.
jodator Jan 28, 2020
f6d2a83
Remove MergeCellsCommand from base table selection solution.
jodator Jan 29, 2020
26ec563
Restore tests from master.
jodator Jan 29, 2020
d23ab36
Align test code to the latest changes in selection post-fixer.
jodator Jan 28, 2020
7f7fe21
Fix assertions in tests.
jodator Jan 30, 2020
50011b2
Revert TableUI tests to the master version.
jodator Jan 30, 2020
c3775a7
Remove redundant code.
jodator Jan 30, 2020
299abcb
Add base docs tags and improve internal methods names.
jodator Jan 30, 2020
3748990
Allow table selection to cross heading.
jodator Jan 30, 2020
5aa6f43
Rename methods to make table selection process more clear.
jodator Jan 30, 2020
04ab2ad
Update documentation.
jodator Jan 30, 2020
00ac0fb
Refactor getSelection() to getSelectedTableCells().
jodator Jan 30, 2020
a602700
Give some TableSelection method better names and hide internal method…
jodator Jan 30, 2020
7c2c090
Add docs to hasValidSelection.
jodator Jan 30, 2020
fa69568
Fix MouseSelectionObserver docs.
jodator Jan 30, 2020
357be26
Add tests for TableSelection#hasValidSelection.
jodator Jan 30, 2020
4766df2
Add more tests.
jodator Jan 30, 2020
a568537
Remove .only from tests.
jodator Jan 30, 2020
ad2dc80
Add tests to other TableSelection methods.
jodator Jan 30, 2020
c837e0b
Remove dead code.
jodator Jan 31, 2020
f18fa50
Remove code from mousemove handler that looks like unnecessary.
jodator Jan 31, 2020
69fa430
Rename MouseSelectionObserver to MouseEventsObserver.
jodator Jan 31, 2020
aafe11b
Extract MouseSelectionHandler class.
jodator Jan 31, 2020
eb49a76
Refactor internal properties of TableSelection.
jodator Jan 31, 2020
ac9a398
Refactor static fields of TableSelection class.
jodator Jan 31, 2020
2cc4001
Extract table selection highlighting.
jodator Jan 31, 2020
69ec561
Re-organize imports.
jodator Jan 31, 2020
05287c1
Merge branch 'master' into i/6113
jodator Jan 31, 2020
9d97fe0
Fix typing inside table cell.
jodator Jan 31, 2020
c2a6882
Extract MouseSelectionHandler to own file.
jodator Jan 31, 2020
39af70a
Change styles for selected table cells.
jodator Jan 31, 2020
243ca25
Update visuals styles for the manual tests model contents.
jodator Jan 31, 2020
5700d18
Fix tests.
jodator Jan 31, 2020
74f9fce
Add tests for getSelectedTableCells().
jodator Jan 31, 2020
92fafcc
Group table selection tests.
jodator Jan 31, 2020
e4b8cf6
Rename test method to better describe its role.
jodator Jan 31, 2020
0db6934
Merge branch 'master' into i/6113
jodator Feb 3, 2020
a15c4ec
Add missing tests for mouse events in mouse selection tests.
jodator Feb 3, 2020
22dc61e
Simplify RemoveColumnCommand.
jodator Feb 4, 2020
5bf9c85
Simplify RemoveRowCommand.
jodator Feb 4, 2020
ef02380
Update table selection manual test description.
jodator Feb 4, 2020
31ffec8
Refactor and document MouseSelectionHandler.
jodator Feb 4, 2020
53d9482
Fix findAncestor docs.
jodator Feb 4, 2020
75175ec
Rename internal param.
jodator Feb 4, 2020
3e8a4c5
Cross ling MouseSelectionHandler and MouseEventsObserver docs.
jodator Feb 4, 2020
9c50778
Document TableSelection properties.
jodator Feb 4, 2020
7078ea6
Remove redundant TableSelection property.
jodator Feb 4, 2020
c04abec
Document private property of Table Selection.
jodator Feb 4, 2020
4e0e4b7
Merge branch 'table-selection' into i/6113
jodator Feb 13, 2020
8c7c34e
Merge branch 'table-selection' into i/6113
jodator Feb 14, 2020
22fa1d8
We shouldn't handle selection of a single cell by the new rendering m…
Reinmar Feb 14, 2020
f37389b
Render table selection when table cells are selected and selection pr…
jodator Feb 14, 2020
7545eb8
Temporally remove selection stop on mouseleave.
jodator Feb 14, 2020
61eceb4
Stop selection on mouse move if button was depressed outside webpage.
jodator Feb 14, 2020
d8204f3
Extract MouseEventObserver tests.
jodator Feb 17, 2020
7dd63b2
Fix fluent tests for MouseSelectionHandler.
jodator Feb 17, 2020
0e01c3f
Update TableSelection logic after fixes in MouseSelectionHandler.
jodator Feb 17, 2020
d497866
Rename tests for MouseSelectionHandler.
jodator Feb 18, 2020
2f1a9dc
TableSelection should be cleared on external selection change.
jodator Feb 18, 2020
7619a77
Extract assertSelectedCells() common test util function.
jodator Feb 18, 2020
3a2e025
Apply suggestions from code review.
jodator Feb 20, 2020
cf6583d
Update src/commands/removerowcommand.js PR suggestions.
jodator Feb 20, 2020
bb8cd22
Apply suggestions from code review
jodator Feb 20, 2020
e4cfc97
Improve TableSelection docs.
jodator Feb 20, 2020
1eae916
Use standard library for basic mathematical operations.
jodator Feb 20, 2020
f7f3902
Remove duplicated Observable mixin.
jodator Feb 20, 2020
9e87cc8
Update src/tableselection/mouseselectionhandler.js
jodator Feb 20, 2020
34df24d
Move selection visual styles to tableselection.css.
jodator Feb 20, 2020
27ce442
Bring back table selection styles.
jodator Feb 20, 2020
4c3c317
And use proper CSS class for a selected table cell.
jodator Feb 20, 2020
bd67fc9
Fix tests after changing CSS class for selected table cell.
jodator Feb 20, 2020
c01394b
Add missing the.
jodator Feb 20, 2020
9133349
Add complex table to the table selection manual test.
jodator Feb 20, 2020
2ba138c
Merge branch 'table-selection' into i/6113
jodator Feb 20, 2020
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
20 changes: 18 additions & 2 deletions src/commands/removecolumncommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,19 @@ export default class RemoveColumnCommand extends Command {
const table = tableRow.parent;

const headingColumns = table.getAttribute( 'headingColumns' ) || 0;
const row = table.getChildIndex( tableRow );

// Cache the table before removing or updating colspans.
const tableMap = [ ...new TableWalker( table ) ];

// Get column index of removed column.
const cellData = tableMap.find( value => value.cell === tableCell );
const removedColumn = cellData.column;
const selectionRow = cellData.row;
const cellToFocus = getCellToFocus( tableCell );

model.change( writer => {
// Update heading columns attribute if removing a row from head section.
if ( headingColumns && row <= headingColumns ) {
if ( headingColumns && selectionRow <= headingColumns ) {
writer.setAttribute( 'headingColumns', headingColumns - 1, table );
}

Expand All @@ -75,6 +76,21 @@ export default class RemoveColumnCommand extends Command {
writer.remove( cell );
}
}

writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
} );
}
}

// Returns a proper table cell to focus after removing a column. It should be a next sibling to selection visually stay in place but:
// - selection is on last table cell it will return previous cell.
// - table cell is spanned over 2+ columns - it will be truncated so the selection should stay in that cell.
function getCellToFocus( tableCell ) {
const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );

if ( colspan > 1 ) {
return tableCell;
}

return tableCell.nextSibling ? tableCell.nextSibling : tableCell.previousSibling;
}
40 changes: 33 additions & 7 deletions src/commands/removerowcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,35 @@ export default class RemoveRowCommand extends Command {
const tableRow = tableCell.parent;
const table = tableRow.parent;

const currentRow = table.getChildIndex( tableRow );
const removedRow = table.getChildIndex( tableRow );

const tableMap = [ ...new TableWalker( table, { endRow: removedRow } ) ];

const cellData = tableMap.find( value => value.cell === tableCell );

const headingRows = table.getAttribute( 'headingRows' ) || 0;

const columnToFocus = cellData.column;

model.change( writer => {
if ( headingRows && currentRow <= headingRows ) {
if ( headingRows && removedRow <= headingRows ) {
updateNumericAttribute( 'headingRows', headingRows - 1, table, writer, 0 );
}

const tableMap = [ ...new TableWalker( table, { endRow: currentRow } ) ];

const cellsToMove = new Map();

// Get cells from removed row that are spanned over multiple rows.
tableMap
.filter( ( { row, rowspan } ) => row === currentRow && rowspan > 1 )
.filter( ( { row, rowspan } ) => row === removedRow && rowspan > 1 )
.forEach( ( { column, cell, rowspan } ) => cellsToMove.set( column, { cell, rowspanToSet: rowspan - 1 } ) );

// Reduce rowspan on cells that are above removed row and overlaps removed row.
tableMap
.filter( ( { row, rowspan } ) => row <= currentRow - 1 && row + rowspan > currentRow )
.filter( ( { row, rowspan } ) => row <= removedRow - 1 && row + rowspan > removedRow )
.forEach( ( { cell, rowspan } ) => updateNumericAttribute( 'rowspan', rowspan - 1, cell, writer ) );

// Move cells to another row.
const targetRow = currentRow + 1;
const targetRow = removedRow + 1;
const tableWalker = new TableWalker( table, { includeSpanned: true, startRow: targetRow, endRow: targetRow } );

let previousCell;
Expand All @@ -93,6 +98,27 @@ export default class RemoveRowCommand extends Command {
}

writer.remove( tableRow );

const cellToFocus = getCellToFocus( table, removedRow, columnToFocus );
writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
} );
}
}

// Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.
function getCellToFocus( table, removedRow, columnToFocus ) {
const row = table.getChild( removedRow );

// Default to first table cell.
let cellToFocus = row.getChild( 0 );
let column = 0;

for ( const tableCell of row.getChildren() ) {
if ( column > columnToFocus ) {
return cellToFocus;
}

cellToFocus = tableCell;
column += parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
}
}
9 changes: 5 additions & 4 deletions src/commands/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
import { isObject } from 'lodash-es';

/**
* Returns the parent element of the given name. Returns undefined if the position is not inside the desired parent.
* Returns the parent element of the given name. Returns undefined if the position or the element is not inside the desired parent.
*
* @param {String} parentName The name of the parent element to find.
* @param {module:engine/model/position~Position|module:engine/model/position~Position} position The position to start searching.
* @param {module:engine/model/position~Position|module:engine/model/position~Position} positionOrElement The position or
* the parentElement to start searching.
* @returns {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment}
*/
export function findAncestor( parentName, position ) {
let parent = position.parent;
export function findAncestor( parentName, positionOrElement ) {
let parent = positionOrElement.parent;

while ( parent ) {
if ( parent.name === parentName ) {
Expand Down
2 changes: 1 addition & 1 deletion src/tableediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class TableEditing extends Plugin {
schema.register( 'tableCell', {
allowIn: 'tableRow',
allowAttributes: [ 'colspan', 'rowspan' ],
isLimit: true
isObject: true
} );

// Allow all $block content inside table cell.
Expand Down
Loading