@milkdown/preset-gfm 7.3.6 → 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/__internal__/index.d.ts.map +1 -1
- package/lib/__internal__/with-meta.d.ts.map +1 -1
- package/lib/composed/commands.d.ts +5 -1
- package/lib/composed/commands.d.ts.map +1 -1
- package/lib/composed/index.d.ts.map +1 -1
- package/lib/composed/inputrules.d.ts.map +1 -1
- package/lib/composed/keymap.d.ts.map +1 -1
- package/lib/composed/plugins.d.ts.map +1 -1
- package/lib/composed/schema.d.ts.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +545 -482
- package/lib/index.es.js.map +1 -1
- package/lib/mark/index.d.ts.map +1 -1
- package/lib/mark/strike-through.d.ts.map +1 -1
- package/lib/node/footnote/definition.d.ts.map +1 -1
- package/lib/node/footnote/index.d.ts.map +1 -1
- package/lib/node/footnote/reference.d.ts.map +1 -1
- package/lib/node/index.d.ts.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/node/task-list-item.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/column-resizing-plugin.d.ts.map +1 -1
- 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/remark-gfm-plugin.d.ts.map +1 -1
- package/lib/plugin/table-editing-plugin.d.ts.map +1 -1
- package/package.json +12 -17
- package/src/__internal__/index.ts +0 -2
- package/src/__internal__/with-meta.ts +0 -1
- package/src/composed/commands.ts +2 -3
- package/src/composed/index.ts +0 -1
- package/src/composed/inputrules.ts +0 -1
- package/src/composed/keymap.ts +0 -1
- package/src/composed/plugins.ts +5 -6
- package/src/composed/schema.ts +11 -2
- package/src/index.ts +1 -3
- package/src/mark/index.ts +0 -1
- package/src/mark/strike-through.ts +0 -1
- package/src/node/footnote/definition.ts +0 -2
- package/src/node/footnote/index.ts +0 -1
- package/src/node/footnote/reference.ts +0 -2
- package/src/node/index.ts +0 -1
- package/src/node/table/command.ts +228 -0
- package/src/node/table/index.ts +3 -451
- package/src/node/table/input.ts +73 -0
- package/src/node/table/schema.ts +216 -0
- package/src/node/table/utils.ts +49 -20
- package/src/node/task-list-item.ts +1 -2
- package/src/plugin/auto-insert-span-plugin.ts +12 -0
- package/src/plugin/column-resizing-plugin.ts +0 -1
- package/src/plugin/index.ts +2 -2
- package/src/plugin/keep-table-align-plugin.ts +60 -0
- package/src/plugin/remark-gfm-plugin.ts +0 -1
- package/src/plugin/table-editing-plugin.ts +1 -2
- 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 -56
|
@@ -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,14 +1,12 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
|
|
3
1
|
import type { ContentNodeWithPos } from '@milkdown/prose'
|
|
4
|
-
import { cloneTr,
|
|
5
|
-
import type { Node } from '@milkdown/prose/model'
|
|
2
|
+
import { cloneTr, findParentNodeClosestToPos } from '@milkdown/prose'
|
|
3
|
+
import type { Node, ResolvedPos } from '@milkdown/prose/model'
|
|
6
4
|
import type { Selection, Transaction } from '@milkdown/prose/state'
|
|
7
5
|
import type { TableRect } from '@milkdown/prose/tables'
|
|
8
6
|
import { CellSelection, TableMap } from '@milkdown/prose/tables'
|
|
9
7
|
|
|
10
8
|
import type { Ctx } from '@milkdown/ctx'
|
|
11
|
-
import { tableCellSchema, tableHeaderSchema, tableRowSchema, tableSchema } from '
|
|
9
|
+
import { tableCellSchema, tableHeaderRowSchema, tableHeaderSchema, tableRowSchema, tableSchema } from './schema'
|
|
12
10
|
|
|
13
11
|
/// @internal
|
|
14
12
|
export interface CellPos {
|
|
@@ -29,19 +27,21 @@ export function createTable(ctx: Ctx, rowsCount = 3, colsCount = 3): Node {
|
|
|
29
27
|
|
|
30
28
|
const rows = Array(rowsCount)
|
|
31
29
|
.fill(0)
|
|
32
|
-
.map((_, i) =>
|
|
30
|
+
.map((_, i) => i === 0
|
|
31
|
+
? tableHeaderRowSchema.type(ctx).create(null, headerCells)
|
|
32
|
+
: tableRowSchema.type(ctx).create(null, cells))
|
|
33
33
|
|
|
34
34
|
return tableSchema.type(ctx).create(null, rows)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/// Find the table node with position information for
|
|
38
|
-
export function findTable(
|
|
39
|
-
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)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/// Get cells in a column of a table.
|
|
43
43
|
export function getCellsInCol(columnIndex: number, selection: Selection): CellPos[] | undefined {
|
|
44
|
-
const table = findTable(selection)
|
|
44
|
+
const table = findTable(selection.$from)
|
|
45
45
|
if (!table)
|
|
46
46
|
return undefined
|
|
47
47
|
const map = TableMap.get(table.node)
|
|
@@ -66,7 +66,7 @@ export function getCellsInCol(columnIndex: number, selection: Selection): CellPo
|
|
|
66
66
|
|
|
67
67
|
/// Get cells in a row of a table.
|
|
68
68
|
export function getCellsInRow(rowIndex: number, selection: Selection): CellPos[] | undefined {
|
|
69
|
-
const table = findTable(selection)
|
|
69
|
+
const table = findTable(selection.$from)
|
|
70
70
|
if (!table)
|
|
71
71
|
return undefined
|
|
72
72
|
const map = TableMap.get(table.node)
|
|
@@ -91,7 +91,7 @@ export function getCellsInRow(rowIndex: number, selection: Selection): CellPos[]
|
|
|
91
91
|
|
|
92
92
|
/// Get all cells in a table.
|
|
93
93
|
export function getAllCellsInTable(selection: Selection) {
|
|
94
|
-
const table = findTable(selection)
|
|
94
|
+
const table = findTable(selection.$from)
|
|
95
95
|
if (!table)
|
|
96
96
|
return
|
|
97
97
|
|
|
@@ -144,8 +144,17 @@ export function addRowWithAlignment(ctx: Ctx, tr: Transaction, { map, tableStart
|
|
|
144
144
|
|
|
145
145
|
/// @internal
|
|
146
146
|
export function selectLine(type: 'row' | 'col') {
|
|
147
|
-
return (index: number) => (tr: Transaction) => {
|
|
148
|
-
|
|
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
|
+
|
|
149
158
|
const isRowSelection = type === 'row'
|
|
150
159
|
if (table) {
|
|
151
160
|
const map = TableMap.get(table.node)
|
|
@@ -157,12 +166,12 @@ export function selectLine(type: 'row' | 'col') {
|
|
|
157
166
|
isRowSelection ? map.width - 1 : index,
|
|
158
167
|
table.node,
|
|
159
168
|
)
|
|
160
|
-
const $lastCell = tr.doc.resolve(table.
|
|
169
|
+
const $lastCell = tr.doc.resolve(table.from + lastCell)
|
|
161
170
|
|
|
162
171
|
const createCellSelection = isRowSelection ? CellSelection.rowSelection : CellSelection.colSelection
|
|
163
172
|
|
|
164
173
|
const firstCell = map.positionAt(isRowSelection ? index : 0, isRowSelection ? 0 : index, table.node)
|
|
165
|
-
const $firstCell = tr.doc.resolve(table.
|
|
174
|
+
const $firstCell = tr.doc.resolve(table.from + firstCell)
|
|
166
175
|
return cloneTr(tr.setSelection(createCellSelection($lastCell, $firstCell) as unknown as Selection))
|
|
167
176
|
}
|
|
168
177
|
}
|
|
@@ -409,11 +418,21 @@ function getSelectionRangeInRow(rowIndex: number, tr: Transaction) {
|
|
|
409
418
|
return { $anchor, $head, indexes }
|
|
410
419
|
}
|
|
411
420
|
|
|
421
|
+
export interface MoveColParams {
|
|
422
|
+
tr: Transaction
|
|
423
|
+
origin: number
|
|
424
|
+
target: number
|
|
425
|
+
select?: boolean
|
|
426
|
+
pos?: number
|
|
427
|
+
}
|
|
428
|
+
|
|
412
429
|
/// If the selection is in a table,
|
|
413
430
|
/// Move the columns at `origin` to `target` in current table.
|
|
414
431
|
/// The `select` is true by default, which means the selection will be set to the moved column.
|
|
415
|
-
export function moveCol(
|
|
416
|
-
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)
|
|
417
436
|
if (!table)
|
|
418
437
|
return tr
|
|
419
438
|
|
|
@@ -453,11 +472,21 @@ export function moveCol(tr: Transaction, origin: number, target: number, select
|
|
|
453
472
|
return _tr.setSelection(createCellSelection($lastCell, $firstCell))
|
|
454
473
|
}
|
|
455
474
|
|
|
475
|
+
export interface MoveRowParams {
|
|
476
|
+
tr: Transaction
|
|
477
|
+
origin: number
|
|
478
|
+
target: number
|
|
479
|
+
select?: boolean
|
|
480
|
+
pos?: number
|
|
481
|
+
}
|
|
482
|
+
|
|
456
483
|
/// If the selection is in a table,
|
|
457
484
|
/// Move the rows at `origin` and `target` in current table.
|
|
458
485
|
/// The `select` is true by default, which means the selection will be set to the moved row.
|
|
459
|
-
export function moveRow(
|
|
460
|
-
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)
|
|
461
490
|
if (!table)
|
|
462
491
|
return tr
|
|
463
492
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
1
|
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
2
|
import { listItemSchema } from '@milkdown/preset-commonmark'
|
|
4
3
|
import { InputRule } from '@milkdown/prose/inputrules'
|
|
@@ -26,7 +25,7 @@ export const extendListItemSchemaForTask = listItemSchema.extendSchema((prev) =>
|
|
|
26
25
|
|
|
27
26
|
return {
|
|
28
27
|
label: dom.dataset.label,
|
|
29
|
-
listType: dom.dataset
|
|
28
|
+
listType: dom.dataset.listType,
|
|
30
29
|
spread: dom.dataset.spread,
|
|
31
30
|
checked: dom.dataset.checked ? dom.dataset.checked === 'true' : null,
|
|
32
31
|
}
|
|
@@ -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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export * from './auto-insert-zero-space-plugin'
|
|
1
|
+
export * from './auto-insert-span-plugin'
|
|
3
2
|
export * from './column-resizing-plugin'
|
|
4
3
|
export * from './table-editing-plugin'
|
|
5
4
|
export * from './remark-gfm-plugin'
|
|
5
|
+
export * from './keep-table-align-plugin'
|
|
@@ -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
|
+
})
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
1
|
import { tableEditing } from '@milkdown/prose/tables'
|
|
3
2
|
import { $prose } from '@milkdown/utils'
|
|
4
3
|
import { withMeta } from '../__internal__'
|
|
5
4
|
|
|
6
5
|
/// This plugin is wrapping the `tableEditing` plugin from [prosemirror-tables](https://github.com/ProseMirror/prosemirror-tables).
|
|
7
|
-
export const tableEditingPlugin = $prose(() => tableEditing())
|
|
6
|
+
export const tableEditingPlugin = $prose(() => tableEditing({ allowTableNodeSelection: true }))
|
|
8
7
|
|
|
9
8
|
withMeta(tableEditingPlugin, {
|
|
10
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":"AAWA,eAAO,MAAM,gCAAgC,kCAuC3C,CAAA"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { browser } from '@milkdown/prose'
|
|
3
|
-
import type { Node } from '@milkdown/prose/model'
|
|
4
|
-
import { isInTable } from '@milkdown/prose/tables'
|
|
5
|
-
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
6
|
-
import { paragraphSchema } from '@milkdown/preset-commonmark'
|
|
7
|
-
import { $prose } from '@milkdown/utils'
|
|
8
|
-
import { withMeta } from '../__internal__'
|
|
9
|
-
|
|
10
|
-
/// This plugin is used to fix the bug of IME composing in table in Safari browser.
|
|
11
|
-
/// original discussion in https://discuss.prosemirror.net/t/ime-composing-problems-on-td-or-th-element-in-safari-browser/4501
|
|
12
|
-
export const autoInsertZeroSpaceInTablePlugin = $prose((ctx) => {
|
|
13
|
-
const pluginKey = new PluginKey('MILKDOWN_AUTO_INSERT_ZERO_SPACE')
|
|
14
|
-
|
|
15
|
-
const isParagraph = (node: Node) => node.type === paragraphSchema.type(ctx)
|
|
16
|
-
|
|
17
|
-
const isEmptyParagraph = (node: Node) => isParagraph(node) && node.nodeSize === 2
|
|
18
|
-
|
|
19
|
-
return new Plugin({
|
|
20
|
-
key: pluginKey,
|
|
21
|
-
props: {
|
|
22
|
-
handleDOMEvents: {
|
|
23
|
-
compositionstart(view) {
|
|
24
|
-
const { state, dispatch } = view
|
|
25
|
-
const { tr, selection } = state
|
|
26
|
-
const { $from } = selection
|
|
27
|
-
if (browser.safari && isInTable(state) && selection.empty && isEmptyParagraph($from.parent))
|
|
28
|
-
dispatch(tr.insertText('\u2060', $from.start()))
|
|
29
|
-
|
|
30
|
-
return false
|
|
31
|
-
},
|
|
32
|
-
compositionend(view) {
|
|
33
|
-
const { state, dispatch } = view
|
|
34
|
-
const { tr, selection } = state
|
|
35
|
-
const { $from } = selection
|
|
36
|
-
|
|
37
|
-
if (
|
|
38
|
-
browser.safari
|
|
39
|
-
&& isInTable(state)
|
|
40
|
-
&& selection.empty
|
|
41
|
-
&& isParagraph($from.parent)
|
|
42
|
-
&& $from.parent.textContent.startsWith('\u2060')
|
|
43
|
-
)
|
|
44
|
-
dispatch(tr.delete($from.start(), $from.start() + 1))
|
|
45
|
-
|
|
46
|
-
return false
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
withMeta(autoInsertZeroSpaceInTablePlugin, {
|
|
54
|
-
displayName: 'Prose<autoInsertZeroSpaceInTablePlugin>',
|
|
55
|
-
group: 'Prose',
|
|
56
|
-
})
|