@milkdown/preset-commonmark 7.5.0 → 7.5.9
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__/serialize-text.d.ts.map +1 -1
- package/lib/__internal__/with-meta.d.ts.map +1 -1
- package/lib/composed/commands.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/schema.d.ts.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +412 -269
- package/lib/index.es.js.map +1 -1
- package/lib/mark/emphasis.d.ts.map +1 -1
- package/lib/mark/inline-code.d.ts.map +1 -1
- package/lib/mark/link.d.ts.map +1 -1
- package/lib/mark/strong.d.ts.map +1 -1
- package/lib/node/blockquote.d.ts.map +1 -1
- package/lib/node/bullet-list.d.ts.map +1 -1
- package/lib/node/code-block.d.ts.map +1 -1
- package/lib/node/hardbreak.d.ts.map +1 -1
- package/lib/node/heading.d.ts.map +1 -1
- package/lib/node/hr.d.ts.map +1 -1
- package/lib/node/html.d.ts.map +1 -1
- package/lib/node/image.d.ts.map +1 -1
- package/lib/node/list-item.d.ts.map +1 -1
- package/lib/node/ordered-list.d.ts.map +1 -1
- package/lib/node/paragraph.d.ts.map +1 -1
- package/lib/plugin/hardbreak-clear-mark-plugin.d.ts.map +1 -1
- package/lib/plugin/hardbreak-filter-plugin.d.ts.map +1 -1
- package/lib/plugin/inline-nodes-cursor-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-add-order-in-list-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-html-transformer.d.ts.map +1 -1
- package/lib/plugin/remark-inline-link-plugin.d.ts.map +1 -1
- package/lib/plugin/remark-line-break.d.ts.map +1 -1
- package/lib/plugin/remark-marker-plugin.d.ts.map +1 -1
- package/lib/plugin/sync-heading-id-plugin.d.ts.map +1 -1
- package/lib/plugin/sync-list-order-plugin.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/__internal__/serialize-text.ts +3 -4
- package/src/__internal__/with-meta.ts +4 -1
- package/src/composed/commands.ts +7 -1
- package/src/composed/inputrules.ts +14 -2
- package/src/composed/keymap.ts +10 -1
- package/src/composed/schema.ts +10 -1
- package/src/index.ts +16 -2
- package/src/mark/emphasis.ts +19 -9
- package/src/mark/inline-code.ts +40 -30
- package/src/mark/link.ts +55 -45
- package/src/mark/strong.ts +13 -7
- package/src/node/blockquote.ts +34 -20
- package/src/node/bullet-list.ts +20 -7
- package/src/node/code-block.ts +43 -18
- package/src/node/doc.ts +1 -1
- package/src/node/hardbreak.ts +49 -28
- package/src/node/heading.ts +44 -27
- package/src/node/hr.ts +27 -28
- package/src/node/html.ts +10 -8
- package/src/node/image.ts +57 -43
- package/src/node/list-item.ts +35 -18
- package/src/node/ordered-list.ts +31 -15
- package/src/node/paragraph.ts +10 -10
- package/src/node/text.ts +1 -1
- package/src/plugin/hardbreak-clear-mark-plugin.ts +16 -9
- package/src/plugin/hardbreak-filter-plugin.ts +5 -3
- package/src/plugin/inline-nodes-cursor-plugin.ts +13 -6
- package/src/plugin/remark-add-order-in-list-plugin.ts +13 -10
- package/src/plugin/remark-html-transformer.ts +24 -17
- package/src/plugin/remark-inline-link-plugin.ts +4 -1
- package/src/plugin/remark-line-break.ts +39 -26
- package/src/plugin/remark-marker-plugin.ts +14 -7
- package/src/plugin/sync-heading-id-plugin.ts +12 -9
- package/src/plugin/sync-list-order-plugin.ts +12 -11
package/src/node/html.ts
CHANGED
|
@@ -28,14 +28,16 @@ export const htmlSchema = $nodeSchema('html', (ctx) => {
|
|
|
28
28
|
span.textContent = node.attrs.value
|
|
29
29
|
return ['span', attr, node.attrs.value]
|
|
30
30
|
},
|
|
31
|
-
parseDOM: [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
parseDOM: [
|
|
32
|
+
{
|
|
33
|
+
tag: 'span[data-type="html"]',
|
|
34
|
+
getAttrs: (dom) => {
|
|
35
|
+
return {
|
|
36
|
+
value: dom.dataset.value ?? '',
|
|
37
|
+
}
|
|
38
|
+
},
|
|
37
39
|
},
|
|
38
|
-
|
|
40
|
+
],
|
|
39
41
|
parseMarkdown: {
|
|
40
42
|
match: ({ type }) => Boolean(type === 'html'),
|
|
41
43
|
runner: (state, node, type) => {
|
|
@@ -43,7 +45,7 @@ export const htmlSchema = $nodeSchema('html', (ctx) => {
|
|
|
43
45
|
},
|
|
44
46
|
},
|
|
45
47
|
toMarkdown: {
|
|
46
|
-
match: node => node.type.name === 'html',
|
|
48
|
+
match: (node) => node.type.name === 'html',
|
|
47
49
|
runner: (state, node) => {
|
|
48
50
|
state.addNode('html', undefined, node.attrs.value)
|
|
49
51
|
},
|
package/src/node/image.ts
CHANGED
|
@@ -32,8 +32,7 @@ export const imageSchema = $nodeSchema('image', (ctx) => {
|
|
|
32
32
|
{
|
|
33
33
|
tag: 'img[src]',
|
|
34
34
|
getAttrs: (dom) => {
|
|
35
|
-
if (!(dom instanceof HTMLElement))
|
|
36
|
-
throw expectDomTypeError(dom)
|
|
35
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
37
36
|
|
|
38
37
|
return {
|
|
39
38
|
src: dom.getAttribute('src') || '',
|
|
@@ -60,7 +59,7 @@ export const imageSchema = $nodeSchema('image', (ctx) => {
|
|
|
60
59
|
},
|
|
61
60
|
},
|
|
62
61
|
toMarkdown: {
|
|
63
|
-
match: node => node.type.name === 'image',
|
|
62
|
+
match: (node) => node.type.name === 'image',
|
|
64
63
|
runner: (state, node) => {
|
|
65
64
|
state.addNode('image', undefined, undefined, {
|
|
66
65
|
title: node.attrs.title,
|
|
@@ -91,20 +90,22 @@ export interface UpdateImageCommandPayload {
|
|
|
91
90
|
|
|
92
91
|
/// This command will insert a image node.
|
|
93
92
|
/// You can pass a payload to set `src`, `alt` and `title` for the image node.
|
|
94
|
-
export const insertImageCommand = $command(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
export const insertImageCommand = $command(
|
|
94
|
+
'InsertImage',
|
|
95
|
+
(ctx) =>
|
|
96
|
+
(payload: UpdateImageCommandPayload = {}) =>
|
|
97
|
+
(state, dispatch) => {
|
|
98
|
+
if (!dispatch) return true
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
const { src = '', alt = '', title = '' } = payload
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return true
|
|
102
|
+
const node = imageSchema.type(ctx).create({ src, alt, title })
|
|
103
|
+
if (!node) return true
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
dispatch(state.tr.replaceSelectionWith(node).scrollIntoView())
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
108
|
+
)
|
|
108
109
|
|
|
109
110
|
withMeta(insertImageCommand, {
|
|
110
111
|
displayName: 'Command<insertImageCommand>',
|
|
@@ -113,25 +114,31 @@ withMeta(insertImageCommand, {
|
|
|
113
114
|
|
|
114
115
|
/// This command will update the selected image node.
|
|
115
116
|
/// You can pass a payload to update `src`, `alt` and `title` for the image node.
|
|
116
|
-
export const updateImageCommand = $command(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
117
|
+
export const updateImageCommand = $command(
|
|
118
|
+
'UpdateImage',
|
|
119
|
+
(ctx) =>
|
|
120
|
+
(payload: UpdateImageCommandPayload = {}) =>
|
|
121
|
+
(state, dispatch) => {
|
|
122
|
+
const nodeWithPos = findSelectedNodeOfType(
|
|
123
|
+
state.selection,
|
|
124
|
+
imageSchema.type(ctx)
|
|
125
|
+
)
|
|
126
|
+
if (!nodeWithPos) return false
|
|
127
|
+
|
|
128
|
+
const { node, pos } = nodeWithPos
|
|
129
|
+
|
|
130
|
+
const newAttrs = { ...node.attrs }
|
|
131
|
+
const { src, alt, title } = payload
|
|
132
|
+
if (src !== undefined) newAttrs.src = src
|
|
133
|
+
if (alt !== undefined) newAttrs.alt = alt
|
|
134
|
+
if (title !== undefined) newAttrs.title = title
|
|
135
|
+
|
|
136
|
+
dispatch?.(
|
|
137
|
+
state.tr.setNodeMarkup(pos, undefined, newAttrs).scrollIntoView()
|
|
138
|
+
)
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
)
|
|
135
142
|
|
|
136
143
|
withMeta(updateImageCommand, {
|
|
137
144
|
displayName: 'Command<updateImageCommand>',
|
|
@@ -141,16 +148,23 @@ withMeta(updateImageCommand, {
|
|
|
141
148
|
/// This input rule will insert a image node.
|
|
142
149
|
/// You can input `` to insert a image node.
|
|
143
150
|
/// The `title` is optional.
|
|
144
|
-
export const insertImageInputRule = $inputRule(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
export const insertImageInputRule = $inputRule(
|
|
152
|
+
(ctx) =>
|
|
153
|
+
new InputRule(
|
|
154
|
+
/!\[(?<alt>.*?)]\((?<filename>.*?)\s*(?="|\))"?(?<title>[^"]+)?"?\)/,
|
|
155
|
+
(state, match, start, end) => {
|
|
156
|
+
const [matched, alt, src = '', title] = match
|
|
157
|
+
if (matched)
|
|
158
|
+
return state.tr.replaceWith(
|
|
159
|
+
start,
|
|
160
|
+
end,
|
|
161
|
+
imageSchema.type(ctx).create({ src, alt, title })
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return null
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
)
|
|
154
168
|
|
|
155
169
|
withMeta(insertImageInputRule, {
|
|
156
170
|
displayName: 'InputRule<insertImageInputRule>',
|
package/src/node/list-item.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { commandsCtx } from '@milkdown/core'
|
|
2
2
|
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
liftListItem,
|
|
5
|
+
sinkListItem,
|
|
6
|
+
splitListItem,
|
|
7
|
+
} from '@milkdown/prose/schema-list'
|
|
4
8
|
import { $command, $nodeAttr, $nodeSchema, $useKeymap } from '@milkdown/utils'
|
|
5
9
|
import { type Command, TextSelection } from '@milkdown/prose/state'
|
|
6
10
|
import type { Ctx } from '@milkdown/ctx'
|
|
@@ -15,7 +19,7 @@ withMeta(listItemAttr, {
|
|
|
15
19
|
})
|
|
16
20
|
|
|
17
21
|
/// Schema for list item node.
|
|
18
|
-
export const listItemSchema = $nodeSchema('list_item', ctx => ({
|
|
22
|
+
export const listItemSchema = $nodeSchema('list_item', (ctx) => ({
|
|
19
23
|
group: 'listItem',
|
|
20
24
|
content: '(paragraph|blockquote) block*',
|
|
21
25
|
attrs: {
|
|
@@ -34,8 +38,7 @@ export const listItemSchema = $nodeSchema('list_item', ctx => ({
|
|
|
34
38
|
{
|
|
35
39
|
tag: 'li',
|
|
36
40
|
getAttrs: (dom) => {
|
|
37
|
-
if (!(dom instanceof HTMLElement))
|
|
38
|
-
throw expectDomTypeError(dom)
|
|
41
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
39
42
|
|
|
40
43
|
return {
|
|
41
44
|
label: dom.dataset.label,
|
|
@@ -45,7 +48,7 @@ export const listItemSchema = $nodeSchema('list_item', ctx => ({
|
|
|
45
48
|
},
|
|
46
49
|
},
|
|
47
50
|
],
|
|
48
|
-
toDOM: node => [
|
|
51
|
+
toDOM: (node) => [
|
|
49
52
|
'li',
|
|
50
53
|
{
|
|
51
54
|
...ctx.get(listItemAttr.key)(node),
|
|
@@ -67,9 +70,11 @@ export const listItemSchema = $nodeSchema('list_item', ctx => ({
|
|
|
67
70
|
},
|
|
68
71
|
},
|
|
69
72
|
toMarkdown: {
|
|
70
|
-
match: node => node.type.name === 'list_item',
|
|
73
|
+
match: (node) => node.type.name === 'list_item',
|
|
71
74
|
runner: (state, node) => {
|
|
72
|
-
state.openNode('listItem', undefined, {
|
|
75
|
+
state.openNode('listItem', undefined, {
|
|
76
|
+
spread: node.attrs.spread === 'true',
|
|
77
|
+
})
|
|
73
78
|
state.next(node.content)
|
|
74
79
|
state.closeNode()
|
|
75
80
|
},
|
|
@@ -98,7 +103,10 @@ withMeta(listItemSchema.ctx, {
|
|
|
98
103
|
/// * List item 1
|
|
99
104
|
/// * List item 2
|
|
100
105
|
/// ```
|
|
101
|
-
export const sinkListItemCommand = $command(
|
|
106
|
+
export const sinkListItemCommand = $command(
|
|
107
|
+
'SinkListItem',
|
|
108
|
+
(ctx) => () => sinkListItem(listItemSchema.type(ctx))
|
|
109
|
+
)
|
|
102
110
|
|
|
103
111
|
withMeta(sinkListItemCommand, {
|
|
104
112
|
displayName: 'Command<sinkListItemCommand>',
|
|
@@ -117,7 +125,10 @@ withMeta(sinkListItemCommand, {
|
|
|
117
125
|
/// * List item 1
|
|
118
126
|
/// * List item 2
|
|
119
127
|
/// ```
|
|
120
|
-
export const liftListItemCommand = $command(
|
|
128
|
+
export const liftListItemCommand = $command(
|
|
129
|
+
'LiftListItem',
|
|
130
|
+
(ctx) => () => liftListItem(listItemSchema.type(ctx))
|
|
131
|
+
)
|
|
121
132
|
|
|
122
133
|
withMeta(liftListItemCommand, {
|
|
123
134
|
displayName: 'Command<liftListItemCommand>',
|
|
@@ -137,7 +148,10 @@ withMeta(liftListItemCommand, {
|
|
|
137
148
|
/// * List item 2
|
|
138
149
|
/// * <- cursor here
|
|
139
150
|
/// ```
|
|
140
|
-
export const splitListItemCommand = $command(
|
|
151
|
+
export const splitListItemCommand = $command(
|
|
152
|
+
'SplitListItem',
|
|
153
|
+
(ctx) => () => splitListItem(listItemSchema.type(ctx))
|
|
154
|
+
)
|
|
141
155
|
|
|
142
156
|
withMeta(splitListItemCommand, {
|
|
143
157
|
displayName: 'Command<splitListItemCommand>',
|
|
@@ -147,24 +161,24 @@ withMeta(splitListItemCommand, {
|
|
|
147
161
|
function liftFirstListItem(ctx: Ctx): Command {
|
|
148
162
|
return (state, dispatch, view) => {
|
|
149
163
|
const { selection } = state
|
|
150
|
-
if (!(selection instanceof TextSelection))
|
|
151
|
-
return false
|
|
164
|
+
if (!(selection instanceof TextSelection)) return false
|
|
152
165
|
|
|
153
166
|
const { empty, $from } = selection
|
|
154
167
|
|
|
155
168
|
// selection should be empty and at the start of the node
|
|
156
|
-
if (!empty || $from.parentOffset !== 0)
|
|
157
|
-
return false
|
|
169
|
+
if (!empty || $from.parentOffset !== 0) return false
|
|
158
170
|
|
|
159
171
|
const parentItem = $from.node(-1)
|
|
160
172
|
// selection should be in list item and list item should be the first child of the list
|
|
161
|
-
if (
|
|
173
|
+
if (
|
|
174
|
+
parentItem.type !== listItemSchema.type(ctx) ||
|
|
175
|
+
parentItem.firstChild !== $from.node()
|
|
176
|
+
)
|
|
162
177
|
return false
|
|
163
178
|
|
|
164
179
|
const list = $from.node(-2)
|
|
165
180
|
// list should have only one list item
|
|
166
|
-
if (list.childCount > 1)
|
|
167
|
-
return false
|
|
181
|
+
if (list.childCount > 1) return false
|
|
168
182
|
|
|
169
183
|
return liftListItem(listItemSchema.type(ctx))(state, dispatch, view)
|
|
170
184
|
}
|
|
@@ -176,7 +190,10 @@ function liftFirstListItem(ctx: Ctx): Command {
|
|
|
176
190
|
/// - List item is the only child of the list.
|
|
177
191
|
///
|
|
178
192
|
/// Most of the time, you shouldn't use this command directly.
|
|
179
|
-
export const liftFirstListItemCommand = $command(
|
|
193
|
+
export const liftFirstListItemCommand = $command(
|
|
194
|
+
'LiftFirstListItem',
|
|
195
|
+
(ctx) => () => liftFirstListItem(ctx)
|
|
196
|
+
)
|
|
180
197
|
|
|
181
198
|
withMeta(liftFirstListItemCommand, {
|
|
182
199
|
displayName: 'Command<liftFirstListItemCommand>',
|
package/src/node/ordered-list.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { commandsCtx } from '@milkdown/core'
|
|
|
2
2
|
import { expectDomTypeError } from '@milkdown/exception'
|
|
3
3
|
import { wrapIn } from '@milkdown/prose/commands'
|
|
4
4
|
import { wrappingInputRule } from '@milkdown/prose/inputrules'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
$command,
|
|
7
|
+
$inputRule,
|
|
8
|
+
$nodeAttr,
|
|
9
|
+
$nodeSchema,
|
|
10
|
+
$useKeymap,
|
|
11
|
+
} from '@milkdown/utils'
|
|
6
12
|
import { withMeta } from '../__internal__'
|
|
7
13
|
|
|
8
14
|
/// HTML attributes for ordered list node.
|
|
@@ -14,7 +20,7 @@ withMeta(orderedListAttr, {
|
|
|
14
20
|
})
|
|
15
21
|
|
|
16
22
|
/// Schema for ordered list node.
|
|
17
|
-
export const orderedListSchema = $nodeSchema('ordered_list', ctx => ({
|
|
23
|
+
export const orderedListSchema = $nodeSchema('ordered_list', (ctx) => ({
|
|
18
24
|
content: 'listItem+',
|
|
19
25
|
group: 'block',
|
|
20
26
|
attrs: {
|
|
@@ -29,17 +35,18 @@ export const orderedListSchema = $nodeSchema('ordered_list', ctx => ({
|
|
|
29
35
|
{
|
|
30
36
|
tag: 'ol',
|
|
31
37
|
getAttrs: (dom) => {
|
|
32
|
-
if (!(dom instanceof HTMLElement))
|
|
33
|
-
throw expectDomTypeError(dom)
|
|
38
|
+
if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom)
|
|
34
39
|
|
|
35
40
|
return {
|
|
36
41
|
spread: dom.dataset.spread,
|
|
37
|
-
order: dom.hasAttribute('start')
|
|
42
|
+
order: dom.hasAttribute('start')
|
|
43
|
+
? Number(dom.getAttribute('start'))
|
|
44
|
+
: 1,
|
|
38
45
|
}
|
|
39
46
|
},
|
|
40
47
|
},
|
|
41
48
|
],
|
|
42
|
-
toDOM: node => [
|
|
49
|
+
toDOM: (node) => [
|
|
43
50
|
'ol',
|
|
44
51
|
{
|
|
45
52
|
...ctx.get(orderedListAttr.key)(node),
|
|
@@ -56,9 +63,13 @@ export const orderedListSchema = $nodeSchema('ordered_list', ctx => ({
|
|
|
56
63
|
},
|
|
57
64
|
},
|
|
58
65
|
toMarkdown: {
|
|
59
|
-
match: node => node.type.name === 'ordered_list',
|
|
66
|
+
match: (node) => node.type.name === 'ordered_list',
|
|
60
67
|
runner: (state, node) => {
|
|
61
|
-
state.openNode('list', undefined, {
|
|
68
|
+
state.openNode('list', undefined, {
|
|
69
|
+
ordered: true,
|
|
70
|
+
start: 1,
|
|
71
|
+
spread: node.attrs.spread === 'true',
|
|
72
|
+
})
|
|
62
73
|
state.next(node.content)
|
|
63
74
|
state.closeNode()
|
|
64
75
|
},
|
|
@@ -76,12 +87,14 @@ withMeta(orderedListSchema.ctx, {
|
|
|
76
87
|
})
|
|
77
88
|
|
|
78
89
|
/// Input rule for wrapping a block in ordered list node.
|
|
79
|
-
export const wrapInOrderedListInputRule = $inputRule(ctx =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
))
|
|
90
|
+
export const wrapInOrderedListInputRule = $inputRule((ctx) =>
|
|
91
|
+
wrappingInputRule(
|
|
92
|
+
/^\s*(\d+)\.\s$/,
|
|
93
|
+
orderedListSchema.type(ctx),
|
|
94
|
+
(match) => ({ order: Number(match[1]) }),
|
|
95
|
+
(match, node) => node.childCount + node.attrs.order === Number(match[1])
|
|
96
|
+
)
|
|
97
|
+
)
|
|
85
98
|
|
|
86
99
|
withMeta(wrapInOrderedListInputRule, {
|
|
87
100
|
displayName: 'InputRule<wrapInOrderedListInputRule>',
|
|
@@ -89,7 +102,10 @@ withMeta(wrapInOrderedListInputRule, {
|
|
|
89
102
|
})
|
|
90
103
|
|
|
91
104
|
/// Command for wrapping a block in ordered list node.
|
|
92
|
-
export const wrapInOrderedListCommand = $command(
|
|
105
|
+
export const wrapInOrderedListCommand = $command(
|
|
106
|
+
'WrapInOrderedList',
|
|
107
|
+
(ctx) => () => wrapIn(orderedListSchema.type(ctx))
|
|
108
|
+
)
|
|
93
109
|
|
|
94
110
|
withMeta(wrapInOrderedListCommand, {
|
|
95
111
|
displayName: 'Command<wrapInOrderedListCommand>',
|
package/src/node/paragraph.ts
CHANGED
|
@@ -12,26 +12,23 @@ withMeta(paragraphAttr, {
|
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
/// Schema for paragraph node.
|
|
15
|
-
export const paragraphSchema = $nodeSchema('paragraph', ctx => ({
|
|
15
|
+
export const paragraphSchema = $nodeSchema('paragraph', (ctx) => ({
|
|
16
16
|
content: 'inline*',
|
|
17
17
|
group: 'block',
|
|
18
18
|
parseDOM: [{ tag: 'p' }],
|
|
19
|
-
toDOM: node => ['p', ctx.get(paragraphAttr.key)(node), 0],
|
|
19
|
+
toDOM: (node) => ['p', ctx.get(paragraphAttr.key)(node), 0],
|
|
20
20
|
parseMarkdown: {
|
|
21
|
-
match: node => node.type === 'paragraph',
|
|
21
|
+
match: (node) => node.type === 'paragraph',
|
|
22
22
|
runner: (state, node, type) => {
|
|
23
23
|
state.openNode(type)
|
|
24
|
-
if (node.children)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
else
|
|
28
|
-
state.addText((node.value || '') as string)
|
|
24
|
+
if (node.children) state.next(node.children)
|
|
25
|
+
else state.addText((node.value || '') as string)
|
|
29
26
|
|
|
30
27
|
state.closeNode()
|
|
31
28
|
},
|
|
32
29
|
},
|
|
33
30
|
toMarkdown: {
|
|
34
|
-
match: node => node.type.name === 'paragraph',
|
|
31
|
+
match: (node) => node.type.name === 'paragraph',
|
|
35
32
|
runner: (state, node) => {
|
|
36
33
|
state.openNode('paragraph')
|
|
37
34
|
serializeText(state, node)
|
|
@@ -50,7 +47,10 @@ withMeta(paragraphSchema.ctx, {
|
|
|
50
47
|
})
|
|
51
48
|
|
|
52
49
|
/// This command can turn the selected block into paragraph.
|
|
53
|
-
export const turnIntoTextCommand = $command(
|
|
50
|
+
export const turnIntoTextCommand = $command(
|
|
51
|
+
'TurnIntoText',
|
|
52
|
+
(ctx) => () => setBlockType(paragraphSchema.type(ctx))
|
|
53
|
+
)
|
|
54
54
|
|
|
55
55
|
withMeta(turnIntoTextCommand, {
|
|
56
56
|
displayName: 'Command<turnIntoTextCommand>',
|
package/src/node/text.ts
CHANGED
|
@@ -11,7 +11,7 @@ export const textSchema = $node('text', () => ({
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
toMarkdown: {
|
|
14
|
-
match: node => node.type.name === 'text',
|
|
14
|
+
match: (node) => node.type.name === 'text',
|
|
15
15
|
runner: (state, node) => {
|
|
16
16
|
state.addNode('text', undefined, node.text as string)
|
|
17
17
|
},
|
|
@@ -9,31 +9,38 @@ export const hardbreakClearMarkPlugin = $prose((ctx) => {
|
|
|
9
9
|
return new Plugin({
|
|
10
10
|
key: new PluginKey('MILKDOWN_HARDBREAK_MARKS'),
|
|
11
11
|
appendTransaction: (trs, _oldState, newState) => {
|
|
12
|
-
if (!trs.length)
|
|
13
|
-
return
|
|
12
|
+
if (!trs.length) return
|
|
14
13
|
|
|
15
14
|
const [tr] = trs
|
|
16
|
-
if (!tr)
|
|
17
|
-
return
|
|
15
|
+
if (!tr) return
|
|
18
16
|
|
|
19
17
|
const [step] = tr.steps
|
|
20
18
|
|
|
21
19
|
const isInsertHr = tr.getMeta('hardbreak')
|
|
22
20
|
if (isInsertHr) {
|
|
23
|
-
if (!(step instanceof ReplaceStep))
|
|
24
|
-
return
|
|
21
|
+
if (!(step instanceof ReplaceStep)) return
|
|
25
22
|
|
|
26
23
|
const { from } = step as unknown as { from: number }
|
|
27
|
-
return newState.tr.setNodeMarkup(
|
|
24
|
+
return newState.tr.setNodeMarkup(
|
|
25
|
+
from,
|
|
26
|
+
hardbreakSchema.type(ctx),
|
|
27
|
+
undefined,
|
|
28
|
+
[]
|
|
29
|
+
)
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
const isAddMarkStep = step instanceof AddMarkStep
|
|
31
33
|
if (isAddMarkStep) {
|
|
32
34
|
let _tr = newState.tr
|
|
33
|
-
const { from, to } = step as unknown as { from: number
|
|
35
|
+
const { from, to } = step as unknown as { from: number; to: number }
|
|
34
36
|
newState.doc.nodesBetween(from, to, (node, pos) => {
|
|
35
37
|
if (node.type === hardbreakSchema.type(ctx))
|
|
36
|
-
_tr = _tr.setNodeMarkup(
|
|
38
|
+
_tr = _tr.setNodeMarkup(
|
|
39
|
+
pos,
|
|
40
|
+
hardbreakSchema.type(ctx),
|
|
41
|
+
undefined,
|
|
42
|
+
[]
|
|
43
|
+
)
|
|
37
44
|
})
|
|
38
45
|
|
|
39
46
|
return _tr
|
|
@@ -3,7 +3,10 @@ import { $ctx, $prose } from '@milkdown/utils'
|
|
|
3
3
|
import { withMeta } from '../__internal__'
|
|
4
4
|
|
|
5
5
|
/// This slice contains the nodes that within which the hardbreak will be ignored.
|
|
6
|
-
export const hardbreakFilterNodes = $ctx(
|
|
6
|
+
export const hardbreakFilterNodes = $ctx(
|
|
7
|
+
['table', 'code_block'],
|
|
8
|
+
'hardbreakFilterNodes'
|
|
9
|
+
)
|
|
7
10
|
|
|
8
11
|
withMeta(hardbreakFilterNodes, {
|
|
9
12
|
displayName: 'Ctx<hardbreakFilterNodes>',
|
|
@@ -25,8 +28,7 @@ export const hardbreakFilterPlugin = $prose((ctx) => {
|
|
|
25
28
|
let curDepth = $from.depth
|
|
26
29
|
let canApply = true
|
|
27
30
|
while (curDepth > 0) {
|
|
28
|
-
if (notIn.includes($from.node(curDepth).type.name))
|
|
29
|
-
canApply = false
|
|
31
|
+
if (notIn.includes($from.node(curDepth).type.name)) canApply = false
|
|
30
32
|
|
|
31
33
|
curDepth--
|
|
32
34
|
}
|
|
@@ -6,7 +6,9 @@ import { withMeta } from '../__internal__'
|
|
|
6
6
|
/// This plugin is to solve the [chrome 98 bug](https://discuss.prosemirror.net/t/cursor-jumps-at-the-end-of-line-when-it-betweens-two-inline-nodes/4641).
|
|
7
7
|
export const inlineNodesCursorPlugin = $prose(() => {
|
|
8
8
|
let lock = false
|
|
9
|
-
const inlineNodesCursorPluginKey = new PluginKey(
|
|
9
|
+
const inlineNodesCursorPluginKey = new PluginKey(
|
|
10
|
+
'MILKDOWN_INLINE_NODES_CURSOR'
|
|
11
|
+
)
|
|
10
12
|
const inlineNodesCursorPlugin: Plugin = new Plugin({
|
|
11
13
|
key: inlineNodesCursorPluginKey,
|
|
12
14
|
state: {
|
|
@@ -14,13 +16,19 @@ export const inlineNodesCursorPlugin = $prose(() => {
|
|
|
14
16
|
return false
|
|
15
17
|
},
|
|
16
18
|
apply(tr) {
|
|
17
|
-
if (!tr.selection.empty)
|
|
18
|
-
return false
|
|
19
|
+
if (!tr.selection.empty) return false
|
|
19
20
|
|
|
20
21
|
const pos = tr.selection.$from
|
|
21
22
|
const left = pos.nodeBefore
|
|
22
23
|
const right = pos.nodeAfter
|
|
23
|
-
if (
|
|
24
|
+
if (
|
|
25
|
+
left &&
|
|
26
|
+
right &&
|
|
27
|
+
left.isInline &&
|
|
28
|
+
!left.isText &&
|
|
29
|
+
right.isInline &&
|
|
30
|
+
!right.isText
|
|
31
|
+
)
|
|
24
32
|
return true
|
|
25
33
|
|
|
26
34
|
return false
|
|
@@ -46,8 +54,7 @@ export const inlineNodesCursorPlugin = $prose(() => {
|
|
|
46
54
|
},
|
|
47
55
|
compositionstart: (view) => {
|
|
48
56
|
const active = inlineNodesCursorPlugin.getState(view.state)
|
|
49
|
-
if (active)
|
|
50
|
-
lock = true
|
|
57
|
+
if (active) lock = true
|
|
51
58
|
|
|
52
59
|
return false
|
|
53
60
|
},
|
|
@@ -3,16 +3,19 @@ import { visit } from 'unist-util-visit'
|
|
|
3
3
|
import { withMeta } from '../__internal__'
|
|
4
4
|
|
|
5
5
|
/// This plugin is used to add order in list for remark AST.
|
|
6
|
-
export const remarkAddOrderInListPlugin = $remark(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
node.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
6
|
+
export const remarkAddOrderInListPlugin = $remark(
|
|
7
|
+
'remarkAddOrderInList',
|
|
8
|
+
() => () => (tree) => {
|
|
9
|
+
visit(tree, 'list', (node) => {
|
|
10
|
+
if (node.ordered) {
|
|
11
|
+
const start = node.start ?? 1
|
|
12
|
+
node.children.forEach((child, index) => {
|
|
13
|
+
;(child as unknown as Record<string, number>).label = index + start
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
)
|
|
16
19
|
|
|
17
20
|
withMeta(remarkAddOrderInListPlugin.plugin, {
|
|
18
21
|
displayName: 'Remark<remarkAddOrderInListPlugin>',
|
|
@@ -2,10 +2,16 @@ import { $remark } from '@milkdown/utils'
|
|
|
2
2
|
import type { Node } from '@milkdown/transformer'
|
|
3
3
|
import { withMeta } from '../__internal__'
|
|
4
4
|
|
|
5
|
-
const isParent = (node: Node): node is Node & { children: Node[] } =>
|
|
6
|
-
|
|
5
|
+
const isParent = (node: Node): node is Node & { children: Node[] } =>
|
|
6
|
+
!!(node as Node & { children: Node[] }).children
|
|
7
|
+
const isHTML = (
|
|
8
|
+
node: Node
|
|
9
|
+
): node is Node & { children: Node[]; value: unknown } => node.type === 'html'
|
|
7
10
|
|
|
8
|
-
function flatMapWithDepth(
|
|
11
|
+
function flatMapWithDepth(
|
|
12
|
+
ast: Node,
|
|
13
|
+
fn: (node: Node, index: number, parent: Node | null) => Node[]
|
|
14
|
+
) {
|
|
9
15
|
return transform(ast, 0, null)[0]
|
|
10
16
|
|
|
11
17
|
function transform(node: Node, index: number, parent: Node | null) {
|
|
@@ -18,8 +24,7 @@ function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Nod
|
|
|
18
24
|
if (xs) {
|
|
19
25
|
for (let j = 0, m = xs.length; j < m; j++) {
|
|
20
26
|
const item = xs[j]
|
|
21
|
-
if (item)
|
|
22
|
-
out.push(item)
|
|
27
|
+
if (item) out.push(item)
|
|
23
28
|
}
|
|
24
29
|
}
|
|
25
30
|
}
|
|
@@ -33,20 +38,22 @@ function flatMapWithDepth(ast: Node, fn: (node: Node, index: number, parent: Nod
|
|
|
33
38
|
|
|
34
39
|
/// @internal
|
|
35
40
|
/// This plugin should be deprecated after we support HTML.
|
|
36
|
-
export const remarkHtmlTransformer = $remark(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
export const remarkHtmlTransformer = $remark(
|
|
42
|
+
'remarkHTMLTransformer',
|
|
43
|
+
() => () => (tree: Node) => {
|
|
44
|
+
flatMapWithDepth(tree, (node, _index, parent) => {
|
|
45
|
+
if (!isHTML(node)) return [node]
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (parent?.type === 'root') {
|
|
48
|
+
node.children = [{ ...node }]
|
|
49
|
+
delete node.value
|
|
50
|
+
;(node as { type: string }).type = 'paragraph'
|
|
51
|
+
}
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
53
|
+
return [node]
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
)
|
|
50
57
|
|
|
51
58
|
withMeta(remarkHtmlTransformer.plugin, {
|
|
52
59
|
displayName: 'Remark<remarkHtmlTransformer>',
|