@prosekit/extensions 0.11.7 → 0.12.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/dist/{drop-indicator-E7nCfdnR.js → drop-indicator-BMvWUDXz.js} +2 -2
- package/dist/{drop-indicator-E7nCfdnR.js.map → drop-indicator-BMvWUDXz.js.map} +1 -1
- package/dist/{enter-rule-5tkoU2Ir.js → enter-rule-D-p4ykfv.js} +2 -2
- package/dist/{enter-rule-5tkoU2Ir.js.map → enter-rule-D-p4ykfv.js.map} +1 -1
- package/dist/{file-nRyo7PMB.js → file-DKoIIa7q.js} +2 -2
- package/dist/{file-nRyo7PMB.js.map → file-DKoIIa7q.js.map} +1 -1
- package/dist/{index-DY6lIIYV.d.ts → index-DdjnBeho.d.ts} +2 -2
- package/dist/index-DdjnBeho.d.ts.map +1 -0
- package/dist/{input-rule-DO_iy2aT.js → input-rule-COGr_GBb.js} +2 -2
- package/dist/{input-rule-DO_iy2aT.js.map → input-rule-COGr_GBb.js.map} +1 -1
- package/dist/{mark-rule-CGmswjQ_.js → mark-rule-v2E7B4C0.js} +2 -2
- package/dist/{mark-rule-CGmswjQ_.js.map → mark-rule-v2E7B4C0.js.map} +1 -1
- package/dist/{paste-rule-Brej6cWi.js → paste-rule-qSz46pqD.js} +2 -2
- package/dist/{paste-rule-Brej6cWi.js.map → paste-rule-qSz46pqD.js.map} +1 -1
- package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -1
- package/dist/prosekit-extensions-blockquote.d.ts.map +1 -1
- package/dist/prosekit-extensions-blockquote.js +1 -1
- package/dist/prosekit-extensions-bold.d.ts.map +1 -1
- package/dist/prosekit-extensions-bold.js +1 -1
- package/dist/prosekit-extensions-code-block.d.ts +1 -1
- package/dist/prosekit-extensions-code-block.d.ts.map +1 -1
- package/dist/prosekit-extensions-code-block.js +2 -2
- package/dist/prosekit-extensions-code.d.ts.map +1 -1
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-commit.d.ts.map +1 -1
- package/dist/prosekit-extensions-doc.d.ts.map +1 -1
- package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -1
- package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -1
- package/dist/prosekit-extensions-drop-indicator.js +1 -1
- package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-enter-rule.js +1 -1
- package/dist/prosekit-extensions-file.d.ts +1 -1
- package/dist/prosekit-extensions-file.js +1 -1
- package/dist/prosekit-extensions-hard-break.d.ts.map +1 -1
- package/dist/prosekit-extensions-heading.d.ts.map +1 -1
- package/dist/prosekit-extensions-heading.js +1 -1
- package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-horizontal-rule.js +1 -1
- package/dist/prosekit-extensions-image.d.ts +1 -1
- package/dist/prosekit-extensions-image.d.ts.map +1 -1
- package/dist/prosekit-extensions-image.js +1 -1
- package/dist/prosekit-extensions-input-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-input-rule.js +1 -1
- package/dist/prosekit-extensions-italic.d.ts.map +1 -1
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.d.ts.map +1 -1
- package/dist/prosekit-extensions-link.js +4 -4
- package/dist/prosekit-extensions-list.d.ts.map +1 -1
- package/dist/prosekit-extensions-list.js +36 -7
- package/dist/prosekit-extensions-list.js.map +1 -1
- package/dist/prosekit-extensions-loro.d.ts.map +1 -1
- package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-mention.d.ts.map +1 -1
- package/dist/prosekit-extensions-paragraph.d.ts.map +1 -1
- package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-paste-rule.js +1 -1
- package/dist/prosekit-extensions-placeholder.d.ts.map +1 -1
- package/dist/prosekit-extensions-placeholder.js +2 -2
- package/dist/prosekit-extensions-search.d.ts.map +1 -1
- package/dist/prosekit-extensions-strike.d.ts.map +1 -1
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.d.ts.map +1 -1
- package/dist/prosekit-extensions-table.js +2 -2
- package/dist/prosekit-extensions-text-align.d.ts.map +1 -1
- package/dist/prosekit-extensions-text.d.ts.map +1 -1
- package/dist/prosekit-extensions-underline.d.ts.map +1 -1
- package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
- package/dist/{shiki-highlighter-chunk-Cwu1Jr9o.d.ts → shiki-highlighter-chunk-DcY3Ud8v.d.ts} +2 -2
- package/dist/shiki-highlighter-chunk-DcY3Ud8v.d.ts.map +1 -0
- package/dist/shiki-highlighter-chunk.d.ts +1 -1
- package/dist/{table-DND_1127.js → table-BLjD91VB.js} +3 -3
- package/dist/{table-DND_1127.js.map → table-BLjD91VB.js.map} +1 -1
- package/package.json +14 -14
- package/src/link/index.spec.ts +1 -1
- package/src/list/list-serializer.ts +57 -3
- package/src/list/list.spec.ts +129 -0
- package/src/testing/keyboard.ts +1 -1
- package/src/testing/markdown.ts +3 -0
- package/dist/index-DY6lIIYV.d.ts.map +0 -1
- package/dist/shiki-highlighter-chunk-Cwu1Jr9o.d.ts.map +0 -1
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type PlainExtension,
|
|
5
5
|
} from '@prosekit/core'
|
|
6
6
|
import {
|
|
7
|
+
findCheckboxInListItem,
|
|
7
8
|
joinListElements,
|
|
8
9
|
listToDOM,
|
|
9
10
|
} from 'prosemirror-flat-list'
|
|
@@ -16,13 +17,15 @@ export function defineListSerializer(): PlainExtension {
|
|
|
16
17
|
serializeFragmentWrapper: (fn) => {
|
|
17
18
|
return (...args) => {
|
|
18
19
|
const dom = fn(...args)
|
|
19
|
-
return joinListElements(dom)
|
|
20
|
+
return normalizeElementTree(joinListElements(dom))
|
|
20
21
|
}
|
|
21
22
|
},
|
|
22
23
|
serializeNodeWrapper: (fn) => {
|
|
23
24
|
return (...args) => {
|
|
24
25
|
const dom = fn(...args)
|
|
25
|
-
return isElementLike(dom)
|
|
26
|
+
return isElementLike(dom)
|
|
27
|
+
? normalizeElementTree(joinListElements(dom))
|
|
28
|
+
: dom
|
|
26
29
|
}
|
|
27
30
|
},
|
|
28
31
|
nodesFromSchemaWrapper: (fn) => {
|
|
@@ -30,9 +33,60 @@ export function defineListSerializer(): PlainExtension {
|
|
|
30
33
|
const nodes = fn(...args)
|
|
31
34
|
return {
|
|
32
35
|
...nodes,
|
|
33
|
-
list: (node) => listToDOM({ node, nativeList: true
|
|
36
|
+
list: (node) => listToDOM({ node, nativeList: true }),
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
},
|
|
37
40
|
})
|
|
38
41
|
}
|
|
42
|
+
|
|
43
|
+
function normalizeElementTree<T extends Element | DocumentFragment>(
|
|
44
|
+
node: T,
|
|
45
|
+
): T {
|
|
46
|
+
if (isElementLike(node)) {
|
|
47
|
+
normalizeTaskList(node)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const child of node.children) {
|
|
51
|
+
normalizeElementTree(child)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return node
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Modifies the DOM tree for task lists to ensure that the output HTML can be
|
|
59
|
+
* parsed by rehype-remark.
|
|
60
|
+
*/
|
|
61
|
+
function normalizeTaskList(node: Element): void {
|
|
62
|
+
if (
|
|
63
|
+
!node.classList.contains('prosemirror-flat-list')
|
|
64
|
+
|| node.getAttribute('data-list-kind') !== 'task'
|
|
65
|
+
|| node.children.length !== 2
|
|
66
|
+
) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const marker = node.children.item(0)
|
|
71
|
+
if (!marker || !marker.classList.contains('list-marker')) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const checkbox = findCheckboxInListItem(marker)
|
|
76
|
+
if (!checkbox) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const content = node.children.item(1)
|
|
81
|
+
if (!content || !content.classList.contains('list-content')) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const textBlock = content.children.item(0)
|
|
86
|
+
if (!textBlock || !['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(textBlock.tagName)) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
node.replaceChildren(...content.children)
|
|
91
|
+
textBlock.prepend(checkbox)
|
|
92
|
+
}
|
package/src/list/list.spec.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createEditor,
|
|
3
|
+
nodeFromHTML,
|
|
3
4
|
union,
|
|
4
5
|
} from '@prosekit/core'
|
|
5
6
|
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
@@ -12,6 +13,11 @@ import {
|
|
|
12
13
|
import { defineDoc } from '../doc'
|
|
13
14
|
import { defineParagraph } from '../paragraph'
|
|
14
15
|
import { setupTest } from '../testing'
|
|
16
|
+
import { formatHTML } from '../testing/format-html'
|
|
17
|
+
import {
|
|
18
|
+
htmlFromMarkdown,
|
|
19
|
+
markdownFromHTML,
|
|
20
|
+
} from '../testing/markdown'
|
|
15
21
|
import { defineText } from '../text'
|
|
16
22
|
|
|
17
23
|
import { defineList } from './index'
|
|
@@ -116,6 +122,10 @@ describe('defineList', () => {
|
|
|
116
122
|
data-list-checked
|
|
117
123
|
>
|
|
118
124
|
<p>
|
|
125
|
+
<input
|
|
126
|
+
type="checkbox"
|
|
127
|
+
checked
|
|
128
|
+
>
|
|
119
129
|
Checked 1
|
|
120
130
|
</p>
|
|
121
131
|
</li>
|
|
@@ -124,6 +134,7 @@ describe('defineList', () => {
|
|
|
124
134
|
data-list-kind="task"
|
|
125
135
|
>
|
|
126
136
|
<p>
|
|
137
|
+
<input type="checkbox">
|
|
127
138
|
Unchecked 2
|
|
128
139
|
</p>
|
|
129
140
|
</li>
|
|
@@ -131,4 +142,122 @@ describe('defineList', () => {
|
|
|
131
142
|
"
|
|
132
143
|
`)
|
|
133
144
|
})
|
|
145
|
+
|
|
146
|
+
it('can generate html that can be parsed by remark', () => {
|
|
147
|
+
const { editor, n } = setupTest()
|
|
148
|
+
|
|
149
|
+
const doc1 = n.doc(
|
|
150
|
+
n.bullet(n.paragraph('Bullet')),
|
|
151
|
+
n.ordered(n.paragraph('Ordered')),
|
|
152
|
+
n.checked(n.paragraph('Checked')),
|
|
153
|
+
n.unchecked(n.paragraph('Unchecked')),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
editor.set(doc1)
|
|
157
|
+
const html1 = editor.getDocHTML()
|
|
158
|
+
expect(formatHTML(html1)).toMatchInlineSnapshot(
|
|
159
|
+
`
|
|
160
|
+
"
|
|
161
|
+
<div>
|
|
162
|
+
<ul>
|
|
163
|
+
<li
|
|
164
|
+
class="prosemirror-flat-list"
|
|
165
|
+
data-list-kind="bullet"
|
|
166
|
+
>
|
|
167
|
+
<p>
|
|
168
|
+
Bullet
|
|
169
|
+
</p>
|
|
170
|
+
</li>
|
|
171
|
+
</ul>
|
|
172
|
+
<ol>
|
|
173
|
+
<li
|
|
174
|
+
class="prosemirror-flat-list"
|
|
175
|
+
data-list-kind="ordered"
|
|
176
|
+
>
|
|
177
|
+
<p>
|
|
178
|
+
Ordered
|
|
179
|
+
</p>
|
|
180
|
+
</li>
|
|
181
|
+
</ol>
|
|
182
|
+
<ul>
|
|
183
|
+
<li
|
|
184
|
+
class="prosemirror-flat-list"
|
|
185
|
+
data-list-kind="task"
|
|
186
|
+
data-list-checked
|
|
187
|
+
>
|
|
188
|
+
<p>
|
|
189
|
+
<input
|
|
190
|
+
type="checkbox"
|
|
191
|
+
checked
|
|
192
|
+
>
|
|
193
|
+
Checked
|
|
194
|
+
</p>
|
|
195
|
+
</li>
|
|
196
|
+
<li
|
|
197
|
+
class="prosemirror-flat-list"
|
|
198
|
+
data-list-kind="task"
|
|
199
|
+
>
|
|
200
|
+
<p>
|
|
201
|
+
<input type="checkbox">
|
|
202
|
+
Unchecked
|
|
203
|
+
</p>
|
|
204
|
+
</li>
|
|
205
|
+
</ul>
|
|
206
|
+
</div>
|
|
207
|
+
"
|
|
208
|
+
`,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
const markdown1 = markdownFromHTML(html1)
|
|
212
|
+
expect(markdown1).toMatchInlineSnapshot(`
|
|
213
|
+
"* Bullet
|
|
214
|
+
|
|
215
|
+
1. Ordered
|
|
216
|
+
|
|
217
|
+
* [x] Checked
|
|
218
|
+
|
|
219
|
+
* [ ] Unchecked
|
|
220
|
+
"
|
|
221
|
+
`)
|
|
222
|
+
|
|
223
|
+
const html2 = htmlFromMarkdown(markdown1)
|
|
224
|
+
expect(formatHTML(html2)).toMatchInlineSnapshot(`
|
|
225
|
+
"
|
|
226
|
+
<ul>
|
|
227
|
+
<li>
|
|
228
|
+
Bullet
|
|
229
|
+
</li>
|
|
230
|
+
</ul>
|
|
231
|
+
<ol>
|
|
232
|
+
<li>
|
|
233
|
+
Ordered
|
|
234
|
+
</li>
|
|
235
|
+
</ol>
|
|
236
|
+
<ul class="contains-task-list">
|
|
237
|
+
<li class="task-list-item">
|
|
238
|
+
<p>
|
|
239
|
+
<input
|
|
240
|
+
type="checkbox"
|
|
241
|
+
checked
|
|
242
|
+
disabled
|
|
243
|
+
>
|
|
244
|
+
Checked
|
|
245
|
+
</p>
|
|
246
|
+
</li>
|
|
247
|
+
<li class="task-list-item">
|
|
248
|
+
<p>
|
|
249
|
+
<input
|
|
250
|
+
type="checkbox"
|
|
251
|
+
disabled
|
|
252
|
+
>
|
|
253
|
+
Unchecked
|
|
254
|
+
</p>
|
|
255
|
+
</li>
|
|
256
|
+
</ul>
|
|
257
|
+
"
|
|
258
|
+
`)
|
|
259
|
+
|
|
260
|
+
const doc2 = nodeFromHTML(html2, { schema: editor.schema })
|
|
261
|
+
expect(doc2.toJSON()).toEqual(doc1.toJSON())
|
|
262
|
+
})
|
|
134
263
|
})
|
package/src/testing/keyboard.ts
CHANGED
package/src/testing/markdown.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import rehypeParse from 'rehype-parse'
|
|
2
2
|
import rehypeRemark from 'rehype-remark'
|
|
3
|
+
import remarkGfm from 'remark-gfm'
|
|
3
4
|
import remarkHtml from 'remark-html'
|
|
4
5
|
import remarkParse from 'remark-parse'
|
|
5
6
|
import remarkStringify from 'remark-stringify'
|
|
@@ -9,6 +10,7 @@ export function markdownFromHTML(html: string): string {
|
|
|
9
10
|
return unified()
|
|
10
11
|
.use(rehypeParse)
|
|
11
12
|
.use(rehypeRemark)
|
|
13
|
+
.use(remarkGfm)
|
|
12
14
|
.use(remarkStringify)
|
|
13
15
|
.processSync(html)
|
|
14
16
|
.toString()
|
|
@@ -17,6 +19,7 @@ export function markdownFromHTML(html: string): string {
|
|
|
17
19
|
export function htmlFromMarkdown(markdown: string): string {
|
|
18
20
|
return unified()
|
|
19
21
|
.use(remarkParse)
|
|
22
|
+
.use(remarkGfm)
|
|
20
23
|
.use(remarkHtml)
|
|
21
24
|
.processSync(markdown)
|
|
22
25
|
.toString()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DY6lIIYV.d.ts","names":[],"sources":["../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":[],"mappings":";;;;UAYiB,sBAAA;;AAAjB;;MAIQ,EAAA,UAAA;;;;EAwBI,KAAA,EAnBH,SAmBG;EAII;;;MAEb,EApBK,IAoBL;EAAc;;;;AClCjB;;;;;;AAuBA;AAIgB,KDCJ,eAAA,GCD0B,CAAA,OAAA,EDE3B,sBCF2B,EAAA,GAAA,OAAA,GAAA,IAAA;AAAA,iBDKtB,qBAAA,CCLsB,OAAA,EDM3B,eCN2B,CAAA,EDOnC,cCPmC;;;UA3BrB,uBAAA;;ADAjB;;MAIQ,ECAA,UDAA;;;;EAwBI,KAAA,ECnBH,cDmBkB;EAIX;;;MAEb,ECpBK,IDoBL;;;;;AClCH;;;AASS,KAcG,gBAAA,GAdH,CAAA,OAAA,EAeE,uBAfF,EAAA,GAAA,OAAA,GAAA,IAAA;AAKD,iBAaQ,sBAAA,CAbR,OAAA,EAcG,gBAdH,CAAA,EAeL,cAfK;;;;;;UCrBS,cAAA;EFOA,MAAA,EAAA,MAAA;EAAsB,KAAA,EAAA,MAAA;;AAS9B,UEPQ,eAAA,CFOR;;;AAmBT;EAIgB,IAAA,EE1BR,IF0BQ;EAAqB;;;EAEpB,UAAA,EAAA,CAAA,QAAA,EEvBQ,cFuBR,EAAA,GAAA,IAAA;;;;AClCjB;;AAIQ,KCcI,QDdJ,CAAA,MAAA,CAAA,GAAA,CAAA,OAAA,ECciC,eDdjC,EAAA,GCcqD,ODdrD,CCc6D,MDd7D,CAAA;;;;AAmBI,cCAC,UDAe,CAAA,MACjB,CAAA,CAAA;EAGK;;;;;;;;AClChB;EASiB,UAAA,IAAA,EAAA,OAAe;EAAA;;;EASO,UAAA,MAAA,EA4BnB,MA5BmB,GAAA,SAAA;EAO3B;;;YAAyD,KAAA,EA0BlD,KA1BkD,GAAA,SAAA;;;AAKrE;EAAuB,SAAA,QAAA,EA0BF,OA1BE,CA0BM,MA1BN,CAAA;UAgBH,WAAA;;;;;;;aAoB+C,CAAA;IAAA,IAAA;IAAA;GAAA,EAAA;IAAT,IAAA,EAAhB,IAAgB;IAiCjC,QAAA,EAjCiC,QAiCjC,CAjC0C,MAiC1C,CAAA;;;;;yCAAA,0BACpB;;;;mDAcA,WAAW"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shiki-highlighter-chunk-Cwu1Jr9o.d.ts","names":[],"sources":["../src/code-block/shiki-highlighter-chunk.ts"],"sourcesContent":[],"mappings":";;;UAeiB,uBAAA,SAAgC,0BAA0B,iBAAiB;AAA3E,UAEA,kBAAA,SAA2B,IAFH,CAEQ,uBAFR,EAAA,OAAA,GAAA,QAAA,CAAA,CAAA;EAAA,MAAA,EAG/B,YAH+B,EAAA;OAAkC,EAAA,CAIjE,eAJiE,GAI/C,eAJ+C,CAAA,EAAA;;AAA1B,KAwCrC,iBAAA,GAxCqC;EAAyB,WAAA,EA0CzD,WA1CyD;EAEzD,OAAA,CAAA,EAAA,SAAA;CAAmB,GAAA;aAAa,CAAA,EAAA,SAAA;SACvC,EA4CG,OA5CH,CAAA,IAAA,CAAA;;AACkB,iBA8CZ,sBAAA,CA9CY,OAAA,EA+CjB,kBA/CiB,CAAA,EAgDzB,iBAhDyB"}
|