@milkdown/preset-gfm 7.4.0 → 7.5.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 +5 -1
- package/lib/composed/commands.d.ts.map +1 -1
- package/lib/composed/schema.d.ts.map +1 -1
- package/lib/index.es.js +544 -481
- package/lib/index.es.js.map +1 -1
- package/lib/node/table/command.d.ts +33 -0
- package/lib/node/table/command.d.ts.map +1 -0
- package/lib/node/table/index.d.ts +3 -30
- package/lib/node/table/index.d.ts.map +1 -1
- package/lib/node/table/input.d.ts +3 -0
- package/lib/node/table/input.d.ts.map +1 -0
- package/lib/node/table/schema.d.ts +6 -0
- package/lib/node/table/schema.d.ts.map +1 -0
- package/lib/node/table/utils.d.ts +21 -7
- package/lib/node/table/utils.d.ts.map +1 -1
- package/lib/plugin/auto-insert-span-plugin.d.ts +2 -0
- package/lib/plugin/auto-insert-span-plugin.d.ts.map +1 -0
- package/lib/plugin/index.d.ts +2 -1
- package/lib/plugin/index.d.ts.map +1 -1
- package/lib/plugin/keep-table-align-plugin.d.ts +2 -0
- package/lib/plugin/keep-table-align-plugin.d.ts.map +1 -0
- package/lib/plugin/table-editing-plugin.d.ts.map +1 -1
- package/package.json +12 -17
- package/src/composed/commands.ts +2 -2
- package/src/composed/plugins.ts +4 -4
- package/src/composed/schema.ts +11 -1
- package/src/index.ts +1 -1
- package/src/node/table/command.ts +228 -0
- package/src/node/table/index.ts +3 -450
- package/src/node/table/input.ts +73 -0
- package/src/node/table/schema.ts +216 -0
- package/src/node/table/utils.ts +49 -18
- package/src/plugin/auto-insert-span-plugin.ts +12 -0
- package/src/plugin/index.ts +2 -1
- package/src/plugin/keep-table-align-plugin.ts +60 -0
- package/src/plugin/table-editing-plugin.ts +1 -1
- package/lib/plugin/auto-insert-zero-space-plugin.d.ts +0 -2
- package/lib/plugin/auto-insert-zero-space-plugin.d.ts.map +0 -1
- package/src/plugin/auto-insert-zero-space-plugin.ts +0 -55
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { tableNodes } from '@milkdown/prose/tables'
|
|
2
|
+
import { $nodeSchema } from '@milkdown/utils'
|
|
3
|
+
import type { MarkdownNode } from '@milkdown/transformer'
|
|
4
|
+
import type { NodeType } from '@milkdown/prose/model'
|
|
5
|
+
import { withMeta } from '../../__internal__'
|
|
6
|
+
|
|
7
|
+
const originalSchema = tableNodes({
|
|
8
|
+
tableGroup: 'block',
|
|
9
|
+
cellContent: 'paragraph',
|
|
10
|
+
cellAttributes: {
|
|
11
|
+
alignment: {
|
|
12
|
+
default: 'left',
|
|
13
|
+
getFromDOM: dom => (dom).style.textAlign || 'left',
|
|
14
|
+
setDOMAttr: (value, attrs) => {
|
|
15
|
+
attrs.style = `text-align: ${value || 'left'}`
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
/// Schema for table node.
|
|
22
|
+
export const tableSchema = $nodeSchema('table', () => ({
|
|
23
|
+
...originalSchema.table,
|
|
24
|
+
content: 'table_header_row table_row+',
|
|
25
|
+
disableDropCursor: true,
|
|
26
|
+
parseMarkdown: {
|
|
27
|
+
match: node => node.type === 'table',
|
|
28
|
+
runner: (state, node, type) => {
|
|
29
|
+
const align = node.align as (string | null)[]
|
|
30
|
+
const children = (node.children as MarkdownNode[]).map((x, i) => ({
|
|
31
|
+
...x,
|
|
32
|
+
align,
|
|
33
|
+
isHeader: i === 0,
|
|
34
|
+
}))
|
|
35
|
+
state.openNode(type)
|
|
36
|
+
state.next(children)
|
|
37
|
+
state.closeNode()
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
toMarkdown: {
|
|
41
|
+
match: node => node.type.name === 'table',
|
|
42
|
+
runner: (state, node) => {
|
|
43
|
+
const firstLine = node.content.firstChild?.content
|
|
44
|
+
if (!firstLine)
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
const align: (string | null)[] = []
|
|
48
|
+
firstLine.forEach((cell) => {
|
|
49
|
+
align.push(cell.attrs.alignment)
|
|
50
|
+
})
|
|
51
|
+
state.openNode('table', undefined, { align })
|
|
52
|
+
state.next(node.content)
|
|
53
|
+
state.closeNode()
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
}))
|
|
57
|
+
|
|
58
|
+
withMeta(tableSchema.node, {
|
|
59
|
+
displayName: 'NodeSchema<table>',
|
|
60
|
+
group: 'Table',
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
withMeta(tableSchema.ctx, {
|
|
64
|
+
displayName: 'NodeSchemaCtx<table>',
|
|
65
|
+
group: 'Table',
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
/// Schema for table header row node.
|
|
69
|
+
export const tableHeaderRowSchema = $nodeSchema('table_header_row', () => ({
|
|
70
|
+
...originalSchema.table_row,
|
|
71
|
+
disableDropCursor: true,
|
|
72
|
+
content: '(table_header)*',
|
|
73
|
+
parseDOM: [{ tag: 'tr[data-is-header]' }],
|
|
74
|
+
toDOM() {
|
|
75
|
+
return ['tr', { 'data-is-header': true }, 0]
|
|
76
|
+
},
|
|
77
|
+
parseMarkdown: {
|
|
78
|
+
match: node => Boolean(node.type === 'tableRow' && node.isHeader),
|
|
79
|
+
runner: (state, node, type) => {
|
|
80
|
+
const align = node.align as (string | null)[]
|
|
81
|
+
const children = (node.children as MarkdownNode[]).map((x, i) => ({
|
|
82
|
+
...x,
|
|
83
|
+
align: align[i],
|
|
84
|
+
isHeader: node.isHeader,
|
|
85
|
+
}))
|
|
86
|
+
state.openNode(type)
|
|
87
|
+
state.next(children)
|
|
88
|
+
state.closeNode()
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
toMarkdown: {
|
|
92
|
+
match: node => node.type.name === 'table_header_row',
|
|
93
|
+
runner: (state, node) => {
|
|
94
|
+
state.openNode('tableRow', undefined, { isHeader: true })
|
|
95
|
+
state.next(node.content)
|
|
96
|
+
state.closeNode()
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
}))
|
|
100
|
+
|
|
101
|
+
withMeta(tableHeaderRowSchema.node, {
|
|
102
|
+
displayName: 'NodeSchema<tableHeaderRow>',
|
|
103
|
+
group: 'Table',
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
withMeta(tableHeaderRowSchema.ctx, {
|
|
107
|
+
displayName: 'NodeSchemaCtx<tableHeaderRow>',
|
|
108
|
+
group: 'Table',
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
/// Schema for table row node.
|
|
112
|
+
export const tableRowSchema = $nodeSchema('table_row', () => ({
|
|
113
|
+
...originalSchema.table_row,
|
|
114
|
+
disableDropCursor: true,
|
|
115
|
+
content: '(table_cell)*',
|
|
116
|
+
parseMarkdown: {
|
|
117
|
+
match: node => node.type === 'tableRow',
|
|
118
|
+
runner: (state, node, type) => {
|
|
119
|
+
const align = node.align as (string | null)[]
|
|
120
|
+
const children = (node.children as MarkdownNode[]).map((x, i) => ({
|
|
121
|
+
...x,
|
|
122
|
+
align: align[i],
|
|
123
|
+
}))
|
|
124
|
+
state.openNode(type)
|
|
125
|
+
state.next(children)
|
|
126
|
+
state.closeNode()
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
toMarkdown: {
|
|
130
|
+
match: node => node.type.name === 'table_row',
|
|
131
|
+
runner: (state, node) => {
|
|
132
|
+
state.openNode('tableRow')
|
|
133
|
+
state.next(node.content)
|
|
134
|
+
state.closeNode()
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
}))
|
|
138
|
+
|
|
139
|
+
withMeta(tableRowSchema.node, {
|
|
140
|
+
displayName: 'NodeSchema<tableRow>',
|
|
141
|
+
group: 'Table',
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
withMeta(tableRowSchema.ctx, {
|
|
145
|
+
displayName: 'NodeSchemaCtx<tableRow>',
|
|
146
|
+
group: 'Table',
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
/// Schema for table cell node.
|
|
150
|
+
export const tableCellSchema = $nodeSchema('table_cell', () => ({
|
|
151
|
+
...originalSchema.table_cell,
|
|
152
|
+
disableDropCursor: true,
|
|
153
|
+
parseMarkdown: {
|
|
154
|
+
match: node => node.type === 'tableCell' && !node.isHeader,
|
|
155
|
+
runner: (state, node, type) => {
|
|
156
|
+
const align = node.align as string
|
|
157
|
+
state
|
|
158
|
+
.openNode(type, { alignment: align })
|
|
159
|
+
.openNode(state.schema.nodes.paragraph as NodeType)
|
|
160
|
+
.next(node.children)
|
|
161
|
+
.closeNode()
|
|
162
|
+
.closeNode()
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
toMarkdown: {
|
|
166
|
+
match: node => node.type.name === 'table_cell',
|
|
167
|
+
runner: (state, node) => {
|
|
168
|
+
state.openNode('tableCell').next(node.content).closeNode()
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
}))
|
|
172
|
+
|
|
173
|
+
withMeta(tableCellSchema.node, {
|
|
174
|
+
displayName: 'NodeSchema<tableCell>',
|
|
175
|
+
group: 'Table',
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
withMeta(tableCellSchema.ctx, {
|
|
179
|
+
displayName: 'NodeSchemaCtx<tableCell>',
|
|
180
|
+
group: 'Table',
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
/// Schema for table header node.
|
|
184
|
+
export const tableHeaderSchema = $nodeSchema('table_header', () => ({
|
|
185
|
+
...originalSchema.table_header,
|
|
186
|
+
disableDropCursor: true,
|
|
187
|
+
parseMarkdown: {
|
|
188
|
+
match: node => node.type === 'tableCell' && !!node.isHeader,
|
|
189
|
+
runner: (state, node, type) => {
|
|
190
|
+
const align = node.align as string
|
|
191
|
+
state.openNode(type, { alignment: align })
|
|
192
|
+
state.openNode(state.schema.nodes.paragraph as NodeType)
|
|
193
|
+
state.next(node.children)
|
|
194
|
+
state.closeNode()
|
|
195
|
+
state.closeNode()
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
toMarkdown: {
|
|
199
|
+
match: node => node.type.name === 'table_header',
|
|
200
|
+
runner: (state, node) => {
|
|
201
|
+
state.openNode('tableCell')
|
|
202
|
+
state.next(node.content)
|
|
203
|
+
state.closeNode()
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
}))
|
|
207
|
+
|
|
208
|
+
withMeta(tableHeaderSchema.node, {
|
|
209
|
+
displayName: 'NodeSchema<tableHeader>',
|
|
210
|
+
group: 'Table',
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
withMeta(tableHeaderSchema.ctx, {
|
|
214
|
+
displayName: 'NodeSchemaCtx<tableHeader>',
|
|
215
|
+
group: 'Table',
|
|
216
|
+
})
|
package/src/node/table/utils.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { ContentNodeWithPos } from '@milkdown/prose'
|
|
2
|
-
import { cloneTr,
|
|
3
|
-
import type { Node } from '@milkdown/prose/model'
|
|
2
|
+
import { cloneTr, findParentNodeClosestToPos } from '@milkdown/prose'
|
|
3
|
+
import type { Node, ResolvedPos } from '@milkdown/prose/model'
|
|
4
4
|
import type { Selection, Transaction } from '@milkdown/prose/state'
|
|
5
5
|
import type { TableRect } from '@milkdown/prose/tables'
|
|
6
6
|
import { CellSelection, TableMap } from '@milkdown/prose/tables'
|
|
7
7
|
|
|
8
8
|
import type { Ctx } from '@milkdown/ctx'
|
|
9
|
-
import { tableCellSchema, tableHeaderSchema, tableRowSchema, tableSchema } from '
|
|
9
|
+
import { tableCellSchema, tableHeaderRowSchema, tableHeaderSchema, tableRowSchema, tableSchema } from './schema'
|
|
10
10
|
|
|
11
11
|
/// @internal
|
|
12
12
|
export interface CellPos {
|
|
@@ -27,19 +27,21 @@ export function createTable(ctx: Ctx, rowsCount = 3, colsCount = 3): Node {
|
|
|
27
27
|
|
|
28
28
|
const rows = Array(rowsCount)
|
|
29
29
|
.fill(0)
|
|
30
|
-
.map((_, i) =>
|
|
30
|
+
.map((_, i) => i === 0
|
|
31
|
+
? tableHeaderRowSchema.type(ctx).create(null, headerCells)
|
|
32
|
+
: tableRowSchema.type(ctx).create(null, cells))
|
|
31
33
|
|
|
32
34
|
return tableSchema.type(ctx).create(null, rows)
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
/// Find the table node with position information for
|
|
36
|
-
export function findTable(
|
|
37
|
-
return
|
|
37
|
+
/// Find the table node with position information for target pos.
|
|
38
|
+
export function findTable($pos: ResolvedPos) {
|
|
39
|
+
return findParentNodeClosestToPos(node => node.type.spec.tableRole === 'table')($pos)
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
/// Get cells in a column of a table.
|
|
41
43
|
export function getCellsInCol(columnIndex: number, selection: Selection): CellPos[] | undefined {
|
|
42
|
-
const table = findTable(selection)
|
|
44
|
+
const table = findTable(selection.$from)
|
|
43
45
|
if (!table)
|
|
44
46
|
return undefined
|
|
45
47
|
const map = TableMap.get(table.node)
|
|
@@ -64,7 +66,7 @@ export function getCellsInCol(columnIndex: number, selection: Selection): CellPo
|
|
|
64
66
|
|
|
65
67
|
/// Get cells in a row of a table.
|
|
66
68
|
export function getCellsInRow(rowIndex: number, selection: Selection): CellPos[] | undefined {
|
|
67
|
-
const table = findTable(selection)
|
|
69
|
+
const table = findTable(selection.$from)
|
|
68
70
|
if (!table)
|
|
69
71
|
return undefined
|
|
70
72
|
const map = TableMap.get(table.node)
|
|
@@ -89,7 +91,7 @@ export function getCellsInRow(rowIndex: number, selection: Selection): CellPos[]
|
|
|
89
91
|
|
|
90
92
|
/// Get all cells in a table.
|
|
91
93
|
export function getAllCellsInTable(selection: Selection) {
|
|
92
|
-
const table = findTable(selection)
|
|
94
|
+
const table = findTable(selection.$from)
|
|
93
95
|
if (!table)
|
|
94
96
|
return
|
|
95
97
|
|
|
@@ -142,8 +144,17 @@ export function addRowWithAlignment(ctx: Ctx, tr: Transaction, { map, tableStart
|
|
|
142
144
|
|
|
143
145
|
/// @internal
|
|
144
146
|
export function selectLine(type: 'row' | 'col') {
|
|
145
|
-
return (index: number) => (tr: Transaction) => {
|
|
146
|
-
|
|
147
|
+
return (index: number, pos?: number) => (tr: Transaction) => {
|
|
148
|
+
pos = pos ?? tr.selection.from
|
|
149
|
+
const $pos = tr.doc.resolve(pos)
|
|
150
|
+
const $node = findParentNodeClosestToPos(node => node.type.name === 'table')($pos)
|
|
151
|
+
const table = $node
|
|
152
|
+
? {
|
|
153
|
+
node: $node.node,
|
|
154
|
+
from: $node.start,
|
|
155
|
+
}
|
|
156
|
+
: undefined
|
|
157
|
+
|
|
147
158
|
const isRowSelection = type === 'row'
|
|
148
159
|
if (table) {
|
|
149
160
|
const map = TableMap.get(table.node)
|
|
@@ -155,12 +166,12 @@ export function selectLine(type: 'row' | 'col') {
|
|
|
155
166
|
isRowSelection ? map.width - 1 : index,
|
|
156
167
|
table.node,
|
|
157
168
|
)
|
|
158
|
-
const $lastCell = tr.doc.resolve(table.
|
|
169
|
+
const $lastCell = tr.doc.resolve(table.from + lastCell)
|
|
159
170
|
|
|
160
171
|
const createCellSelection = isRowSelection ? CellSelection.rowSelection : CellSelection.colSelection
|
|
161
172
|
|
|
162
173
|
const firstCell = map.positionAt(isRowSelection ? index : 0, isRowSelection ? 0 : index, table.node)
|
|
163
|
-
const $firstCell = tr.doc.resolve(table.
|
|
174
|
+
const $firstCell = tr.doc.resolve(table.from + firstCell)
|
|
164
175
|
return cloneTr(tr.setSelection(createCellSelection($lastCell, $firstCell) as unknown as Selection))
|
|
165
176
|
}
|
|
166
177
|
}
|
|
@@ -407,11 +418,21 @@ function getSelectionRangeInRow(rowIndex: number, tr: Transaction) {
|
|
|
407
418
|
return { $anchor, $head, indexes }
|
|
408
419
|
}
|
|
409
420
|
|
|
421
|
+
export interface MoveColParams {
|
|
422
|
+
tr: Transaction
|
|
423
|
+
origin: number
|
|
424
|
+
target: number
|
|
425
|
+
select?: boolean
|
|
426
|
+
pos?: number
|
|
427
|
+
}
|
|
428
|
+
|
|
410
429
|
/// If the selection is in a table,
|
|
411
430
|
/// Move the columns at `origin` to `target` in current table.
|
|
412
431
|
/// The `select` is true by default, which means the selection will be set to the moved column.
|
|
413
|
-
export function moveCol(
|
|
414
|
-
const
|
|
432
|
+
export function moveCol(moveColParams: MoveColParams) {
|
|
433
|
+
const { tr, origin, target, select = true, pos } = moveColParams
|
|
434
|
+
const $pos = pos != null ? tr.doc.resolve(pos) : tr.selection.$from
|
|
435
|
+
const table = findTable($pos)
|
|
415
436
|
if (!table)
|
|
416
437
|
return tr
|
|
417
438
|
|
|
@@ -451,11 +472,21 @@ export function moveCol(tr: Transaction, origin: number, target: number, select
|
|
|
451
472
|
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
452
473
|
}
|
|
453
474
|
|
|
475
|
+
export interface MoveRowParams {
|
|
476
|
+
tr: Transaction
|
|
477
|
+
origin: number
|
|
478
|
+
target: number
|
|
479
|
+
select?: boolean
|
|
480
|
+
pos?: number
|
|
481
|
+
}
|
|
482
|
+
|
|
454
483
|
/// If the selection is in a table,
|
|
455
484
|
/// Move the rows at `origin` and `target` in current table.
|
|
456
485
|
/// The `select` is true by default, which means the selection will be set to the moved row.
|
|
457
|
-
export function moveRow(
|
|
458
|
-
const
|
|
486
|
+
export function moveRow(moveRowParams: MoveRowParams) {
|
|
487
|
+
const { tr, origin, target, select = true, pos } = moveRowParams
|
|
488
|
+
const $pos = pos != null ? tr.doc.resolve(pos) : tr.selection.$from
|
|
489
|
+
const table = findTable($pos)
|
|
459
490
|
if (!table)
|
|
460
491
|
return tr
|
|
461
492
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { $prose } from '@milkdown/utils'
|
|
2
|
+
import { imeSpan } from 'prosemirror-safari-ime-span'
|
|
3
|
+
import { withMeta } from '../__internal__'
|
|
4
|
+
|
|
5
|
+
/// This plugin is used to fix the bug of IME composing in table in Safari browser.
|
|
6
|
+
/// original discussion in https://discuss.prosemirror.net/t/ime-composing-problems-on-td-or-th-element-in-safari-browser/4501
|
|
7
|
+
export const autoInsertSpanPlugin = $prose(() => imeSpan)
|
|
8
|
+
|
|
9
|
+
withMeta(autoInsertSpanPlugin, {
|
|
10
|
+
displayName: 'Prose<autoInsertSpanPlugin>',
|
|
11
|
+
group: 'Prose',
|
|
12
|
+
})
|
package/src/plugin/index.ts
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Transaction } from '@milkdown/prose/state'
|
|
2
|
+
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
3
|
+
import type { Node } from '@milkdown/prose/model'
|
|
4
|
+
import { $prose } from '@milkdown/utils'
|
|
5
|
+
import { withMeta } from '../__internal__'
|
|
6
|
+
|
|
7
|
+
const pluginKey = new PluginKey('MILKDOWN_KEEP_TABLE_ALIGN_PLUGIN')
|
|
8
|
+
|
|
9
|
+
function getChildIndex(node: Node, parent: Node) {
|
|
10
|
+
let index = 0
|
|
11
|
+
parent.forEach((child, _offset, i) => {
|
|
12
|
+
if (child === node)
|
|
13
|
+
index = i
|
|
14
|
+
})
|
|
15
|
+
return index
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const keepTableAlignPlugin = $prose(() => {
|
|
19
|
+
return new Plugin({
|
|
20
|
+
key: pluginKey,
|
|
21
|
+
appendTransaction: (_tr, oldState, state) => {
|
|
22
|
+
let tr: Transaction | undefined
|
|
23
|
+
const check = (node: Node, pos: number) => {
|
|
24
|
+
if (!tr)
|
|
25
|
+
tr = state.tr
|
|
26
|
+
|
|
27
|
+
if (node.type.name !== 'table_cell')
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
const $pos = state.doc.resolve(pos)
|
|
31
|
+
const tableRow = $pos.node($pos.depth)
|
|
32
|
+
const table = $pos.node($pos.depth - 1)
|
|
33
|
+
const tableHeaderRow = table.firstChild
|
|
34
|
+
// TODO: maybe consider add a header row
|
|
35
|
+
if (!tableHeaderRow)
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
const index = getChildIndex(node, tableRow)
|
|
39
|
+
const headerCell = tableHeaderRow.maybeChild(index)
|
|
40
|
+
if (!headerCell)
|
|
41
|
+
return
|
|
42
|
+
const align = headerCell.attrs.alignment
|
|
43
|
+
const currentAlign = node.attrs.alignment
|
|
44
|
+
if (align === currentAlign)
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
tr.setNodeMarkup(pos, undefined, { ...node.attrs, alignment: align })
|
|
48
|
+
}
|
|
49
|
+
if (oldState.doc !== state.doc)
|
|
50
|
+
state.doc.descendants(check)
|
|
51
|
+
|
|
52
|
+
return tr
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
withMeta(keepTableAlignPlugin, {
|
|
58
|
+
displayName: 'Prose<keepTableAlignPlugin>',
|
|
59
|
+
group: 'Prose',
|
|
60
|
+
})
|
|
@@ -3,7 +3,7 @@ import { $prose } from '@milkdown/utils'
|
|
|
3
3
|
import { withMeta } from '../__internal__'
|
|
4
4
|
|
|
5
5
|
/// This plugin is wrapping the `tableEditing` plugin from [prosemirror-tables](https://github.com/ProseMirror/prosemirror-tables).
|
|
6
|
-
export const tableEditingPlugin = $prose(() => tableEditing())
|
|
6
|
+
export const tableEditingPlugin = $prose(() => tableEditing({ allowTableNodeSelection: true }))
|
|
7
7
|
|
|
8
8
|
withMeta(tableEditingPlugin, {
|
|
9
9
|
displayName: 'Prose<tableEditingPlugin>',
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auto-insert-zero-space-plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/auto-insert-zero-space-plugin.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,gCAAgC,kCAuC3C,CAAA"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { browser } from '@milkdown/prose'
|
|
2
|
-
import type { Node } from '@milkdown/prose/model'
|
|
3
|
-
import { isInTable } from '@milkdown/prose/tables'
|
|
4
|
-
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
5
|
-
import { paragraphSchema } from '@milkdown/preset-commonmark'
|
|
6
|
-
import { $prose } from '@milkdown/utils'
|
|
7
|
-
import { withMeta } from '../__internal__'
|
|
8
|
-
|
|
9
|
-
/// This plugin is used to fix the bug of IME composing in table in Safari browser.
|
|
10
|
-
/// original discussion in https://discuss.prosemirror.net/t/ime-composing-problems-on-td-or-th-element-in-safari-browser/4501
|
|
11
|
-
export const autoInsertZeroSpaceInTablePlugin = $prose((ctx) => {
|
|
12
|
-
const pluginKey = new PluginKey('MILKDOWN_AUTO_INSERT_ZERO_SPACE')
|
|
13
|
-
|
|
14
|
-
const isParagraph = (node: Node) => node.type === paragraphSchema.type(ctx)
|
|
15
|
-
|
|
16
|
-
const isEmptyParagraph = (node: Node) => isParagraph(node) && node.nodeSize === 2
|
|
17
|
-
|
|
18
|
-
return new Plugin({
|
|
19
|
-
key: pluginKey,
|
|
20
|
-
props: {
|
|
21
|
-
handleDOMEvents: {
|
|
22
|
-
compositionstart(view) {
|
|
23
|
-
const { state, dispatch } = view
|
|
24
|
-
const { tr, selection } = state
|
|
25
|
-
const { $from } = selection
|
|
26
|
-
if (browser.safari && isInTable(state) && selection.empty && isEmptyParagraph($from.parent))
|
|
27
|
-
dispatch(tr.insertText('\u2060', $from.start()))
|
|
28
|
-
|
|
29
|
-
return false
|
|
30
|
-
},
|
|
31
|
-
compositionend(view) {
|
|
32
|
-
const { state, dispatch } = view
|
|
33
|
-
const { tr, selection } = state
|
|
34
|
-
const { $from } = selection
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
browser.safari
|
|
38
|
-
&& isInTable(state)
|
|
39
|
-
&& selection.empty
|
|
40
|
-
&& isParagraph($from.parent)
|
|
41
|
-
&& $from.parent.textContent.startsWith('\u2060')
|
|
42
|
-
)
|
|
43
|
-
dispatch(tr.delete($from.start(), $from.start() + 1))
|
|
44
|
-
|
|
45
|
-
return false
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
withMeta(autoInsertZeroSpaceInTablePlugin, {
|
|
53
|
-
displayName: 'Prose<autoInsertZeroSpaceInTablePlugin>',
|
|
54
|
-
group: 'Prose',
|
|
55
|
-
})
|