1 import {NodeClipboard} from "./node-clipboard";
2 import {CustomTableRowNode} from "../nodes/custom-table-row";
3 import {$getTableFromSelection, $getTableRowsFromSelection} from "./tables";
4 import {$getSelection, LexicalEditor} from "lexical";
5 import {$createCustomTableCellNode, $isCustomTableCellNode} from "../nodes/custom-table-cell";
6 import {CustomTableNode} from "../nodes/custom-table";
7 import {TableMap} from "./table-map";
9 const rowClipboard: NodeClipboard<CustomTableRowNode> = new NodeClipboard<CustomTableRowNode>(CustomTableRowNode);
11 export function isRowClipboardEmpty(): boolean {
12 return rowClipboard.size() === 0;
15 export function validateRowsToCopy(rows: CustomTableRowNode[]): void {
16 let commonRowSize: number|null = null;
18 for (const row of rows) {
19 const cells = row.getChildren().filter(n => $isCustomTableCellNode(n));
21 for (const cell of cells) {
22 rowSize += cell.getColSpan() || 1;
23 if (cell.getRowSpan() > 1) {
24 throw Error('Cannot copy rows with merged cells');
28 if (commonRowSize === null) {
29 commonRowSize = rowSize;
30 } else if (commonRowSize !== rowSize) {
31 throw Error('Cannot copy rows with inconsistent sizes');
36 export function validateRowsToPaste(rows: CustomTableRowNode[], targetTable: CustomTableNode): void {
37 const tableColCount = (new TableMap(targetTable)).columnCount;
38 for (const row of rows) {
39 const cells = row.getChildren().filter(n => $isCustomTableCellNode(n));
41 for (const cell of cells) {
42 rowSize += cell.getColSpan() || 1;
45 if (rowSize > tableColCount) {
46 throw Error('Cannot paste rows that are wider than target table');
49 while (rowSize < tableColCount) {
50 row.append($createCustomTableCellNode());
56 export function $cutSelectedRowsToClipboard(): void {
57 const rows = $getTableRowsFromSelection($getSelection());
58 validateRowsToCopy(rows);
59 rowClipboard.set(...rows);
60 for (const row of rows) {
65 export function $copySelectedRowsToClipboard(): void {
66 const rows = $getTableRowsFromSelection($getSelection());
67 validateRowsToCopy(rows);
68 rowClipboard.set(...rows);
71 export function $pasteClipboardRowsBefore(editor: LexicalEditor): void {
72 const selection = $getSelection();
73 const rows = $getTableRowsFromSelection(selection);
74 const table = $getTableFromSelection(selection);
75 const lastRow = rows[rows.length - 1];
76 if (lastRow && table) {
77 const clipboardRows = rowClipboard.get(editor);
78 validateRowsToPaste(clipboardRows, table);
79 for (const row of clipboardRows) {
80 lastRow.insertBefore(row);
85 export function $pasteRowsAfter(editor: LexicalEditor): void {
86 const selection = $getSelection();
87 const rows = $getTableRowsFromSelection(selection);
88 const table = $getTableFromSelection(selection);
89 const lastRow = rows[rows.length - 1];
90 if (lastRow && table) {
91 const clipboardRows = rowClipboard.get(editor).reverse();
92 validateRowsToPaste(clipboardRows, table);
93 for (const row of clipboardRows) {
94 lastRow.insertAfter(row);