@milkdown/preset-commonmark 6.5.1 → 6.5.3

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.
Files changed (88) hide show
  1. package/lib/index.d.ts +1 -1
  2. package/lib/index.d.ts.map +1 -1
  3. package/lib/index.es.js +453 -412
  4. package/lib/index.es.js.map +1 -1
  5. package/lib/mark/code-inline.d.ts +1 -1
  6. package/lib/mark/code-inline.d.ts.map +1 -1
  7. package/lib/mark/em.d.ts +1 -1
  8. package/lib/mark/em.d.ts.map +1 -1
  9. package/lib/mark/index.d.ts.map +1 -1
  10. package/lib/mark/link.d.ts +4 -3
  11. package/lib/mark/link.d.ts.map +1 -1
  12. package/lib/mark/strong.d.ts +1 -1
  13. package/lib/mark/strong.d.ts.map +1 -1
  14. package/lib/node/blockquote.d.ts +1 -1
  15. package/lib/node/blockquote.d.ts.map +1 -1
  16. package/lib/node/bullet-list.d.ts +1 -1
  17. package/lib/node/bullet-list.d.ts.map +1 -1
  18. package/lib/node/code-fence.d.ts.map +1 -1
  19. package/lib/node/doc.d.ts +1 -1
  20. package/lib/node/doc.d.ts.map +1 -1
  21. package/lib/node/hardbreak.d.ts.map +1 -1
  22. package/lib/node/heading.d.ts +2 -2
  23. package/lib/node/heading.d.ts.map +1 -1
  24. package/lib/node/hr.d.ts +1 -1
  25. package/lib/node/hr.d.ts.map +1 -1
  26. package/lib/node/image.d.ts +2 -2
  27. package/lib/node/image.d.ts.map +1 -1
  28. package/lib/node/index.d.ts +1 -1
  29. package/lib/node/index.d.ts.map +1 -1
  30. package/lib/node/list-item.d.ts +2 -2
  31. package/lib/node/list-item.d.ts.map +1 -1
  32. package/lib/node/ordered-list.d.ts +1 -1
  33. package/lib/node/ordered-list.d.ts.map +1 -1
  34. package/lib/node/paragraph.d.ts +1 -1
  35. package/lib/node/paragraph.d.ts.map +1 -1
  36. package/lib/node/text.d.ts +1 -1
  37. package/lib/node/text.d.ts.map +1 -1
  38. package/lib/plugin/add-order-in-list.d.ts +1 -1
  39. package/lib/plugin/add-order-in-list.d.ts.map +1 -1
  40. package/lib/plugin/filter-html.d.ts +1 -1
  41. package/lib/plugin/filter-html.d.ts.map +1 -1
  42. package/lib/plugin/index.d.ts +1 -1
  43. package/lib/plugin/index.d.ts.map +1 -1
  44. package/lib/plugin/inline-nodes-cursor.d.ts.map +1 -1
  45. package/lib/plugin/inline-sync/config.d.ts +8 -8
  46. package/lib/plugin/inline-sync/config.d.ts.map +1 -1
  47. package/lib/plugin/inline-sync/context.d.ts +5 -5
  48. package/lib/plugin/inline-sync/context.d.ts.map +1 -1
  49. package/lib/plugin/inline-sync/index.d.ts +1 -1
  50. package/lib/plugin/inline-sync/index.d.ts.map +1 -1
  51. package/lib/plugin/inline-sync/regexp.d.ts.map +1 -1
  52. package/lib/plugin/inline-sync/replacer.d.ts +3 -3
  53. package/lib/plugin/inline-sync/replacer.d.ts.map +1 -1
  54. package/lib/plugin/inline-sync/utils.d.ts +2 -2
  55. package/lib/plugin/inline-sync/utils.d.ts.map +1 -1
  56. package/lib/supported-keys.d.ts +1 -1
  57. package/lib/supported-keys.d.ts.map +1 -1
  58. package/package.json +17 -17
  59. package/src/index.ts +52 -52
  60. package/src/mark/code-inline.ts +56 -55
  61. package/src/mark/em.ts +36 -36
  62. package/src/mark/index.ts +9 -9
  63. package/src/mark/link.ts +250 -218
  64. package/src/mark/strong.ts +37 -37
  65. package/src/node/blockquote.ts +35 -35
  66. package/src/node/bullet-list.ts +65 -65
  67. package/src/node/code-fence.ts +236 -229
  68. package/src/node/doc.ts +21 -21
  69. package/src/node/hardbreak.ts +108 -107
  70. package/src/node/heading.ts +275 -272
  71. package/src/node/hr.ts +55 -55
  72. package/src/node/image.ts +216 -210
  73. package/src/node/index.ts +38 -38
  74. package/src/node/list-item.ts +139 -140
  75. package/src/node/ordered-list.ts +71 -71
  76. package/src/node/paragraph.ts +55 -53
  77. package/src/node/text.ts +18 -18
  78. package/src/plugin/add-order-in-list.ts +15 -15
  79. package/src/plugin/filter-html.ts +31 -33
  80. package/src/plugin/index.ts +13 -13
  81. package/src/plugin/inline-nodes-cursor.ts +78 -79
  82. package/src/plugin/inline-sync/config.ts +46 -45
  83. package/src/plugin/inline-sync/context.ts +88 -83
  84. package/src/plugin/inline-sync/index.ts +46 -42
  85. package/src/plugin/inline-sync/regexp.ts +2 -2
  86. package/src/plugin/inline-sync/replacer.ts +33 -31
  87. package/src/plugin/inline-sync/utils.ts +53 -55
  88. package/src/supported-keys.ts +22 -21
package/src/mark/link.ts CHANGED
@@ -1,221 +1,253 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { commandsCtx, createCmd, createCmdKey, ThemeInputChipType } from '@milkdown/core';
3
- import { expectDomTypeError, missingRootElement } from '@milkdown/exception';
4
- import { calculateTextPosition } from '@milkdown/prose';
5
- import { toggleMark } from '@milkdown/prose/commands';
6
- import { Node as ProseNode } from '@milkdown/prose/model';
7
- import { NodeSelection, Plugin, PluginKey, TextSelection } from '@milkdown/prose/state';
8
- import { EditorView } from '@milkdown/prose/view';
9
- import { createMark } from '@milkdown/utils';
10
-
11
- const key = new PluginKey('MILKDOWN_LINK_INPUT');
12
-
13
- export const ToggleLink = createCmdKey<string>('ToggleLink');
14
- export const ModifyLink = createCmdKey<string>('ModifyLink');
15
- const id = 'link';
16
- export type LinkOptions = {
17
- input: {
18
- placeholder: string;
19
- buttonText?: string;
20
- };
21
- };
2
+ import type { ThemeInputChipType } from '@milkdown/core'
3
+ import { commandsCtx, createCmd, createCmdKey } from '@milkdown/core'
4
+ import { expectDomTypeError, missingRootElement } from '@milkdown/exception'
5
+ import { calculateTextPosition } from '@milkdown/prose'
6
+ import { toggleMark } from '@milkdown/prose/commands'
7
+ import type { Node as ProseNode } from '@milkdown/prose/model'
8
+ import { NodeSelection, Plugin, PluginKey, TextSelection } from '@milkdown/prose/state'
9
+ import type { EditorView } from '@milkdown/prose/view'
10
+ import { createMark } from '@milkdown/utils'
11
+
12
+ const key = new PluginKey('MILKDOWN_LINK_INPUT')
13
+
14
+ export const ToggleLink = createCmdKey<string>('ToggleLink')
15
+ export const ModifyLink = createCmdKey<string>('ModifyLink')
16
+ const id = 'link'
17
+ export interface LinkOptions {
18
+ input: {
19
+ placeholder?: string
20
+ buttonText?: string
21
+ displayWhenSelected?: boolean
22
+ }
23
+ }
22
24
  export const link = createMark<string, LinkOptions>((utils, options) => {
23
- return {
24
- id,
25
- schema: () => ({
26
- attrs: {
27
- href: {},
28
- title: { default: null },
29
- },
30
- parseDOM: [
31
- {
32
- tag: 'a[href]',
33
- getAttrs: (dom) => {
34
- if (!(dom instanceof HTMLElement)) {
35
- throw expectDomTypeError(dom);
36
- }
37
- return { href: dom.getAttribute('href'), title: dom.getAttribute('title') };
38
- },
39
- },
40
- ],
41
- toDOM: (mark) => ['a', { ...mark.attrs, class: utils.getClassName(mark.attrs, id) }],
42
- parseMarkdown: {
43
- match: (node) => node.type === 'link',
44
- runner: (state, node, markType) => {
45
- const url = node['url'] as string;
46
- const title = node['title'] as string;
47
- state.openMark(markType, { href: url, title });
48
- state.next(node.children);
49
- state.closeMark(markType);
50
- },
51
- },
52
- toMarkdown: {
53
- match: (mark) => mark.type.name === id,
54
- runner: (state, mark) => {
55
- state.withMark(mark, 'link', undefined, {
56
- title: mark.attrs['title'],
57
- url: mark.attrs['href'],
58
- });
59
- },
60
- },
61
- }),
62
- commands: (markType) => [
63
- createCmd(ToggleLink, (href = '') => toggleMark(markType, { href })),
64
- createCmd(ModifyLink, (href = '') => (state, dispatch) => {
65
- if (!dispatch) return false;
66
-
67
- const { marks } = state.schema;
68
-
69
- let node: ProseNode | undefined;
70
- let pos = -1;
71
- const { selection } = state;
72
- const { from, to } = selection;
73
- state.doc.nodesBetween(from, from === to ? to + 1 : to, (n, p) => {
74
- if (marks['link']?.isInSet(n.marks)) {
75
- node = n;
76
- pos = p;
77
- return false;
78
- }
79
- return;
80
- });
81
- if (!node) return false;
82
-
83
- const mark = node.marks.find(({ type }) => type === markType);
84
- if (!mark) return false;
85
-
86
- const start = pos;
87
- const end = pos + node.nodeSize;
88
- const { tr } = state;
89
- const linkMark = marks['link']?.create({ ...mark.attrs, href });
90
- if (!linkMark) return false;
91
- dispatch(
92
- tr
93
- .removeMark(start, end, mark)
94
- .addMark(start, end, linkMark)
95
- .setSelection(new TextSelection(tr.selection.$anchor))
96
- .scrollIntoView(),
97
- );
98
-
99
- return true;
100
- }),
101
- ],
102
- prosePlugins: (type, ctx) => {
103
- let renderOnTop = false;
104
- return [
105
- new Plugin({
106
- key,
107
- view: (editorView) => {
108
- const inputChipRenderer = utils.themeManager.get<ThemeInputChipType>('input-chip', {
109
- placeholder: options?.input?.placeholder ?? 'Input Web Link',
110
- buttonText: options?.input?.buttonText,
111
- onUpdate: (value) => {
112
- ctx.get(commandsCtx).call(ModifyLink, value);
113
- },
114
- calculatePosition: (view, input) => {
115
- calculateTextPosition(view, input, (start, end, target, parent) => {
116
- const $editor = view.dom.parentElement;
117
- if (!$editor) {
118
- throw missingRootElement();
119
- }
120
-
121
- const selectionWidth = end.left - start.left;
122
- let left = start.left - parent.left - (target.width - selectionWidth) / 2;
123
- let top = start.bottom - parent.top + 14 + $editor.scrollTop;
124
-
125
- if (renderOnTop) {
126
- top = start.top - parent.top - target.height - 14 + $editor.scrollTop;
127
- }
128
-
129
- if (left < 0) left = 0;
130
-
131
- return [top, left];
132
- });
133
- },
134
- });
135
- if (!inputChipRenderer) return {};
136
- const shouldDisplay = (view: EditorView) => {
137
- const { selection, doc } = view.state;
138
- const { from, to } = selection;
139
-
140
- if (!view.hasFocus()) {
141
- return false;
142
- }
143
-
144
- if (
145
- selection.empty &&
146
- selection instanceof TextSelection &&
147
- to < doc.content.size &&
148
- from < doc.content.size &&
149
- doc.rangeHasMark(from, from === to ? to + 1 : to, type)
150
- ) {
151
- renderOnTop = false;
152
- return true;
153
- }
154
-
155
- if (selection instanceof NodeSelection) {
156
- const { node } = selection;
157
- if (
158
- node.type.name === 'image' &&
159
- node.marks.findIndex((mark) => mark.type.name === id) > -1
160
- ) {
161
- renderOnTop = true;
162
- return true;
163
- }
164
- }
165
-
166
- return false;
167
- };
168
- const getCurrentLink = (view: EditorView) => {
169
- const { selection } = view.state;
170
- let node: ProseNode | undefined;
171
- const { from, to } = selection;
172
- view.state.doc.nodesBetween(from, from === to ? to + 1 : to, (n) => {
173
- if (type.isInSet(n.marks)) {
174
- node = n;
175
- return false;
176
- }
177
- return;
178
- });
179
- if (!node) return;
180
-
181
- const mark = node.marks.find((m) => m.type === type);
182
- if (!mark) return;
183
-
184
- const value = mark.attrs['href'];
185
- return value;
186
- };
187
- const renderByView = (view: EditorView) => {
188
- if (!view.editable) {
189
- return;
190
- }
191
- const display = shouldDisplay(view);
192
- if (display) {
193
- inputChipRenderer.show(view);
194
- inputChipRenderer.update(getCurrentLink(view));
195
- } else {
196
- inputChipRenderer.hide();
197
- }
198
- };
199
- inputChipRenderer.init(editorView);
200
- renderByView(editorView);
201
-
202
- return {
203
- update: (view, prevState) => {
204
- const isEqualSelection =
205
- prevState?.doc.eq(view.state.doc) && prevState.selection.eq(view.state.selection);
206
- if (isEqualSelection) return;
207
-
208
- requestAnimationFrame(() => {
209
- renderByView(view);
210
- });
211
- },
212
- destroy: () => {
213
- inputChipRenderer.destroy();
214
- },
215
- };
216
- },
217
- }),
218
- ];
25
+ return {
26
+ id,
27
+ schema: () => ({
28
+ attrs: {
29
+ href: {},
30
+ title: { default: null },
31
+ },
32
+ parseDOM: [
33
+ {
34
+ tag: 'a[href]',
35
+ getAttrs: (dom) => {
36
+ if (!(dom instanceof HTMLElement))
37
+ throw expectDomTypeError(dom)
38
+
39
+ return { href: dom.getAttribute('href'), title: dom.getAttribute('title') }
40
+ },
41
+ },
42
+ ],
43
+ toDOM: mark => ['a', { ...mark.attrs, class: utils.getClassName(mark.attrs, id) }],
44
+ parseMarkdown: {
45
+ match: node => node.type === 'link',
46
+ runner: (state, node, markType) => {
47
+ const url = node.url as string
48
+ const title = node.title as string
49
+ state.openMark(markType, { href: url, title })
50
+ state.next(node.children)
51
+ state.closeMark(markType)
52
+ },
53
+ },
54
+ toMarkdown: {
55
+ match: mark => mark.type.name === id,
56
+ runner: (state, mark) => {
57
+ state.withMark(mark, 'link', undefined, {
58
+ title: mark.attrs.title,
59
+ url: mark.attrs.href,
60
+ })
219
61
  },
220
- };
221
- });
62
+ },
63
+ }),
64
+ commands: markType => [
65
+ createCmd(ToggleLink, (href = '') => toggleMark(markType, { href })),
66
+ createCmd(ModifyLink, (href = '') => (state, dispatch) => {
67
+ if (!dispatch)
68
+ return false
69
+
70
+ const { marks } = state.schema
71
+
72
+ let node: ProseNode | undefined
73
+ let pos = -1
74
+ const { selection } = state
75
+ const { from, to } = selection
76
+ state.doc.nodesBetween(from, from === to ? to + 1 : to, (n, p) => {
77
+ if (marks.link?.isInSet(n.marks)) {
78
+ node = n
79
+ pos = p
80
+ return false
81
+ }
82
+
83
+ return undefined
84
+ })
85
+ if (!node)
86
+ return false
87
+
88
+ const mark = node.marks.find(({ type }) => type === markType)
89
+ if (!mark)
90
+ return false
91
+
92
+ const start = pos
93
+ const end = pos + node.nodeSize
94
+ const { tr } = state
95
+ const linkMark = marks.link?.create({ ...mark.attrs, href })
96
+ if (!linkMark)
97
+ return false
98
+ dispatch(
99
+ tr
100
+ .removeMark(start, end, mark)
101
+ .addMark(start, end, linkMark)
102
+ .setSelection(new TextSelection(tr.selection.$anchor))
103
+ .scrollIntoView(),
104
+ )
105
+
106
+ return true
107
+ }),
108
+ ],
109
+ prosePlugins: (type, ctx) => {
110
+ let renderOnTop = false
111
+ return [
112
+ new Plugin({
113
+ key,
114
+ view: (editorView) => {
115
+ const inputChipRenderer = utils.themeManager.get<ThemeInputChipType>('input-chip', {
116
+ placeholder: options?.input?.placeholder ?? 'Input Web Link',
117
+ buttonText: options?.input?.buttonText,
118
+ onUpdate: (value) => {
119
+ ctx.get(commandsCtx).call(ModifyLink, value)
120
+ },
121
+ calculatePosition: (view, input) => {
122
+ calculateTextPosition(view, input, (start, end, target, parent) => {
123
+ const $editor = view.dom.parentElement
124
+ if (!$editor)
125
+ throw missingRootElement()
126
+
127
+ const selectionWidth = end.left - start.left
128
+ let left = start.left - parent.left - (target.width - selectionWidth) / 2
129
+ let top = start.bottom - parent.top + 14 + $editor.scrollTop
130
+
131
+ if (renderOnTop)
132
+ top = start.top - parent.top - target.height - 14 + $editor.scrollTop
133
+
134
+ if (left < 0)
135
+ left = 0
136
+
137
+ const maxLeft = $editor.clientWidth - (target.width + 4)
138
+ if (left > maxLeft)
139
+ left = maxLeft
140
+
141
+ return [top, left]
142
+ })
143
+ },
144
+ })
145
+ if (!inputChipRenderer)
146
+ return {}
147
+ const shouldDisplay = (view: EditorView) => {
148
+ const { selection, doc } = view.state
149
+ const { from, to } = selection
150
+
151
+ if (!view.hasFocus())
152
+ return false
153
+
154
+ if (
155
+ selection instanceof TextSelection
156
+ && to < doc.content.size
157
+ && from < doc.content.size
158
+ && doc.rangeHasMark(from, from === to ? to + 1 : to, type)
159
+ ) {
160
+ let shouldDisplay = selection.empty
161
+ if (options?.input?.displayWhenSelected && !shouldDisplay) {
162
+ doc.nodesBetween(from, from === to ? to + 1 : to, (node, pos) => {
163
+ if (
164
+ node.marks.some(
165
+ mark =>
166
+ mark.type === type && from >= pos && to <= pos + node.nodeSize,
167
+ )
168
+ ) {
169
+ shouldDisplay = true
170
+ return false
171
+ }
172
+
173
+ return undefined
174
+ })
175
+ }
176
+ if (shouldDisplay) {
177
+ renderOnTop = false
178
+ return true
179
+ }
180
+ }
181
+
182
+ if (selection instanceof NodeSelection) {
183
+ const { node } = selection
184
+ if (
185
+ node.type.name === 'image'
186
+ && node.marks.findIndex(mark => mark.type.name === id) > -1
187
+ ) {
188
+ renderOnTop = true
189
+ return true
190
+ }
191
+ }
192
+
193
+ return false
194
+ }
195
+ const getCurrentLink = (view: EditorView) => {
196
+ const { selection } = view.state
197
+ let node: ProseNode | undefined
198
+ const { from, to } = selection
199
+ view.state.doc.nodesBetween(from, from === to ? to + 1 : to, (n) => {
200
+ if (type.isInSet(n.marks)) {
201
+ node = n
202
+ return false
203
+ }
204
+
205
+ return undefined
206
+ })
207
+ if (!node)
208
+ return
209
+
210
+ const mark = node.marks.find(m => m.type === type)
211
+ if (!mark)
212
+ return
213
+
214
+ const value = mark.attrs.href
215
+ return value
216
+ }
217
+ const renderByView = (view: EditorView) => {
218
+ if (!view.editable)
219
+ return
220
+
221
+ const display = shouldDisplay(view)
222
+ if (display) {
223
+ inputChipRenderer.show(view)
224
+ inputChipRenderer.update(getCurrentLink(view))
225
+ }
226
+ else {
227
+ inputChipRenderer.hide()
228
+ }
229
+ }
230
+ inputChipRenderer.init(editorView)
231
+ renderByView(editorView)
232
+
233
+ return {
234
+ update: (view, prevState) => {
235
+ const isEqualSelection
236
+ = prevState?.doc.eq(view.state.doc) && prevState.selection.eq(view.state.selection)
237
+ if (isEqualSelection)
238
+ return
239
+
240
+ requestAnimationFrame(() => {
241
+ renderByView(view)
242
+ })
243
+ },
244
+ destroy: () => {
245
+ inputChipRenderer.destroy()
246
+ },
247
+ }
248
+ },
249
+ }),
250
+ ]
251
+ },
252
+ }
253
+ })
@@ -1,42 +1,42 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey } from '@milkdown/core';
3
- import { toggleMark } from '@milkdown/prose/commands';
4
- import { createMark, createShortcut } from '@milkdown/utils';
2
+ import { createCmd, createCmdKey } from '@milkdown/core'
3
+ import { toggleMark } from '@milkdown/prose/commands'
4
+ import { createMark, createShortcut } from '@milkdown/utils'
5
5
 
6
- import { SupportedKeys } from '../supported-keys';
6
+ import { SupportedKeys } from '../supported-keys'
7
7
 
8
- type Keys = SupportedKeys['Bold'];
9
- const id = 'strong';
10
- export const ToggleBold = createCmdKey('ToggleBold');
8
+ type Keys = SupportedKeys['Bold']
9
+ const id = 'strong'
10
+ export const ToggleBold = createCmdKey('ToggleBold')
11
11
  export const strong = createMark<Keys>((utils) => {
12
- return {
13
- id,
14
- schema: () => ({
15
- inclusive: false,
16
- parseDOM: [
17
- { tag: 'b' },
18
- { tag: 'strong' },
19
- { style: 'font-style', getAttrs: (value) => (value === 'bold') as false },
20
- ],
21
- toDOM: (mark) => ['strong', { class: utils.getClassName(mark.attrs, id) }],
22
- parseMarkdown: {
23
- match: (node) => node.type === 'strong',
24
- runner: (state, node, markType) => {
25
- state.openMark(markType);
26
- state.next(node.children);
27
- state.closeMark(markType);
28
- },
29
- },
30
- toMarkdown: {
31
- match: (mark) => mark.type.name === id,
32
- runner: (state, mark) => {
33
- state.withMark(mark, 'strong');
34
- },
35
- },
36
- }),
37
- commands: (markType) => [createCmd(ToggleBold, () => toggleMark(markType))],
38
- shortcuts: {
39
- [SupportedKeys.Bold]: createShortcut(ToggleBold, 'Mod-b'),
12
+ return {
13
+ id,
14
+ schema: () => ({
15
+ inclusive: false,
16
+ parseDOM: [
17
+ { tag: 'b' },
18
+ { tag: 'strong' },
19
+ { style: 'font-style', getAttrs: value => (value === 'bold') as false },
20
+ ],
21
+ toDOM: mark => ['strong', { class: utils.getClassName(mark.attrs, id) }],
22
+ parseMarkdown: {
23
+ match: node => node.type === 'strong',
24
+ runner: (state, node, markType) => {
25
+ state.openMark(markType)
26
+ state.next(node.children)
27
+ state.closeMark(markType)
40
28
  },
41
- };
42
- });
29
+ },
30
+ toMarkdown: {
31
+ match: mark => mark.type.name === id,
32
+ runner: (state, mark) => {
33
+ state.withMark(mark, 'strong')
34
+ },
35
+ },
36
+ }),
37
+ commands: markType => [createCmd(ToggleBold, () => toggleMark(markType))],
38
+ shortcuts: {
39
+ [SupportedKeys.Bold]: createShortcut(ToggleBold, 'Mod-b'),
40
+ },
41
+ }
42
+ })
@@ -1,43 +1,43 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey } from '@milkdown/core';
3
- import { wrapIn } from '@milkdown/prose/commands';
4
- import { wrappingInputRule } from '@milkdown/prose/inputrules';
5
- import { createNode, createShortcut } from '@milkdown/utils';
2
+ import { createCmd, createCmdKey } from '@milkdown/core'
3
+ import { wrapIn } from '@milkdown/prose/commands'
4
+ import { wrappingInputRule } from '@milkdown/prose/inputrules'
5
+ import { createNode, createShortcut } from '@milkdown/utils'
6
6
 
7
- import { SupportedKeys } from '../supported-keys';
7
+ import { SupportedKeys } from '../supported-keys'
8
8
 
9
- type Keys = SupportedKeys['Blockquote'];
9
+ type Keys = SupportedKeys['Blockquote']
10
10
 
11
- const id = 'blockquote';
11
+ const id = 'blockquote'
12
12
 
13
- export const WrapInBlockquote = createCmdKey('WrapInBlockquote');
13
+ export const WrapInBlockquote = createCmdKey('WrapInBlockquote')
14
14
 
15
15
  export const blockquote = createNode<Keys>((utils) => {
16
- return {
17
- id,
18
- schema: () => ({
19
- content: 'block+',
20
- group: 'block',
21
- defining: true,
22
- parseDOM: [{ tag: 'blockquote' }],
23
- toDOM: (node) => ['blockquote', { class: utils.getClassName(node.attrs, id) }, 0],
24
- parseMarkdown: {
25
- match: ({ type }) => type === id,
26
- runner: (state, node, type) => {
27
- state.openNode(type).next(node.children).closeNode();
28
- },
29
- },
30
- toMarkdown: {
31
- match: (node) => node.type.name === id,
32
- runner: (state, node) => {
33
- state.openNode('blockquote').next(node.content).closeNode();
34
- },
35
- },
36
- }),
37
- inputRules: (nodeType) => [wrappingInputRule(/^\s*>\s$/, nodeType)],
38
- commands: (nodeType) => [createCmd(WrapInBlockquote, () => wrapIn(nodeType))],
39
- shortcuts: {
40
- [SupportedKeys.Blockquote]: createShortcut(WrapInBlockquote, 'Mod-Shift-b'),
16
+ return {
17
+ id,
18
+ schema: () => ({
19
+ content: 'block+',
20
+ group: 'block',
21
+ defining: true,
22
+ parseDOM: [{ tag: 'blockquote' }],
23
+ toDOM: node => ['blockquote', { class: utils.getClassName(node.attrs, id) }, 0],
24
+ parseMarkdown: {
25
+ match: ({ type }) => type === id,
26
+ runner: (state, node, type) => {
27
+ state.openNode(type).next(node.children).closeNode()
41
28
  },
42
- };
43
- });
29
+ },
30
+ toMarkdown: {
31
+ match: node => node.type.name === id,
32
+ runner: (state, node) => {
33
+ state.openNode('blockquote').next(node.content).closeNode()
34
+ },
35
+ },
36
+ }),
37
+ inputRules: nodeType => [wrappingInputRule(/^\s*>\s$/, nodeType)],
38
+ commands: nodeType => [createCmd(WrapInBlockquote, () => wrapIn(nodeType))],
39
+ shortcuts: {
40
+ [SupportedKeys.Blockquote]: createShortcut(WrapInBlockquote, 'Mod-Shift-b'),
41
+ },
42
+ }
43
+ })