@milkdown/preset-gfm 6.5.3 → 7.0.0-next.0
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/composed/commands.d.ts +8 -0
- package/lib/composed/commands.d.ts.map +1 -0
- package/lib/composed/index.d.ts +6 -0
- package/lib/composed/index.d.ts.map +1 -0
- package/lib/composed/inputrules.d.ts +3 -0
- package/lib/composed/inputrules.d.ts.map +1 -0
- package/lib/composed/keymap.d.ts +3 -0
- package/lib/composed/keymap.d.ts.map +1 -0
- package/lib/composed/plugins.d.ts +3 -0
- package/lib/composed/plugins.d.ts.map +1 -0
- package/lib/composed/schema.d.ts +3 -0
- package/lib/composed/schema.d.ts.map +1 -0
- package/lib/index.d.ts +4 -34
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +633 -2328
- package/lib/index.es.js.map +1 -1
- package/lib/mark/index.d.ts +2 -0
- package/lib/mark/index.d.ts.map +1 -0
- package/lib/mark/strike-through.d.ts +4 -0
- package/lib/mark/strike-through.d.ts.map +1 -0
- package/lib/node/footnote/definition.d.ts +2 -0
- package/lib/node/footnote/definition.d.ts.map +1 -0
- package/lib/{footnote → node/footnote}/index.d.ts +0 -0
- package/lib/node/footnote/index.d.ts.map +1 -0
- package/lib/node/footnote/reference.d.ts +2 -0
- package/lib/node/footnote/reference.d.ts.map +1 -0
- package/lib/node/index.d.ts +4 -0
- package/lib/node/index.d.ts.map +1 -0
- package/lib/node/table/index.d.ts +32 -0
- package/lib/node/table/index.d.ts.map +1 -0
- package/lib/node/table/utils.d.ts +27 -0
- package/lib/node/table/utils.d.ts.map +1 -0
- package/lib/node/task-list-item.d.ts +2 -0
- package/lib/node/task-list-item.d.ts.map +1 -0
- package/lib/plugin/auto-insert-zero-space-plugin.d.ts +2 -0
- package/lib/plugin/auto-insert-zero-space-plugin.d.ts.map +1 -0
- package/lib/plugin/column-resizing-plugin.d.ts +2 -0
- package/lib/plugin/column-resizing-plugin.d.ts.map +1 -0
- package/lib/plugin/index.d.ts +5 -0
- package/lib/plugin/index.d.ts.map +1 -0
- package/lib/plugin/remark-gfm-plugin.d.ts +2 -0
- package/lib/plugin/remark-gfm-plugin.d.ts.map +1 -0
- package/lib/plugin/table-editing-plugin.d.ts +2 -0
- package/lib/plugin/table-editing-plugin.d.ts.map +1 -0
- package/package.json +18 -10
- package/src/composed/commands.ts +23 -0
- package/src/composed/index.ts +6 -0
- package/src/composed/inputrules.ts +7 -0
- package/src/composed/keymap.ts +9 -0
- package/src/composed/plugins.ts +10 -0
- package/src/composed/schema.ts +18 -0
- package/src/index.ts +5 -89
- package/src/mark/index.ts +2 -0
- package/src/mark/strike-through.ts +39 -0
- package/src/node/footnote/definition.ts +68 -0
- package/src/{footnote → node/footnote}/index.ts +0 -0
- package/src/node/footnote/reference.ts +58 -0
- package/src/node/index.ts +4 -0
- package/src/node/table/index.ts +283 -0
- package/src/node/table/utils.ts +489 -0
- package/src/node/task-list-item.ts +87 -0
- package/src/{table/plugin/auto-insert-zero-space.ts → plugin/auto-insert-zero-space-plugin.ts} +13 -15
- package/src/plugin/column-resizing-plugin.ts +4 -0
- package/src/plugin/index.ts +5 -0
- package/src/plugin/remark-gfm-plugin.ts +5 -0
- package/src/plugin/table-editing-plugin.ts +4 -0
- package/lib/footnote/definition.d.ts +0 -3
- package/lib/footnote/definition.d.ts.map +0 -1
- package/lib/footnote/index.d.ts.map +0 -1
- package/lib/footnote/reference.d.ts +0 -3
- package/lib/footnote/reference.d.ts.map +0 -1
- package/lib/footnote/utils.d.ts +0 -3
- package/lib/footnote/utils.d.ts.map +0 -1
- package/lib/strike-through.d.ts +0 -3
- package/lib/strike-through.d.ts.map +0 -1
- package/lib/supported-keys.d.ts +0 -28
- package/lib/supported-keys.d.ts.map +0 -1
- package/lib/table/command.d.ts +0 -4
- package/lib/table/command.d.ts.map +0 -1
- package/lib/table/index.d.ts +0 -10
- package/lib/table/index.d.ts.map +0 -1
- package/lib/table/nodes/index.d.ts +0 -12
- package/lib/table/nodes/index.d.ts.map +0 -1
- package/lib/table/operator-plugin/actions.d.ts +0 -20
- package/lib/table/operator-plugin/actions.d.ts.map +0 -1
- package/lib/table/operator-plugin/calc-pos.d.ts +0 -3
- package/lib/table/operator-plugin/calc-pos.d.ts.map +0 -1
- package/lib/table/operator-plugin/constant.d.ts +0 -6
- package/lib/table/operator-plugin/constant.d.ts.map +0 -1
- package/lib/table/operator-plugin/helper.d.ts +0 -7
- package/lib/table/operator-plugin/helper.d.ts.map +0 -1
- package/lib/table/operator-plugin/index.d.ts +0 -6
- package/lib/table/operator-plugin/index.d.ts.map +0 -1
- package/lib/table/operator-plugin/style.d.ts +0 -3
- package/lib/table/operator-plugin/style.d.ts.map +0 -1
- package/lib/table/operator-plugin/widget.d.ts +0 -8
- package/lib/table/operator-plugin/widget.d.ts.map +0 -1
- package/lib/table/plugin/auto-insert-zero-space.d.ts +0 -3
- package/lib/table/plugin/auto-insert-zero-space.d.ts.map +0 -1
- package/lib/table/plugin/cell-selection.d.ts +0 -40
- package/lib/table/plugin/cell-selection.d.ts.map +0 -1
- package/lib/table/plugin/column-resizing.d.ts +0 -18
- package/lib/table/plugin/column-resizing.d.ts.map +0 -1
- package/lib/table/plugin/commands.d.ts +0 -30
- package/lib/table/plugin/commands.d.ts.map +0 -1
- package/lib/table/plugin/copy-paste.d.ts +0 -14
- package/lib/table/plugin/copy-paste.d.ts.map +0 -1
- package/lib/table/plugin/fix-tables.d.ts +0 -7
- package/lib/table/plugin/fix-tables.d.ts.map +0 -1
- package/lib/table/plugin/index.d.ts +0 -4
- package/lib/table/plugin/index.d.ts.map +0 -1
- package/lib/table/plugin/schema.d.ts +0 -4
- package/lib/table/plugin/schema.d.ts.map +0 -1
- package/lib/table/plugin/table-editing.d.ts +0 -9
- package/lib/table/plugin/table-editing.d.ts.map +0 -1
- package/lib/table/plugin/table-map.d.ts +0 -44
- package/lib/table/plugin/table-map.d.ts.map +0 -1
- package/lib/table/plugin/table-view.d.ts +0 -15
- package/lib/table/plugin/table-view.d.ts.map +0 -1
- package/lib/table/plugin/types.d.ts +0 -15
- package/lib/table/plugin/types.d.ts.map +0 -1
- package/lib/table/plugin/util.d.ts +0 -16
- package/lib/table/plugin/util.d.ts.map +0 -1
- package/lib/table/utils.d.ts +0 -21
- package/lib/table/utils.d.ts.map +0 -1
- package/lib/task-list-item.d.ts +0 -9
- package/lib/task-list-item.d.ts.map +0 -1
- package/src/footnote/definition.ts +0 -187
- package/src/footnote/reference.ts +0 -178
- package/src/footnote/utils.ts +0 -4
- package/src/strike-through.ts +0 -43
- package/src/supported-keys.ts +0 -13
- package/src/table/command.ts +0 -20
- package/src/table/index.ts +0 -13
- package/src/table/nodes/index.ts +0 -189
- package/src/table/operator-plugin/actions.ts +0 -116
- package/src/table/operator-plugin/calc-pos.ts +0 -36
- package/src/table/operator-plugin/constant.ts +0 -7
- package/src/table/operator-plugin/helper.ts +0 -39
- package/src/table/operator-plugin/index.ts +0 -110
- package/src/table/operator-plugin/style.ts +0 -123
- package/src/table/operator-plugin/widget.ts +0 -57
- package/src/table/plugin/cell-selection.ts +0 -381
- package/src/table/plugin/column-resizing.ts +0 -288
- package/src/table/plugin/commands.ts +0 -594
- package/src/table/plugin/copy-paste.ts +0 -322
- package/src/table/plugin/fix-tables.ts +0 -132
- package/src/table/plugin/index.ts +0 -4
- package/src/table/plugin/schema.ts +0 -120
- package/src/table/plugin/table-editing.ts +0 -369
- package/src/table/plugin/table-map.ts +0 -345
- package/src/table/plugin/table-view.ts +0 -80
- package/src/table/plugin/types.ts +0 -16
- package/src/table/plugin/util.ts +0 -119
- package/src/table/utils.ts +0 -165
- package/src/task-list-item.ts +0 -159
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
|
|
3
|
+
import type { ContentNodeWithPos } from '@milkdown/prose'
|
|
4
|
+
import { cloneTr, findParentNode } from '@milkdown/prose'
|
|
5
|
+
import type { Node } from '@milkdown/prose/model'
|
|
6
|
+
import type { Selection, Transaction } from '@milkdown/prose/state'
|
|
7
|
+
import type { TableRect } from '@milkdown/prose/tables'
|
|
8
|
+
import { CellSelection, TableMap } from '@milkdown/prose/tables'
|
|
9
|
+
|
|
10
|
+
import { tableCellSchema, tableHeaderSchema, tableRowSchema, tableSchema } from '.'
|
|
11
|
+
|
|
12
|
+
export interface CellPos {
|
|
13
|
+
pos: number
|
|
14
|
+
start: number
|
|
15
|
+
node: Node
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const createTable = (rowsCount = 3, colsCount = 3): Node => {
|
|
19
|
+
const cells = Array(colsCount)
|
|
20
|
+
.fill(0)
|
|
21
|
+
.map(() => tableCellSchema.type().createAndFill()!)
|
|
22
|
+
|
|
23
|
+
const headerCells = Array(colsCount)
|
|
24
|
+
.fill(0)
|
|
25
|
+
.map(() => tableHeaderSchema.type().createAndFill()!)
|
|
26
|
+
|
|
27
|
+
const rows = Array(rowsCount)
|
|
28
|
+
.fill(0)
|
|
29
|
+
.map((_, i) => tableRowSchema.type().create(null, i === 0 ? headerCells : cells))
|
|
30
|
+
|
|
31
|
+
return tableSchema.type().create(null, rows)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const findTable = (selection: Selection) =>
|
|
35
|
+
findParentNode(node => node.type.spec.tableRole === 'table')(selection)
|
|
36
|
+
|
|
37
|
+
export const getCellsInColumn = (columnIndex: number, selection: Selection): CellPos[] | undefined => {
|
|
38
|
+
const table = findTable(selection)
|
|
39
|
+
if (!table)
|
|
40
|
+
return undefined
|
|
41
|
+
const map = TableMap.get(table.node)
|
|
42
|
+
if (columnIndex < 0 || columnIndex >= map.width)
|
|
43
|
+
return undefined
|
|
44
|
+
|
|
45
|
+
return map
|
|
46
|
+
.cellsInRect({ left: columnIndex, right: columnIndex + 1, top: 0, bottom: map.height })
|
|
47
|
+
.map((pos) => {
|
|
48
|
+
const node = table.node.nodeAt(pos)
|
|
49
|
+
if (!node)
|
|
50
|
+
return undefined
|
|
51
|
+
const start = pos + table.start
|
|
52
|
+
return {
|
|
53
|
+
pos: start,
|
|
54
|
+
start: start + 1,
|
|
55
|
+
node,
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.filter((x): x is CellPos => x != null)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const getCellsInRow = (rowIndex: number, selection: Selection): CellPos[] | undefined => {
|
|
62
|
+
const table = findTable(selection)
|
|
63
|
+
if (!table)
|
|
64
|
+
return undefined
|
|
65
|
+
const map = TableMap.get(table.node)
|
|
66
|
+
if (rowIndex < 0 || rowIndex >= map.height)
|
|
67
|
+
return undefined
|
|
68
|
+
|
|
69
|
+
return map
|
|
70
|
+
.cellsInRect({ left: 0, right: map.width, top: rowIndex, bottom: rowIndex + 1 })
|
|
71
|
+
.map((pos) => {
|
|
72
|
+
const node = table.node.nodeAt(pos)
|
|
73
|
+
if (!node)
|
|
74
|
+
return undefined
|
|
75
|
+
const start = pos + table.start
|
|
76
|
+
return {
|
|
77
|
+
pos: start,
|
|
78
|
+
start: start + 1,
|
|
79
|
+
node,
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
.filter((x): x is CellPos => x != null)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export const getAllCellsInTable = (selection: Selection) => {
|
|
86
|
+
const table = findTable(selection)
|
|
87
|
+
if (!table)
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
const map = TableMap.get(table.node)
|
|
91
|
+
const cells = map.cellsInRect({
|
|
92
|
+
left: 0,
|
|
93
|
+
right: map.width,
|
|
94
|
+
top: 0,
|
|
95
|
+
bottom: map.height,
|
|
96
|
+
})
|
|
97
|
+
return cells.map((nodePos) => {
|
|
98
|
+
const node = table.node.nodeAt(nodePos)
|
|
99
|
+
const pos = nodePos + table.start
|
|
100
|
+
return { pos, start: pos + 1, node }
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const selectTable = (tr: Transaction) => {
|
|
105
|
+
const cells = getAllCellsInTable(tr.selection)
|
|
106
|
+
if (cells && cells[0]) {
|
|
107
|
+
const $firstCell = tr.doc.resolve(cells[0].pos)
|
|
108
|
+
const last = cells[cells.length - 1]
|
|
109
|
+
if (last) {
|
|
110
|
+
const $lastCell = tr.doc.resolve(last.pos)
|
|
111
|
+
return cloneTr(tr.setSelection(new CellSelection($lastCell, $firstCell)))
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return tr
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function addRowWithAlignment(tr: Transaction, { map, tableStart, table }: TableRect, row: number) {
|
|
118
|
+
const rowPos = Array(row)
|
|
119
|
+
.fill(0)
|
|
120
|
+
.reduce((acc, _, i) => {
|
|
121
|
+
return acc + table.child(i).nodeSize
|
|
122
|
+
}, tableStart)
|
|
123
|
+
|
|
124
|
+
const cells = Array(map.width)
|
|
125
|
+
.fill(0)
|
|
126
|
+
.map((_, col) => {
|
|
127
|
+
const headerCol = table.nodeAt(map.map[col] as number)
|
|
128
|
+
return tableCellSchema.type().createAndFill({ alignment: headerCol?.attrs.alignment }) as Node
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
tr.insert(rowPos, tableRowSchema.type().create(null, cells))
|
|
132
|
+
return tr
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const selectLine = (type: 'row' | 'col') => (index: number) => (tr: Transaction) => {
|
|
136
|
+
const table = findTable(tr.selection)
|
|
137
|
+
const isRowSelection = type === 'row'
|
|
138
|
+
if (table) {
|
|
139
|
+
const map = TableMap.get(table.node)
|
|
140
|
+
|
|
141
|
+
// Check if the index is valid
|
|
142
|
+
if (index >= 0 && index < (isRowSelection ? map.height : map.width)) {
|
|
143
|
+
const lastCell = map.positionAt(
|
|
144
|
+
isRowSelection ? index : map.height - 1,
|
|
145
|
+
isRowSelection ? map.width - 1 : index,
|
|
146
|
+
table.node,
|
|
147
|
+
)
|
|
148
|
+
const $lastCell = tr.doc.resolve(table.start + lastCell)
|
|
149
|
+
|
|
150
|
+
const createCellSelection = isRowSelection ? CellSelection.rowSelection : CellSelection.colSelection
|
|
151
|
+
|
|
152
|
+
const firstCell = map.positionAt(isRowSelection ? index : 0, isRowSelection ? 0 : index, table.node)
|
|
153
|
+
const $firstCell = tr.doc.resolve(table.start + firstCell)
|
|
154
|
+
return cloneTr(tr.setSelection(createCellSelection($lastCell, $firstCell) as unknown as Selection))
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return tr
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const selectRow = selectLine('row')
|
|
161
|
+
export const selectCol = selectLine('col')
|
|
162
|
+
|
|
163
|
+
const transpose = <T>(array: T[][]) => {
|
|
164
|
+
return array[0]!.map((_, i) => {
|
|
165
|
+
return array.map(column => column[i])
|
|
166
|
+
}) as T[][]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const convertArrayOfRowsToTableNode = (tableNode: Node, arrayOfNodes: (Node | null)[][]) => {
|
|
170
|
+
const rowsPM = []
|
|
171
|
+
const map = TableMap.get(tableNode)
|
|
172
|
+
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
173
|
+
const row = tableNode.child(rowIndex)
|
|
174
|
+
const rowCells = []
|
|
175
|
+
|
|
176
|
+
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
177
|
+
if (!arrayOfNodes[rowIndex]![colIndex])
|
|
178
|
+
continue
|
|
179
|
+
|
|
180
|
+
const cellPos = map.map[rowIndex * map.width + colIndex]!
|
|
181
|
+
|
|
182
|
+
const cell = arrayOfNodes[rowIndex]![colIndex]!
|
|
183
|
+
const oldCell = tableNode.nodeAt(cellPos)!
|
|
184
|
+
const newCell = oldCell.type.createChecked(
|
|
185
|
+
Object.assign({}, cell.attrs),
|
|
186
|
+
cell.content,
|
|
187
|
+
cell.marks,
|
|
188
|
+
)
|
|
189
|
+
rowCells.push(newCell)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
rowsPM.push(row.type.createChecked(row.attrs, rowCells, row.marks))
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const newTable = tableNode.type.createChecked(
|
|
196
|
+
tableNode.attrs,
|
|
197
|
+
rowsPM,
|
|
198
|
+
tableNode.marks,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return newTable
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export const convertTableNodeToArrayOfRows = (tableNode: Node) => {
|
|
205
|
+
const map = TableMap.get(tableNode)
|
|
206
|
+
const rows: (Node | null)[][] = []
|
|
207
|
+
for (let rowIndex = 0; rowIndex < map.height; rowIndex++) {
|
|
208
|
+
const rowCells: (Node | null)[] = []
|
|
209
|
+
const seen: Record<number, boolean> = {}
|
|
210
|
+
|
|
211
|
+
for (let colIndex = 0; colIndex < map.width; colIndex++) {
|
|
212
|
+
const cellPos = map.map[rowIndex * map.width + colIndex]!
|
|
213
|
+
const cell = tableNode.nodeAt(cellPos)
|
|
214
|
+
const rect = map.findCell(cellPos)
|
|
215
|
+
if (seen[cellPos] || rect.top !== rowIndex) {
|
|
216
|
+
rowCells.push(null)
|
|
217
|
+
continue
|
|
218
|
+
}
|
|
219
|
+
seen[cellPos] = true
|
|
220
|
+
|
|
221
|
+
rowCells.push(cell)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
rows.push(rowCells)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return rows
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const moveRowInArrayOfRows = (
|
|
231
|
+
rows: (Node | null)[][],
|
|
232
|
+
indexesOrigin: number[],
|
|
233
|
+
indexesTarget: number[],
|
|
234
|
+
directionOverride: -1 | 1 | 0,
|
|
235
|
+
) => {
|
|
236
|
+
const direction = indexesOrigin[0]! > indexesTarget[0]! ? -1 : 1
|
|
237
|
+
|
|
238
|
+
const rowsExtracted = rows.splice(indexesOrigin[0]!, indexesOrigin.length)
|
|
239
|
+
const positionOffset = rowsExtracted.length % 2 === 0 ? 1 : 0
|
|
240
|
+
let target: number
|
|
241
|
+
|
|
242
|
+
if (directionOverride === -1 && direction === 1) {
|
|
243
|
+
target = indexesTarget[0]! - 1
|
|
244
|
+
}
|
|
245
|
+
else if (directionOverride === 1 && direction === -1) {
|
|
246
|
+
target = indexesTarget[indexesTarget.length - 1]! - positionOffset + 1
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
target
|
|
250
|
+
= direction === -1
|
|
251
|
+
? indexesTarget[0]!
|
|
252
|
+
: indexesTarget[indexesTarget.length - 1]! - positionOffset
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
rows.splice(target, 0, ...rowsExtracted)
|
|
256
|
+
return rows
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const moveTableColumn = (
|
|
260
|
+
table: ContentNodeWithPos,
|
|
261
|
+
indexesOrigin: number[],
|
|
262
|
+
indexesTarget: number[],
|
|
263
|
+
direction: -1 | 1 | 0,
|
|
264
|
+
) => {
|
|
265
|
+
let rows = transpose(convertTableNodeToArrayOfRows(table.node))
|
|
266
|
+
|
|
267
|
+
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction)
|
|
268
|
+
rows = transpose(rows)
|
|
269
|
+
|
|
270
|
+
return convertArrayOfRowsToTableNode(table.node, rows)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const moveTableRow = (
|
|
274
|
+
table: ContentNodeWithPos,
|
|
275
|
+
indexesOrigin: number[],
|
|
276
|
+
indexesTarget: number[],
|
|
277
|
+
direction: -1 | 1 | 0,
|
|
278
|
+
) => {
|
|
279
|
+
let rows = convertTableNodeToArrayOfRows(table.node)
|
|
280
|
+
|
|
281
|
+
rows = moveRowInArrayOfRows(rows, indexesOrigin, indexesTarget, direction)
|
|
282
|
+
|
|
283
|
+
return convertArrayOfRowsToTableNode(table.node, rows)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const getSelectionRangeInColumn = (columnIndex: number, tr: Transaction) => {
|
|
287
|
+
let startIndex = columnIndex
|
|
288
|
+
let endIndex = columnIndex
|
|
289
|
+
|
|
290
|
+
// looking for selection start column (startIndex)
|
|
291
|
+
for (let i = columnIndex; i >= 0; i--) {
|
|
292
|
+
const cells = getCellsInColumn(i, tr.selection)
|
|
293
|
+
if (cells) {
|
|
294
|
+
cells.forEach((cell) => {
|
|
295
|
+
const maybeEndIndex = cell.node.attrs.colspan + i - 1
|
|
296
|
+
if (maybeEndIndex >= startIndex)
|
|
297
|
+
startIndex = i
|
|
298
|
+
|
|
299
|
+
if (maybeEndIndex > endIndex)
|
|
300
|
+
endIndex = maybeEndIndex
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// looking for selection end column (endIndex)
|
|
305
|
+
for (let i = columnIndex; i <= endIndex; i++) {
|
|
306
|
+
const cells = getCellsInColumn(i, tr.selection)
|
|
307
|
+
if (cells) {
|
|
308
|
+
cells.forEach((cell) => {
|
|
309
|
+
const maybeEndIndex = cell.node.attrs.colspan + i - 1
|
|
310
|
+
if (cell.node.attrs.colspan > 1 && maybeEndIndex > endIndex)
|
|
311
|
+
endIndex = maybeEndIndex
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// filter out columns without cells (where all rows have colspan > 1 in the same column)
|
|
317
|
+
const indexes = []
|
|
318
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
319
|
+
const maybeCells = getCellsInColumn(i, tr.selection)
|
|
320
|
+
if (maybeCells && maybeCells.length)
|
|
321
|
+
indexes.push(i)
|
|
322
|
+
}
|
|
323
|
+
startIndex = indexes[0]!
|
|
324
|
+
endIndex = indexes[indexes.length - 1]!
|
|
325
|
+
|
|
326
|
+
const firstSelectedColumnCells = getCellsInColumn(startIndex, tr.selection)!
|
|
327
|
+
const firstRowCells = getCellsInRow(0, tr.selection)!
|
|
328
|
+
const $anchor = tr.doc.resolve(
|
|
329
|
+
firstSelectedColumnCells[firstSelectedColumnCells.length - 1]!.pos,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
let headCell: CellPos | undefined
|
|
333
|
+
for (let i = endIndex; i >= startIndex; i--) {
|
|
334
|
+
const columnCells = getCellsInColumn(i, tr.selection)
|
|
335
|
+
if (columnCells && columnCells.length) {
|
|
336
|
+
for (let j = firstRowCells.length - 1; j >= 0; j--) {
|
|
337
|
+
if (firstRowCells[j]!.pos === columnCells[0]!.pos) {
|
|
338
|
+
headCell = columnCells[0]
|
|
339
|
+
break
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (headCell)
|
|
343
|
+
break
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const $head = tr.doc.resolve(headCell!.pos)
|
|
348
|
+
return { $anchor, $head, indexes }
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const getSelectionRangeInRow = (rowIndex: number, tr: Transaction) => {
|
|
352
|
+
let startIndex = rowIndex
|
|
353
|
+
let endIndex = rowIndex
|
|
354
|
+
// looking for selection start row (startIndex)
|
|
355
|
+
for (let i = rowIndex; i >= 0; i--) {
|
|
356
|
+
const cells = getCellsInRow(i, tr.selection)
|
|
357
|
+
cells!.forEach((cell) => {
|
|
358
|
+
const maybeEndIndex = cell.node.attrs.rowspan + i - 1
|
|
359
|
+
if (maybeEndIndex >= startIndex)
|
|
360
|
+
startIndex = i
|
|
361
|
+
|
|
362
|
+
if (maybeEndIndex > endIndex)
|
|
363
|
+
endIndex = maybeEndIndex
|
|
364
|
+
})
|
|
365
|
+
}
|
|
366
|
+
// looking for selection end row (endIndex)
|
|
367
|
+
for (let i = rowIndex; i <= endIndex; i++) {
|
|
368
|
+
const cells = getCellsInRow(i, tr.selection)
|
|
369
|
+
cells!.forEach((cell) => {
|
|
370
|
+
const maybeEndIndex = cell.node.attrs.rowspan + i - 1
|
|
371
|
+
if (cell.node.attrs.rowspan > 1 && maybeEndIndex > endIndex)
|
|
372
|
+
endIndex = maybeEndIndex
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// filter out rows without cells (where all columns have rowspan > 1 in the same row)
|
|
377
|
+
const indexes = []
|
|
378
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
379
|
+
const maybeCells = getCellsInRow(i, tr.selection)
|
|
380
|
+
if (maybeCells && maybeCells.length)
|
|
381
|
+
indexes.push(i)
|
|
382
|
+
}
|
|
383
|
+
startIndex = indexes[0]!
|
|
384
|
+
endIndex = indexes[indexes.length - 1]!
|
|
385
|
+
|
|
386
|
+
const firstSelectedRowCells = getCellsInRow(startIndex, tr.selection)!
|
|
387
|
+
const firstColumnCells = getCellsInColumn(0, tr.selection)!
|
|
388
|
+
const $anchor = tr.doc.resolve(firstSelectedRowCells[firstSelectedRowCells.length - 1]!.pos)
|
|
389
|
+
|
|
390
|
+
let headCell: CellPos | undefined
|
|
391
|
+
for (let i = endIndex; i >= startIndex; i--) {
|
|
392
|
+
const rowCells = getCellsInRow(i, tr.selection)
|
|
393
|
+
if (rowCells && rowCells.length) {
|
|
394
|
+
for (let j = firstColumnCells.length - 1; j >= 0; j--) {
|
|
395
|
+
if (firstColumnCells[j]!.pos === rowCells[0]!.pos) {
|
|
396
|
+
headCell = rowCells[0]!
|
|
397
|
+
break
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (headCell)
|
|
401
|
+
break
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const $head = tr.doc.resolve(headCell!.pos)
|
|
406
|
+
return { $anchor, $head, indexes }
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function moveCol(tr: Transaction, origin: number, target: number, select = true) {
|
|
410
|
+
const table = findTable(tr.selection)
|
|
411
|
+
if (!table)
|
|
412
|
+
return tr
|
|
413
|
+
|
|
414
|
+
const { indexes: indexesOriginColumn } = getSelectionRangeInColumn(origin, tr)
|
|
415
|
+
const { indexes: indexesTargetColumn } = getSelectionRangeInColumn(target, tr)
|
|
416
|
+
|
|
417
|
+
if (indexesOriginColumn.includes(target))
|
|
418
|
+
return tr
|
|
419
|
+
|
|
420
|
+
const newTable = moveTableColumn(
|
|
421
|
+
table,
|
|
422
|
+
indexesOriginColumn,
|
|
423
|
+
indexesTargetColumn,
|
|
424
|
+
0,
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
const _tr = cloneTr(tr).replaceWith(
|
|
428
|
+
table.pos,
|
|
429
|
+
table.pos + table.node.nodeSize,
|
|
430
|
+
newTable,
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
if (!select)
|
|
434
|
+
return _tr
|
|
435
|
+
|
|
436
|
+
const map = TableMap.get(newTable)
|
|
437
|
+
const start = table.start
|
|
438
|
+
const index = target
|
|
439
|
+
const lastCell = map.positionAt(map.height - 1, index, newTable)
|
|
440
|
+
const $lastCell = _tr.doc.resolve(start + lastCell)
|
|
441
|
+
|
|
442
|
+
const createCellSelection = CellSelection.colSelection
|
|
443
|
+
|
|
444
|
+
const firstCell = map.positionAt(0, index, newTable)
|
|
445
|
+
const $firstCell = _tr.doc.resolve(start + firstCell)
|
|
446
|
+
|
|
447
|
+
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export function moveRow(tr: Transaction, origin: number, target: number, select = true) {
|
|
451
|
+
const table = findTable(tr.selection)
|
|
452
|
+
if (!table)
|
|
453
|
+
return tr
|
|
454
|
+
|
|
455
|
+
const { indexes: indexesOriginRow } = getSelectionRangeInRow(origin, tr)
|
|
456
|
+
const { indexes: indexesTargetRow } = getSelectionRangeInRow(target, tr)
|
|
457
|
+
|
|
458
|
+
if (indexesOriginRow.includes(target))
|
|
459
|
+
return tr
|
|
460
|
+
|
|
461
|
+
const newTable = moveTableRow(
|
|
462
|
+
table,
|
|
463
|
+
indexesOriginRow,
|
|
464
|
+
indexesTargetRow,
|
|
465
|
+
0,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
const _tr = cloneTr(tr).replaceWith(
|
|
469
|
+
table.pos,
|
|
470
|
+
table.pos + table.node.nodeSize,
|
|
471
|
+
newTable,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
if (!select)
|
|
475
|
+
return _tr
|
|
476
|
+
|
|
477
|
+
const map = TableMap.get(newTable)
|
|
478
|
+
const start = table.start
|
|
479
|
+
const index = target
|
|
480
|
+
const lastCell = map.positionAt(index, map.width - 1, newTable)
|
|
481
|
+
const $lastCell = _tr.doc.resolve(start + lastCell)
|
|
482
|
+
|
|
483
|
+
const createCellSelection = CellSelection.rowSelection
|
|
484
|
+
|
|
485
|
+
const firstCell = map.positionAt(index, 0, newTable)
|
|
486
|
+
const $firstCell = _tr.doc.resolve(start + firstCell)
|
|
487
|
+
|
|
488
|
+
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
489
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
+
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
|
+
import { listItemSchema } from '@milkdown/preset-commonmark'
|
|
4
|
+
|
|
5
|
+
export const extendListItemSchemaForTask = listItemSchema.extendSchema((prev) => {
|
|
6
|
+
return (ctx) => {
|
|
7
|
+
const baseSchema = prev(ctx)
|
|
8
|
+
return {
|
|
9
|
+
...baseSchema,
|
|
10
|
+
attrs: {
|
|
11
|
+
...baseSchema.attrs,
|
|
12
|
+
checked: {
|
|
13
|
+
default: null,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
parseDOM: [
|
|
17
|
+
{
|
|
18
|
+
tag: 'li[data-item-type="task"]',
|
|
19
|
+
getAttrs: (dom) => {
|
|
20
|
+
if (!(dom instanceof HTMLElement))
|
|
21
|
+
throw expectDomTypeError(dom)
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
label: dom.dataset.label,
|
|
25
|
+
listType: dom.dataset['list-type'],
|
|
26
|
+
spread: dom.dataset.spread,
|
|
27
|
+
checked: dom.dataset.checked ? dom.dataset.checked === 'true' : null,
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
...baseSchema?.parseDOM || [],
|
|
32
|
+
],
|
|
33
|
+
toDOM: (node) => {
|
|
34
|
+
if (baseSchema.toDOM && node.attrs.checked == null)
|
|
35
|
+
return baseSchema.toDOM(node)
|
|
36
|
+
|
|
37
|
+
return [
|
|
38
|
+
'li',
|
|
39
|
+
{
|
|
40
|
+
'data-item-type': 'task',
|
|
41
|
+
'data-label': node.attrs.label,
|
|
42
|
+
'data-list-type': node.attrs.listType,
|
|
43
|
+
'data-spread': node.attrs.spread,
|
|
44
|
+
'data-checked': node.attrs.checked,
|
|
45
|
+
},
|
|
46
|
+
0,
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
parseMarkdown: {
|
|
50
|
+
match: ({ type }) => type === 'listItem',
|
|
51
|
+
runner: (state, node, type) => {
|
|
52
|
+
if (node.checked == null) {
|
|
53
|
+
baseSchema.parseMarkdown.runner(state, node, type)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const label = node.label != null ? `${node.label}.` : '•'
|
|
58
|
+
const checked = node.checked != null ? Boolean(node.checked) : null
|
|
59
|
+
const listType = node.label != null ? 'ordered' : 'bullet'
|
|
60
|
+
const spread = node.spread != null ? `${node.spread}` : 'true'
|
|
61
|
+
|
|
62
|
+
state.openNode(type, { label, listType, spread, checked })
|
|
63
|
+
state.next(node.children)
|
|
64
|
+
state.closeNode()
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
toMarkdown: {
|
|
68
|
+
match: node => node.type.name === 'list_item',
|
|
69
|
+
runner: (state, node) => {
|
|
70
|
+
if (node.attrs.checked == null) {
|
|
71
|
+
baseSchema.toMarkdown.runner(state, node)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const label = node.attrs.label
|
|
76
|
+
const listType = node.attrs.listType
|
|
77
|
+
const spread = node.attrs.spread === 'true'
|
|
78
|
+
const checked = node.attrs.checked
|
|
79
|
+
|
|
80
|
+
state.openNode('listItem', undefined, { label, listType, spread, checked })
|
|
81
|
+
state.next(node.content)
|
|
82
|
+
state.closeNode()
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})
|
package/src/{table/plugin/auto-insert-zero-space.ts → plugin/auto-insert-zero-space-plugin.ts}
RENAMED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
import { browser } from '@milkdown/prose'
|
|
3
3
|
import type { Node } from '@milkdown/prose/model'
|
|
4
|
+
import { isInTable } from '@milkdown/prose/tables'
|
|
4
5
|
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
6
|
+
import { paragraphSchema } from '@milkdown/preset-commonmark'
|
|
7
|
+
import { $prose } from '@milkdown/utils'
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
// original discussion in https://discuss.prosemirror.net/t/ime-composing-problems-on-td-or-th-element-in-safari-browser/4501
|
|
10
|
+
export const autoInsertZeroSpaceInTablePlugin = $prose(() => {
|
|
11
|
+
const pluginKey = new PluginKey('MILKDOWN_AUTO_INSERT_ZERO_SPACE')
|
|
7
12
|
|
|
8
|
-
const
|
|
9
|
-
return node.type.name === 'paragraph' && node.nodeSize === 2
|
|
10
|
-
}
|
|
13
|
+
const isParagraph = (node: Node) => node.type === paragraphSchema.type()
|
|
11
14
|
|
|
12
|
-
const
|
|
13
|
-
return node.type.name === 'paragraph'
|
|
14
|
-
}
|
|
15
|
+
const isEmptyParagraph = (node: Node) => isParagraph(node) && node.nodeSize === 2
|
|
15
16
|
|
|
16
|
-
const pluginKey = new PluginKey('plugin_autoInsertZeroSpace')
|
|
17
|
-
|
|
18
|
-
export const autoInsertZeroSpace = () => {
|
|
19
17
|
return new Plugin({
|
|
20
18
|
key: pluginKey,
|
|
21
19
|
props: {
|
|
@@ -36,10 +34,10 @@ export const autoInsertZeroSpace = () => {
|
|
|
36
34
|
|
|
37
35
|
if (
|
|
38
36
|
browser.safari
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
&& isInTable(state)
|
|
38
|
+
&& selection.empty
|
|
39
|
+
&& isParagraph($from.parent)
|
|
40
|
+
&& $from.parent.textContent.startsWith('\u2060')
|
|
43
41
|
)
|
|
44
42
|
dispatch(tr.delete($from.start(), $from.start() + 1))
|
|
45
43
|
|
|
@@ -48,4 +46,4 @@ export const autoInsertZeroSpace = () => {
|
|
|
48
46
|
},
|
|
49
47
|
},
|
|
50
48
|
})
|
|
51
|
-
}
|
|
49
|
+
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/footnote/definition.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB,yCAA4C,CAAA;AAE1E,eAAO,MAAM,kBAAkB,mDA0K7B,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/footnote/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/footnote/reference.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,iBAAiB,yCAA4C,CAAA;AAG1E,eAAO,MAAM,iBAAiB,mDAiK5B,CAAA"}
|
package/lib/footnote/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/footnote/utils.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gBAAgB,UAAW,MAAM,WAA4B,CAAA;AAE1E,eAAO,MAAM,gBAAgB,UAAW,MAAM,WAA4B,CAAA"}
|
package/lib/strike-through.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"strike-through.d.ts","sourceRoot":"","sources":["../src/strike-through.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,mBAAmB,4CAAsC,CAAA;AAGtE,eAAO,MAAM,aAAa,mDA8BxB,CAAA"}
|