@milkdown/preset-gfm 7.15.0 → 7.15.2
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/lib/index.js +265 -205
- package/lib/index.js.map +1 -1
- package/lib/mark/strike-through.d.ts.map +1 -1
- package/lib/node/table/command.d.ts.map +1 -1
- package/lib/node/table/utils/add-row-with-alignment.d.ts +5 -0
- package/lib/node/table/utils/add-row-with-alignment.d.ts.map +1 -0
- package/lib/node/table/utils/convert-rows-to-table.d.ts +3 -0
- package/lib/node/table/utils/convert-rows-to-table.d.ts.map +1 -0
- package/lib/node/table/utils/convert-table-to-rows.d.ts +3 -0
- package/lib/node/table/utils/convert-table-to-rows.d.ts.map +1 -0
- package/lib/node/table/utils/create-table.d.ts +4 -0
- package/lib/node/table/utils/create-table.d.ts.map +1 -0
- package/lib/node/table/utils/find-table.d.ts +3 -0
- package/lib/node/table/utils/find-table.d.ts.map +1 -0
- package/lib/node/table/utils/get-all-cells-in-table.d.ts +7 -0
- package/lib/node/table/utils/get-all-cells-in-table.d.ts.map +1 -0
- package/lib/node/table/utils/get-cells-in-col.d.ts +4 -0
- package/lib/node/table/utils/get-cells-in-col.d.ts.map +1 -0
- package/lib/node/table/utils/get-cells-in-row.d.ts +4 -0
- package/lib/node/table/utils/get-cells-in-row.d.ts.map +1 -0
- package/lib/node/table/utils/get-selection-range-in-col.d.ts +4 -0
- package/lib/node/table/utils/get-selection-range-in-col.d.ts.map +1 -0
- package/lib/node/table/utils/get-selection-range-in-row.d.ts +4 -0
- package/lib/node/table/utils/get-selection-range-in-row.d.ts.map +1 -0
- package/lib/node/table/utils/index.d.ts +12 -0
- package/lib/node/table/utils/index.d.ts.map +1 -0
- package/lib/node/table/utils/move-col.d.ts +10 -0
- package/lib/node/table/utils/move-col.d.ts.map +1 -0
- package/lib/node/table/utils/move-row-in-array-of-rows.d.ts +3 -0
- package/lib/node/table/utils/move-row-in-array-of-rows.d.ts.map +1 -0
- package/lib/node/table/utils/move-row.d.ts +10 -0
- package/lib/node/table/utils/move-row.d.ts.map +1 -0
- package/lib/node/table/utils/select-line.d.ts +5 -0
- package/lib/node/table/utils/select-line.d.ts.map +1 -0
- package/lib/node/table/utils/select-table.d.ts +3 -0
- package/lib/node/table/utils/select-table.d.ts.map +1 -0
- package/lib/node/table/utils/transpose.d.ts +2 -0
- package/lib/node/table/utils/transpose.d.ts.map +1 -0
- package/lib/node/table/utils/types.d.ts +12 -0
- package/lib/node/table/utils/types.d.ts.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/mark/strike-through.ts +4 -1
- package/src/node/table/command.ts +28 -10
- package/src/node/table/utils/add-row-with-alignment.ts +32 -0
- package/src/node/table/utils/convert-rows-to-table.ts +43 -0
- package/src/node/table/utils/convert-table-to-rows.ts +65 -0
- package/src/node/table/utils/create-table.ts +31 -0
- package/src/node/table/utils/find-table.ts +10 -0
- package/src/node/table/utils/get-all-cells-in-table.ts +24 -0
- package/src/node/table/utils/get-cells-in-col.ts +35 -0
- package/src/node/table/utils/get-cells-in-row.ts +37 -0
- package/src/node/table/utils/get-selection-range-in-col.ts +86 -0
- package/src/node/table/utils/get-selection-range-in-row.ts +86 -0
- package/src/node/table/utils/index.ts +11 -0
- package/src/node/table/utils/move-col.ts +73 -0
- package/src/node/table/utils/move-row-in-array-of-rows.ts +29 -0
- package/src/node/table/utils/move-row.ts +71 -0
- package/src/node/table/utils/select-line.ts +61 -0
- package/src/node/table/utils/select-table.ts +20 -0
- package/src/node/table/utils/transpose.ts +26 -0
- package/src/node/table/utils/types.ts +16 -0
- package/lib/node/table/utils.d.ts +0 -41
- package/lib/node/table/utils.d.ts.map +0 -1
- package/src/node/table/utils.ts +0 -564
package/src/node/table/utils.ts
DELETED
|
@@ -1,564 +0,0 @@
|
|
|
1
|
-
import type { Ctx } from '@milkdown/ctx'
|
|
2
|
-
import type { ContentNodeWithPos } from '@milkdown/prose'
|
|
3
|
-
import type { Node, ResolvedPos } from '@milkdown/prose/model'
|
|
4
|
-
import type { Selection, Transaction } from '@milkdown/prose/state'
|
|
5
|
-
import type { TableRect } from '@milkdown/prose/tables'
|
|
6
|
-
|
|
7
|
-
import { cloneTr, findParentNodeClosestToPos } from '@milkdown/prose'
|
|
8
|
-
import { CellSelection, TableMap } from '@milkdown/prose/tables'
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
tableCellSchema,
|
|
12
|
-
tableHeaderRowSchema,
|
|
13
|
-
tableHeaderSchema,
|
|
14
|
-
tableRowSchema,
|
|
15
|
-
tableSchema,
|
|
16
|
-
} from './schema'
|
|
17
|
-
|
|
18
|
-
/// @internal
|
|
19
|
-
export interface CellPos {
|
|
20
|
-
pos: number
|
|
21
|
-
start: number
|
|
22
|
-
node: Node
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/// @internal
|
|
26
|
-
export function createTable(ctx: Ctx, rowsCount = 3, colsCount = 3): Node {
|
|
27
|
-
const cells = Array(colsCount)
|
|
28
|
-
.fill(0)
|
|
29
|
-
.map(() => tableCellSchema.type(ctx).createAndFill()!)
|
|
30
|
-
|
|
31
|
-
const headerCells = Array(colsCount)
|
|
32
|
-
.fill(0)
|
|
33
|
-
.map(() => tableHeaderSchema.type(ctx).createAndFill()!)
|
|
34
|
-
|
|
35
|
-
const rows = Array(rowsCount)
|
|
36
|
-
.fill(0)
|
|
37
|
-
.map((_, i) =>
|
|
38
|
-
i === 0
|
|
39
|
-
? tableHeaderRowSchema.type(ctx).create(null, headerCells)
|
|
40
|
-
: tableRowSchema.type(ctx).create(null, cells)
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
return tableSchema.type(ctx).create(null, rows)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/// Find the table node with position information for target pos.
|
|
47
|
-
export function findTable($pos: ResolvedPos) {
|
|
48
|
-
return findParentNodeClosestToPos(
|
|
49
|
-
(node) => node.type.spec.tableRole === 'table'
|
|
50
|
-
)($pos)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// Get cells in a column of a table.
|
|
54
|
-
export function getCellsInCol(
|
|
55
|
-
columnIndex: number,
|
|
56
|
-
selection: Selection
|
|
57
|
-
): CellPos[] | undefined {
|
|
58
|
-
const table = findTable(selection.$from)
|
|
59
|
-
if (!table) return undefined
|
|
60
|
-
const map = TableMap.get(table.node)
|
|
61
|
-
if (columnIndex < 0 || columnIndex >= map.width) return undefined
|
|
62
|
-
|
|
63
|
-
return map
|
|
64
|
-
.cellsInRect({
|
|
65
|
-
left: columnIndex,
|
|
66
|
-
right: columnIndex + 1,
|
|
67
|
-
top: 0,
|
|
68
|
-
bottom: map.height,
|
|
69
|
-
})
|
|
70
|
-
.map((pos) => {
|
|
71
|
-
const node = table.node.nodeAt(pos)
|
|
72
|
-
if (!node) return undefined
|
|
73
|
-
const start = pos + table.start
|
|
74
|
-
return {
|
|
75
|
-
pos: start,
|
|
76
|
-
start: start + 1,
|
|
77
|
-
node,
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
.filter((x): x is CellPos => x != null)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/// Get cells in a row of a table.
|
|
84
|
-
export function getCellsInRow(
|
|
85
|
-
rowIndex: number,
|
|
86
|
-
selection: Selection
|
|
87
|
-
): CellPos[] | undefined {
|
|
88
|
-
const table = findTable(selection.$from)
|
|
89
|
-
if (!table) return undefined
|
|
90
|
-
const map = TableMap.get(table.node)
|
|
91
|
-
if (rowIndex < 0 || rowIndex >= map.height) return undefined
|
|
92
|
-
|
|
93
|
-
return map
|
|
94
|
-
.cellsInRect({
|
|
95
|
-
left: 0,
|
|
96
|
-
right: map.width,
|
|
97
|
-
top: rowIndex,
|
|
98
|
-
bottom: rowIndex + 1,
|
|
99
|
-
})
|
|
100
|
-
.map((pos) => {
|
|
101
|
-
const node = table.node.nodeAt(pos)
|
|
102
|
-
if (!node) return undefined
|
|
103
|
-
const start = pos + table.start
|
|
104
|
-
return {
|
|
105
|
-
pos: start,
|
|
106
|
-
start: start + 1,
|
|
107
|
-
node,
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
.filter((x): x is CellPos => x != null)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/// Get all cells in a table.
|
|
114
|
-
export function getAllCellsInTable(selection: Selection) {
|
|
115
|
-
const table = findTable(selection.$from)
|
|
116
|
-
if (!table) return
|
|
117
|
-
|
|
118
|
-
const map = TableMap.get(table.node)
|
|
119
|
-
const cells = map.cellsInRect({
|
|
120
|
-
left: 0,
|
|
121
|
-
right: map.width,
|
|
122
|
-
top: 0,
|
|
123
|
-
bottom: map.height,
|
|
124
|
-
})
|
|
125
|
-
return cells.map((nodePos) => {
|
|
126
|
-
const node = table.node.nodeAt(nodePos)
|
|
127
|
-
const pos = nodePos + table.start
|
|
128
|
-
return { pos, start: pos + 1, node }
|
|
129
|
-
})
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/// Select a possible table in current selection.
|
|
133
|
-
export function selectTable(tr: Transaction) {
|
|
134
|
-
const cells = getAllCellsInTable(tr.selection)
|
|
135
|
-
if (cells && cells[0]) {
|
|
136
|
-
const $firstCell = tr.doc.resolve(cells[0].pos)
|
|
137
|
-
const last = cells[cells.length - 1]
|
|
138
|
-
if (last) {
|
|
139
|
-
const $lastCell = tr.doc.resolve(last.pos)
|
|
140
|
-
return cloneTr(tr.setSelection(new CellSelection($lastCell, $firstCell)))
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return tr
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/// @internal
|
|
147
|
-
export function addRowWithAlignment(
|
|
148
|
-
ctx: Ctx,
|
|
149
|
-
tr: Transaction,
|
|
150
|
-
{ map, tableStart, table }: TableRect,
|
|
151
|
-
row: number
|
|
152
|
-
) {
|
|
153
|
-
const rowPos = Array(row)
|
|
154
|
-
.fill(0)
|
|
155
|
-
.reduce((acc, _, i) => {
|
|
156
|
-
return acc + table.child(i).nodeSize
|
|
157
|
-
}, tableStart)
|
|
158
|
-
|
|
159
|
-
const cells = Array(map.width)
|
|
160
|
-
.fill(0)
|
|
161
|
-
.map((_, col) => {
|
|
162
|
-
const headerCol = table.nodeAt(map.map[col] as number)
|
|
163
|
-
return tableCellSchema
|
|
164
|
-
.type(ctx)
|
|
165
|
-
.createAndFill({ alignment: headerCol?.attrs.alignment }) as Node
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
tr.insert(rowPos, tableRowSchema.type(ctx).create(null, cells))
|
|
169
|
-
return tr
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/// @internal
|
|
173
|
-
export function selectLine(type: 'row' | 'col') {
|
|
174
|
-
return (index: number, pos?: number) => (tr: Transaction) => {
|
|
175
|
-
pos = pos ?? tr.selection.from
|
|
176
|
-
const $pos = tr.doc.resolve(pos)
|
|
177
|
-
const $node = findParentNodeClosestToPos(
|
|
178
|
-
(node) => node.type.name === 'table'
|
|
179
|
-
)($pos)
|
|
180
|
-
const table = $node
|
|
181
|
-
? {
|
|
182
|
-
node: $node.node,
|
|
183
|
-
from: $node.start,
|
|
184
|
-
}
|
|
185
|
-
: undefined
|
|
186
|
-
|
|
187
|
-
const isRowSelection = type === 'row'
|
|
188
|
-
if (table) {
|
|
189
|
-
const map = TableMap.get(table.node)
|
|
190
|
-
|
|
191
|
-
// Check if the index is valid
|
|
192
|
-
if (index >= 0 && index < (isRowSelection ? map.height : map.width)) {
|
|
193
|
-
const lastCell = map.positionAt(
|
|
194
|
-
isRowSelection ? index : map.height - 1,
|
|
195
|
-
isRowSelection ? map.width - 1 : index,
|
|
196
|
-
table.node
|
|
197
|
-
)
|
|
198
|
-
const $lastCell = tr.doc.resolve(table.from + lastCell)
|
|
199
|
-
|
|
200
|
-
const createCellSelection = isRowSelection
|
|
201
|
-
? CellSelection.rowSelection
|
|
202
|
-
: CellSelection.colSelection
|
|
203
|
-
|
|
204
|
-
const firstCell = map.positionAt(
|
|
205
|
-
isRowSelection ? index : 0,
|
|
206
|
-
isRowSelection ? 0 : index,
|
|
207
|
-
table.node
|
|
208
|
-
)
|
|
209
|
-
const $firstCell = tr.doc.resolve(table.from + firstCell)
|
|
210
|
-
return cloneTr(
|
|
211
|
-
tr.setSelection(
|
|
212
|
-
createCellSelection($lastCell, $firstCell) as unknown as Selection
|
|
213
|
-
)
|
|
214
|
-
)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return tr
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/// If the selection is in a table,
|
|
222
|
-
/// select the {index} row.
|
|
223
|
-
export const selectRow = selectLine('row')
|
|
224
|
-
|
|
225
|
-
/// If the selection is in a table,
|
|
226
|
-
/// select the {index} column.
|
|
227
|
-
export const selectCol = selectLine('col')
|
|
228
|
-
|
|
229
|
-
function transpose<T>(array: T[][]) {
|
|
230
|
-
return array[0]!.map((_, i) => {
|
|
231
|
-
return array.map((column) => column[i])
|
|
232
|
-
}) as T[][]
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function convertArrayOfRowsToTableNode(
|
|
236
|
-
tableNode: Node,
|
|
237
|
-
arrayOfNodes: (Node | null)[][]
|
|
238
|
-
) {
|
|
239
|
-
const rowsPM = []
|
|
240
|
-
const map = TableMap.get(tableNode)
|
|
241
|
-
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
242
|
-
const row = tableNode.child(rowIndex)
|
|
243
|
-
const rowCells = []
|
|
244
|
-
|
|
245
|
-
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
246
|
-
if (!arrayOfNodes[rowIndex]![colIndex]) continue
|
|
247
|
-
|
|
248
|
-
const cellPos = map.map[rowIndex * map.width + colIndex]!
|
|
249
|
-
|
|
250
|
-
const cell = arrayOfNodes[rowIndex]![colIndex]!
|
|
251
|
-
const oldCell = tableNode.nodeAt(cellPos)!
|
|
252
|
-
const newCell = oldCell.type.createChecked(
|
|
253
|
-
Object.assign({}, cell.attrs),
|
|
254
|
-
cell.content,
|
|
255
|
-
cell.marks
|
|
256
|
-
)
|
|
257
|
-
rowCells.push(newCell)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
rowsPM.push(row.type.createChecked(row.attrs, rowCells, row.marks))
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const newTable = tableNode.type.createChecked(
|
|
264
|
-
tableNode.attrs,
|
|
265
|
-
rowsPM,
|
|
266
|
-
tableNode.marks
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
return newTable
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function convertTableNodeToArrayOfRows(tableNode: Node) {
|
|
273
|
-
const map = TableMap.get(tableNode)
|
|
274
|
-
const rows: (Node | null)[][] = []
|
|
275
|
-
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
276
|
-
const rowCells: (Node | null)[] = []
|
|
277
|
-
const seen: Record<number, boolean> = {}
|
|
278
|
-
|
|
279
|
-
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
280
|
-
const cellPos = map.map[rowIndex * map.width + colIndex]!
|
|
281
|
-
const cell = tableNode.nodeAt(cellPos)
|
|
282
|
-
const rect = map.findCell(cellPos)
|
|
283
|
-
if (seen[cellPos] || rect.top !== rowIndex) {
|
|
284
|
-
rowCells.push(null)
|
|
285
|
-
continue
|
|
286
|
-
}
|
|
287
|
-
seen[cellPos] = true
|
|
288
|
-
|
|
289
|
-
rowCells.push(cell)
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
rows.push(rowCells)
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return rows
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
function moveRowInArrayOfRows(
|
|
299
|
-
rows: (Node | null)[][],
|
|
300
|
-
indexesOrigin: number[],
|
|
301
|
-
indexesTarget: number[],
|
|
302
|
-
directionOverride: -1 | 1 | 0
|
|
303
|
-
) {
|
|
304
|
-
const direction = indexesOrigin[0]! > indexesTarget[0]! ? -1 : 1
|
|
305
|
-
|
|
306
|
-
const rowsExtracted = rows.splice(indexesOrigin[0]!, indexesOrigin.length)
|
|
307
|
-
const positionOffset = rowsExtracted.length % 2 === 0 ? 1 : 0
|
|
308
|
-
let target: number
|
|
309
|
-
|
|
310
|
-
if (directionOverride === -1 && direction === 1) {
|
|
311
|
-
target = indexesTarget[0]! - 1
|
|
312
|
-
} else if (directionOverride === 1 && direction === -1) {
|
|
313
|
-
target = indexesTarget[indexesTarget.length - 1]! - positionOffset + 1
|
|
314
|
-
} else {
|
|
315
|
-
target =
|
|
316
|
-
direction === -1
|
|
317
|
-
? indexesTarget[0]!
|
|
318
|
-
: indexesTarget[indexesTarget.length - 1]! - positionOffset
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
rows.splice(target, 0, ...rowsExtracted)
|
|
322
|
-
return rows
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function moveTableColumn(
|
|
326
|
-
table: ContentNodeWithPos,
|
|
327
|
-
indexesOrigin: number[],
|
|
328
|
-
indexesTarget: number[],
|
|
329
|
-
direction: -1 | 1 | 0
|
|
330
|
-
) {
|
|
331
|
-
let rows = transpose(convertTableNodeToArrayOfRows(table.node))
|
|
332
|
-
|
|
333
|
-
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction)
|
|
334
|
-
rows = transpose(rows)
|
|
335
|
-
|
|
336
|
-
return convertArrayOfRowsToTableNode(table.node, rows)
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function moveTableRow(
|
|
340
|
-
table: ContentNodeWithPos,
|
|
341
|
-
indexesOrigin: number[],
|
|
342
|
-
indexesTarget: number[],
|
|
343
|
-
direction: -1 | 1 | 0
|
|
344
|
-
) {
|
|
345
|
-
let rows = convertTableNodeToArrayOfRows(table.node)
|
|
346
|
-
|
|
347
|
-
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction)
|
|
348
|
-
|
|
349
|
-
return convertArrayOfRowsToTableNode(table.node, rows)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function getSelectionRangeInColumn(columnIndex: number, tr: Transaction) {
|
|
353
|
-
let startIndex = columnIndex
|
|
354
|
-
let endIndex = columnIndex
|
|
355
|
-
|
|
356
|
-
// looking for selection start column (startIndex)
|
|
357
|
-
for (let i = columnIndex; i >= 0; i--) {
|
|
358
|
-
const cells = getCellsInCol(i, tr.selection)
|
|
359
|
-
if (cells) {
|
|
360
|
-
cells.forEach((cell) => {
|
|
361
|
-
const maybeEndIndex = cell.node.attrs.colspan + i - 1
|
|
362
|
-
if (maybeEndIndex >= startIndex) startIndex = i
|
|
363
|
-
|
|
364
|
-
if (maybeEndIndex > endIndex) endIndex = maybeEndIndex
|
|
365
|
-
})
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
// looking for selection end column (endIndex)
|
|
369
|
-
for (let i = columnIndex; i <= endIndex; i++) {
|
|
370
|
-
const cells = getCellsInCol(i, tr.selection)
|
|
371
|
-
if (cells) {
|
|
372
|
-
cells.forEach((cell) => {
|
|
373
|
-
const maybeEndIndex = cell.node.attrs.colspan + i - 1
|
|
374
|
-
if (cell.node.attrs.colspan > 1 && maybeEndIndex > endIndex)
|
|
375
|
-
endIndex = maybeEndIndex
|
|
376
|
-
})
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// filter out columns without cells (where all rows have colspan > 1 in the same column)
|
|
381
|
-
const indexes = []
|
|
382
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
383
|
-
const maybeCells = getCellsInCol(i, tr.selection)
|
|
384
|
-
if (maybeCells && maybeCells.length) indexes.push(i)
|
|
385
|
-
}
|
|
386
|
-
startIndex = indexes[0]!
|
|
387
|
-
endIndex = indexes[indexes.length - 1]!
|
|
388
|
-
|
|
389
|
-
const firstSelectedColumnCells = getCellsInCol(startIndex, tr.selection)!
|
|
390
|
-
const firstRowCells = getCellsInRow(0, tr.selection)!
|
|
391
|
-
const $anchor = tr.doc.resolve(
|
|
392
|
-
firstSelectedColumnCells[firstSelectedColumnCells.length - 1]!.pos
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
let headCell: CellPos | undefined
|
|
396
|
-
for (let i = endIndex; i >= startIndex; i--) {
|
|
397
|
-
const columnCells = getCellsInCol(i, tr.selection)
|
|
398
|
-
if (columnCells && columnCells.length) {
|
|
399
|
-
for (let j = firstRowCells.length - 1; j >= 0; j--) {
|
|
400
|
-
if (firstRowCells[j]!.pos === columnCells[0]!.pos) {
|
|
401
|
-
headCell = columnCells[0]
|
|
402
|
-
break
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
if (headCell) break
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const $head = tr.doc.resolve(headCell!.pos)
|
|
410
|
-
return { $anchor, $head, indexes }
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
function getSelectionRangeInRow(rowIndex: number, tr: Transaction) {
|
|
414
|
-
let startIndex = rowIndex
|
|
415
|
-
let endIndex = rowIndex
|
|
416
|
-
// looking for selection start row (startIndex)
|
|
417
|
-
for (let i = rowIndex; i >= 0; i--) {
|
|
418
|
-
const cells = getCellsInRow(i, tr.selection)
|
|
419
|
-
cells!.forEach((cell) => {
|
|
420
|
-
const maybeEndIndex = cell.node.attrs.rowspan + i - 1
|
|
421
|
-
if (maybeEndIndex >= startIndex) startIndex = i
|
|
422
|
-
|
|
423
|
-
if (maybeEndIndex > endIndex) endIndex = maybeEndIndex
|
|
424
|
-
})
|
|
425
|
-
}
|
|
426
|
-
// looking for selection end row (endIndex)
|
|
427
|
-
for (let i = rowIndex; i <= endIndex; i++) {
|
|
428
|
-
const cells = getCellsInRow(i, tr.selection)
|
|
429
|
-
cells!.forEach((cell) => {
|
|
430
|
-
const maybeEndIndex = cell.node.attrs.rowspan + i - 1
|
|
431
|
-
if (cell.node.attrs.rowspan > 1 && maybeEndIndex > endIndex)
|
|
432
|
-
endIndex = maybeEndIndex
|
|
433
|
-
})
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// filter out rows without cells (where all columns have rowspan > 1 in the same row)
|
|
437
|
-
const indexes = []
|
|
438
|
-
for (let i = startIndex; i <= endIndex; i++) {
|
|
439
|
-
const maybeCells = getCellsInRow(i, tr.selection)
|
|
440
|
-
if (maybeCells && maybeCells.length) indexes.push(i)
|
|
441
|
-
}
|
|
442
|
-
startIndex = indexes[0]!
|
|
443
|
-
endIndex = indexes[indexes.length - 1]!
|
|
444
|
-
|
|
445
|
-
const firstSelectedRowCells = getCellsInRow(startIndex, tr.selection)!
|
|
446
|
-
const firstColumnCells = getCellsInCol(0, tr.selection)!
|
|
447
|
-
const $anchor = tr.doc.resolve(
|
|
448
|
-
firstSelectedRowCells[firstSelectedRowCells.length - 1]!.pos
|
|
449
|
-
)
|
|
450
|
-
|
|
451
|
-
let headCell: CellPos | undefined
|
|
452
|
-
for (let i = endIndex; i >= startIndex; i--) {
|
|
453
|
-
const rowCells = getCellsInRow(i, tr.selection)
|
|
454
|
-
if (rowCells && rowCells.length) {
|
|
455
|
-
for (let j = firstColumnCells.length - 1; j >= 0; j--) {
|
|
456
|
-
if (firstColumnCells[j]!.pos === rowCells[0]!.pos) {
|
|
457
|
-
headCell = rowCells[0]!
|
|
458
|
-
break
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
if (headCell) break
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
const $head = tr.doc.resolve(headCell!.pos)
|
|
466
|
-
return { $anchor, $head, indexes }
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
export interface MoveColParams {
|
|
470
|
-
tr: Transaction
|
|
471
|
-
origin: number
|
|
472
|
-
target: number
|
|
473
|
-
select?: boolean
|
|
474
|
-
pos?: number
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/// If the selection is in a table,
|
|
478
|
-
/// Move the columns at `origin` to `target` in current table.
|
|
479
|
-
/// The `select` is true by default, which means the selection will be set to the moved column.
|
|
480
|
-
export function moveCol(moveColParams: MoveColParams) {
|
|
481
|
-
const { tr, origin, target, select = true, pos } = moveColParams
|
|
482
|
-
const $pos = pos != null ? tr.doc.resolve(pos) : tr.selection.$from
|
|
483
|
-
const table = findTable($pos)
|
|
484
|
-
if (!table) return tr
|
|
485
|
-
|
|
486
|
-
const { indexes: indexesOriginColumn } = getSelectionRangeInColumn(origin, tr)
|
|
487
|
-
const { indexes: indexesTargetColumn } = getSelectionRangeInColumn(target, tr)
|
|
488
|
-
|
|
489
|
-
if (indexesOriginColumn.includes(target)) return tr
|
|
490
|
-
|
|
491
|
-
const newTable = moveTableColumn(
|
|
492
|
-
table,
|
|
493
|
-
indexesOriginColumn,
|
|
494
|
-
indexesTargetColumn,
|
|
495
|
-
0
|
|
496
|
-
)
|
|
497
|
-
|
|
498
|
-
const _tr = cloneTr(tr).replaceWith(
|
|
499
|
-
table.pos,
|
|
500
|
-
table.pos + table.node.nodeSize,
|
|
501
|
-
newTable
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
if (!select) return _tr
|
|
505
|
-
|
|
506
|
-
const map = TableMap.get(newTable)
|
|
507
|
-
const start = table.start
|
|
508
|
-
const index = target
|
|
509
|
-
const lastCell = map.positionAt(map.height - 1, index, newTable)
|
|
510
|
-
const $lastCell = _tr.doc.resolve(start + lastCell)
|
|
511
|
-
|
|
512
|
-
const createCellSelection = CellSelection.colSelection
|
|
513
|
-
|
|
514
|
-
const firstCell = map.positionAt(0, index, newTable)
|
|
515
|
-
const $firstCell = _tr.doc.resolve(start + firstCell)
|
|
516
|
-
|
|
517
|
-
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
export interface MoveRowParams {
|
|
521
|
-
tr: Transaction
|
|
522
|
-
origin: number
|
|
523
|
-
target: number
|
|
524
|
-
select?: boolean
|
|
525
|
-
pos?: number
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
/// If the selection is in a table,
|
|
529
|
-
/// Move the rows at `origin` and `target` in current table.
|
|
530
|
-
/// The `select` is true by default, which means the selection will be set to the moved row.
|
|
531
|
-
export function moveRow(moveRowParams: MoveRowParams) {
|
|
532
|
-
const { tr, origin, target, select = true, pos } = moveRowParams
|
|
533
|
-
const $pos = pos != null ? tr.doc.resolve(pos) : tr.selection.$from
|
|
534
|
-
const table = findTable($pos)
|
|
535
|
-
if (!table) return tr
|
|
536
|
-
|
|
537
|
-
const { indexes: indexesOriginRow } = getSelectionRangeInRow(origin, tr)
|
|
538
|
-
const { indexes: indexesTargetRow } = getSelectionRangeInRow(target, tr)
|
|
539
|
-
|
|
540
|
-
if (indexesOriginRow.includes(target)) return tr
|
|
541
|
-
|
|
542
|
-
const newTable = moveTableRow(table, indexesOriginRow, indexesTargetRow, 0)
|
|
543
|
-
|
|
544
|
-
const _tr = cloneTr(tr).replaceWith(
|
|
545
|
-
table.pos,
|
|
546
|
-
table.pos + table.node.nodeSize,
|
|
547
|
-
newTable
|
|
548
|
-
)
|
|
549
|
-
|
|
550
|
-
if (!select) return _tr
|
|
551
|
-
|
|
552
|
-
const map = TableMap.get(newTable)
|
|
553
|
-
const start = table.start
|
|
554
|
-
const index = target
|
|
555
|
-
const lastCell = map.positionAt(index, map.width - 1, newTable)
|
|
556
|
-
const $lastCell = _tr.doc.resolve(start + lastCell)
|
|
557
|
-
|
|
558
|
-
const createCellSelection = CellSelection.rowSelection
|
|
559
|
-
|
|
560
|
-
const firstCell = map.positionAt(index, 0, newTable)
|
|
561
|
-
const $firstCell = _tr.doc.resolve(start + firstCell)
|
|
562
|
-
|
|
563
|
-
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
564
|
-
}
|