@milkdown/preset-gfm 7.4.0 → 7.5.8
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__/with-meta.d.ts.map +1 -1
- package/lib/composed/commands.d.ts +9 -5
- package/lib/composed/commands.d.ts.map +1 -1
- package/lib/composed/inputrules.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 +816 -669
- package/lib/index.es.js.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/reference.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/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__/with-meta.ts +4 -1
- package/src/composed/commands.ts +18 -2
- package/src/composed/inputrules.ts +1 -3
- package/src/composed/plugins.ts +4 -4
- package/src/composed/schema.ts +11 -1
- package/src/index.ts +16 -2
- package/src/mark/strike-through.ts +21 -9
- package/src/node/footnote/definition.ts +56 -54
- package/src/node/footnote/reference.ts +47 -45
- package/src/node/table/command.ts +304 -0
- package/src/node/table/index.ts +3 -450
- package/src/node/table/input.ts +90 -0
- package/src/node/table/schema.ts +215 -0
- package/src/node/table/utils.ts +163 -96
- package/src/node/task-list-item.ts +100 -88
- 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 +53 -0
- package/src/plugin/remark-gfm-plugin.ts +2 -1
- package/src/plugin/table-editing-plugin.ts +3 -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
|
@@ -5,89 +5,97 @@ import { $inputRule } from '@milkdown/utils'
|
|
|
5
5
|
import { withMeta } from '../__internal__'
|
|
6
6
|
|
|
7
7
|
/// This schema extends the [list item](/preset-commonmark#list-item) schema and add task list support for it.
|
|
8
|
-
export const extendListItemSchemaForTask = listItemSchema.extendSchema(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
parseDOM: [
|
|
20
|
-
{
|
|
21
|
-
tag: 'li[data-item-type="task"]',
|
|
22
|
-
getAttrs: (dom) => {
|
|
23
|
-
if (!(dom instanceof HTMLElement))
|
|
24
|
-
throw expectDomTypeError(dom)
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
label: dom.dataset.label,
|
|
28
|
-
listType: dom.dataset.listType,
|
|
29
|
-
spread: dom.dataset.spread,
|
|
30
|
-
checked: dom.dataset.checked ? dom.dataset.checked === 'true' : null,
|
|
31
|
-
}
|
|
8
|
+
export const extendListItemSchemaForTask = listItemSchema.extendSchema(
|
|
9
|
+
(prev) => {
|
|
10
|
+
return (ctx) => {
|
|
11
|
+
const baseSchema = prev(ctx)
|
|
12
|
+
return {
|
|
13
|
+
...baseSchema,
|
|
14
|
+
attrs: {
|
|
15
|
+
...baseSchema.attrs,
|
|
16
|
+
checked: {
|
|
17
|
+
default: null,
|
|
32
18
|
},
|
|
33
19
|
},
|
|
34
|
-
|
|
35
|
-
],
|
|
36
|
-
toDOM: (node) => {
|
|
37
|
-
if (baseSchema.toDOM && node.attrs.checked == null)
|
|
38
|
-
return baseSchema.toDOM(node)
|
|
39
|
-
|
|
40
|
-
return [
|
|
41
|
-
'li',
|
|
20
|
+
parseDOM: [
|
|
42
21
|
{
|
|
43
|
-
'data-item-type
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
22
|
+
tag: 'li[data-item-type="task"]',
|
|
23
|
+
getAttrs: (dom) => {
|
|
24
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
label: dom.dataset.label,
|
|
28
|
+
listType: dom.dataset.listType,
|
|
29
|
+
spread: dom.dataset.spread,
|
|
30
|
+
checked: dom.dataset.checked
|
|
31
|
+
? dom.dataset.checked === 'true'
|
|
32
|
+
: null,
|
|
33
|
+
}
|
|
34
|
+
},
|
|
48
35
|
},
|
|
49
|
-
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
...(baseSchema?.parseDOM || []),
|
|
37
|
+
],
|
|
38
|
+
toDOM: (node) => {
|
|
39
|
+
if (baseSchema.toDOM && node.attrs.checked == null)
|
|
40
|
+
return baseSchema.toDOM(node)
|
|
41
|
+
|
|
42
|
+
return [
|
|
43
|
+
'li',
|
|
44
|
+
{
|
|
45
|
+
'data-item-type': 'task',
|
|
46
|
+
'data-label': node.attrs.label,
|
|
47
|
+
'data-list-type': node.attrs.listType,
|
|
48
|
+
'data-spread': node.attrs.spread,
|
|
49
|
+
'data-checked': node.attrs.checked,
|
|
50
|
+
},
|
|
51
|
+
0,
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
parseMarkdown: {
|
|
55
|
+
match: ({ type }) => type === 'listItem',
|
|
56
|
+
runner: (state, node, type) => {
|
|
57
|
+
if (node.checked == null) {
|
|
58
|
+
baseSchema.parseMarkdown.runner(state, node, type)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const label = node.label != null ? `${node.label}.` : '•'
|
|
63
|
+
const checked = node.checked != null ? Boolean(node.checked) : null
|
|
64
|
+
const listType = node.label != null ? 'ordered' : 'bullet'
|
|
65
|
+
const spread = node.spread != null ? `${node.spread}` : 'true'
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
state.openNode(type, { label, listType, spread, checked })
|
|
68
|
+
state.next(node.children)
|
|
69
|
+
state.closeNode()
|
|
70
|
+
},
|
|
68
71
|
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
72
|
+
toMarkdown: {
|
|
73
|
+
match: (node) => node.type.name === 'list_item',
|
|
74
|
+
runner: (state, node) => {
|
|
75
|
+
if (node.attrs.checked == null) {
|
|
76
|
+
baseSchema.toMarkdown.runner(state, node)
|
|
77
|
+
return
|
|
78
|
+
}
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
const label = node.attrs.label
|
|
81
|
+
const listType = node.attrs.listType
|
|
82
|
+
const spread = node.attrs.spread === 'true'
|
|
83
|
+
const checked = node.attrs.checked
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
state.openNode('listItem', undefined, {
|
|
86
|
+
label,
|
|
87
|
+
listType,
|
|
88
|
+
spread,
|
|
89
|
+
checked,
|
|
90
|
+
})
|
|
91
|
+
state.next(node.content)
|
|
92
|
+
state.closeNode()
|
|
93
|
+
},
|
|
86
94
|
},
|
|
87
|
-
}
|
|
95
|
+
}
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
|
-
|
|
98
|
+
)
|
|
91
99
|
|
|
92
100
|
withMeta(extendListItemSchemaForTask, {
|
|
93
101
|
displayName: 'NodeSchema<listItem>',
|
|
@@ -97,28 +105,32 @@ withMeta(extendListItemSchemaForTask, {
|
|
|
97
105
|
/// Input rule for wrapping a block in task list node.
|
|
98
106
|
/// Users can type `[ ] ` or `[x] ` to wrap the block in task list node with checked status.
|
|
99
107
|
export const wrapInTaskListInputRule = $inputRule(() => {
|
|
100
|
-
return new InputRule(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
depth
|
|
106
|
-
node
|
|
107
|
-
|
|
108
|
+
return new InputRule(
|
|
109
|
+
/^\[(?<checked>\s|x)\]\s$/,
|
|
110
|
+
(state, match, start, end) => {
|
|
111
|
+
const pos = state.doc.resolve(start)
|
|
112
|
+
let depth = 0
|
|
113
|
+
let node = pos.node(depth)
|
|
114
|
+
while (node && node.type.name !== 'list_item') {
|
|
115
|
+
depth--
|
|
116
|
+
node = pos.node(depth)
|
|
117
|
+
}
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
return null
|
|
119
|
+
if (!node || node.attrs.checked != null) return null
|
|
111
120
|
|
|
112
|
-
|
|
121
|
+
const checked = Boolean(match.groups?.checked === 'x')
|
|
113
122
|
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
const finPos = pos.before(depth)
|
|
124
|
+
const tr = state.tr
|
|
116
125
|
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
tr.deleteRange(start, end).setNodeMarkup(finPos, undefined, {
|
|
127
|
+
...node.attrs,
|
|
128
|
+
checked,
|
|
129
|
+
})
|
|
119
130
|
|
|
120
|
-
|
|
121
|
-
|
|
131
|
+
return tr
|
|
132
|
+
}
|
|
133
|
+
)
|
|
122
134
|
})
|
|
123
135
|
|
|
124
136
|
withMeta(wrapInTaskListInputRule, {
|
|
@@ -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,53 @@
|
|
|
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) index = i
|
|
13
|
+
})
|
|
14
|
+
return index
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const keepTableAlignPlugin = $prose(() => {
|
|
18
|
+
return new Plugin({
|
|
19
|
+
key: pluginKey,
|
|
20
|
+
appendTransaction: (_tr, oldState, state) => {
|
|
21
|
+
let tr: Transaction | undefined
|
|
22
|
+
const check = (node: Node, pos: number) => {
|
|
23
|
+
if (!tr) tr = state.tr
|
|
24
|
+
|
|
25
|
+
if (node.type.name !== 'table_cell') return
|
|
26
|
+
|
|
27
|
+
const $pos = state.doc.resolve(pos)
|
|
28
|
+
const tableRow = $pos.node($pos.depth)
|
|
29
|
+
const table = $pos.node($pos.depth - 1)
|
|
30
|
+
const tableHeaderRow = table.firstChild
|
|
31
|
+
// TODO: maybe consider add a header row
|
|
32
|
+
if (!tableHeaderRow) return
|
|
33
|
+
|
|
34
|
+
const index = getChildIndex(node, tableRow)
|
|
35
|
+
const headerCell = tableHeaderRow.maybeChild(index)
|
|
36
|
+
if (!headerCell) return
|
|
37
|
+
const align = headerCell.attrs.alignment
|
|
38
|
+
const currentAlign = node.attrs.alignment
|
|
39
|
+
if (align === currentAlign) return
|
|
40
|
+
|
|
41
|
+
tr.setNodeMarkup(pos, undefined, { ...node.attrs, alignment: align })
|
|
42
|
+
}
|
|
43
|
+
if (oldState.doc !== state.doc) state.doc.descendants(check)
|
|
44
|
+
|
|
45
|
+
return tr
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
withMeta(keepTableAlignPlugin, {
|
|
51
|
+
displayName: 'Prose<keepTableAlignPlugin>',
|
|
52
|
+
group: 'Prose',
|
|
53
|
+
})
|
|
@@ -5,7 +5,8 @@ import remarkGFM from 'remark-gfm'
|
|
|
5
5
|
import { withMeta } from '../__internal__'
|
|
6
6
|
|
|
7
7
|
/// This plugin is wrapping the [remark-gfm](https://github.com/remarkjs/remark-gfm).
|
|
8
|
-
export const remarkGFMPlugin: $Remark<'remarkGFM', Options | null | undefined> =
|
|
8
|
+
export const remarkGFMPlugin: $Remark<'remarkGFM', Options | null | undefined> =
|
|
9
|
+
$remark('remarkGFM', () => remarkGFM)
|
|
9
10
|
|
|
10
11
|
withMeta(remarkGFMPlugin.plugin, {
|
|
11
12
|
displayName: 'Remark<remarkGFMPlugin>',
|
|
@@ -3,7 +3,9 @@ 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(() =>
|
|
6
|
+
export const tableEditingPlugin = $prose(() =>
|
|
7
|
+
tableEditing({ allowTableNodeSelection: true })
|
|
8
|
+
)
|
|
7
9
|
|
|
8
10
|
withMeta(tableEditingPlugin, {
|
|
9
11
|
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
|
-
})
|