@milkdown/preset-commonmark 5.5.0 → 6.0.0-next.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.
Files changed (84) hide show
  1. package/README.md +5 -4
  2. package/lib/index.d.ts +34 -1
  3. package/lib/index.d.ts.map +1 -0
  4. package/lib/index.es.js +260 -523
  5. package/lib/index.es.js.map +1 -1
  6. package/lib/{src/mark → mark}/code-inline.d.ts +1 -1
  7. package/lib/mark/code-inline.d.ts.map +1 -0
  8. package/lib/{src/mark → mark}/em.d.ts +1 -1
  9. package/lib/mark/em.d.ts.map +1 -0
  10. package/lib/mark/index.d.ts +6 -0
  11. package/lib/mark/index.d.ts.map +1 -0
  12. package/lib/{src/mark → mark}/link.d.ts +7 -1
  13. package/lib/mark/link.d.ts.map +1 -0
  14. package/lib/{src/mark → mark}/strong.d.ts +1 -1
  15. package/lib/mark/strong.d.ts.map +1 -0
  16. package/lib/{src/node → node}/blockquote.d.ts +1 -1
  17. package/lib/node/blockquote.d.ts.map +1 -0
  18. package/lib/{src/node → node}/bullet-list.d.ts +1 -1
  19. package/lib/node/bullet-list.d.ts.map +1 -0
  20. package/lib/{src/node → node}/code-fence.d.ts +1 -1
  21. package/lib/node/code-fence.d.ts.map +1 -0
  22. package/lib/{src/node → node}/doc.d.ts +1 -1
  23. package/lib/node/doc.d.ts.map +1 -0
  24. package/lib/{src/node → node}/hardbreak.d.ts +1 -1
  25. package/lib/node/hardbreak.d.ts.map +1 -0
  26. package/lib/{src/node → node}/heading.d.ts +1 -1
  27. package/lib/node/heading.d.ts.map +1 -0
  28. package/lib/{src/node → node}/hr.d.ts +1 -1
  29. package/lib/node/hr.d.ts.map +1 -0
  30. package/lib/{src/node → node}/image.d.ts +5 -5
  31. package/lib/node/image.d.ts.map +1 -0
  32. package/lib/{src/node → node}/index.d.ts +2 -2
  33. package/lib/node/index.d.ts.map +1 -0
  34. package/lib/{src/node → node}/list-item.d.ts +1 -1
  35. package/lib/node/list-item.d.ts.map +1 -0
  36. package/lib/{src/node → node}/ordered-list.d.ts +1 -1
  37. package/lib/node/ordered-list.d.ts.map +1 -0
  38. package/lib/{src/node → node}/paragraph.d.ts +1 -1
  39. package/lib/node/paragraph.d.ts.map +1 -0
  40. package/lib/{src/node → node}/text.d.ts +1 -1
  41. package/lib/node/text.d.ts.map +1 -0
  42. package/lib/{src/plugin → plugin}/filter-html.d.ts +0 -0
  43. package/lib/plugin/filter-html.d.ts.map +1 -0
  44. package/lib/plugin/index.d.ts +2 -0
  45. package/lib/plugin/index.d.ts.map +1 -0
  46. package/lib/{src/supported-keys.d.ts → supported-keys.d.ts} +0 -0
  47. package/lib/supported-keys.d.ts.map +1 -0
  48. package/package.json +33 -10
  49. package/src/mark/code-inline.ts +1 -12
  50. package/src/mark/link.ts +92 -18
  51. package/src/mark/strong.ts +1 -7
  52. package/src/node/blockquote.ts +1 -14
  53. package/src/node/code-fence.ts +75 -183
  54. package/src/node/heading.ts +1 -41
  55. package/src/node/hr.ts +1 -8
  56. package/src/node/image.ts +80 -232
  57. package/src/node/list-item.ts +34 -53
  58. package/src/node/paragraph.ts +1 -9
  59. package/lib/src/index.d.ts +0 -34
  60. package/lib/src/index.d.ts.map +0 -1
  61. package/lib/src/mark/code-inline.d.ts.map +0 -1
  62. package/lib/src/mark/em.d.ts.map +0 -1
  63. package/lib/src/mark/index.d.ts +0 -6
  64. package/lib/src/mark/index.d.ts.map +0 -1
  65. package/lib/src/mark/link.d.ts.map +0 -1
  66. package/lib/src/mark/strong.d.ts.map +0 -1
  67. package/lib/src/node/blockquote.d.ts.map +0 -1
  68. package/lib/src/node/bullet-list.d.ts.map +0 -1
  69. package/lib/src/node/code-fence.d.ts.map +0 -1
  70. package/lib/src/node/doc.d.ts.map +0 -1
  71. package/lib/src/node/hardbreak.d.ts.map +0 -1
  72. package/lib/src/node/heading.d.ts.map +0 -1
  73. package/lib/src/node/hr.d.ts.map +0 -1
  74. package/lib/src/node/image.d.ts.map +0 -1
  75. package/lib/src/node/index.d.ts.map +0 -1
  76. package/lib/src/node/list-item.d.ts.map +0 -1
  77. package/lib/src/node/ordered-list.d.ts.map +0 -1
  78. package/lib/src/node/paragraph.d.ts.map +0 -1
  79. package/lib/src/node/text.d.ts.map +0 -1
  80. package/lib/src/plugin/filter-html.d.ts.map +0 -1
  81. package/lib/src/plugin/index.d.ts +0 -2
  82. package/lib/src/plugin/index.d.ts.map +0 -1
  83. package/lib/src/supported-keys.d.ts.map +0 -1
  84. package/lib/src/types.d.ts +0 -5
@@ -1,5 +1,5 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { createCmd, createCmdKey, themeToolCtx } from '@milkdown/core';
2
+ import { createCmd, createCmdKey, editorViewCtx, ThemeCodeFenceType } from '@milkdown/core';
3
3
  import { setBlockType, textblockTypeInputRule } from '@milkdown/prose';
4
4
  import { createNode, createShortcut } from '@milkdown/utils';
5
5
 
@@ -33,119 +33,11 @@ export const TurnIntoCodeFence = createCmdKey('TurnIntoCodeFence');
33
33
 
34
34
  const id = 'fence';
35
35
  export const codeFence = createNode<Keys, { languageList?: string[] }>((utils, options) => {
36
- const style = utils.getStyle(({ palette, mixin, size, font }, { css }) => {
37
- const { shadow, scrollbar, border } = mixin;
38
- const { lineWidth, radius } = size;
39
- return css`
40
- background-color: ${palette('background')};
41
- color: ${palette('neutral')};
42
- font-size: 0.85rem;
43
- padding: 1.2rem 0.4rem 1.4rem;
44
- border-radius: ${radius};
45
- font-family: ${font.typography};
46
-
47
- * {
48
- margin: 0;
49
- }
50
-
51
- .code-fence_select-wrapper {
52
- position: relative;
53
- }
54
-
55
- .code-fence_value {
56
- width: 10.25rem;
57
- box-sizing: border-box;
58
- border-radius: ${size.radius};
59
- margin: 0 1.2rem 1.2rem;
60
- ${border()};
61
- ${shadow()};
62
- cursor: pointer;
63
- background-color: ${palette('surface')};
64
- position: relative;
65
- display: flex;
66
- color: ${palette('neutral', 0.87)};
67
- letter-spacing: 0.5px;
68
- height: 2.625rem;
69
- align-items: center;
70
-
71
- & > .icon {
72
- width: 2.625rem;
73
- height: 100%;
74
- display: flex;
75
- justify-content: center;
76
- align-items: center;
77
- color: ${palette('solid', 0.87)};
78
- border-left: ${lineWidth} solid ${palette('line')};
79
-
80
- text-align: center;
81
- transition: all 0.2s ease-in-out;
82
- &:hover {
83
- background: ${palette('background')};
84
- color: ${palette('primary')};
85
- }
86
- }
87
-
88
- > span:first-child {
89
- padding-left: 1rem;
90
- flex: 1;
91
- font-weight: 500;
92
- }
93
- }
94
-
95
- .code-fence_select-option {
96
- list-style: none;
97
- line-height: 2rem;
98
- padding-left: 1rem;
99
- cursor: pointer;
100
- :hover {
101
- background: ${palette('secondary', 0.12)};
102
- color: ${palette('primary')};
103
- }
104
- }
105
-
106
- .code-fence_select {
107
- &[data-fold='true'] {
108
- display: none;
109
- }
110
-
111
- font-weight: 500;
112
- position: absolute;
113
- z-index: 1;
114
- top: 2.625rem;
115
- box-sizing: border-box;
116
- left: 1.2rem;
117
- padding: 0.5rem 0;
118
- max-height: 16.75rem;
119
- width: 10.25rem;
120
- ${border()};
121
- ${shadow()};
122
- background-color: ${palette('surface')};
123
- border-top: none;
124
- overflow-y: auto;
125
- display: flex;
126
- flex-direction: column;
127
-
128
- ${scrollbar('y')}
129
- }
130
-
131
- code {
132
- line-height: 1.5;
133
- font-family: ${font.code};
134
- }
135
-
136
- pre {
137
- font-family: ${font.code};
138
- margin: 0 1.2rem !important;
139
- white-space: pre;
140
- overflow: auto;
141
- ${scrollbar('x')};
142
- }
143
- `;
144
- });
36
+ const languageList = options?.languageList || languageOptions;
145
37
 
146
38
  return {
147
39
  id,
148
- schema: () => ({
40
+ schema: (ctx) => ({
149
41
  content: 'text*',
150
42
  group: 'block',
151
43
  marks: '',
@@ -172,13 +64,54 @@ export const codeFence = createNode<Keys, { languageList?: string[] }>((utils, o
172
64
  },
173
65
  ],
174
66
  toDOM: (node) => {
67
+ const select = document.createElement('select');
68
+ languageList.forEach((lang) => {
69
+ const option = document.createElement('option');
70
+ option.value = lang;
71
+ option.innerText = !lang ? '--' : lang;
72
+ if (lang === node.attrs['language']) {
73
+ option.selected = true;
74
+ }
75
+ select.appendChild(option);
76
+ });
77
+ select.onchange = (e) => {
78
+ const target = e.target;
79
+ if (!(target instanceof HTMLSelectElement)) {
80
+ return;
81
+ }
82
+ const view = ctx.get(editorViewCtx);
83
+ if (!view.editable) {
84
+ target.value = node.attrs['language'];
85
+ return;
86
+ }
87
+
88
+ const { top, left } = target.getBoundingClientRect();
89
+ const result = view.posAtCoords({ top, left });
90
+ if (!result) return;
91
+
92
+ const { tr } = view.state;
93
+
94
+ view.dispatch(
95
+ tr.setNodeMarkup(result.inside, undefined, {
96
+ ...node.attrs,
97
+ language: target.value,
98
+ }),
99
+ );
100
+ };
175
101
  return [
176
- 'pre',
102
+ 'div',
177
103
  {
178
- 'data-language': node.attrs['language'],
179
- class: utils.getClassName(node.attrs, 'code-fence', style),
104
+ class: 'code-fence-container',
180
105
  },
181
- ['code', { spellCheck: 'false' }, 0],
106
+ select,
107
+ [
108
+ 'pre',
109
+ {
110
+ 'data-language': node.attrs['language'],
111
+ class: utils.getClassName(node.attrs, 'code-fence'),
112
+ },
113
+ ['code', { spellCheck: 'false' }, 0],
114
+ ],
182
115
  ];
183
116
  },
184
117
  parseMarkdown: {
@@ -218,103 +151,62 @@ export const codeFence = createNode<Keys, { languageList?: string[] }>((utils, o
218
151
  shortcuts: {
219
152
  [SupportedKeys.CodeFence]: createShortcut(TurnIntoCodeFence, 'Mod-Alt-c'),
220
153
  },
221
- view: (ctx) => (node, view, getPos) => {
222
- const container = document.createElement('div');
223
- const selectWrapper = document.createElement('div');
224
- const select = document.createElement('ul');
225
- const pre = document.createElement('pre');
226
- const code = document.createElement('code');
154
+ view: () => (node, view, getPos) => {
155
+ let currNode = node;
227
156
 
228
- const valueWrapper = document.createElement('div');
229
- valueWrapper.className = 'code-fence_value';
230
- const value = document.createElement('span');
231
- valueWrapper.appendChild(value);
232
- if (view.editable) {
233
- valueWrapper.appendChild(ctx.get(themeToolCtx).slots.icon('downArrow'));
234
- }
235
-
236
- select.className = 'code-fence_select';
237
- select.addEventListener('mousedown', (e) => {
238
- e.preventDefault();
239
- e.stopPropagation();
240
-
241
- if (!view.editable) return;
242
-
243
- const el = e.target;
244
- if (!(el instanceof HTMLLIElement)) return;
157
+ const onSelectLanguage = (language: string) => {
245
158
  const { tr } = view.state;
246
-
247
159
  view.dispatch(
248
160
  tr.setNodeMarkup(getPos(), undefined, {
249
161
  fold: true,
250
- language: el.dataset['value'],
162
+ language,
251
163
  }),
252
164
  );
253
- });
254
- valueWrapper.addEventListener('mousedown', (e) => {
255
- e.preventDefault();
256
- e.stopPropagation();
257
-
258
- if (!view.editable) return;
165
+ };
166
+ const onBlur = () => {
259
167
  const { tr } = view.state;
260
168
 
261
169
  view.dispatch(
262
170
  tr.setNodeMarkup(getPos(), undefined, {
263
- fold: false,
264
- language: container.dataset['language'],
171
+ ...currNode.attrs,
172
+ fold: true,
265
173
  }),
266
174
  );
267
- });
268
- document.addEventListener('mousedown', () => {
269
- if (!view.editable || select.dataset['fold'] === 'true') return;
270
-
175
+ };
176
+ const onFocus = () => {
271
177
  const { tr } = view.state;
272
178
 
273
179
  view.dispatch(
274
180
  tr.setNodeMarkup(getPos(), undefined, {
275
- fold: true,
276
- language: container.dataset['language'],
181
+ ...currNode.attrs,
182
+ fold: false,
277
183
  }),
278
184
  );
279
- });
185
+ };
280
186
 
281
- (options?.languageList || languageOptions).forEach((lang) => {
282
- const option = document.createElement('li');
283
- option.className = 'code-fence_select-option';
284
- option.innerText = lang || '--';
285
- select.appendChild(option);
286
- option.setAttribute('data-value', lang);
187
+ const renderer = utils.themeManager.get<ThemeCodeFenceType>('code-fence', {
188
+ onBlur,
189
+ onFocus,
190
+ onSelectLanguage,
191
+ editable: () => view.editable,
192
+ languageList,
287
193
  });
194
+ if (!renderer) return {};
288
195
 
289
- code.spellcheck = false;
290
- selectWrapper.className = 'code-fence_select-wrapper';
291
- selectWrapper.contentEditable = 'false';
292
- selectWrapper.append(valueWrapper);
293
- selectWrapper.append(select);
294
- pre.append(code);
295
- const codeContent = document.createElement('div');
296
- code.append(codeContent);
297
- codeContent.style.whiteSpace = 'inherit';
298
-
299
- container.append(selectWrapper, pre);
300
- container.setAttribute('class', utils.getClassName(node.attrs, 'code-fence', style));
301
- container.setAttribute('data-language', node.attrs['language']);
302
- value.innerText = node.attrs['language'] || '--';
303
- select.setAttribute('data-fold', node.attrs['fold'] ? 'true' : 'false');
196
+ const { dom, contentDOM, onUpdate, onDestroy } = renderer;
197
+ onUpdate(currNode);
304
198
 
305
199
  return {
306
- dom: container,
307
- contentDOM: codeContent,
200
+ dom,
201
+ contentDOM,
308
202
  update: (updatedNode) => {
309
203
  if (updatedNode.type.name !== id) return false;
310
-
311
- const lang = updatedNode.attrs['language'];
312
- container.dataset['language'] = lang;
313
- value.innerText = lang || '--';
314
- select.setAttribute('data-fold', updatedNode.attrs['fold'] ? 'true' : 'false');
204
+ currNode = updatedNode;
205
+ onUpdate(currNode);
315
206
 
316
207
  return true;
317
208
  },
209
+ destroy: onDestroy,
318
210
  };
319
211
  },
320
212
  };
@@ -32,42 +32,6 @@ export const headingPluginKey = new PluginKey('MILKDOWN_PLUGIN_ID');
32
32
  export const heading = createNode<Keys>((utils) => {
33
33
  const id = 'heading';
34
34
 
35
- const style = (level: number) =>
36
- utils.getStyle((_, { css }) => {
37
- const headingMap: Record<number, string> = {
38
- 1: css`
39
- font-size: 3rem;
40
- line-height: 3.5rem;
41
- `,
42
- 2: css`
43
- font-size: 2.5rem;
44
- line-height: 3rem;
45
- `,
46
- 3: css`
47
- font-size: 2.125rem;
48
- line-height: 2.25rem;
49
- `,
50
- 4: css`
51
- font-size: 1.75rem;
52
- line-height: 2rem;
53
- `,
54
- 5: css`
55
- font-size: 1.5rem;
56
- line-height: 1.5rem;
57
- `,
58
- 6: css`
59
- font-size: 1.25rem;
60
- line-height: 1.25rem;
61
- `,
62
- };
63
-
64
- return css`
65
- ${headingMap[level] || ''}
66
- margin: 2.5rem 0 !important;
67
- font-weight: 400;
68
- `;
69
- });
70
-
71
35
  return {
72
36
  id,
73
37
  schema: () => ({
@@ -96,11 +60,7 @@ export const heading = createNode<Keys>((utils) => {
96
60
  `h${node.attrs['level']}`,
97
61
  {
98
62
  id: node.attrs['id'] || node.textContent.split(' ').join('-').toLocaleLowerCase(),
99
- class: utils.getClassName(
100
- node.attrs,
101
- `heading h${node.attrs['level']}`,
102
- style(node.attrs['level']),
103
- ),
63
+ class: utils.getClassName(node.attrs, `heading h${node.attrs['level']}`),
104
64
  },
105
65
  0,
106
66
  ];
package/src/node/hr.ts CHANGED
@@ -6,19 +6,12 @@ import { createNode } from '@milkdown/utils';
6
6
  const id = 'hr';
7
7
  export const InsertHr = createCmdKey<string>('InsertHr');
8
8
  export const hr = createNode((utils) => {
9
- const style = utils.getStyle(
10
- (themeTool, { css }) => css`
11
- height: ${themeTool.size.lineWidth};
12
- background-color: ${themeTool.palette('line')};
13
- border-width: 0;
14
- `,
15
- );
16
9
  return {
17
10
  id,
18
11
  schema: () => ({
19
12
  group: 'block',
20
13
  parseDOM: [{ tag: 'hr' }],
21
- toDOM: (node) => ['hr', { class: utils.getClassName(node.attrs, id, style) }],
14
+ toDOM: (node) => ['hr', { class: utils.getClassName(node.attrs, id) }],
22
15
  parseMarkdown: {
23
16
  match: ({ type }) => type === 'thematicBreak',
24
17
  runner: (state, _, type) => {