@lofcz/platejs-table 52.0.11 → 52.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{constants-B6Sm9BNa.js → constants-DGdhsla3.js} +679 -523
- package/dist/{index-CbSGuAlP.d.ts → index-CU48xuSN.d.ts} +186 -33
- package/dist/index.d.ts +2 -2
- package/dist/index.js +28 -8
- package/dist/react/index.d.ts +119 -22
- package/dist/react/index.js +355 -234
- package/package.json +4 -3
- package/dist/constants-B6Sm9BNa.js.map +0 -1
- package/dist/index-CbSGuAlP.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElementApi, KEYS, NodeApi, PathApi, PointApi, RangeApi, TextApi, bindFirst, combineTransformMatchOptions, createSlatePlugin, createTSlatePlugin, getEditorPlugin, getPluginTypes
|
|
1
|
+
import { ElementApi, KEYS, NodeApi, PathApi, PointApi, RangeApi, TextApi, bindFirst, combineTransformMatchOptions, createSlatePlugin, createTSlatePlugin, getEditorPlugin, getPluginTypes } from "platejs";
|
|
2
2
|
import cloneDeep from "lodash/cloneDeep.js";
|
|
3
3
|
|
|
4
4
|
//#region src/lib/api/getEmptyCellNode.ts
|
|
@@ -34,30 +34,6 @@ const getEmptyTableNode = (editor, { colCount, header, rowCount = 0, ...cellOpti
|
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region src/lib/queries/getCellInNextTableRow.ts
|
|
39
|
-
const getCellInNextTableRow = (editor, currentRowPath) => {
|
|
40
|
-
const nextRow = editor.api.node(PathApi.next(currentRowPath));
|
|
41
|
-
if (!nextRow) return;
|
|
42
|
-
const [nextRowNode, nextRowPath] = nextRow;
|
|
43
|
-
const nextCell = nextRowNode?.children?.[0];
|
|
44
|
-
const nextCellPath = nextRowPath.concat(0);
|
|
45
|
-
if (nextCell && nextCellPath) return editor.api.node(nextCellPath);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/lib/queries/getCellInPreviousTableRow.ts
|
|
50
|
-
const getCellInPreviousTableRow = (editor, currentRowPath) => {
|
|
51
|
-
const prevPath = PathApi.previous(currentRowPath);
|
|
52
|
-
if (!prevPath) return;
|
|
53
|
-
const previousRow = editor.api.node(prevPath);
|
|
54
|
-
if (!previousRow) return;
|
|
55
|
-
const [previousRowNode, previousRowPath] = previousRow;
|
|
56
|
-
const previousCell = previousRowNode?.children?.[previousRowNode.children.length - 1];
|
|
57
|
-
const previousCellPath = previousRowPath.concat(previousRowNode.children.length - 1);
|
|
58
|
-
if (previousCell && previousCellPath) return editor.api.node(previousCellPath);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
37
|
//#endregion
|
|
62
38
|
//#region src/lib/queries/getColSpan.ts
|
|
63
39
|
/**
|
|
@@ -67,6 +43,22 @@ const getCellInPreviousTableRow = (editor, currentRowPath) => {
|
|
|
67
43
|
*/
|
|
68
44
|
const getColSpan = (cellElem) => cellElem.colSpan || Number(cellElem.attributes?.colspan) || 1;
|
|
69
45
|
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/lib/queries/getRowSpan.ts
|
|
48
|
+
/**
|
|
49
|
+
* Returns the rowspan attribute of the table cell element.
|
|
50
|
+
*
|
|
51
|
+
* @default 1 if undefined
|
|
52
|
+
*/
|
|
53
|
+
const getRowSpan = (cellElem) => cellElem.rowSpan || Number(cellElem.attributes?.rowspan) || 1;
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/lib/merge/getCellIndicesWithSpans.ts
|
|
57
|
+
const getCellIndicesWithSpans = ({ col, row }, endCell) => ({
|
|
58
|
+
col: col + getColSpan(endCell) - 1,
|
|
59
|
+
row: row + getRowSpan(endCell) - 1
|
|
60
|
+
});
|
|
61
|
+
|
|
70
62
|
//#endregion
|
|
71
63
|
//#region src/lib/utils/computeCellIndices.ts
|
|
72
64
|
function computeCellIndices(editor, { all, cellNode, tableNode }) {
|
|
@@ -142,17 +134,100 @@ const getCellRowIndexByPath = (cellPath) => {
|
|
|
142
134
|
const getCellTypes = (editor) => getPluginTypes(editor, [KEYS.td, KEYS.th]);
|
|
143
135
|
|
|
144
136
|
//#endregion
|
|
145
|
-
//#region src/lib/queries/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (!
|
|
152
|
-
const
|
|
153
|
-
|
|
137
|
+
//#region src/lib/queries/getTableEntries.ts
|
|
138
|
+
/**
|
|
139
|
+
* If at (default = selection) is in table>tr>td|th, return table, row, and cell
|
|
140
|
+
* node entries.
|
|
141
|
+
*/
|
|
142
|
+
const getTableEntries = (editor, { at = editor.selection } = {}) => {
|
|
143
|
+
if (!at) return;
|
|
144
|
+
const cellEntry = editor.api.node({
|
|
145
|
+
at,
|
|
146
|
+
match: { type: getCellTypes(editor) }
|
|
147
|
+
});
|
|
148
|
+
if (!cellEntry) return;
|
|
149
|
+
const [, cellPath] = cellEntry;
|
|
150
|
+
const rowEntry = editor.api.above({
|
|
151
|
+
at: cellPath,
|
|
152
|
+
match: { type: editor.getType(KEYS.tr) }
|
|
153
|
+
});
|
|
154
|
+
if (!rowEntry) return;
|
|
155
|
+
const [, rowPath] = rowEntry;
|
|
156
|
+
const tableEntry = editor.api.above({
|
|
157
|
+
at: rowPath,
|
|
158
|
+
match: { type: editor.getType(KEYS.table) }
|
|
159
|
+
});
|
|
160
|
+
if (!tableEntry) return;
|
|
161
|
+
return {
|
|
162
|
+
cell: cellEntry,
|
|
163
|
+
row: rowEntry,
|
|
164
|
+
table: tableEntry
|
|
165
|
+
};
|
|
154
166
|
};
|
|
155
167
|
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/lib/queries/getAdjacentTableCell.ts
|
|
170
|
+
const adjacentTableCellLookup = /* @__PURE__ */ new WeakMap();
|
|
171
|
+
const getLookupKey = (row, col) => `${row}:${col}`;
|
|
172
|
+
const createTableCellLookup = (editor, tableEntry) => {
|
|
173
|
+
const [table, tablePath] = tableEntry;
|
|
174
|
+
const cachedLookup = adjacentTableCellLookup.get(table);
|
|
175
|
+
if (cachedLookup) return cachedLookup;
|
|
176
|
+
const nextLookup = /* @__PURE__ */ new Map();
|
|
177
|
+
table.children.forEach((rowNode, rowIndex) => {
|
|
178
|
+
rowNode.children.forEach((cellNode, cellIndex) => {
|
|
179
|
+
const cellEntry = [cellNode, tablePath.concat([rowIndex, cellIndex])];
|
|
180
|
+
const indices = getCellIndices(editor, cellEntry[0]);
|
|
181
|
+
const { col: endCol, row: endRow } = getCellIndicesWithSpans(indices, cellEntry[0]);
|
|
182
|
+
for (let row = indices.row; row <= endRow; row++) for (let col = indices.col; col <= endCol; col++) nextLookup.set(getLookupKey(row, col), cellEntry);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
adjacentTableCellLookup.set(table, nextLookup);
|
|
186
|
+
return nextLookup;
|
|
187
|
+
};
|
|
188
|
+
const getAdjacentTableCell = (editor, { at, deltaCol = 0, deltaRow = 0 } = {}) => {
|
|
189
|
+
const entries = getTableEntries(editor, { at });
|
|
190
|
+
if (!entries) return;
|
|
191
|
+
const [cell] = entries.cell;
|
|
192
|
+
const tableEntry = entries.table;
|
|
193
|
+
const { col, row } = getCellIndices(editor, cell);
|
|
194
|
+
const nextCol = col + deltaCol;
|
|
195
|
+
const nextRow = row + deltaRow;
|
|
196
|
+
if (nextCol < 0 || nextRow < 0) return;
|
|
197
|
+
return createTableCellLookup(editor, tableEntry).get(getLookupKey(nextRow, nextCol));
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/lib/queries/getCellInNextTableRow.ts
|
|
202
|
+
const getCellInNextTableRow = (editor, currentRowPath) => {
|
|
203
|
+
const nextRow = editor.api.node(PathApi.next(currentRowPath));
|
|
204
|
+
if (!nextRow) return;
|
|
205
|
+
const [nextRowNode, nextRowPath] = nextRow;
|
|
206
|
+
const nextCell = nextRowNode?.children?.[0];
|
|
207
|
+
const nextCellPath = nextRowPath.concat(0);
|
|
208
|
+
if (nextCell && nextCellPath) return editor.api.node(nextCellPath);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/lib/queries/getCellInPreviousTableRow.ts
|
|
213
|
+
const getCellInPreviousTableRow = (editor, currentRowPath) => {
|
|
214
|
+
const prevPath = PathApi.previous(currentRowPath);
|
|
215
|
+
if (!prevPath) return;
|
|
216
|
+
const previousRow = editor.api.node(prevPath);
|
|
217
|
+
if (!previousRow) return;
|
|
218
|
+
const [previousRowNode, previousRowPath] = previousRow;
|
|
219
|
+
const previousCell = previousRowNode?.children?.[previousRowNode.children.length - 1];
|
|
220
|
+
const previousCellPath = previousRowPath.concat(previousRowNode.children.length - 1);
|
|
221
|
+
if (previousCell && previousCellPath) return editor.api.node(previousCellPath);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/lib/queries/getLeftTableCell.ts
|
|
226
|
+
const getLeftTableCell = (editor, { at: cellPath } = {}) => getAdjacentTableCell(editor, {
|
|
227
|
+
at: cellPath,
|
|
228
|
+
deltaCol: -1
|
|
229
|
+
});
|
|
230
|
+
|
|
156
231
|
//#endregion
|
|
157
232
|
//#region src/lib/queries/getNextTableCell.ts
|
|
158
233
|
const getNextTableCell = (editor, _currentCell, currentPath, currentRow) => {
|
|
@@ -163,25 +238,277 @@ const getNextTableCell = (editor, _currentCell, currentPath, currentRow) => {
|
|
|
163
238
|
};
|
|
164
239
|
|
|
165
240
|
//#endregion
|
|
166
|
-
//#region src/lib/queries/getPreviousTableCell.ts
|
|
167
|
-
const getPreviousTableCell = (editor, _currentCell, currentPath, currentRow) => {
|
|
168
|
-
const prevPath = PathApi.previous(currentPath);
|
|
169
|
-
if (!prevPath) {
|
|
170
|
-
const [, currentRowPath] = currentRow;
|
|
171
|
-
return getCellInPreviousTableRow(editor, currentRowPath);
|
|
241
|
+
//#region src/lib/queries/getPreviousTableCell.ts
|
|
242
|
+
const getPreviousTableCell = (editor, _currentCell, currentPath, currentRow) => {
|
|
243
|
+
const prevPath = PathApi.previous(currentPath);
|
|
244
|
+
if (!prevPath) {
|
|
245
|
+
const [, currentRowPath] = currentRow;
|
|
246
|
+
return getCellInPreviousTableRow(editor, currentRowPath);
|
|
247
|
+
}
|
|
248
|
+
const cell = editor.api.node(prevPath);
|
|
249
|
+
if (cell) return cell;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/lib/merge/findCellByIndexes.ts
|
|
254
|
+
const findCellByIndexes = (editor, table, searchRowIndex, searchColIndex) => {
|
|
255
|
+
return table.children.flatMap((current) => current.children).find((cellNode) => {
|
|
256
|
+
const indices = getCellIndices(editor, cellNode);
|
|
257
|
+
const { col: _startColIndex, row: _startRowIndex } = indices;
|
|
258
|
+
const { col: _endColIndex, row: _endRowIndex } = getCellIndicesWithSpans(indices, cellNode);
|
|
259
|
+
if (searchColIndex >= _startColIndex && searchColIndex <= _endColIndex && searchRowIndex >= _startRowIndex && searchRowIndex <= _endRowIndex) return true;
|
|
260
|
+
return false;
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/lib/merge/getTableGridByRange.ts
|
|
266
|
+
/**
|
|
267
|
+
* Get sub table between 2 cell paths. Ensure that the selection is always a
|
|
268
|
+
* valid table grid.
|
|
269
|
+
*/
|
|
270
|
+
const getTableMergeGridByRange = (editor, { at, format }) => {
|
|
271
|
+
const { api, type } = getEditorPlugin(editor, BaseTablePlugin);
|
|
272
|
+
const startCellEntry = editor.api.node({
|
|
273
|
+
at: at.anchor.path,
|
|
274
|
+
match: { type: getCellTypes(editor) }
|
|
275
|
+
});
|
|
276
|
+
const endCellEntry = editor.api.node({
|
|
277
|
+
at: at.focus.path,
|
|
278
|
+
match: { type: getCellTypes(editor) }
|
|
279
|
+
});
|
|
280
|
+
const startCell = startCellEntry[0];
|
|
281
|
+
const endCell = endCellEntry[0];
|
|
282
|
+
const tablePath = startCellEntry[1].slice(0, -2);
|
|
283
|
+
const realTable = editor.api.node({
|
|
284
|
+
at: tablePath,
|
|
285
|
+
match: { type }
|
|
286
|
+
})[0];
|
|
287
|
+
const { col: _startColIndex, row: _startRowIndex } = getCellIndicesWithSpans(getCellIndices(editor, startCell), startCell);
|
|
288
|
+
const { col: _endColIndex, row: _endRowIndex } = getCellIndicesWithSpans(getCellIndices(editor, endCell), endCell);
|
|
289
|
+
let startRowIndex = Math.min(_startRowIndex, _endRowIndex);
|
|
290
|
+
let endRowIndex = Math.max(_startRowIndex, _endRowIndex);
|
|
291
|
+
let startColIndex = Math.min(_startColIndex, _endColIndex);
|
|
292
|
+
let endColIndex = Math.max(_startColIndex, _endColIndex);
|
|
293
|
+
const relativeRowIndex = endRowIndex - startRowIndex;
|
|
294
|
+
const relativeColIndex = endColIndex - startColIndex;
|
|
295
|
+
let table = api.create.table({
|
|
296
|
+
children: [],
|
|
297
|
+
colCount: relativeColIndex + 1,
|
|
298
|
+
rowCount: relativeRowIndex + 1
|
|
299
|
+
});
|
|
300
|
+
let cellEntries = [];
|
|
301
|
+
let cellsSet = /* @__PURE__ */ new WeakSet();
|
|
302
|
+
let rowIndex = startRowIndex;
|
|
303
|
+
let colIndex = startColIndex;
|
|
304
|
+
while (true) {
|
|
305
|
+
const cell = findCellByIndexes(editor, realTable, rowIndex, colIndex);
|
|
306
|
+
if (!cell) break;
|
|
307
|
+
const indicies = getCellIndices(editor, cell);
|
|
308
|
+
const { col: cellColWithSpan, row: cellRowWithSpan } = getCellIndicesWithSpans(indicies, cell);
|
|
309
|
+
const { col: cellCol, row: cellRow } = indicies;
|
|
310
|
+
if (cellRow < startRowIndex || cellRowWithSpan > endRowIndex || cellCol < startColIndex || cellColWithSpan > endColIndex) {
|
|
311
|
+
cellsSet = /* @__PURE__ */ new WeakSet();
|
|
312
|
+
cellEntries = [];
|
|
313
|
+
startRowIndex = Math.min(startRowIndex, cellRow);
|
|
314
|
+
endRowIndex = Math.max(endRowIndex, cellRowWithSpan);
|
|
315
|
+
startColIndex = Math.min(startColIndex, cellCol);
|
|
316
|
+
endColIndex = Math.max(endColIndex, cellColWithSpan);
|
|
317
|
+
rowIndex = startRowIndex;
|
|
318
|
+
colIndex = startColIndex;
|
|
319
|
+
const newRelativeRowIndex = endRowIndex - startRowIndex;
|
|
320
|
+
const newRelativeColIndex = endColIndex - startColIndex;
|
|
321
|
+
table = api.create.table({
|
|
322
|
+
children: [],
|
|
323
|
+
colCount: newRelativeColIndex + 1,
|
|
324
|
+
rowCount: newRelativeRowIndex + 1
|
|
325
|
+
});
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (!cellsSet.has(cell)) {
|
|
329
|
+
cellsSet.add(cell);
|
|
330
|
+
const rows = table.children[rowIndex - startRowIndex].children;
|
|
331
|
+
rows[colIndex - startColIndex] = cell;
|
|
332
|
+
const cellPath = editor.api.findPath(cell);
|
|
333
|
+
cellEntries.push([cell, cellPath]);
|
|
334
|
+
}
|
|
335
|
+
if (colIndex + 1 <= endColIndex) colIndex += 1;
|
|
336
|
+
else if (rowIndex + 1 <= endRowIndex) {
|
|
337
|
+
colIndex = startColIndex;
|
|
338
|
+
rowIndex += 1;
|
|
339
|
+
} else break;
|
|
340
|
+
}
|
|
341
|
+
const formatType = format || "table";
|
|
342
|
+
if (formatType === "cell") return cellEntries;
|
|
343
|
+
table.children?.forEach((rowEl) => {
|
|
344
|
+
const rowElement = rowEl;
|
|
345
|
+
rowElement.children = rowElement.children?.filter((cellEl) => {
|
|
346
|
+
const cellElement = cellEl;
|
|
347
|
+
return api.table.getCellChildren(cellElement).length > 0;
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
if (formatType === "table") return [[table, tablePath]];
|
|
351
|
+
return {
|
|
352
|
+
cellEntries,
|
|
353
|
+
tableEntries: [[table, tablePath]]
|
|
354
|
+
};
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/lib/queries/getTableGridByRange.ts
|
|
359
|
+
/** Get sub table between 2 cell paths. */
|
|
360
|
+
const getTableGridByRange = (editor, { at, format = "table" }) => {
|
|
361
|
+
const { api } = editor.getPlugin({ key: KEYS.table });
|
|
362
|
+
const { disableMerge } = editor.getOptions(BaseTablePlugin);
|
|
363
|
+
if (!disableMerge) return getTableMergeGridByRange(editor, {
|
|
364
|
+
at,
|
|
365
|
+
format
|
|
366
|
+
});
|
|
367
|
+
const startCellPath = at.anchor.path;
|
|
368
|
+
const endCellPath = at.focus.path;
|
|
369
|
+
const _startRowIndex = startCellPath.at(-2);
|
|
370
|
+
const _endRowIndex = endCellPath.at(-2);
|
|
371
|
+
const _startColIndex = startCellPath.at(-1);
|
|
372
|
+
const _endColIndex = endCellPath.at(-1);
|
|
373
|
+
const startRowIndex = Math.min(_startRowIndex, _endRowIndex);
|
|
374
|
+
const endRowIndex = Math.max(_startRowIndex, _endRowIndex);
|
|
375
|
+
const startColIndex = Math.min(_startColIndex, _endColIndex);
|
|
376
|
+
const endColIndex = Math.max(_startColIndex, _endColIndex);
|
|
377
|
+
const tablePath = startCellPath.slice(0, -2);
|
|
378
|
+
const relativeRowIndex = endRowIndex - startRowIndex;
|
|
379
|
+
const relativeColIndex = endColIndex - startColIndex;
|
|
380
|
+
const table = api.create.table({
|
|
381
|
+
children: [],
|
|
382
|
+
colCount: relativeColIndex + 1,
|
|
383
|
+
rowCount: relativeRowIndex + 1
|
|
384
|
+
});
|
|
385
|
+
let rowIndex = startRowIndex;
|
|
386
|
+
let colIndex = startColIndex;
|
|
387
|
+
const cellEntries = [];
|
|
388
|
+
while (true) {
|
|
389
|
+
const cellPath = tablePath.concat([rowIndex, colIndex]);
|
|
390
|
+
const cell = NodeApi.get(editor, cellPath);
|
|
391
|
+
if (!cell) break;
|
|
392
|
+
const rows = table.children[rowIndex - startRowIndex].children;
|
|
393
|
+
rows[colIndex - startColIndex] = cell;
|
|
394
|
+
cellEntries.push([cell, cellPath]);
|
|
395
|
+
if (colIndex + 1 <= endColIndex) colIndex += 1;
|
|
396
|
+
else if (rowIndex + 1 <= endRowIndex) {
|
|
397
|
+
colIndex = startColIndex;
|
|
398
|
+
rowIndex += 1;
|
|
399
|
+
} else break;
|
|
400
|
+
}
|
|
401
|
+
if (format === "cell") return cellEntries;
|
|
402
|
+
return [[table, tablePath]];
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/lib/queries/getTableGridAbove.ts
|
|
407
|
+
/** Get sub table above anchor and focus. Format: tables or cells. */
|
|
408
|
+
const getTableGridAbove = (editor, { format = "table", ...options } = {}) => {
|
|
409
|
+
const { api } = editor.getPlugin({ key: KEYS.table });
|
|
410
|
+
const edges = editor.api.edgeBlocks({
|
|
411
|
+
match: { type: getCellTypes(editor) },
|
|
412
|
+
...options
|
|
413
|
+
});
|
|
414
|
+
if (edges) {
|
|
415
|
+
const [start, end] = edges;
|
|
416
|
+
if (!PathApi.equals(start[1], end[1])) return getTableGridByRange(editor, {
|
|
417
|
+
at: {
|
|
418
|
+
anchor: {
|
|
419
|
+
offset: 0,
|
|
420
|
+
path: start[1]
|
|
421
|
+
},
|
|
422
|
+
focus: {
|
|
423
|
+
offset: 0,
|
|
424
|
+
path: end[1]
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
format
|
|
428
|
+
});
|
|
429
|
+
if (format === "table") {
|
|
430
|
+
const table = api.create.table({ rowCount: 1 });
|
|
431
|
+
table.children[0].children = [start[0]];
|
|
432
|
+
return [[table, start[1].slice(0, -2)]];
|
|
433
|
+
}
|
|
434
|
+
return [start];
|
|
435
|
+
}
|
|
436
|
+
return [];
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/lib/queries/getSelectedCells.ts
|
|
441
|
+
const selectionQueryCache = /* @__PURE__ */ new WeakMap();
|
|
442
|
+
const getSelectionQueryCache = (editor) => {
|
|
443
|
+
const { selection } = editor;
|
|
444
|
+
const { children } = editor;
|
|
445
|
+
const cachedValue = selectionQueryCache.get(editor);
|
|
446
|
+
if (cachedValue && cachedValue.children === children && cachedValue.selection === selection) return cachedValue;
|
|
447
|
+
const nextValue = {
|
|
448
|
+
children,
|
|
449
|
+
selection
|
|
450
|
+
};
|
|
451
|
+
selectionQueryCache.set(editor, nextValue);
|
|
452
|
+
return nextValue;
|
|
453
|
+
};
|
|
454
|
+
const getSelectedCellEntries = (editor) => {
|
|
455
|
+
const cache = getSelectionQueryCache(editor);
|
|
456
|
+
if ("cellEntries" in cache) return cache.cellEntries ?? [];
|
|
457
|
+
const cellEntries = getTableGridAbove(editor, { format: "cell" });
|
|
458
|
+
const nextValue = cellEntries.length > 1 ? cellEntries : [];
|
|
459
|
+
cache.cellEntries = nextValue;
|
|
460
|
+
return nextValue;
|
|
461
|
+
};
|
|
462
|
+
const getSelectedCells = (editor) => {
|
|
463
|
+
const cache = getSelectionQueryCache(editor);
|
|
464
|
+
if ("selectedCells" in cache) return cache.selectedCells ?? null;
|
|
465
|
+
const cellEntries = getSelectedCellEntries(editor);
|
|
466
|
+
if (cellEntries.length === 0) {
|
|
467
|
+
cache.selectedCells = null;
|
|
468
|
+
return null;
|
|
172
469
|
}
|
|
173
|
-
const
|
|
174
|
-
|
|
470
|
+
const nextValue = cellEntries.map(([cell]) => cell);
|
|
471
|
+
cache.selectedCells = nextValue;
|
|
472
|
+
return nextValue;
|
|
175
473
|
};
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
474
|
+
const getSelectedCellIds = (editor) => {
|
|
475
|
+
const cache = getSelectionQueryCache(editor);
|
|
476
|
+
if ("selectedCellIds" in cache) return cache.selectedCellIds ?? null;
|
|
477
|
+
const selectedCellIds = getSelectedCellEntries(editor).map(([cell]) => cell.id).filter((id) => !!id);
|
|
478
|
+
const nextValue = selectedCellIds.length > 0 ? selectedCellIds : null;
|
|
479
|
+
cache.selectedCellIds = nextValue;
|
|
480
|
+
return nextValue;
|
|
481
|
+
};
|
|
482
|
+
const getSelectedTableIds = (editor) => {
|
|
483
|
+
const cache = getSelectionQueryCache(editor);
|
|
484
|
+
if ("selectedTableIds" in cache) return cache.selectedTableIds ?? null;
|
|
485
|
+
const selectedTables = getSelectedTables(editor);
|
|
486
|
+
if (!selectedTables) {
|
|
487
|
+
cache.selectedTableIds = null;
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
const selectedTableIds = selectedTables.map((table) => table.id).filter((id) => !!id);
|
|
491
|
+
const nextValue = selectedTableIds.length > 0 ? selectedTableIds : null;
|
|
492
|
+
cache.selectedTableIds = nextValue;
|
|
493
|
+
return nextValue;
|
|
494
|
+
};
|
|
495
|
+
const getSelectedCell = (editor, id) => {
|
|
496
|
+
if (!id) return null;
|
|
497
|
+
return getSelectedCellEntries(editor).find(([cell]) => cell.id === id)?.[0] ?? null;
|
|
498
|
+
};
|
|
499
|
+
const getSelectedTables = (editor) => {
|
|
500
|
+
const cache = getSelectionQueryCache(editor);
|
|
501
|
+
if ("selectedTables" in cache) return cache.selectedTables ?? null;
|
|
502
|
+
if (getSelectedCellEntries(editor).length === 0) {
|
|
503
|
+
cache.selectedTables = null;
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
const nextValue = getTableGridAbove(editor, { format: "table" }).map(([table]) => table);
|
|
507
|
+
cache.selectedTables = nextValue;
|
|
508
|
+
return nextValue;
|
|
509
|
+
};
|
|
510
|
+
const isCellSelected = (editor, id) => !!getSelectedCell(editor, id);
|
|
511
|
+
const isSelectingCell = (editor) => getSelectedCellEntries(editor).length > 0;
|
|
185
512
|
|
|
186
513
|
//#endregion
|
|
187
514
|
//#region src/lib/queries/getSelectedCellsBoundingBox.ts
|
|
@@ -211,21 +538,10 @@ function getSelectedCellsBoundingBox(editor, cells) {
|
|
|
211
538
|
|
|
212
539
|
//#endregion
|
|
213
540
|
//#region src/lib/queries/getTopTableCell.ts
|
|
214
|
-
const getTopTableCell = (editor, { at: cellPath } = {}) => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
const cellIndex = cellPath.at(-1);
|
|
220
|
-
const rowIndex = cellPath.at(-2);
|
|
221
|
-
if (rowIndex === 0) return;
|
|
222
|
-
const cellAbovePath = [
|
|
223
|
-
...PathApi.parent(PathApi.parent(cellPath)),
|
|
224
|
-
rowIndex - 1,
|
|
225
|
-
cellIndex
|
|
226
|
-
];
|
|
227
|
-
return editor.api.node(cellAbovePath);
|
|
228
|
-
};
|
|
541
|
+
const getTopTableCell = (editor, { at: cellPath } = {}) => getAdjacentTableCell(editor, {
|
|
542
|
+
at: cellPath,
|
|
543
|
+
deltaRow: -1
|
|
544
|
+
});
|
|
229
545
|
|
|
230
546
|
//#endregion
|
|
231
547
|
//#region src/lib/queries/getSelectedCellsBorders.ts
|
|
@@ -419,317 +735,104 @@ function isSelectedCellBorder(editor, cells, side) {
|
|
|
419
735
|
if (!cellAboveEntry) return true;
|
|
420
736
|
const [cellAboveNode] = cellAboveEntry;
|
|
421
737
|
return (cellAboveNode.borders?.bottom?.size ?? 1) >= 1;
|
|
422
|
-
}
|
|
423
|
-
if (side === "bottom" && rr === maxRow) return (cell.borders?.bottom?.size ?? 1) >= 1;
|
|
424
|
-
if (side === "left" && cc === minCol) {
|
|
425
|
-
if (col === 0) return (cell.borders?.left?.size ?? 1) >= 1;
|
|
426
|
-
const prevCellEntry = getLeftTableCell(editor, { at: cellPath });
|
|
427
|
-
if (!prevCellEntry) return true;
|
|
428
|
-
const [prevCellNode] = prevCellEntry;
|
|
429
|
-
return (prevCellNode.borders?.right?.size ?? 1) >= 1;
|
|
430
|
-
}
|
|
431
|
-
if (side === "right" && cc === maxCol) return (cell.borders?.right?.size ?? 1) >= 1;
|
|
432
|
-
}
|
|
433
|
-
return true;
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
//#endregion
|
|
438
|
-
//#region src/lib/queries/getTableAbove.ts
|
|
439
|
-
const getTableAbove = (editor, options) => editor.api.block({
|
|
440
|
-
above: true,
|
|
441
|
-
match: { type: editor.getType(KEYS.table) },
|
|
442
|
-
...options
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
//#endregion
|
|
446
|
-
//#region src/lib/queries/getTableCellBorders.ts
|
|
447
|
-
const getTableCellBorders = (editor, { cellIndices, defaultBorder = { size: 1 }, element }) => {
|
|
448
|
-
const cellPath = editor.api.findPath(element);
|
|
449
|
-
const [rowNode, rowPath] = editor.api.parent(cellPath) ?? [];
|
|
450
|
-
if (!rowNode || !rowPath) return {
|
|
451
|
-
bottom: defaultBorder,
|
|
452
|
-
right: defaultBorder
|
|
453
|
-
};
|
|
454
|
-
const [tableNode] = editor.api.parent(rowPath);
|
|
455
|
-
const { col } = cellIndices ?? getCellIndices(editor, element);
|
|
456
|
-
const isFirstCell = col === 0;
|
|
457
|
-
const isFirstRow = tableNode.children?.[0] === rowNode;
|
|
458
|
-
const getBorder = (dir) => {
|
|
459
|
-
const border = element.borders?.[dir];
|
|
460
|
-
return {
|
|
461
|
-
color: border?.color ?? defaultBorder.color,
|
|
462
|
-
size: border?.size ?? defaultBorder.size,
|
|
463
|
-
style: border?.style ?? defaultBorder.style
|
|
464
|
-
};
|
|
465
|
-
};
|
|
466
|
-
return {
|
|
467
|
-
bottom: getBorder("bottom"),
|
|
468
|
-
left: isFirstCell ? getBorder("left") : void 0,
|
|
469
|
-
right: getBorder("right"),
|
|
470
|
-
top: isFirstRow ? getBorder("top") : void 0
|
|
471
|
-
};
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
//#endregion
|
|
475
|
-
//#region src/lib/queries/getTableCellSize.ts
|
|
476
|
-
/** Get the width of a cell with colSpan support. */
|
|
477
|
-
const getTableCellSize = (editor, { cellIndices, colSizes, element, rowSize }) => {
|
|
478
|
-
const { api } = getEditorPlugin(editor, { key: KEYS.table });
|
|
479
|
-
const path = editor.api.findPath(element);
|
|
480
|
-
if (!rowSize) {
|
|
481
|
-
const [rowElement] = editor.api.parent(path) ?? [];
|
|
482
|
-
if (!rowElement) return {
|
|
483
|
-
minHeight: 0,
|
|
484
|
-
width: 0
|
|
485
|
-
};
|
|
486
|
-
rowSize = rowElement.size;
|
|
487
|
-
}
|
|
488
|
-
if (!colSizes) {
|
|
489
|
-
const [, rowPath] = editor.api.parent(path);
|
|
490
|
-
const [tableNode] = editor.api.parent(rowPath);
|
|
491
|
-
colSizes = getTableOverriddenColSizes(tableNode);
|
|
492
|
-
}
|
|
493
|
-
const colSpan = api.table.getColSpan(element);
|
|
494
|
-
const { col } = cellIndices ?? getCellIndices(editor, element);
|
|
495
|
-
const width = (colSizes ?? []).slice(col, col + colSpan).reduce((total, w) => total + (w || 0), 0);
|
|
496
|
-
return {
|
|
497
|
-
minHeight: rowSize,
|
|
498
|
-
width
|
|
499
|
-
};
|
|
500
|
-
};
|
|
501
|
-
|
|
502
|
-
//#endregion
|
|
503
|
-
//#region src/lib/queries/getTableColumnCount.ts
|
|
504
|
-
const getTableColumnCount = (tableNode) => {
|
|
505
|
-
if (tableNode.children?.[0]?.children) return tableNode.children[0].children.map((element) => element.colSpan || (element?.attributes)?.colspan || 1).reduce((total, num) => Number(total) + Number(num));
|
|
506
|
-
return 0;
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
//#endregion
|
|
510
|
-
//#region src/lib/queries/getTableEntries.ts
|
|
511
|
-
/**
|
|
512
|
-
* If at (default = selection) is in table>tr>td|th, return table, row, and cell
|
|
513
|
-
* node entries.
|
|
514
|
-
*/
|
|
515
|
-
const getTableEntries = (editor, { at = editor.selection } = {}) => {
|
|
516
|
-
if (!at) return;
|
|
517
|
-
const cellEntry = editor.api.node({
|
|
518
|
-
at,
|
|
519
|
-
match: { type: getCellTypes(editor) }
|
|
520
|
-
});
|
|
521
|
-
if (!cellEntry) return;
|
|
522
|
-
const [, cellPath] = cellEntry;
|
|
523
|
-
const rowEntry = editor.api.above({
|
|
524
|
-
at: cellPath,
|
|
525
|
-
match: { type: editor.getType(KEYS.tr) }
|
|
526
|
-
});
|
|
527
|
-
if (!rowEntry) return;
|
|
528
|
-
const [, rowPath] = rowEntry;
|
|
529
|
-
const tableEntry = editor.api.above({
|
|
530
|
-
at: rowPath,
|
|
531
|
-
match: { type: editor.getType(KEYS.table) }
|
|
532
|
-
});
|
|
533
|
-
if (!tableEntry) return;
|
|
534
|
-
return {
|
|
535
|
-
cell: cellEntry,
|
|
536
|
-
row: rowEntry,
|
|
537
|
-
table: tableEntry
|
|
538
|
-
};
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
//#endregion
|
|
542
|
-
//#region src/lib/merge/getCellIndicesWithSpans.ts
|
|
543
|
-
const getCellIndicesWithSpans = ({ col, row }, endCell) => ({
|
|
544
|
-
col: col + getColSpan(endCell) - 1,
|
|
545
|
-
row: row + getRowSpan(endCell) - 1
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
//#endregion
|
|
549
|
-
//#region src/lib/merge/findCellByIndexes.ts
|
|
550
|
-
const findCellByIndexes = (editor, table, searchRowIndex, searchColIndex) => {
|
|
551
|
-
return table.children.flatMap((current) => current.children).find((cellNode) => {
|
|
552
|
-
const indices = getCellIndices(editor, cellNode);
|
|
553
|
-
const { col: _startColIndex, row: _startRowIndex } = indices;
|
|
554
|
-
const { col: _endColIndex, row: _endRowIndex } = getCellIndicesWithSpans(indices, cellNode);
|
|
555
|
-
if (searchColIndex >= _startColIndex && searchColIndex <= _endColIndex && searchRowIndex >= _startRowIndex && searchRowIndex <= _endRowIndex) return true;
|
|
556
|
-
return false;
|
|
557
|
-
});
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
//#endregion
|
|
561
|
-
//#region src/lib/merge/getTableGridByRange.ts
|
|
562
|
-
/**
|
|
563
|
-
* Get sub table between 2 cell paths. Ensure that the selection is always a
|
|
564
|
-
* valid table grid.
|
|
565
|
-
*/
|
|
566
|
-
const getTableMergeGridByRange = (editor, { at, format }) => {
|
|
567
|
-
const { api, type } = getEditorPlugin(editor, BaseTablePlugin);
|
|
568
|
-
const startCellEntry = editor.api.node({
|
|
569
|
-
at: at.anchor.path,
|
|
570
|
-
match: { type: getCellTypes(editor) }
|
|
571
|
-
});
|
|
572
|
-
const endCellEntry = editor.api.node({
|
|
573
|
-
at: at.focus.path,
|
|
574
|
-
match: { type: getCellTypes(editor) }
|
|
575
|
-
});
|
|
576
|
-
const startCell = startCellEntry[0];
|
|
577
|
-
const endCell = endCellEntry[0];
|
|
578
|
-
const tablePath = at.anchor.path.slice(0, -2);
|
|
579
|
-
const realTable = editor.api.node({
|
|
580
|
-
at: tablePath,
|
|
581
|
-
match: { type }
|
|
582
|
-
})[0];
|
|
583
|
-
const { col: _startColIndex, row: _startRowIndex } = getCellIndicesWithSpans(getCellIndices(editor, startCell), startCell);
|
|
584
|
-
const { col: _endColIndex, row: _endRowIndex } = getCellIndicesWithSpans(getCellIndices(editor, endCell), endCell);
|
|
585
|
-
let startRowIndex = Math.min(_startRowIndex, _endRowIndex);
|
|
586
|
-
let endRowIndex = Math.max(_startRowIndex, _endRowIndex);
|
|
587
|
-
let startColIndex = Math.min(_startColIndex, _endColIndex);
|
|
588
|
-
let endColIndex = Math.max(_startColIndex, _endColIndex);
|
|
589
|
-
const relativeRowIndex = endRowIndex - startRowIndex;
|
|
590
|
-
const relativeColIndex = endColIndex - startColIndex;
|
|
591
|
-
let table = api.create.table({
|
|
592
|
-
children: [],
|
|
593
|
-
colCount: relativeColIndex + 1,
|
|
594
|
-
rowCount: relativeRowIndex + 1
|
|
595
|
-
});
|
|
596
|
-
let cellEntries = [];
|
|
597
|
-
let cellsSet = /* @__PURE__ */ new WeakSet();
|
|
598
|
-
let rowIndex = startRowIndex;
|
|
599
|
-
let colIndex = startColIndex;
|
|
600
|
-
while (true) {
|
|
601
|
-
const cell = findCellByIndexes(editor, realTable, rowIndex, colIndex);
|
|
602
|
-
if (!cell) break;
|
|
603
|
-
const indicies = getCellIndices(editor, cell);
|
|
604
|
-
const { col: cellColWithSpan, row: cellRowWithSpan } = getCellIndicesWithSpans(indicies, cell);
|
|
605
|
-
const { col: cellCol, row: cellRow } = indicies;
|
|
606
|
-
if (cellRow < startRowIndex || cellRowWithSpan > endRowIndex || cellCol < startColIndex || cellColWithSpan > endColIndex) {
|
|
607
|
-
cellsSet = /* @__PURE__ */ new WeakSet();
|
|
608
|
-
cellEntries = [];
|
|
609
|
-
startRowIndex = Math.min(startRowIndex, cellRow);
|
|
610
|
-
endRowIndex = Math.max(endRowIndex, cellRowWithSpan);
|
|
611
|
-
startColIndex = Math.min(startColIndex, cellCol);
|
|
612
|
-
endColIndex = Math.max(endColIndex, cellColWithSpan);
|
|
613
|
-
rowIndex = startRowIndex;
|
|
614
|
-
colIndex = startColIndex;
|
|
615
|
-
const newRelativeRowIndex = endRowIndex - startRowIndex;
|
|
616
|
-
const newRelativeColIndex = endColIndex - startColIndex;
|
|
617
|
-
table = api.create.table({
|
|
618
|
-
children: [],
|
|
619
|
-
colCount: newRelativeColIndex + 1,
|
|
620
|
-
rowCount: newRelativeRowIndex + 1
|
|
621
|
-
});
|
|
622
|
-
continue;
|
|
623
|
-
}
|
|
624
|
-
if (!cellsSet.has(cell)) {
|
|
625
|
-
cellsSet.add(cell);
|
|
626
|
-
const rows = table.children[rowIndex - startRowIndex].children;
|
|
627
|
-
rows[colIndex - startColIndex] = cell;
|
|
628
|
-
const cellPath = editor.api.findPath(cell);
|
|
629
|
-
cellEntries.push([cell, cellPath]);
|
|
630
|
-
}
|
|
631
|
-
if (colIndex + 1 <= endColIndex) colIndex += 1;
|
|
632
|
-
else if (rowIndex + 1 <= endRowIndex) {
|
|
633
|
-
colIndex = startColIndex;
|
|
634
|
-
rowIndex += 1;
|
|
635
|
-
} else break;
|
|
636
|
-
}
|
|
637
|
-
const formatType = format || "table";
|
|
638
|
-
if (formatType === "cell") return cellEntries;
|
|
639
|
-
table.children?.forEach((rowEl) => {
|
|
640
|
-
const rowElement = rowEl;
|
|
641
|
-
rowElement.children = rowElement.children?.filter((cellEl) => {
|
|
642
|
-
const cellElement = cellEl;
|
|
643
|
-
return api.table.getCellChildren(cellElement).length > 0;
|
|
644
|
-
});
|
|
738
|
+
}
|
|
739
|
+
if (side === "bottom" && rr === maxRow) return (cell.borders?.bottom?.size ?? 1) >= 1;
|
|
740
|
+
if (side === "left" && cc === minCol) {
|
|
741
|
+
if (col === 0) return (cell.borders?.left?.size ?? 1) >= 1;
|
|
742
|
+
const prevCellEntry = getLeftTableCell(editor, { at: cellPath });
|
|
743
|
+
if (!prevCellEntry) return true;
|
|
744
|
+
const [prevCellNode] = prevCellEntry;
|
|
745
|
+
return (prevCellNode.borders?.right?.size ?? 1) >= 1;
|
|
746
|
+
}
|
|
747
|
+
if (side === "right" && cc === maxCol) return (cell.borders?.right?.size ?? 1) >= 1;
|
|
748
|
+
}
|
|
749
|
+
return true;
|
|
645
750
|
});
|
|
646
|
-
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
//#endregion
|
|
754
|
+
//#region src/lib/queries/getTableAbove.ts
|
|
755
|
+
const getTableAbove = (editor, options) => editor.api.block({
|
|
756
|
+
above: true,
|
|
757
|
+
match: { type: editor.getType(KEYS.table) },
|
|
758
|
+
...options
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
//#endregion
|
|
762
|
+
//#region src/lib/queries/getTableCellBorders.ts
|
|
763
|
+
const getTableCellBorders = (editor, { cellIndices, defaultBorder = { size: 1 }, element }) => {
|
|
764
|
+
const cellPath = editor.api.findPath(element);
|
|
765
|
+
const [rowNode, rowPath] = editor.api.parent(cellPath) ?? [];
|
|
766
|
+
if (!rowNode || !rowPath) return {
|
|
767
|
+
bottom: defaultBorder,
|
|
768
|
+
right: defaultBorder
|
|
769
|
+
};
|
|
770
|
+
const [tableNode] = editor.api.parent(rowPath) ?? [];
|
|
771
|
+
const tableType = editor.getType(KEYS.table);
|
|
772
|
+
if (!tableNode || tableNode.type !== tableType) return {
|
|
773
|
+
bottom: defaultBorder,
|
|
774
|
+
right: defaultBorder
|
|
775
|
+
};
|
|
776
|
+
const { col } = cellIndices ?? getCellIndices(editor, element);
|
|
777
|
+
const isFirstCell = col === 0;
|
|
778
|
+
const isFirstRow = tableNode.children?.[0] === rowNode;
|
|
779
|
+
const getBorder = (dir) => {
|
|
780
|
+
const border = element.borders?.[dir];
|
|
781
|
+
return {
|
|
782
|
+
color: border?.color ?? defaultBorder.color,
|
|
783
|
+
size: border?.size ?? defaultBorder.size,
|
|
784
|
+
style: border?.style ?? defaultBorder.style
|
|
785
|
+
};
|
|
786
|
+
};
|
|
647
787
|
return {
|
|
648
|
-
|
|
649
|
-
|
|
788
|
+
bottom: getBorder("bottom"),
|
|
789
|
+
left: isFirstCell ? getBorder("left") : void 0,
|
|
790
|
+
right: getBorder("right"),
|
|
791
|
+
top: isFirstRow ? getBorder("top") : void 0
|
|
650
792
|
};
|
|
651
793
|
};
|
|
652
794
|
|
|
653
795
|
//#endregion
|
|
654
|
-
//#region src/lib/queries/
|
|
655
|
-
/** Get
|
|
656
|
-
const
|
|
657
|
-
const { api } = editor
|
|
658
|
-
const
|
|
659
|
-
if (!
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const _endRowIndex = endCellPath.at(-2);
|
|
667
|
-
const _startColIndex = startCellPath.at(-1);
|
|
668
|
-
const _endColIndex = endCellPath.at(-1);
|
|
669
|
-
const startRowIndex = Math.min(_startRowIndex, _endRowIndex);
|
|
670
|
-
const endRowIndex = Math.max(_startRowIndex, _endRowIndex);
|
|
671
|
-
const startColIndex = Math.min(_startColIndex, _endColIndex);
|
|
672
|
-
const endColIndex = Math.max(_startColIndex, _endColIndex);
|
|
673
|
-
const tablePath = startCellPath.slice(0, -2);
|
|
674
|
-
const relativeRowIndex = endRowIndex - startRowIndex;
|
|
675
|
-
const relativeColIndex = endColIndex - startColIndex;
|
|
676
|
-
const table = api.create.table({
|
|
677
|
-
children: [],
|
|
678
|
-
colCount: relativeColIndex + 1,
|
|
679
|
-
rowCount: relativeRowIndex + 1
|
|
680
|
-
});
|
|
681
|
-
let rowIndex = startRowIndex;
|
|
682
|
-
let colIndex = startColIndex;
|
|
683
|
-
const cellEntries = [];
|
|
684
|
-
while (true) {
|
|
685
|
-
const cellPath = tablePath.concat([rowIndex, colIndex]);
|
|
686
|
-
const cell = NodeApi.get(editor, cellPath);
|
|
687
|
-
if (!cell) break;
|
|
688
|
-
const rows = table.children[rowIndex - startRowIndex].children;
|
|
689
|
-
rows[colIndex - startColIndex] = cell;
|
|
690
|
-
cellEntries.push([cell, cellPath]);
|
|
691
|
-
if (colIndex + 1 <= endColIndex) colIndex += 1;
|
|
692
|
-
else if (rowIndex + 1 <= endRowIndex) {
|
|
693
|
-
colIndex = startColIndex;
|
|
694
|
-
rowIndex += 1;
|
|
695
|
-
} else break;
|
|
796
|
+
//#region src/lib/queries/getTableCellSize.ts
|
|
797
|
+
/** Get the width of a cell with colSpan support. */
|
|
798
|
+
const getTableCellSize = (editor, { cellIndices, colSizes, element, rowSize }) => {
|
|
799
|
+
const { api } = getEditorPlugin(editor, { key: KEYS.table });
|
|
800
|
+
const path = editor.api.findPath(element);
|
|
801
|
+
if (!rowSize) {
|
|
802
|
+
const [rowElement] = editor.api.parent(path) ?? [];
|
|
803
|
+
if (!rowElement || rowElement.type !== editor.getType(KEYS.tr)) return {
|
|
804
|
+
minHeight: 0,
|
|
805
|
+
width: 0
|
|
806
|
+
};
|
|
807
|
+
rowSize = rowElement.size ?? 0;
|
|
696
808
|
}
|
|
697
|
-
if (
|
|
698
|
-
|
|
809
|
+
if (!colSizes) {
|
|
810
|
+
const [, rowPath] = editor.api.parent(path) ?? [];
|
|
811
|
+
if (!rowPath) return {
|
|
812
|
+
minHeight: rowSize,
|
|
813
|
+
width: 0
|
|
814
|
+
};
|
|
815
|
+
const [tableNode] = editor.api.parent(rowPath) ?? [];
|
|
816
|
+
if (!tableNode) return {
|
|
817
|
+
minHeight: rowSize,
|
|
818
|
+
width: 0
|
|
819
|
+
};
|
|
820
|
+
colSizes = getTableOverriddenColSizes(tableNode);
|
|
821
|
+
}
|
|
822
|
+
const colSpan = api.table.getColSpan(element);
|
|
823
|
+
const { col } = cellIndices ?? getCellIndices(editor, element);
|
|
824
|
+
const width = (colSizes ?? []).slice(col, col + colSpan).reduce((total, w) => total + (w || 0), 0);
|
|
825
|
+
return {
|
|
826
|
+
minHeight: rowSize,
|
|
827
|
+
width
|
|
828
|
+
};
|
|
699
829
|
};
|
|
700
830
|
|
|
701
831
|
//#endregion
|
|
702
|
-
//#region src/lib/queries/
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
const edges = editor.api.edgeBlocks({
|
|
707
|
-
match: { type: getCellTypes(editor) },
|
|
708
|
-
...options
|
|
709
|
-
});
|
|
710
|
-
if (edges) {
|
|
711
|
-
const [start, end] = edges;
|
|
712
|
-
if (!PathApi.equals(start[1], end[1])) return getTableGridByRange(editor, {
|
|
713
|
-
at: {
|
|
714
|
-
anchor: {
|
|
715
|
-
offset: 0,
|
|
716
|
-
path: start[1]
|
|
717
|
-
},
|
|
718
|
-
focus: {
|
|
719
|
-
offset: 0,
|
|
720
|
-
path: end[1]
|
|
721
|
-
}
|
|
722
|
-
},
|
|
723
|
-
format
|
|
724
|
-
});
|
|
725
|
-
if (format === "table") {
|
|
726
|
-
const table = api.create.table({ rowCount: 1 });
|
|
727
|
-
table.children[0].children = [start[0]];
|
|
728
|
-
return [[table, start[1].slice(0, -2)]];
|
|
729
|
-
}
|
|
730
|
-
return [start];
|
|
731
|
-
}
|
|
732
|
-
return [];
|
|
832
|
+
//#region src/lib/queries/getTableColumnCount.ts
|
|
833
|
+
const getTableColumnCount = (tableNode) => {
|
|
834
|
+
if (tableNode.children?.[0]?.children) return tableNode.children[0].children.map((element) => element.colSpan || (element?.attributes)?.colspan || 1).reduce((total, num) => Number(total) + Number(num));
|
|
835
|
+
return 0;
|
|
733
836
|
};
|
|
734
837
|
|
|
735
838
|
//#endregion
|
|
@@ -1215,27 +1318,6 @@ const insertTableMergeRow = (editor, { at, before, fromRow, header, select: shou
|
|
|
1215
1318
|
});
|
|
1216
1319
|
};
|
|
1217
1320
|
|
|
1218
|
-
//#endregion
|
|
1219
|
-
//#region src/lib/merge/isTableRectangular.ts
|
|
1220
|
-
const allEqual = (arr) => arr.every((val) => val === arr[0]);
|
|
1221
|
-
/**
|
|
1222
|
-
* Checks if the given table is rectangular, meaning all rows have the same
|
|
1223
|
-
* effective number of cells, considering colspan and rowspan.
|
|
1224
|
-
*/
|
|
1225
|
-
const isTableRectangular = (table) => {
|
|
1226
|
-
const arr = [];
|
|
1227
|
-
table?.children?.forEach((row, rI) => {
|
|
1228
|
-
row.children?.forEach((cell) => {
|
|
1229
|
-
const cellElem = cell;
|
|
1230
|
-
Array.from({ length: getRowSpan(cellElem) || 1 }).forEach((_, i) => {
|
|
1231
|
-
if (!arr[rI + i]) arr[rI + i] = 0;
|
|
1232
|
-
arr[rI + i] += getColSpan(cellElem);
|
|
1233
|
-
});
|
|
1234
|
-
});
|
|
1235
|
-
});
|
|
1236
|
-
return allEqual(arr);
|
|
1237
|
-
};
|
|
1238
|
-
|
|
1239
1321
|
//#endregion
|
|
1240
1322
|
//#region src/lib/merge/mergeTableCells.ts
|
|
1241
1323
|
/** Merges multiple selected cells into one. */
|
|
@@ -1661,51 +1743,6 @@ const moveSelectionFromCell = (editor, { at, edge, fromOneCell, reverse } = {})
|
|
|
1661
1743
|
}
|
|
1662
1744
|
};
|
|
1663
1745
|
|
|
1664
|
-
//#endregion
|
|
1665
|
-
//#region src/lib/transforms/overrideSelectionFromCell.ts
|
|
1666
|
-
/**
|
|
1667
|
-
* Override the new selection if the previous selection and the new one are in
|
|
1668
|
-
* different cells.
|
|
1669
|
-
*/
|
|
1670
|
-
const overrideSelectionFromCell = (editor, newSelection) => {
|
|
1671
|
-
let hotkey;
|
|
1672
|
-
if (!editor.dom.currentKeyboardEvent || ![
|
|
1673
|
-
"up",
|
|
1674
|
-
"down",
|
|
1675
|
-
"shift+up",
|
|
1676
|
-
"shift+right",
|
|
1677
|
-
"shift+down",
|
|
1678
|
-
"shift+left"
|
|
1679
|
-
].some((key) => {
|
|
1680
|
-
const valid = isHotkey(key, editor.dom.currentKeyboardEvent);
|
|
1681
|
-
if (valid) hotkey = key;
|
|
1682
|
-
return valid;
|
|
1683
|
-
}) || !editor.selection?.focus || !newSelection?.focus || !editor.api.isAt({
|
|
1684
|
-
at: {
|
|
1685
|
-
anchor: editor.selection.focus,
|
|
1686
|
-
focus: newSelection.focus
|
|
1687
|
-
},
|
|
1688
|
-
blocks: true,
|
|
1689
|
-
match: { type: getCellTypes(editor) }
|
|
1690
|
-
})) return;
|
|
1691
|
-
if (!hotkey) return;
|
|
1692
|
-
const edge = KEY_SHIFT_EDGES[hotkey];
|
|
1693
|
-
if (edge && !editor.api.isAt({
|
|
1694
|
-
block: true,
|
|
1695
|
-
match: { type: getCellTypes(editor) }
|
|
1696
|
-
})) return;
|
|
1697
|
-
const prevSelection = editor.selection;
|
|
1698
|
-
const reverse = ["shift+up", "up"].includes(hotkey);
|
|
1699
|
-
setTimeout(() => {
|
|
1700
|
-
moveSelectionFromCell(editor, {
|
|
1701
|
-
at: prevSelection,
|
|
1702
|
-
edge,
|
|
1703
|
-
fromOneCell: true,
|
|
1704
|
-
reverse
|
|
1705
|
-
});
|
|
1706
|
-
}, 0);
|
|
1707
|
-
};
|
|
1708
|
-
|
|
1709
1746
|
//#endregion
|
|
1710
1747
|
//#region src/lib/transforms/setBorderSize.ts
|
|
1711
1748
|
const setBorderSize = (editor, size, { at, border = "all" } = {}) => {
|
|
@@ -1844,6 +1881,54 @@ const setTableRowSize = (editor, { height, rowIndex }, options = {}) => {
|
|
|
1844
1881
|
editor.tf.setNodes({ size: height }, { at: tableRowPath });
|
|
1845
1882
|
};
|
|
1846
1883
|
|
|
1884
|
+
//#endregion
|
|
1885
|
+
//#region src/lib/transforms/shouldMoveSelectionFromCell.ts
|
|
1886
|
+
const VISUAL_LINE_TOLERANCE = 1;
|
|
1887
|
+
const getRangeClientRects = (domRange) => Array.from(domRange?.getClientRects?.() ?? []).filter((rect) => rect.height > 0);
|
|
1888
|
+
const getTableMoveSelectionContext = (editor, point = editor.selection?.anchor) => {
|
|
1889
|
+
if (!point || !editor.api.isAt({
|
|
1890
|
+
block: true,
|
|
1891
|
+
match: { type: getCellTypes(editor) }
|
|
1892
|
+
})) return;
|
|
1893
|
+
const cellEntry = editor.api.block({
|
|
1894
|
+
at: point,
|
|
1895
|
+
match: { type: getCellTypes(editor) }
|
|
1896
|
+
});
|
|
1897
|
+
const blockEntry = editor.api.block({ at: point });
|
|
1898
|
+
if (!cellEntry || !blockEntry) return;
|
|
1899
|
+
const [, cellPath] = cellEntry;
|
|
1900
|
+
const [, blockPath] = blockEntry;
|
|
1901
|
+
return {
|
|
1902
|
+
blockPath,
|
|
1903
|
+
cellPath,
|
|
1904
|
+
point
|
|
1905
|
+
};
|
|
1906
|
+
};
|
|
1907
|
+
const hasAdjacentBlockInCell = (editor, { blockPath, cellPath, reverse }) => {
|
|
1908
|
+
const adjacentBlock = reverse ? editor.api.previous({
|
|
1909
|
+
at: blockPath,
|
|
1910
|
+
block: true
|
|
1911
|
+
}) : editor.api.next({
|
|
1912
|
+
at: blockPath,
|
|
1913
|
+
block: true
|
|
1914
|
+
});
|
|
1915
|
+
return !!adjacentBlock && PathApi.isAncestor(cellPath, adjacentBlock[1]);
|
|
1916
|
+
};
|
|
1917
|
+
const shouldMoveSelectionFromCell = (editor, { blockPath, point, reverse }) => {
|
|
1918
|
+
const blockRange = editor.api.range(blockPath);
|
|
1919
|
+
const isAtBlockEdge = reverse ? editor.api.isStart(point, blockPath) : editor.api.isEnd(point, blockPath);
|
|
1920
|
+
if (!blockRange) return isAtBlockEdge;
|
|
1921
|
+
const caretRects = getRangeClientRects(editor.api.toDOMRange({
|
|
1922
|
+
anchor: point,
|
|
1923
|
+
focus: point
|
|
1924
|
+
}));
|
|
1925
|
+
const blockRects = getRangeClientRects(editor.api.toDOMRange(blockRange));
|
|
1926
|
+
if (caretRects.length === 0 || blockRects.length === 0) return isAtBlockEdge;
|
|
1927
|
+
const caretRect = caretRects.at(-1);
|
|
1928
|
+
const boundary = reverse ? Math.min(...blockRects.map((rect) => rect.top)) : Math.max(...blockRects.map((rect) => rect.bottom));
|
|
1929
|
+
return reverse ? caretRect.top <= boundary + VISUAL_LINE_TOLERANCE : caretRect.bottom >= boundary - VISUAL_LINE_TOLERANCE;
|
|
1930
|
+
};
|
|
1931
|
+
|
|
1847
1932
|
//#endregion
|
|
1848
1933
|
//#region src/lib/withApplyTable.ts
|
|
1849
1934
|
/**
|
|
@@ -1889,7 +1974,6 @@ const withApplyTable = ({ api: _api, editor, getOptions, tf: { apply }, type: ta
|
|
|
1889
1974
|
}
|
|
1890
1975
|
}
|
|
1891
1976
|
}
|
|
1892
|
-
overrideSelectionFromCell(editor, newSelection);
|
|
1893
1977
|
}
|
|
1894
1978
|
const opType = op.type === "remove_node" ? op.node.type : op.type === "move_node" ? editor.api.node(op.path)?.[0].type : void 0;
|
|
1895
1979
|
const isTableOperation = (op.type === "remove_node" || op.type === "move_node") && opType && [
|
|
@@ -2250,108 +2334,116 @@ const withSetFragmentDataTable = ({ api, editor, plugin, tf: { setFragmentData }
|
|
|
2250
2334
|
|
|
2251
2335
|
//#endregion
|
|
2252
2336
|
//#region src/lib/withTableCellSelection.tsx
|
|
2253
|
-
const
|
|
2254
|
-
return
|
|
2255
|
-
|
|
2337
|
+
const isTargetingSelectedCell = (editor, target, cellPaths) => {
|
|
2338
|
+
if (PathApi.isPath(target)) return cellPaths.some((cellPath) => PathApi.isCommon(cellPath, target));
|
|
2339
|
+
const range = editor.api.range(target);
|
|
2340
|
+
if (!range) return false;
|
|
2341
|
+
return cellPaths.some((cellPath) => {
|
|
2342
|
+
const cellRange = editor.api.range(cellPath);
|
|
2343
|
+
if (!cellRange) return false;
|
|
2344
|
+
return RangeApi.includes(cellRange, range.anchor) || RangeApi.includes(cellRange, range.focus) || RangeApi.includes(range, cellRange);
|
|
2345
|
+
});
|
|
2346
|
+
};
|
|
2347
|
+
const withTableCellSelection = ({ api: { marks }, editor, tf: { addMark, removeMark, setNodes } }) => ({
|
|
2348
|
+
api: { marks() {
|
|
2349
|
+
const apply = () => {
|
|
2350
|
+
const { selection } = editor;
|
|
2351
|
+
if (!selection || editor.api.isCollapsed()) return;
|
|
2352
|
+
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2353
|
+
if (matchesCell.length <= 1) return;
|
|
2354
|
+
const markCounts = {};
|
|
2355
|
+
const totalMarks = {};
|
|
2356
|
+
let totalNodes = 0;
|
|
2357
|
+
matchesCell.forEach(([_cell, cellPath]) => {
|
|
2358
|
+
const textNodeEntry = editor.api.nodes({
|
|
2359
|
+
at: cellPath,
|
|
2360
|
+
match: (n) => TextApi.isText(n)
|
|
2361
|
+
});
|
|
2362
|
+
Array.from(textNodeEntry, (item) => item[0]).forEach((item) => {
|
|
2363
|
+
totalNodes++;
|
|
2364
|
+
const keys = Object.keys(item);
|
|
2365
|
+
if (keys.length === 1) return;
|
|
2366
|
+
keys.splice(keys.indexOf("text"), 1);
|
|
2367
|
+
keys.forEach((k) => {
|
|
2368
|
+
markCounts[k] = (markCounts[k] || 0) + 1;
|
|
2369
|
+
totalMarks[k] = item[k];
|
|
2370
|
+
});
|
|
2371
|
+
});
|
|
2372
|
+
});
|
|
2373
|
+
Object.keys(markCounts).forEach((mark) => {
|
|
2374
|
+
if (markCounts[mark] !== totalNodes) delete totalMarks[mark];
|
|
2375
|
+
});
|
|
2376
|
+
return totalMarks;
|
|
2377
|
+
};
|
|
2378
|
+
const result = apply();
|
|
2379
|
+
if (result) return result;
|
|
2380
|
+
return marks();
|
|
2381
|
+
} },
|
|
2382
|
+
transforms: {
|
|
2383
|
+
addMark(key, value) {
|
|
2256
2384
|
const apply = () => {
|
|
2257
2385
|
const { selection } = editor;
|
|
2258
|
-
if (!selection || editor.api.isCollapsed()) return;
|
|
2386
|
+
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2259
2387
|
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2260
2388
|
if (matchesCell.length <= 1) return;
|
|
2261
|
-
const markCounts = {};
|
|
2262
|
-
const totalMarks = {};
|
|
2263
|
-
let totalNodes = 0;
|
|
2264
2389
|
matchesCell.forEach(([_cell, cellPath]) => {
|
|
2265
|
-
|
|
2390
|
+
editor.tf.setNodes({ [key]: value }, {
|
|
2266
2391
|
at: cellPath,
|
|
2392
|
+
split: true,
|
|
2393
|
+
voids: true,
|
|
2267
2394
|
match: (n) => TextApi.isText(n)
|
|
2268
2395
|
});
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2396
|
+
});
|
|
2397
|
+
return true;
|
|
2398
|
+
};
|
|
2399
|
+
if (apply()) return;
|
|
2400
|
+
return addMark(key, value);
|
|
2401
|
+
},
|
|
2402
|
+
removeMark(key) {
|
|
2403
|
+
const apply = () => {
|
|
2404
|
+
const { selection } = editor;
|
|
2405
|
+
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2406
|
+
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2407
|
+
if (matchesCell.length <= 1) return;
|
|
2408
|
+
matchesCell.forEach(([_cell, cellPath]) => {
|
|
2409
|
+
editor.tf.setNodes({ [key]: null }, {
|
|
2410
|
+
at: cellPath,
|
|
2411
|
+
split: true,
|
|
2412
|
+
voids: true,
|
|
2413
|
+
match: (n) => TextApi.isText(n)
|
|
2278
2414
|
});
|
|
2279
2415
|
});
|
|
2280
|
-
|
|
2281
|
-
|
|
2416
|
+
return true;
|
|
2417
|
+
};
|
|
2418
|
+
if (apply()) return;
|
|
2419
|
+
return removeMark(key);
|
|
2420
|
+
},
|
|
2421
|
+
setNodes(props, options) {
|
|
2422
|
+
const apply = () => {
|
|
2423
|
+
const { selection } = editor;
|
|
2424
|
+
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2425
|
+
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2426
|
+
if (matchesCell.length <= 1) return;
|
|
2427
|
+
if (options?.at) {
|
|
2428
|
+
const cellPaths = matchesCell.map(([, cellPath]) => cellPath);
|
|
2429
|
+
if (!isTargetingSelectedCell(editor, options.at, cellPaths)) return;
|
|
2430
|
+
}
|
|
2431
|
+
setNodes(props, {
|
|
2432
|
+
...options,
|
|
2433
|
+
match: combineTransformMatchOptions(editor, (_, p) => matchesCell.some(([_$1, cellPath]) => PathApi.isCommon(cellPath, p)), options)
|
|
2282
2434
|
});
|
|
2283
|
-
return
|
|
2435
|
+
return true;
|
|
2284
2436
|
};
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
return marks();
|
|
2288
|
-
} },
|
|
2289
|
-
transforms: {
|
|
2290
|
-
addMark(key, value) {
|
|
2291
|
-
const apply = () => {
|
|
2292
|
-
const { selection } = editor;
|
|
2293
|
-
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2294
|
-
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2295
|
-
if (matchesCell.length <= 1) return;
|
|
2296
|
-
matchesCell.forEach(([_cell, cellPath]) => {
|
|
2297
|
-
editor.tf.setNodes({ [key]: value }, {
|
|
2298
|
-
at: cellPath,
|
|
2299
|
-
split: true,
|
|
2300
|
-
voids: true,
|
|
2301
|
-
match: (n) => TextApi.isText(n)
|
|
2302
|
-
});
|
|
2303
|
-
});
|
|
2304
|
-
return true;
|
|
2305
|
-
};
|
|
2306
|
-
if (apply()) return;
|
|
2307
|
-
return addMark(key, value);
|
|
2308
|
-
},
|
|
2309
|
-
removeMark(key) {
|
|
2310
|
-
const apply = () => {
|
|
2311
|
-
const { selection } = editor;
|
|
2312
|
-
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2313
|
-
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2314
|
-
if (matchesCell.length <= 1) return;
|
|
2315
|
-
matchesCell.forEach(([_cell, cellPath]) => {
|
|
2316
|
-
editor.tf.setNodes({ [key]: null }, {
|
|
2317
|
-
at: cellPath,
|
|
2318
|
-
split: true,
|
|
2319
|
-
voids: true,
|
|
2320
|
-
match: (n) => TextApi.isText(n)
|
|
2321
|
-
});
|
|
2322
|
-
});
|
|
2323
|
-
return true;
|
|
2324
|
-
};
|
|
2325
|
-
if (apply()) return;
|
|
2326
|
-
return removeMark(key);
|
|
2327
|
-
},
|
|
2328
|
-
setNodes(props, options) {
|
|
2329
|
-
const apply = () => {
|
|
2330
|
-
const { selection } = editor;
|
|
2331
|
-
if (!selection || editor.api.isCollapsed() || editor.meta.isNormalizing) return;
|
|
2332
|
-
if (options?.at) {
|
|
2333
|
-
const range = editor.api.range(options.at);
|
|
2334
|
-
if (range && !RangeApi.includes(selection, range)) return;
|
|
2335
|
-
}
|
|
2336
|
-
const matchesCell = getTableGridAbove(editor, { format: "cell" });
|
|
2337
|
-
if (matchesCell.length <= 1) return;
|
|
2338
|
-
setNodes(props, {
|
|
2339
|
-
...options,
|
|
2340
|
-
match: combineTransformMatchOptions(editor, (_, p) => matchesCell.some(([_$1, cellPath]) => PathApi.isCommon(cellPath, p)), options)
|
|
2341
|
-
});
|
|
2342
|
-
return true;
|
|
2343
|
-
};
|
|
2344
|
-
if (apply()) return;
|
|
2345
|
-
return setNodes(props, options);
|
|
2346
|
-
}
|
|
2437
|
+
if (apply()) return;
|
|
2438
|
+
return setNodes(props, options);
|
|
2347
2439
|
}
|
|
2348
|
-
}
|
|
2349
|
-
};
|
|
2440
|
+
}
|
|
2441
|
+
});
|
|
2350
2442
|
|
|
2351
2443
|
//#endregion
|
|
2352
2444
|
//#region src/lib/withTable.ts
|
|
2353
2445
|
const withTable = (ctx) => {
|
|
2354
|
-
const { editor, tf: { selectAll, tab }, type } = ctx;
|
|
2446
|
+
const { editor, tf: { moveLine, selectAll, tab }, type } = ctx;
|
|
2355
2447
|
const cellSelection = withTableCellSelection(ctx);
|
|
2356
2448
|
return {
|
|
2357
2449
|
api: {
|
|
@@ -2359,6 +2451,27 @@ const withTable = (ctx) => {
|
|
|
2359
2451
|
...cellSelection.api
|
|
2360
2452
|
},
|
|
2361
2453
|
transforms: {
|
|
2454
|
+
moveLine: (options) => {
|
|
2455
|
+
const apply = () => {
|
|
2456
|
+
if (!editor.api.isCollapsed()) return;
|
|
2457
|
+
const context = getTableMoveSelectionContext(editor);
|
|
2458
|
+
if (!context) return;
|
|
2459
|
+
const { blockPath, cellPath, point } = context;
|
|
2460
|
+
if (hasAdjacentBlockInCell(editor, {
|
|
2461
|
+
blockPath,
|
|
2462
|
+
cellPath,
|
|
2463
|
+
reverse: options.reverse
|
|
2464
|
+
})) return;
|
|
2465
|
+
if (!shouldMoveSelectionFromCell(editor, {
|
|
2466
|
+
blockPath,
|
|
2467
|
+
point,
|
|
2468
|
+
reverse: options.reverse
|
|
2469
|
+
})) return;
|
|
2470
|
+
return moveSelectionFromCell(editor, { reverse: options.reverse });
|
|
2471
|
+
};
|
|
2472
|
+
if (apply()) return true;
|
|
2473
|
+
return moveLine(options);
|
|
2474
|
+
},
|
|
2362
2475
|
selectAll: () => {
|
|
2363
2476
|
const apply = () => {
|
|
2364
2477
|
const table = editor.api.above({ match: { type } });
|
|
@@ -2481,6 +2594,9 @@ const BaseTablePlugin = createTSlatePlugin({
|
|
|
2481
2594
|
normalizeInitialValue: normalizeInitialValueTable,
|
|
2482
2595
|
options: {
|
|
2483
2596
|
_cellIndices: {},
|
|
2597
|
+
_selectedCellIds: void 0,
|
|
2598
|
+
_selectedTableIds: void 0,
|
|
2599
|
+
_selectionVersion: 0,
|
|
2484
2600
|
disableMerge: false,
|
|
2485
2601
|
minColumnWidth: 48,
|
|
2486
2602
|
selectedCells: null,
|
|
@@ -2492,7 +2608,41 @@ const BaseTablePlugin = createTSlatePlugin({
|
|
|
2492
2608
|
BaseTableCellPlugin,
|
|
2493
2609
|
BaseTableCellHeaderPlugin
|
|
2494
2610
|
]
|
|
2495
|
-
}).extendSelectors(({
|
|
2611
|
+
}).extendSelectors(({ editor, getOptions }) => ({
|
|
2612
|
+
cellIndices: (id) => getOptions()._cellIndices[id],
|
|
2613
|
+
isCellSelected: (id) => {
|
|
2614
|
+
const selectedCellIds = getOptions()._selectedCellIds;
|
|
2615
|
+
if (selectedCellIds !== void 0) return !!id && (selectedCellIds?.includes(id) ?? false);
|
|
2616
|
+
return isCellSelected(editor, id);
|
|
2617
|
+
},
|
|
2618
|
+
isSelectingCell: () => {
|
|
2619
|
+
const selectedCellIds = getOptions()._selectedCellIds;
|
|
2620
|
+
if (selectedCellIds !== void 0) return !!selectedCellIds;
|
|
2621
|
+
return isSelectingCell(editor);
|
|
2622
|
+
},
|
|
2623
|
+
selectedCell: (id) => {
|
|
2624
|
+
getOptions()._selectionVersion;
|
|
2625
|
+
return getSelectedCell(editor, id);
|
|
2626
|
+
},
|
|
2627
|
+
selectedCellIds: () => {
|
|
2628
|
+
const selectedCellIds = getOptions()._selectedCellIds;
|
|
2629
|
+
if (selectedCellIds !== void 0) return selectedCellIds;
|
|
2630
|
+
return getSelectedCellIds(editor);
|
|
2631
|
+
},
|
|
2632
|
+
selectedCells: () => {
|
|
2633
|
+
getOptions()._selectionVersion;
|
|
2634
|
+
return getSelectedCells(editor);
|
|
2635
|
+
},
|
|
2636
|
+
selectedTableIds: () => {
|
|
2637
|
+
const selectedTableIds = getOptions()._selectedTableIds;
|
|
2638
|
+
if (selectedTableIds !== void 0) return selectedTableIds;
|
|
2639
|
+
return getSelectedTableIds(editor);
|
|
2640
|
+
},
|
|
2641
|
+
selectedTables: () => {
|
|
2642
|
+
getOptions()._selectionVersion;
|
|
2643
|
+
return getSelectedTables(editor);
|
|
2644
|
+
}
|
|
2645
|
+
})).extendEditorApi(({ editor }) => ({
|
|
2496
2646
|
create: {
|
|
2497
2647
|
table: bindFirst(getEmptyTableNode, editor),
|
|
2498
2648
|
tableCell: bindFirst(getEmptyCellNode, editor),
|
|
@@ -2501,9 +2651,16 @@ const BaseTablePlugin = createTSlatePlugin({
|
|
|
2501
2651
|
table: {
|
|
2502
2652
|
getCellBorders: bindFirst(getTableCellBorders, editor),
|
|
2503
2653
|
getCellSize: bindFirst(getTableCellSize, editor),
|
|
2654
|
+
getSelectedCell: bindFirst(getSelectedCell, editor),
|
|
2655
|
+
getSelectedCellIds: bindFirst(getSelectedCellIds, editor),
|
|
2656
|
+
getSelectedCells: bindFirst(getSelectedCells, editor),
|
|
2657
|
+
getSelectedTableIds: bindFirst(getSelectedTableIds, editor),
|
|
2658
|
+
getSelectedTables: bindFirst(getSelectedTables, editor),
|
|
2504
2659
|
getColSpan,
|
|
2505
2660
|
getRowSpan,
|
|
2506
|
-
getCellChildren: (cell) => cell.children
|
|
2661
|
+
getCellChildren: (cell) => cell.children,
|
|
2662
|
+
isCellSelected: bindFirst(isCellSelected, editor),
|
|
2663
|
+
isSelectingCell: bindFirst(isSelectingCell, editor)
|
|
2507
2664
|
}
|
|
2508
2665
|
})).extendEditorTransforms(({ editor }) => ({
|
|
2509
2666
|
insert: {
|
|
@@ -2532,5 +2689,4 @@ const KEY_SHIFT_EDGES = {
|
|
|
2532
2689
|
};
|
|
2533
2690
|
|
|
2534
2691
|
//#endregion
|
|
2535
|
-
export {
|
|
2536
|
-
//# sourceMappingURL=constants-B6Sm9BNa.js.map
|
|
2692
|
+
export { getSelectedCellEntries as $, normalizeInitialValueTable as A, deleteColumnWhenExpanded as B, moveSelectionFromCell as C, getColSpan as Ct, deleteTable as D, insertTable as E, getEmptyCellNode as Et, getTableMergedColumnCount as F, getTableAbove as G, getTableColumnCount as H, deleteTableMergeRow as I, isSelectedCellBordersNone as J, getSelectedCellsBorders as K, deleteRowWhenExpanded as L, mergeTableCells as M, insertTableMergeRow as N, deleteRow as O, insertTableMergeColumn as P, getSelectedCell as Q, deleteTableMergeColumn as R, setBorderSize as S, getRowSpan as St, insertTableColumn as T, getEmptyRowNode as Tt, getTableCellSize as U, getTableOverriddenColSizes as V, getTableCellBorders as W, getTopTableCell as X, isSelectedCellBordersOuter as Y, getSelectedCellsBoundingBox as Z, hasAdjacentBlockInCell as _, getCellTypes as _t, BaseTableRowPlugin as a, isSelectingCell as at, setTableMarginLeft as b, computeCellIndices as bt, withSetFragmentDataTable as c, getTableMergeGridByRange as ct, withInsertFragmentTable as d, getNextTableCell as dt, getSelectedCellIds as et, withGetFragmentTable as f, getLeftTableCell as ft, getTableMoveSelectionContext as g, getTableEntries as gt, withApplyTable as h, getAdjacentTableCell as ht, BaseTablePlugin as i, isCellSelected as it, splitTableCell as j, deleteColumn as k, withNormalizeTable as l, findCellByIndexes as lt, withDeleteTable as m, getCellInNextTableRow as mt, BaseTableCellHeaderPlugin as n, getSelectedTableIds as nt, withTable as o, getTableGridAbove as ot, preventDeleteTableCell as p, getCellInPreviousTableRow as pt, isSelectedCellBorder as q, BaseTableCellPlugin as r, getSelectedTables as rt, withTableCellSelection as s, getTableGridByRange as st, KEY_SHIFT_EDGES as t, getSelectedCells as tt, withInsertTextTable as u, getPreviousTableCell as ut, shouldMoveSelectionFromCell as v, getCellRowIndexByPath as vt, insertTableRow as w, getEmptyTableNode as wt, setTableColSize as x, getCellIndicesWithSpans as xt, setTableRowSize as y, getCellIndices as yt, getCellPath as z };
|