prosekit 0.0.0-next-20230627094841
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/LICENSE +21 -0
- package/README.md +13 -0
- package/dist/basic/style.css +133 -0
- package/dist/chunk-23S3SZFA.js +46 -0
- package/dist/chunk-2MVHS73Q.js +709 -0
- package/dist/chunk-4GDRVRDP.js +0 -0
- package/dist/chunk-5PFF57NB.js +1546 -0
- package/dist/chunk-6A2XHVFY.js +46 -0
- package/dist/chunk-7OYIOTDD.js +16472 -0
- package/dist/chunk-ARJTWYPA.js +1321 -0
- package/dist/chunk-CDGN4JUS.js +1546 -0
- package/dist/chunk-CG5B6PMC.js +973 -0
- package/dist/chunk-DDN3TFRH.js +185 -0
- package/dist/chunk-EQV3CWHZ.js +2213 -0
- package/dist/chunk-ERNIDFFW.js +1711 -0
- package/dist/chunk-FAVXZAF7.js +3279 -0
- package/dist/chunk-HSPTUO6P.js +53 -0
- package/dist/chunk-JMNJUDT7.js +165 -0
- package/dist/chunk-LXCCO2LO.js +52 -0
- package/dist/chunk-MIPON3OH.js +922 -0
- package/dist/chunk-NAWSCY5F.js +166 -0
- package/dist/chunk-S64NFSV2.js +236 -0
- package/dist/chunk-S65R2BUY.js +15 -0
- package/dist/chunk-T2V5UU6H.js +204 -0
- package/dist/chunk-TWIMWRRZ.js +57 -0
- package/dist/chunk-US2P3K6I.js +185 -0
- package/dist/chunk-UTNVEPBA.js +950 -0
- package/dist/chunk-UWHQRU5N.js +4883 -0
- package/dist/chunk-VIKPJJET.js +662 -0
- package/dist/chunk-WAMZOD5I.js +67 -0
- package/dist/chunk-YUY5I2TY.js +236 -0
- package/dist/core/style.css +54 -0
- package/dist/extension-list/style.css +78 -0
- package/dist/pm/view/style/prosemirror.css +52 -0
- package/dist/prosekit-basic.js +2 -0
- package/dist/prosekit-core.js +2 -0
- package/dist/prosekit-extension-blockquote.js +2 -0
- package/dist/prosekit-extension-bold.js +2 -0
- package/dist/prosekit-extension-code-block.js +2 -0
- package/dist/prosekit-extension-code.js +2 -0
- package/dist/prosekit-extension-heading.js +2 -0
- package/dist/prosekit-extension-horizontal-rule.js +2 -0
- package/dist/prosekit-extension-italic.js +2 -0
- package/dist/prosekit-extension-list.js +2 -0
- package/dist/prosekit-extension-suggestion.js +2 -0
- package/dist/prosekit-lit-elements-menu-item.js +2 -0
- package/dist/prosekit-lit-elements-menu.js +2 -0
- package/dist/prosekit-lit-elements-popover.js +2 -0
- package/dist/prosekit-lit.js +2 -0
- package/dist/prosekit-pm-commands.js +2 -0
- package/dist/prosekit-pm-inputrules.js +2 -0
- package/dist/prosekit-pm-keymap.js +2 -0
- package/dist/prosekit-pm-model.js +2 -0
- package/dist/prosekit-pm-state.js +2 -0
- package/dist/prosekit-pm-transform.js +2 -0
- package/dist/prosekit-pm-view.js +2 -0
- package/dist/prosekit-pm.js +2 -0
- package/dist/prosekit-react-components-menu-item.js +2 -0
- package/dist/prosekit-react-components-menu.js +2 -0
- package/dist/prosekit-react-components-popover-suggestion.js +2 -0
- package/dist/prosekit-react-components-popover.js +2 -0
- package/dist/prosekit-react.js +2 -0
- package/dist/prosekit-vue-components-menu-item.js +2 -0
- package/dist/prosekit-vue-components-menu.js +2 -0
- package/dist/prosekit-vue-components-popover-suggestion.js +2 -0
- package/dist/prosekit-vue-components-popover.js +2 -0
- package/dist/prosekit-vue.js +2 -0
- package/dist/prosekit.js +0 -0
- package/package.json +262 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AllSelection,
|
|
3
|
+
NodeSelection,
|
|
4
|
+
Selection,
|
|
5
|
+
TextSelection
|
|
6
|
+
} from "./chunk-UTNVEPBA.js";
|
|
7
|
+
import {
|
|
8
|
+
ReplaceAroundStep,
|
|
9
|
+
ReplaceStep,
|
|
10
|
+
canJoin,
|
|
11
|
+
canSplit,
|
|
12
|
+
findWrapping,
|
|
13
|
+
joinPoint,
|
|
14
|
+
liftTarget,
|
|
15
|
+
replaceStep
|
|
16
|
+
} from "./chunk-ERNIDFFW.js";
|
|
17
|
+
import {
|
|
18
|
+
Fragment,
|
|
19
|
+
Slice
|
|
20
|
+
} from "./chunk-FAVXZAF7.js";
|
|
21
|
+
|
|
22
|
+
// ../../node_modules/.pnpm/prosemirror-commands@1.5.2/node_modules/prosemirror-commands/dist/index.js
|
|
23
|
+
var deleteSelection = (state, dispatch) => {
|
|
24
|
+
if (state.selection.empty)
|
|
25
|
+
return false;
|
|
26
|
+
if (dispatch)
|
|
27
|
+
dispatch(state.tr.deleteSelection().scrollIntoView());
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
function atBlockStart(state, view) {
|
|
31
|
+
let { $cursor } = state.selection;
|
|
32
|
+
if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0))
|
|
33
|
+
return null;
|
|
34
|
+
return $cursor;
|
|
35
|
+
}
|
|
36
|
+
var joinBackward = (state, dispatch, view) => {
|
|
37
|
+
let $cursor = atBlockStart(state, view);
|
|
38
|
+
if (!$cursor)
|
|
39
|
+
return false;
|
|
40
|
+
let $cut = findCutBefore($cursor);
|
|
41
|
+
if (!$cut) {
|
|
42
|
+
let range = $cursor.blockRange(), target = range && liftTarget(range);
|
|
43
|
+
if (target == null)
|
|
44
|
+
return false;
|
|
45
|
+
if (dispatch)
|
|
46
|
+
dispatch(state.tr.lift(range, target).scrollIntoView());
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
let before = $cut.nodeBefore;
|
|
50
|
+
if (!before.type.spec.isolating && deleteBarrier(state, $cut, dispatch))
|
|
51
|
+
return true;
|
|
52
|
+
if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) {
|
|
53
|
+
let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty);
|
|
54
|
+
if (delStep && delStep.slice.size < delStep.to - delStep.from) {
|
|
55
|
+
if (dispatch) {
|
|
56
|
+
let tr = state.tr.step(delStep);
|
|
57
|
+
tr.setSelection(textblockAt(before, "end") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize));
|
|
58
|
+
dispatch(tr.scrollIntoView());
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (before.isAtom && $cut.depth == $cursor.depth - 1) {
|
|
64
|
+
if (dispatch)
|
|
65
|
+
dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView());
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
};
|
|
70
|
+
var joinTextblockBackward = (state, dispatch, view) => {
|
|
71
|
+
let $cursor = atBlockStart(state, view);
|
|
72
|
+
if (!$cursor)
|
|
73
|
+
return false;
|
|
74
|
+
let $cut = findCutBefore($cursor);
|
|
75
|
+
return $cut ? joinTextblocksAround(state, $cut, dispatch) : false;
|
|
76
|
+
};
|
|
77
|
+
var joinTextblockForward = (state, dispatch, view) => {
|
|
78
|
+
let $cursor = atBlockEnd(state, view);
|
|
79
|
+
if (!$cursor)
|
|
80
|
+
return false;
|
|
81
|
+
let $cut = findCutAfter($cursor);
|
|
82
|
+
return $cut ? joinTextblocksAround(state, $cut, dispatch) : false;
|
|
83
|
+
};
|
|
84
|
+
function joinTextblocksAround(state, $cut, dispatch) {
|
|
85
|
+
let before = $cut.nodeBefore, beforeText = before, beforePos = $cut.pos - 1;
|
|
86
|
+
for (; !beforeText.isTextblock; beforePos--) {
|
|
87
|
+
if (beforeText.type.spec.isolating)
|
|
88
|
+
return false;
|
|
89
|
+
let child = beforeText.lastChild;
|
|
90
|
+
if (!child)
|
|
91
|
+
return false;
|
|
92
|
+
beforeText = child;
|
|
93
|
+
}
|
|
94
|
+
let after = $cut.nodeAfter, afterText = after, afterPos = $cut.pos + 1;
|
|
95
|
+
for (; !afterText.isTextblock; afterPos++) {
|
|
96
|
+
if (afterText.type.spec.isolating)
|
|
97
|
+
return false;
|
|
98
|
+
let child = afterText.firstChild;
|
|
99
|
+
if (!child)
|
|
100
|
+
return false;
|
|
101
|
+
afterText = child;
|
|
102
|
+
}
|
|
103
|
+
let step = replaceStep(state.doc, beforePos, afterPos, Slice.empty);
|
|
104
|
+
if (!step || step.from != beforePos || step instanceof ReplaceStep && step.slice.size >= afterPos - beforePos)
|
|
105
|
+
return false;
|
|
106
|
+
if (dispatch) {
|
|
107
|
+
let tr = state.tr.step(step);
|
|
108
|
+
tr.setSelection(TextSelection.create(tr.doc, beforePos));
|
|
109
|
+
dispatch(tr.scrollIntoView());
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
function textblockAt(node, side, only = false) {
|
|
114
|
+
for (let scan = node; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) {
|
|
115
|
+
if (scan.isTextblock)
|
|
116
|
+
return true;
|
|
117
|
+
if (only && scan.childCount != 1)
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
var selectNodeBackward = (state, dispatch, view) => {
|
|
123
|
+
let { $head, empty } = state.selection, $cut = $head;
|
|
124
|
+
if (!empty)
|
|
125
|
+
return false;
|
|
126
|
+
if ($head.parent.isTextblock) {
|
|
127
|
+
if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0)
|
|
128
|
+
return false;
|
|
129
|
+
$cut = findCutBefore($head);
|
|
130
|
+
}
|
|
131
|
+
let node = $cut && $cut.nodeBefore;
|
|
132
|
+
if (!node || !NodeSelection.isSelectable(node))
|
|
133
|
+
return false;
|
|
134
|
+
if (dispatch)
|
|
135
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node.nodeSize)).scrollIntoView());
|
|
136
|
+
return true;
|
|
137
|
+
};
|
|
138
|
+
function findCutBefore($pos) {
|
|
139
|
+
if (!$pos.parent.type.spec.isolating)
|
|
140
|
+
for (let i = $pos.depth - 1; i >= 0; i--) {
|
|
141
|
+
if ($pos.index(i) > 0)
|
|
142
|
+
return $pos.doc.resolve($pos.before(i + 1));
|
|
143
|
+
if ($pos.node(i).type.spec.isolating)
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function atBlockEnd(state, view) {
|
|
149
|
+
let { $cursor } = state.selection;
|
|
150
|
+
if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size))
|
|
151
|
+
return null;
|
|
152
|
+
return $cursor;
|
|
153
|
+
}
|
|
154
|
+
var joinForward = (state, dispatch, view) => {
|
|
155
|
+
let $cursor = atBlockEnd(state, view);
|
|
156
|
+
if (!$cursor)
|
|
157
|
+
return false;
|
|
158
|
+
let $cut = findCutAfter($cursor);
|
|
159
|
+
if (!$cut)
|
|
160
|
+
return false;
|
|
161
|
+
let after = $cut.nodeAfter;
|
|
162
|
+
if (deleteBarrier(state, $cut, dispatch))
|
|
163
|
+
return true;
|
|
164
|
+
if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) {
|
|
165
|
+
let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty);
|
|
166
|
+
if (delStep && delStep.slice.size < delStep.to - delStep.from) {
|
|
167
|
+
if (dispatch) {
|
|
168
|
+
let tr = state.tr.step(delStep);
|
|
169
|
+
tr.setSelection(textblockAt(after, "start") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos)), 1) : NodeSelection.create(tr.doc, tr.mapping.map($cut.pos)));
|
|
170
|
+
dispatch(tr.scrollIntoView());
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (after.isAtom && $cut.depth == $cursor.depth - 1) {
|
|
176
|
+
if (dispatch)
|
|
177
|
+
dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView());
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
};
|
|
182
|
+
var selectNodeForward = (state, dispatch, view) => {
|
|
183
|
+
let { $head, empty } = state.selection, $cut = $head;
|
|
184
|
+
if (!empty)
|
|
185
|
+
return false;
|
|
186
|
+
if ($head.parent.isTextblock) {
|
|
187
|
+
if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size)
|
|
188
|
+
return false;
|
|
189
|
+
$cut = findCutAfter($head);
|
|
190
|
+
}
|
|
191
|
+
let node = $cut && $cut.nodeAfter;
|
|
192
|
+
if (!node || !NodeSelection.isSelectable(node))
|
|
193
|
+
return false;
|
|
194
|
+
if (dispatch)
|
|
195
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView());
|
|
196
|
+
return true;
|
|
197
|
+
};
|
|
198
|
+
function findCutAfter($pos) {
|
|
199
|
+
if (!$pos.parent.type.spec.isolating)
|
|
200
|
+
for (let i = $pos.depth - 1; i >= 0; i--) {
|
|
201
|
+
let parent = $pos.node(i);
|
|
202
|
+
if ($pos.index(i) + 1 < parent.childCount)
|
|
203
|
+
return $pos.doc.resolve($pos.after(i + 1));
|
|
204
|
+
if (parent.type.spec.isolating)
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
var joinUp = (state, dispatch) => {
|
|
210
|
+
let sel = state.selection, nodeSel = sel instanceof NodeSelection, point;
|
|
211
|
+
if (nodeSel) {
|
|
212
|
+
if (sel.node.isTextblock || !canJoin(state.doc, sel.from))
|
|
213
|
+
return false;
|
|
214
|
+
point = sel.from;
|
|
215
|
+
} else {
|
|
216
|
+
point = joinPoint(state.doc, sel.from, -1);
|
|
217
|
+
if (point == null)
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
if (dispatch) {
|
|
221
|
+
let tr = state.tr.join(point);
|
|
222
|
+
if (nodeSel)
|
|
223
|
+
tr.setSelection(NodeSelection.create(tr.doc, point - state.doc.resolve(point).nodeBefore.nodeSize));
|
|
224
|
+
dispatch(tr.scrollIntoView());
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
};
|
|
228
|
+
var joinDown = (state, dispatch) => {
|
|
229
|
+
let sel = state.selection, point;
|
|
230
|
+
if (sel instanceof NodeSelection) {
|
|
231
|
+
if (sel.node.isTextblock || !canJoin(state.doc, sel.to))
|
|
232
|
+
return false;
|
|
233
|
+
point = sel.to;
|
|
234
|
+
} else {
|
|
235
|
+
point = joinPoint(state.doc, sel.to, 1);
|
|
236
|
+
if (point == null)
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
if (dispatch)
|
|
240
|
+
dispatch(state.tr.join(point).scrollIntoView());
|
|
241
|
+
return true;
|
|
242
|
+
};
|
|
243
|
+
var lift = (state, dispatch) => {
|
|
244
|
+
let { $from, $to } = state.selection;
|
|
245
|
+
let range = $from.blockRange($to), target = range && liftTarget(range);
|
|
246
|
+
if (target == null)
|
|
247
|
+
return false;
|
|
248
|
+
if (dispatch)
|
|
249
|
+
dispatch(state.tr.lift(range, target).scrollIntoView());
|
|
250
|
+
return true;
|
|
251
|
+
};
|
|
252
|
+
var newlineInCode = (state, dispatch) => {
|
|
253
|
+
let { $head, $anchor } = state.selection;
|
|
254
|
+
if (!$head.parent.type.spec.code || !$head.sameParent($anchor))
|
|
255
|
+
return false;
|
|
256
|
+
if (dispatch)
|
|
257
|
+
dispatch(state.tr.insertText("\n").scrollIntoView());
|
|
258
|
+
return true;
|
|
259
|
+
};
|
|
260
|
+
function defaultBlockAt(match) {
|
|
261
|
+
for (let i = 0; i < match.edgeCount; i++) {
|
|
262
|
+
let { type } = match.edge(i);
|
|
263
|
+
if (type.isTextblock && !type.hasRequiredAttrs())
|
|
264
|
+
return type;
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
var exitCode = (state, dispatch) => {
|
|
269
|
+
let { $head, $anchor } = state.selection;
|
|
270
|
+
if (!$head.parent.type.spec.code || !$head.sameParent($anchor))
|
|
271
|
+
return false;
|
|
272
|
+
let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt(above.contentMatchAt(after));
|
|
273
|
+
if (!type || !above.canReplaceWith(after, after, type))
|
|
274
|
+
return false;
|
|
275
|
+
if (dispatch) {
|
|
276
|
+
let pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill());
|
|
277
|
+
tr.setSelection(Selection.near(tr.doc.resolve(pos), 1));
|
|
278
|
+
dispatch(tr.scrollIntoView());
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
};
|
|
282
|
+
var createParagraphNear = (state, dispatch) => {
|
|
283
|
+
let sel = state.selection, { $from, $to } = sel;
|
|
284
|
+
if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent)
|
|
285
|
+
return false;
|
|
286
|
+
let type = defaultBlockAt($to.parent.contentMatchAt($to.indexAfter()));
|
|
287
|
+
if (!type || !type.isTextblock)
|
|
288
|
+
return false;
|
|
289
|
+
if (dispatch) {
|
|
290
|
+
let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos;
|
|
291
|
+
let tr = state.tr.insert(side, type.createAndFill());
|
|
292
|
+
tr.setSelection(TextSelection.create(tr.doc, side + 1));
|
|
293
|
+
dispatch(tr.scrollIntoView());
|
|
294
|
+
}
|
|
295
|
+
return true;
|
|
296
|
+
};
|
|
297
|
+
var liftEmptyBlock = (state, dispatch) => {
|
|
298
|
+
let { $cursor } = state.selection;
|
|
299
|
+
if (!$cursor || $cursor.parent.content.size)
|
|
300
|
+
return false;
|
|
301
|
+
if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) {
|
|
302
|
+
let before = $cursor.before();
|
|
303
|
+
if (canSplit(state.doc, before)) {
|
|
304
|
+
if (dispatch)
|
|
305
|
+
dispatch(state.tr.split(before).scrollIntoView());
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
let range = $cursor.blockRange(), target = range && liftTarget(range);
|
|
310
|
+
if (target == null)
|
|
311
|
+
return false;
|
|
312
|
+
if (dispatch)
|
|
313
|
+
dispatch(state.tr.lift(range, target).scrollIntoView());
|
|
314
|
+
return true;
|
|
315
|
+
};
|
|
316
|
+
function splitBlockAs(splitNode) {
|
|
317
|
+
return (state, dispatch) => {
|
|
318
|
+
let { $from, $to } = state.selection;
|
|
319
|
+
if (state.selection instanceof NodeSelection && state.selection.node.isBlock) {
|
|
320
|
+
if (!$from.parentOffset || !canSplit(state.doc, $from.pos))
|
|
321
|
+
return false;
|
|
322
|
+
if (dispatch)
|
|
323
|
+
dispatch(state.tr.split($from.pos).scrollIntoView());
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
if (!$from.parent.isBlock)
|
|
327
|
+
return false;
|
|
328
|
+
if (dispatch) {
|
|
329
|
+
let atEnd = $to.parentOffset == $to.parent.content.size;
|
|
330
|
+
let tr = state.tr;
|
|
331
|
+
if (state.selection instanceof TextSelection || state.selection instanceof AllSelection)
|
|
332
|
+
tr.deleteSelection();
|
|
333
|
+
let deflt = $from.depth == 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
|
|
334
|
+
let splitType = splitNode && splitNode($to.parent, atEnd);
|
|
335
|
+
let types = splitType ? [splitType] : atEnd && deflt ? [{ type: deflt }] : void 0;
|
|
336
|
+
let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
|
|
337
|
+
if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) {
|
|
338
|
+
if (deflt)
|
|
339
|
+
types = [{ type: deflt }];
|
|
340
|
+
can = true;
|
|
341
|
+
}
|
|
342
|
+
if (can) {
|
|
343
|
+
tr.split(tr.mapping.map($from.pos), 1, types);
|
|
344
|
+
if (!atEnd && !$from.parentOffset && $from.parent.type != deflt) {
|
|
345
|
+
let first = tr.mapping.map($from.before()), $first = tr.doc.resolve(first);
|
|
346
|
+
if (deflt && $from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt))
|
|
347
|
+
tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
dispatch(tr.scrollIntoView());
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
var splitBlock = splitBlockAs();
|
|
356
|
+
var splitBlockKeepMarks = (state, dispatch) => {
|
|
357
|
+
return splitBlock(state, dispatch && ((tr) => {
|
|
358
|
+
let marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
|
|
359
|
+
if (marks)
|
|
360
|
+
tr.ensureMarks(marks);
|
|
361
|
+
dispatch(tr);
|
|
362
|
+
}));
|
|
363
|
+
};
|
|
364
|
+
var selectParentNode = (state, dispatch) => {
|
|
365
|
+
let { $from, to } = state.selection, pos;
|
|
366
|
+
let same = $from.sharedDepth(to);
|
|
367
|
+
if (same == 0)
|
|
368
|
+
return false;
|
|
369
|
+
pos = $from.before(same);
|
|
370
|
+
if (dispatch)
|
|
371
|
+
dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos)));
|
|
372
|
+
return true;
|
|
373
|
+
};
|
|
374
|
+
var selectAll = (state, dispatch) => {
|
|
375
|
+
if (dispatch)
|
|
376
|
+
dispatch(state.tr.setSelection(new AllSelection(state.doc)));
|
|
377
|
+
return true;
|
|
378
|
+
};
|
|
379
|
+
function joinMaybeClear(state, $pos, dispatch) {
|
|
380
|
+
let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index();
|
|
381
|
+
if (!before || !after || !before.type.compatibleContent(after.type))
|
|
382
|
+
return false;
|
|
383
|
+
if (!before.content.size && $pos.parent.canReplace(index - 1, index)) {
|
|
384
|
+
if (dispatch)
|
|
385
|
+
dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView());
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos)))
|
|
389
|
+
return false;
|
|
390
|
+
if (dispatch)
|
|
391
|
+
dispatch(state.tr.clearIncompatible($pos.pos, before.type, before.contentMatchAt(before.childCount)).join($pos.pos).scrollIntoView());
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
function deleteBarrier(state, $cut, dispatch) {
|
|
395
|
+
let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match;
|
|
396
|
+
if (before.type.spec.isolating || after.type.spec.isolating)
|
|
397
|
+
return false;
|
|
398
|
+
if (joinMaybeClear(state, $cut, dispatch))
|
|
399
|
+
return true;
|
|
400
|
+
let canDelAfter = $cut.parent.canReplace($cut.index(), $cut.index() + 1);
|
|
401
|
+
if (canDelAfter && (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match.matchType(conn[0] || after.type).validEnd) {
|
|
402
|
+
if (dispatch) {
|
|
403
|
+
let end = $cut.pos + after.nodeSize, wrap = Fragment.empty;
|
|
404
|
+
for (let i = conn.length - 1; i >= 0; i--)
|
|
405
|
+
wrap = Fragment.from(conn[i].create(null, wrap));
|
|
406
|
+
wrap = Fragment.from(before.copy(wrap));
|
|
407
|
+
let tr = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap, 1, 0), conn.length, true));
|
|
408
|
+
let joinAt = end + 2 * conn.length;
|
|
409
|
+
if (canJoin(tr.doc, joinAt))
|
|
410
|
+
tr.join(joinAt);
|
|
411
|
+
dispatch(tr.scrollIntoView());
|
|
412
|
+
}
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
let selAfter = Selection.findFrom($cut, 1);
|
|
416
|
+
let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range);
|
|
417
|
+
if (target != null && target >= $cut.depth) {
|
|
418
|
+
if (dispatch)
|
|
419
|
+
dispatch(state.tr.lift(range, target).scrollIntoView());
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) {
|
|
423
|
+
let at = before, wrap = [];
|
|
424
|
+
for (; ; ) {
|
|
425
|
+
wrap.push(at);
|
|
426
|
+
if (at.isTextblock)
|
|
427
|
+
break;
|
|
428
|
+
at = at.lastChild;
|
|
429
|
+
}
|
|
430
|
+
let afterText = after, afterDepth = 1;
|
|
431
|
+
for (; !afterText.isTextblock; afterText = afterText.firstChild)
|
|
432
|
+
afterDepth++;
|
|
433
|
+
if (at.canReplace(at.childCount, at.childCount, afterText.content)) {
|
|
434
|
+
if (dispatch) {
|
|
435
|
+
let end = Fragment.empty;
|
|
436
|
+
for (let i = wrap.length - 1; i >= 0; i--)
|
|
437
|
+
end = Fragment.from(wrap[i].copy(end));
|
|
438
|
+
let tr = state.tr.step(new ReplaceAroundStep($cut.pos - wrap.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end, wrap.length, 0), 0, true));
|
|
439
|
+
dispatch(tr.scrollIntoView());
|
|
440
|
+
}
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
function selectTextblockSide(side) {
|
|
447
|
+
return function(state, dispatch) {
|
|
448
|
+
let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to;
|
|
449
|
+
let depth = $pos.depth;
|
|
450
|
+
while ($pos.node(depth).isInline) {
|
|
451
|
+
if (!depth)
|
|
452
|
+
return false;
|
|
453
|
+
depth--;
|
|
454
|
+
}
|
|
455
|
+
if (!$pos.node(depth).isTextblock)
|
|
456
|
+
return false;
|
|
457
|
+
if (dispatch)
|
|
458
|
+
dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth))));
|
|
459
|
+
return true;
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
var selectTextblockStart = selectTextblockSide(-1);
|
|
463
|
+
var selectTextblockEnd = selectTextblockSide(1);
|
|
464
|
+
function wrapIn(nodeType, attrs = null) {
|
|
465
|
+
return function(state, dispatch) {
|
|
466
|
+
let { $from, $to } = state.selection;
|
|
467
|
+
let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs);
|
|
468
|
+
if (!wrapping)
|
|
469
|
+
return false;
|
|
470
|
+
if (dispatch)
|
|
471
|
+
dispatch(state.tr.wrap(range, wrapping).scrollIntoView());
|
|
472
|
+
return true;
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
function setBlockType(nodeType, attrs = null) {
|
|
476
|
+
return function(state, dispatch) {
|
|
477
|
+
let applicable = false;
|
|
478
|
+
for (let i = 0; i < state.selection.ranges.length && !applicable; i++) {
|
|
479
|
+
let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
|
|
480
|
+
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
481
|
+
if (applicable)
|
|
482
|
+
return false;
|
|
483
|
+
if (!node.isTextblock || node.hasMarkup(nodeType, attrs))
|
|
484
|
+
return;
|
|
485
|
+
if (node.type == nodeType) {
|
|
486
|
+
applicable = true;
|
|
487
|
+
} else {
|
|
488
|
+
let $pos = state.doc.resolve(pos), index = $pos.index();
|
|
489
|
+
applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
if (!applicable)
|
|
494
|
+
return false;
|
|
495
|
+
if (dispatch) {
|
|
496
|
+
let tr = state.tr;
|
|
497
|
+
for (let i = 0; i < state.selection.ranges.length; i++) {
|
|
498
|
+
let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i];
|
|
499
|
+
tr.setBlockType(from, to, nodeType, attrs);
|
|
500
|
+
}
|
|
501
|
+
dispatch(tr.scrollIntoView());
|
|
502
|
+
}
|
|
503
|
+
return true;
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
function markApplies(doc, ranges, type) {
|
|
507
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
508
|
+
let { $from, $to } = ranges[i];
|
|
509
|
+
let can = $from.depth == 0 ? doc.inlineContent && doc.type.allowsMarkType(type) : false;
|
|
510
|
+
doc.nodesBetween($from.pos, $to.pos, (node) => {
|
|
511
|
+
if (can)
|
|
512
|
+
return false;
|
|
513
|
+
can = node.inlineContent && node.type.allowsMarkType(type);
|
|
514
|
+
});
|
|
515
|
+
if (can)
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
function toggleMark(markType, attrs = null) {
|
|
521
|
+
return function(state, dispatch) {
|
|
522
|
+
let { empty, $cursor, ranges } = state.selection;
|
|
523
|
+
if (empty && !$cursor || !markApplies(state.doc, ranges, markType))
|
|
524
|
+
return false;
|
|
525
|
+
if (dispatch) {
|
|
526
|
+
if ($cursor) {
|
|
527
|
+
if (markType.isInSet(state.storedMarks || $cursor.marks()))
|
|
528
|
+
dispatch(state.tr.removeStoredMark(markType));
|
|
529
|
+
else
|
|
530
|
+
dispatch(state.tr.addStoredMark(markType.create(attrs)));
|
|
531
|
+
} else {
|
|
532
|
+
let has = false, tr = state.tr;
|
|
533
|
+
for (let i = 0; !has && i < ranges.length; i++) {
|
|
534
|
+
let { $from, $to } = ranges[i];
|
|
535
|
+
has = state.doc.rangeHasMark($from.pos, $to.pos, markType);
|
|
536
|
+
}
|
|
537
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
538
|
+
let { $from, $to } = ranges[i];
|
|
539
|
+
if (has) {
|
|
540
|
+
tr.removeMark($from.pos, $to.pos, markType);
|
|
541
|
+
} else {
|
|
542
|
+
let from = $from.pos, to = $to.pos, start = $from.nodeAfter, end = $to.nodeBefore;
|
|
543
|
+
let spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0;
|
|
544
|
+
let spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0;
|
|
545
|
+
if (from + spaceStart < to) {
|
|
546
|
+
from += spaceStart;
|
|
547
|
+
to -= spaceEnd;
|
|
548
|
+
}
|
|
549
|
+
tr.addMark(from, to, markType.create(attrs));
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
dispatch(tr.scrollIntoView());
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return true;
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
function wrapDispatchForJoin(dispatch, isJoinable) {
|
|
559
|
+
return (tr) => {
|
|
560
|
+
if (!tr.isGeneric)
|
|
561
|
+
return dispatch(tr);
|
|
562
|
+
let ranges = [];
|
|
563
|
+
for (let i = 0; i < tr.mapping.maps.length; i++) {
|
|
564
|
+
let map = tr.mapping.maps[i];
|
|
565
|
+
for (let j = 0; j < ranges.length; j++)
|
|
566
|
+
ranges[j] = map.map(ranges[j]);
|
|
567
|
+
map.forEach((_s, _e, from, to) => ranges.push(from, to));
|
|
568
|
+
}
|
|
569
|
+
let joinable = [];
|
|
570
|
+
for (let i = 0; i < ranges.length; i += 2) {
|
|
571
|
+
let from = ranges[i], to = ranges[i + 1];
|
|
572
|
+
let $from = tr.doc.resolve(from), depth = $from.sharedDepth(to), parent = $from.node(depth);
|
|
573
|
+
for (let index = $from.indexAfter(depth), pos = $from.after(depth + 1); pos <= to; ++index) {
|
|
574
|
+
let after = parent.maybeChild(index);
|
|
575
|
+
if (!after)
|
|
576
|
+
break;
|
|
577
|
+
if (index && joinable.indexOf(pos) == -1) {
|
|
578
|
+
let before = parent.child(index - 1);
|
|
579
|
+
if (before.type == after.type && isJoinable(before, after))
|
|
580
|
+
joinable.push(pos);
|
|
581
|
+
}
|
|
582
|
+
pos += after.nodeSize;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
joinable.sort((a, b) => a - b);
|
|
586
|
+
for (let i = joinable.length - 1; i >= 0; i--) {
|
|
587
|
+
if (canJoin(tr.doc, joinable[i]))
|
|
588
|
+
tr.join(joinable[i]);
|
|
589
|
+
}
|
|
590
|
+
dispatch(tr);
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
function autoJoin(command, isJoinable) {
|
|
594
|
+
let canJoin2 = Array.isArray(isJoinable) ? (node) => isJoinable.indexOf(node.type.name) > -1 : isJoinable;
|
|
595
|
+
return (state, dispatch, view) => command(state, dispatch && wrapDispatchForJoin(dispatch, canJoin2), view);
|
|
596
|
+
}
|
|
597
|
+
function chainCommands(...commands) {
|
|
598
|
+
return function(state, dispatch, view) {
|
|
599
|
+
for (let i = 0; i < commands.length; i++)
|
|
600
|
+
if (commands[i](state, dispatch, view))
|
|
601
|
+
return true;
|
|
602
|
+
return false;
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
var backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
|
|
606
|
+
var del = chainCommands(deleteSelection, joinForward, selectNodeForward);
|
|
607
|
+
var pcBaseKeymap = {
|
|
608
|
+
"Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock),
|
|
609
|
+
"Mod-Enter": exitCode,
|
|
610
|
+
"Backspace": backspace,
|
|
611
|
+
"Mod-Backspace": backspace,
|
|
612
|
+
"Shift-Backspace": backspace,
|
|
613
|
+
"Delete": del,
|
|
614
|
+
"Mod-Delete": del,
|
|
615
|
+
"Mod-a": selectAll
|
|
616
|
+
};
|
|
617
|
+
var macBaseKeymap = {
|
|
618
|
+
"Ctrl-h": pcBaseKeymap["Backspace"],
|
|
619
|
+
"Alt-Backspace": pcBaseKeymap["Mod-Backspace"],
|
|
620
|
+
"Ctrl-d": pcBaseKeymap["Delete"],
|
|
621
|
+
"Ctrl-Alt-Backspace": pcBaseKeymap["Mod-Delete"],
|
|
622
|
+
"Alt-Delete": pcBaseKeymap["Mod-Delete"],
|
|
623
|
+
"Alt-d": pcBaseKeymap["Mod-Delete"],
|
|
624
|
+
"Ctrl-a": selectTextblockStart,
|
|
625
|
+
"Ctrl-e": selectTextblockEnd
|
|
626
|
+
};
|
|
627
|
+
for (let key in pcBaseKeymap)
|
|
628
|
+
macBaseKeymap[key] = pcBaseKeymap[key];
|
|
629
|
+
var mac = typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : typeof os != "undefined" && os.platform ? os.platform() == "darwin" : false;
|
|
630
|
+
var baseKeymap = mac ? macBaseKeymap : pcBaseKeymap;
|
|
631
|
+
|
|
632
|
+
export {
|
|
633
|
+
deleteSelection,
|
|
634
|
+
joinBackward,
|
|
635
|
+
joinTextblockBackward,
|
|
636
|
+
joinTextblockForward,
|
|
637
|
+
selectNodeBackward,
|
|
638
|
+
joinForward,
|
|
639
|
+
selectNodeForward,
|
|
640
|
+
joinUp,
|
|
641
|
+
joinDown,
|
|
642
|
+
lift,
|
|
643
|
+
newlineInCode,
|
|
644
|
+
exitCode,
|
|
645
|
+
createParagraphNear,
|
|
646
|
+
liftEmptyBlock,
|
|
647
|
+
splitBlockAs,
|
|
648
|
+
splitBlock,
|
|
649
|
+
splitBlockKeepMarks,
|
|
650
|
+
selectParentNode,
|
|
651
|
+
selectAll,
|
|
652
|
+
selectTextblockStart,
|
|
653
|
+
selectTextblockEnd,
|
|
654
|
+
wrapIn,
|
|
655
|
+
setBlockType,
|
|
656
|
+
toggleMark,
|
|
657
|
+
autoJoin,
|
|
658
|
+
chainCommands,
|
|
659
|
+
pcBaseKeymap,
|
|
660
|
+
macBaseKeymap,
|
|
661
|
+
baseKeymap
|
|
662
|
+
};
|