Skip to content

Commit

Permalink
Add expand support to selectRow and selectColumn
Browse files Browse the repository at this point in the history
  • Loading branch information
torifat committed May 20, 2019
1 parent 86ce67a commit 65200da
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 33 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=true
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,9 @@ npm install prosemirror-utils
```


* **`selectColumn`**`(columnIndex: number) → fn(tr: Transaction) → Transaction`\
* **`selectColumn`**`(columnIndex: number, expand: ?boolean) → fn(tr: Transaction) → Transaction`\
Returns a new transaction that creates a `CellSelection` on a column at index `columnIndex`.
Use the optional `expand` param to extend from current selection.

```javascript
dispatch(
Expand All @@ -287,8 +288,9 @@ npm install prosemirror-utils
```


* **`selectRow`**`(rowIndex: number) → fn(tr: Transaction) → Transaction`\
* **`selectRow`**`(rowIndex: number, expand: ?boolean) → fn(tr: Transaction) → Transaction`\
Returns a new transaction that creates a `CellSelection` on a column at index `rowIndex`.
Use the optional `expand` param to extend from current selection.

```javascript
dispatch(
Expand Down
92 changes: 86 additions & 6 deletions __tests__/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,48 @@ describe('table', () => {
);
const newTr = selectColumn(0)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(2);
expect(newTr.selection.$headCell.pos).toEqual(14);
expect(newTr.selection.$anchorCell.pos).toEqual(14);
expect(newTr.selection.$headCell.pos).toEqual(2);
});

describe('Expand', () => {
it('should return a new transaction that expands the existing selection', () => {
const {
state: { tr }
} = createEditor(
doc(
table(
row(td(p('1<head>')), tdEmpty, tdEmpty),
row(tdEmpty, tdEmpty, tdEmpty),
row(tdEmpty, td(p('2<anchor>')), tdEmpty)
)
)
);

const newTr = selectColumn(2, true)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(40);
expect(newTr.selection.$headCell.pos).toEqual(2);
});

it('should return a new transaction that expands the existing text selection', () => {
const {
state: { tr }
} = createEditor(
doc(
table(
row(td(p('1')), tdEmpty, tdEmpty),
row(td(p('2<cursor>')), tdEmpty, td(p('3'))),
row(tdEmpty, tdEmpty, tdEmpty)
)
)
);

const newTr = selectColumn(2, true)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(41);
expect(newTr.selection.$headCell.pos).toEqual(2);
});
});
});

Expand All @@ -428,8 +468,48 @@ describe('table', () => {
);
const newTr = selectRow(0)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(2);
expect(newTr.selection.$headCell.pos).toEqual(7);
expect(newTr.selection.$anchorCell.pos).toEqual(7);
expect(newTr.selection.$headCell.pos).toEqual(2);
});

describe('Expand', () => {
it('should return a new transaction that expands the existing selection', () => {
const {
state: { tr }
} = createEditor(
doc(
table(
row(td(p('1<head>')), tdEmpty, tdEmpty),
row(tdEmpty, tdEmpty, td(p('2<anchor>'))),
row(tdEmpty, tdEmpty, tdEmpty)
)
)
);

const newTr = selectRow(2, true)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(40);
expect(newTr.selection.$headCell.pos).toEqual(2);
});

it('should return a new transaction that expands the existing text selection', () => {
const {
state: { tr }
} = createEditor(
doc(
table(
row(td(p('1')), td(p('2<cursor>')), tdEmpty),
row(tdEmpty, tdEmpty, td(p('3'))),
row(tdEmpty, tdEmpty, tdEmpty)
)
)
);

const newTr = selectRow(2, true)(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(41);
expect(newTr.selection.$headCell.pos).toEqual(2);
});
});
});

Expand All @@ -447,8 +527,8 @@ describe('table', () => {
);
const newTr = selectTable(tr);
expect(newTr).not.toBe(tr);
expect(newTr.selection.$anchorCell.pos).toEqual(2);
expect(newTr.selection.$headCell.pos).toEqual(19);
expect(newTr.selection.$anchorCell.pos).toEqual(19);
expect(newTr.selection.$headCell.pos).toEqual(2);
});
});

Expand Down
77 changes: 54 additions & 23 deletions src/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,41 +210,72 @@ export const getCellsInTable = selection => {
}
};

// :: (columnIndex: number) → (tr: Transaction) → Transaction
const select = type => (index, expand) => tr => {
const table = findTable(tr.selection);
const isRowSelection = type === 'row';
if (table) {
const map = TableMap.get(table.node);

// Check if the index is valid
if (index >= 0 && index < (isRowSelection ? map.height : map.width)) {
let $firstCell;

const lastCell = map.positionAt(
isRowSelection ? index : map.height - 1,
isRowSelection ? map.width - 1 : index,
table.node
);
const $lastCell = tr.doc.resolve(table.start + lastCell);

const createCellSelection = isRowSelection
? CellSelection.rowSelection
: CellSelection.colSelection;

if (expand) {
const cell = findCellClosestToPos(tr.selection.$from);
if (cell) {
$firstCell = tr.doc.resolve(cell.pos);
return cloneTr(
tr.setSelection(createCellSelection($lastCell, $firstCell))
);
}
} else {
const firstCell = map.positionAt(
isRowSelection ? index : 0,
isRowSelection ? 0 : index,
table.node
);
$firstCell = tr.doc.resolve(table.start + firstCell);
return cloneTr(
tr.setSelection(createCellSelection($lastCell, $firstCell))
);
}
}
}
return tr;
};

// :: (columnIndex: number, expand: ?boolean) → (tr: Transaction) → Transaction
// Returns a new transaction that creates a `CellSelection` on a column at index `columnIndex`.
// Use the optional `expand` param to extend from current selection.
//
// ```javascript
// dispatch(
// selectColumn(i)(state.tr)
// );
// ```
export const selectColumn = columnIndex => tr => {
const cells = getCellsInColumn(columnIndex)(tr.selection);
if (cells) {
const $anchor = tr.doc.resolve(cells[0].pos);
const $head = tr.doc.resolve(cells[cells.length - 1].pos);
return cloneTr(tr.setSelection(new CellSelection($anchor, $head)));
}
return tr;
};
export const selectColumn = select('column');

// :: (rowIndex: number) → (tr: Transaction) → Transaction
// :: (rowIndex: number, expand: ?boolean) → (tr: Transaction) → Transaction
// Returns a new transaction that creates a `CellSelection` on a column at index `rowIndex`.
// Use the optional `expand` param to extend from current selection.
//
// ```javascript
// dispatch(
// selectRow(i)(state.tr)
// );
// ```
export const selectRow = rowIndex => tr => {
const cells = getCellsInRow(rowIndex)(tr.selection);
if (cells) {
const $anchor = tr.doc.resolve(cells[0].pos);
const $head = tr.doc.resolve(cells[cells.length - 1].pos);
return cloneTr(tr.setSelection(new CellSelection($anchor, $head)));
}
return tr;
};
export const selectRow = select('row');

// :: (selection: Selection) → (tr: Transaction) → Transaction
// Returns a new transaction that creates a `CellSelection` on the entire table.
Expand All @@ -257,9 +288,9 @@ export const selectRow = rowIndex => tr => {
export const selectTable = tr => {
const cells = getCellsInTable(tr.selection);
if (cells) {
const $anchor = tr.doc.resolve(cells[0].pos);
const $head = tr.doc.resolve(cells[cells.length - 1].pos);
return cloneTr(tr.setSelection(new CellSelection($anchor, $head)));
const $firstCell = tr.doc.resolve(cells[0].pos);
const $lastCell = tr.doc.resolve(cells[cells.length - 1].pos);
return cloneTr(tr.setSelection(new CellSelection($lastCell, $firstCell)));
}
return tr;
};
Expand Down
4 changes: 2 additions & 2 deletions typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ export function getCellsInRow(rowIndex: number | number[]): (selection: Selectio

export function getCellsInTable(selection: Selection): ContentNodeWithPos[] | undefined;

export function selectColumn(columnIndex: number): (tr: Transaction) => Transaction;
export function selectColumn(columnIndex: number, expand?: boolean): (tr: Transaction) => Transaction;

export function selectRow(rowIndex: number): (tr: Transaction) => Transaction;
export function selectRow(rowIndex: number, expand?: boolean): (tr: Transaction) => Transaction;

export function selectTable(tr: Transaction): Transaction;

Expand Down

0 comments on commit 65200da

Please sign in to comment.