@prosekit/core 0.8.7 → 0.10.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/{editor-M9OimMiI.d.ts → editor-BULC1zqX.d.ts} +31 -71
- package/dist/editor-BULC1zqX.d.ts.map +1 -0
- package/dist/{editor-B0L9BgMi.js → editor-g-Rqn-ZE.js} +119 -136
- package/dist/editor-g-Rqn-ZE.js.map +1 -0
- package/dist/prosekit-core-test.d.ts +1 -2
- package/dist/prosekit-core-test.d.ts.map +1 -1
- package/dist/prosekit-core-test.js +1 -1
- package/dist/prosekit-core-test.js.map +1 -1
- package/dist/prosekit-core.d.ts +182 -202
- package/dist/prosekit-core.d.ts.map +1 -1
- package/dist/prosekit-core.js +543 -549
- package/dist/prosekit-core.js.map +1 -1
- package/package.json +9 -12
- package/src/commands/add-mark.ts +1 -4
- package/src/commands/expand-mark.ts +2 -9
- package/src/commands/insert-default-block.spec.ts +1 -5
- package/src/commands/insert-default-block.ts +1 -4
- package/src/commands/insert-node.ts +4 -8
- package/src/commands/remove-mark.ts +1 -4
- package/src/commands/remove-node.ts +2 -2
- package/src/commands/select-all.ts +3 -8
- package/src/commands/select-block.spec.ts +81 -0
- package/src/commands/select-block.ts +56 -0
- package/src/commands/set-block-type.ts +1 -4
- package/src/commands/set-node-attrs-between.spec.ts +221 -0
- package/src/commands/set-node-attrs-between.ts +77 -0
- package/src/commands/set-node-attrs.spec.ts +129 -0
- package/src/commands/set-node-attrs.ts +25 -26
- package/src/commands/toggle-mark.ts +1 -4
- package/src/commands/toggle-node.ts +2 -5
- package/src/commands/toggle-wrap.spec.ts +1 -5
- package/src/commands/toggle-wrap.ts +1 -4
- package/src/commands/unset-block-type.spec.ts +1 -5
- package/src/commands/unset-block-type.ts +2 -8
- package/src/commands/unset-mark.spec.ts +1 -5
- package/src/commands/wrap.ts +2 -10
- package/src/editor/action.spec.ts +2 -6
- package/src/editor/action.ts +2 -19
- package/src/editor/editor.spec.ts +2 -9
- package/src/editor/editor.ts +31 -77
- package/src/editor/union.spec.ts +1 -5
- package/src/editor/union.ts +1 -4
- package/src/extensions/clipboard-serializer.ts +4 -16
- package/src/extensions/command.ts +20 -48
- package/src/extensions/default-state.spec.ts +1 -9
- package/src/extensions/default-state.ts +6 -32
- package/src/extensions/events/dom-event.spec.ts +1 -6
- package/src/extensions/events/dom-event.ts +5 -20
- package/src/extensions/events/editor-event.ts +5 -17
- package/src/extensions/events/focus.spec.ts +1 -6
- package/src/extensions/events/plugin-view.ts +2 -9
- package/src/extensions/history.ts +3 -10
- package/src/extensions/keymap-base.spec.ts +89 -0
- package/src/extensions/keymap-base.ts +34 -13
- package/src/extensions/keymap.spec.ts +12 -22
- package/src/extensions/keymap.ts +16 -69
- package/src/extensions/mark-spec.spec.ts +5 -20
- package/src/extensions/mark-spec.ts +33 -41
- package/src/extensions/mark-view-effect.ts +3 -9
- package/src/extensions/mark-view.ts +2 -8
- package/src/extensions/node-spec.spec.ts +5 -21
- package/src/extensions/node-spec.ts +31 -33
- package/src/extensions/node-view-effect.ts +3 -9
- package/src/extensions/node-view.ts +2 -8
- package/src/extensions/plugin.spec.ts +3 -16
- package/src/extensions/plugin.ts +4 -14
- package/src/facets/base-extension.ts +1 -4
- package/src/facets/command.ts +10 -10
- package/src/facets/facet-extension.spec.ts +4 -15
- package/src/facets/facet-node.spec.ts +2 -9
- package/src/facets/facet-node.ts +4 -9
- package/src/facets/facet.spec.ts +1 -4
- package/src/facets/schema-spec.ts +2 -9
- package/src/facets/schema.ts +3 -12
- package/src/facets/state.spec.ts +8 -15
- package/src/facets/state.ts +5 -20
- package/src/facets/union-extension.ts +2 -8
- package/src/index.ts +42 -188
- package/src/test/index.ts +1 -4
- package/src/test/test-builder.ts +1 -4
- package/src/test/test-editor.spec.ts +1 -5
- package/src/test/test-editor.ts +5 -24
- package/src/testing/index.ts +18 -14
- package/src/types/extension-command.ts +0 -7
- package/src/types/extension.spec.ts +1 -4
- package/src/types/extension.ts +3 -29
- package/src/types/simplify-union.ts +1 -4
- package/src/utils/array-grouping.spec.ts +2 -15
- package/src/utils/array-grouping.ts +1 -14
- package/src/utils/array.ts +0 -4
- package/src/utils/attrs-match.ts +1 -5
- package/src/utils/clsx.spec.ts +1 -4
- package/src/utils/combine-event-handlers.spec.ts +1 -5
- package/src/utils/combine-event-handlers.ts +4 -6
- package/src/utils/default-block-at.ts +1 -4
- package/src/utils/editor-content.spec.ts +1 -4
- package/src/utils/editor-content.ts +7 -19
- package/src/utils/find-node.ts +65 -0
- package/src/utils/find-parent-node-of-type.ts +6 -12
- package/src/utils/find-parent-node.spec.ts +1 -5
- package/src/utils/find-parent-node.ts +1 -4
- package/src/utils/get-custom-selection.ts +1 -5
- package/src/utils/get-mark-type.ts +1 -4
- package/src/utils/get-node-type.ts +1 -4
- package/src/utils/get-node-types.ts +1 -4
- package/src/utils/includes-mark.ts +1 -5
- package/src/utils/is-at-block-start.ts +1 -4
- package/src/utils/is-mark-absent.spec.ts +1 -4
- package/src/utils/is-mark-absent.ts +1 -5
- package/src/utils/is-mark-active.ts +1 -4
- package/src/utils/is-node-active.spec.ts +109 -0
- package/src/utils/is-node-active.ts +17 -8
- package/src/utils/is-subset.spec.ts +1 -4
- package/src/utils/maybe-run.spec.ts +1 -5
- package/src/utils/merge-objects.spec.ts +1 -4
- package/src/utils/merge-objects.ts +2 -1
- package/src/utils/merge-specs.ts +1 -4
- package/src/utils/object-equal.spec.ts +1 -4
- package/src/utils/output-spec.test.ts +1 -5
- package/src/utils/output-spec.ts +12 -9
- package/src/utils/parse.spec.ts +2 -11
- package/src/utils/parse.ts +12 -24
- package/src/utils/remove-undefined-values.spec.ts +1 -4
- package/src/utils/set-selection-around.ts +1 -4
- package/src/utils/type-assertion.ts +2 -21
- package/src/utils/unicode.spec.ts +1 -4
- package/dist/editor-B0L9BgMi.js.map +0 -1
- package/dist/editor-M9OimMiI.d.ts.map +0 -1
- package/src/extensions/doc.ts +0 -31
- package/src/extensions/paragraph.ts +0 -61
- package/src/extensions/text.ts +0 -34
- package/src/types/base-node-view-options.ts +0 -33
- package/src/types/object-entries.ts +0 -13
- package/src/utils/collect-children.ts +0 -21
- package/src/utils/collect-nodes.ts +0 -37
- package/src/utils/deep-equals.spec.ts +0 -26
- package/src/utils/deep-equals.ts +0 -29
- package/src/utils/get-id.spec.ts +0 -14
- package/src/utils/get-id.ts +0 -13
package/dist/prosekit-core.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { isElementLike, once } from "@ocavue/utils";
|
|
7
|
-
import OrderedMap from "orderedmap";
|
|
8
|
-
import mapValues from "just-map-values";
|
|
9
|
-
import clone from "just-clone";
|
|
1
|
+
import { A as isFragment, B as EditorNotFoundError, C as defineFacetPayload, D as Priority, E as defineFacet, F as isSlice, I as isTextSelection, L as getNodeType, M as isNodeSelection, N as isProseMirrorNode, O as isNodeActive, P as isSelection, R as assert, S as stateFacet, T as rootFacet, V as ProseKitError, _ as jsonFromState, a as union, b as nodeFromJSON, c as isMarkActive, d as elementFromJSON, f as elementFromNode, g as jsonFromNode, h as jsonFromHTML, j as isMark, k as isAllSelection, l as isMarkAbsent, m as htmlFromNode, p as htmlFromJSON, r as createEditor, t as Editor, u as defineDefaultState, v as nodeFromElement, w as schemaFacet, x as stateFromJSON, y as nodeFromHTML, z as getMarkType } from "./editor-g-Rqn-ZE.js";
|
|
2
|
+
import { Plugin, PluginKey, ProseMirrorPlugin, TextSelection } from "@prosekit/pm/state";
|
|
3
|
+
import { DOMSerializer, Fragment, Slice } from "@prosekit/pm/model";
|
|
4
|
+
import { ReplaceAroundStep, dropPoint, findWrapping } from "@prosekit/pm/transform";
|
|
5
|
+
import { baseKeymap, chainCommands, createParagraphNear, deleteSelection, joinTextblockBackward, lift, liftEmptyBlock, newlineInCode, selectAll as selectAll$1, selectNodeBackward, setBlockType as setBlockType$1, toggleMark as toggleMark$1 } from "@prosekit/pm/commands";
|
|
6
|
+
import { isElementLike, isNotNullish, mapGroupBy, once } from "@ocavue/utils";
|
|
10
7
|
import { history, redo, undo } from "@prosekit/pm/history";
|
|
11
8
|
import { keydownHandler } from "@prosekit/pm/keymap";
|
|
12
9
|
import { splitSplittableBlock } from "prosemirror-splittable";
|
|
10
|
+
import OrderedMap from "orderedmap";
|
|
13
11
|
import clsxLite from "clsx/lite";
|
|
14
12
|
|
|
15
13
|
//#region src/commands/add-mark.ts
|
|
@@ -131,7 +129,7 @@ function insertNode(options) {
|
|
|
131
129
|
return (state, dispatch) => {
|
|
132
130
|
const node = options.node ? options.node : options.type ? getNodeType(state.schema, options.type).createAndFill(options.attrs) : null;
|
|
133
131
|
assert(node, "You must provide either a node or a type");
|
|
134
|
-
const insertPos =
|
|
132
|
+
const insertPos = dropPoint(state.doc, options.pos ?? state.selection.anchor, new Slice(Fragment.from([node]), 0, 0));
|
|
135
133
|
if (insertPos == null) return false;
|
|
136
134
|
if (dispatch) {
|
|
137
135
|
const tr = state.tr.insert(insertPos, node);
|
|
@@ -180,6 +178,16 @@ function findParentNode(predicate, $pos) {
|
|
|
180
178
|
}
|
|
181
179
|
}
|
|
182
180
|
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/utils/get-node-types.ts
|
|
183
|
+
/**
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
186
|
+
function getNodeTypes(schema, types) {
|
|
187
|
+
if (Array.isArray(types)) return types.map((type) => getNodeType(schema, type));
|
|
188
|
+
return [getNodeType(schema, types)];
|
|
189
|
+
}
|
|
190
|
+
|
|
183
191
|
//#endregion
|
|
184
192
|
//#region src/utils/find-parent-node-of-type.ts
|
|
185
193
|
/**
|
|
@@ -188,8 +196,8 @@ function findParentNode(predicate, $pos) {
|
|
|
188
196
|
* @public
|
|
189
197
|
*/
|
|
190
198
|
function findParentNodeOfType(type, $pos) {
|
|
191
|
-
const
|
|
192
|
-
return findParentNode((node) => node.type
|
|
199
|
+
const nodeTypes = getNodeTypes($pos.doc.type.schema, type);
|
|
200
|
+
return findParentNode((node) => nodeTypes.includes(node.type), $pos);
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
//#endregion
|
|
@@ -210,6 +218,56 @@ function removeNode(options) {
|
|
|
210
218
|
};
|
|
211
219
|
}
|
|
212
220
|
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/commands/select-all.ts
|
|
223
|
+
/**
|
|
224
|
+
* Returns a command that selects the whole document.
|
|
225
|
+
*
|
|
226
|
+
* @public
|
|
227
|
+
*/
|
|
228
|
+
function selectAll() {
|
|
229
|
+
return selectAll$1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/commands/select-block.ts
|
|
234
|
+
function getTextblockEndpoint(selection, side) {
|
|
235
|
+
const $pos = side < 0 ? selection.$from : selection.$to;
|
|
236
|
+
let depth = $pos.depth;
|
|
237
|
+
while ($pos.node(depth).isInline) {
|
|
238
|
+
if (!depth) return;
|
|
239
|
+
depth--;
|
|
240
|
+
}
|
|
241
|
+
if (!$pos.node(depth).isTextblock) return;
|
|
242
|
+
return side < 0 ? $pos.start(depth) : $pos.end(depth);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
const selectBlockCommand = (state, dispatch) => {
|
|
248
|
+
const { selection } = state;
|
|
249
|
+
if (!isTextSelection(selection)) return false;
|
|
250
|
+
const expectedFrom = getTextblockEndpoint(selection, -1);
|
|
251
|
+
const expectedTo = getTextblockEndpoint(selection, 1);
|
|
252
|
+
if (expectedFrom == null || expectedTo == null) return false;
|
|
253
|
+
if (selection.from <= expectedFrom && selection.to >= expectedTo) return false;
|
|
254
|
+
if (dispatch) {
|
|
255
|
+
const newSelection = TextSelection.create(state.doc, expectedFrom, expectedTo);
|
|
256
|
+
dispatch(state.tr.setSelection(newSelection));
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Returns a command to expand the text selection to cover the current block
|
|
262
|
+
* node. If the text selection spans multiple blocks, it will select all
|
|
263
|
+
* blocks in the selection.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
*/
|
|
267
|
+
function selectBlock() {
|
|
268
|
+
return selectBlockCommand;
|
|
269
|
+
}
|
|
270
|
+
|
|
213
271
|
//#endregion
|
|
214
272
|
//#region src/utils/get-custom-selection.ts
|
|
215
273
|
function getCustomSelection(state, from, to) {
|
|
@@ -262,36 +320,65 @@ function setBlockType(options) {
|
|
|
262
320
|
}
|
|
263
321
|
|
|
264
322
|
//#endregion
|
|
265
|
-
//#region src/
|
|
323
|
+
//#region src/commands/set-node-attrs.ts
|
|
266
324
|
/**
|
|
267
|
-
*
|
|
325
|
+
* Returns a command that sets the attributes of the current node.
|
|
326
|
+
*
|
|
327
|
+
* @param options
|
|
328
|
+
*
|
|
329
|
+
* @public
|
|
268
330
|
*/
|
|
269
|
-
function
|
|
270
|
-
|
|
271
|
-
|
|
331
|
+
function setNodeAttrs({ type, attrs, pos }) {
|
|
332
|
+
return (state, dispatch) => {
|
|
333
|
+
let updatePos;
|
|
334
|
+
if (pos == null) {
|
|
335
|
+
const found = findParentNodeOfType(type, state.selection.$anchor);
|
|
336
|
+
if (!found) return false;
|
|
337
|
+
updatePos = found.pos;
|
|
338
|
+
} else {
|
|
339
|
+
const found = state.doc.nodeAt(pos);
|
|
340
|
+
if (!found) return false;
|
|
341
|
+
if (!getNodeTypes(state.schema, type).includes(found.type)) return false;
|
|
342
|
+
updatePos = pos;
|
|
343
|
+
}
|
|
344
|
+
if (dispatch) {
|
|
345
|
+
const { tr } = state;
|
|
346
|
+
for (const [key, value] of Object.entries(attrs)) tr.setNodeAttribute(updatePos, key, value);
|
|
347
|
+
dispatch(tr);
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
};
|
|
272
351
|
}
|
|
273
352
|
|
|
274
353
|
//#endregion
|
|
275
|
-
//#region src/commands/set-node-attrs.ts
|
|
354
|
+
//#region src/commands/set-node-attrs-between.ts
|
|
276
355
|
/**
|
|
277
|
-
* Returns a command that
|
|
356
|
+
* Returns a command that sets the attributes of all matching nodes between the
|
|
357
|
+
* `from` and `to` positions.
|
|
358
|
+
*
|
|
359
|
+
* @param options
|
|
278
360
|
*
|
|
279
361
|
* @public
|
|
280
362
|
*/
|
|
281
|
-
function
|
|
363
|
+
function setNodeAttrsBetween(options) {
|
|
282
364
|
return (state, dispatch) => {
|
|
365
|
+
const from = options.from ?? state.selection.from;
|
|
366
|
+
const to = options.to ?? state.selection.to;
|
|
367
|
+
if (from > to) return false;
|
|
283
368
|
const nodeTypes = getNodeTypes(state.schema, options.type);
|
|
284
|
-
const from = options.pos ?? state.selection.from;
|
|
285
|
-
const to = options.pos ?? state.selection.to;
|
|
286
369
|
const positions = [];
|
|
370
|
+
let found = false;
|
|
287
371
|
state.doc.nodesBetween(from, to, (node, pos) => {
|
|
288
|
-
if (nodeTypes.includes(node.type))
|
|
289
|
-
|
|
372
|
+
if (nodeTypes.includes(node.type)) {
|
|
373
|
+
positions.push(pos);
|
|
374
|
+
found = true;
|
|
375
|
+
}
|
|
376
|
+
if (!dispatch && found) return false;
|
|
290
377
|
});
|
|
291
|
-
if (
|
|
378
|
+
if (!found) return false;
|
|
292
379
|
if (dispatch) {
|
|
293
380
|
const { tr } = state;
|
|
294
|
-
for (const
|
|
381
|
+
for (const [key, value] of Object.entries(options.attrs)) for (const pos of positions) tr.setNodeAttribute(pos, key, value);
|
|
295
382
|
dispatch(tr);
|
|
296
383
|
}
|
|
297
384
|
return true;
|
|
@@ -319,7 +406,7 @@ function toggleMark({ type, attrs, removeWhenPresent = false, enterInlineAtoms =
|
|
|
319
406
|
//#endregion
|
|
320
407
|
//#region src/commands/toggle-node.ts
|
|
321
408
|
/**
|
|
322
|
-
* Returns a command that
|
|
409
|
+
* Returns a command that sets the selected textblocks to the given node type
|
|
323
410
|
* with the given attributes.
|
|
324
411
|
*
|
|
325
412
|
* @param options
|
|
@@ -350,7 +437,7 @@ function wrap(options) {
|
|
|
350
437
|
const { $from, $to } = state.selection;
|
|
351
438
|
const range = $from.blockRange($to);
|
|
352
439
|
if (!range) return false;
|
|
353
|
-
const wrapping = findWrapping(range, getNodeType(state.schema, options.
|
|
440
|
+
const wrapping = findWrapping(range, getNodeType(state.schema, options.type), options.attrs);
|
|
354
441
|
if (!wrapping) return false;
|
|
355
442
|
dispatch?.(state.tr.wrap(range, wrapping));
|
|
356
443
|
return true;
|
|
@@ -480,7 +567,7 @@ const pluginFacet = defineFacet({
|
|
|
480
567
|
else if (Array.isArray(payload) && payload.every((p) => p instanceof Plugin)) plugins.push(...payload);
|
|
481
568
|
else if (typeof payload === "function") plugins.push(...[payload({ schema })].flat());
|
|
482
569
|
else throw new ProseKitError("Invalid plugin");
|
|
483
|
-
return { plugins:
|
|
570
|
+
return { plugins: [...plugins].reverse() };
|
|
484
571
|
};
|
|
485
572
|
},
|
|
486
573
|
parent: stateFacet
|
|
@@ -489,7 +576,7 @@ const pluginFacet = defineFacet({
|
|
|
489
576
|
//#endregion
|
|
490
577
|
//#region src/extensions/clipboard-serializer.ts
|
|
491
578
|
function mergeWrappers(wrappers) {
|
|
492
|
-
return (fn) => wrappers.filter(isNotNullish).reduce((fn
|
|
579
|
+
return (fn) => wrappers.filter(isNotNullish).reduce((fn, wrapper) => wrapper(fn), fn);
|
|
493
580
|
}
|
|
494
581
|
function wrapFunction(fn, wrapper) {
|
|
495
582
|
return wrapper ? wrapper(fn) : fn;
|
|
@@ -501,11 +588,11 @@ var CustomDOMSerializer = class extends DOMSerializer {
|
|
|
501
588
|
this.serializeNodeWrapper = serializeNodeWrapper;
|
|
502
589
|
}
|
|
503
590
|
serializeFragment(...args) {
|
|
504
|
-
const fn = (...args
|
|
591
|
+
const fn = (...args) => super.serializeFragment(...args);
|
|
505
592
|
return wrapFunction(fn, this.serializeFragmentWrapper)(...args);
|
|
506
593
|
}
|
|
507
594
|
serializeNode(...args) {
|
|
508
|
-
const fn = (...args
|
|
595
|
+
const fn = (...args) => super.serializeNode(...args);
|
|
509
596
|
return wrapFunction(fn, this.serializeNodeWrapper)(...args);
|
|
510
597
|
}
|
|
511
598
|
};
|
|
@@ -554,25 +641,15 @@ function insertText({ text, from, to }) {
|
|
|
554
641
|
};
|
|
555
642
|
}
|
|
556
643
|
|
|
557
|
-
//#endregion
|
|
558
|
-
//#region src/commands/select-all.ts
|
|
559
|
-
/**
|
|
560
|
-
* Returns a command that selects the whole document.
|
|
561
|
-
*
|
|
562
|
-
* @public
|
|
563
|
-
*/
|
|
564
|
-
function selectAll() {
|
|
565
|
-
return (state, dispatch) => {
|
|
566
|
-
dispatch?.(state.tr.setSelection(new AllSelection(state.doc)));
|
|
567
|
-
return true;
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
|
|
571
644
|
//#endregion
|
|
572
645
|
//#region src/facets/command.ts
|
|
573
646
|
const commandFacet = defineFacet({
|
|
574
647
|
reducer: (inputs) => {
|
|
575
|
-
|
|
648
|
+
switch (inputs.length) {
|
|
649
|
+
case 0: return { commands: {} };
|
|
650
|
+
case 1: return { commands: inputs[0] };
|
|
651
|
+
default: return { commands: Object.assign({}, ...inputs) };
|
|
652
|
+
}
|
|
576
653
|
},
|
|
577
654
|
parent: rootFacet,
|
|
578
655
|
singleton: true
|
|
@@ -580,8 +657,8 @@ const commandFacet = defineFacet({
|
|
|
580
657
|
|
|
581
658
|
//#endregion
|
|
582
659
|
//#region src/extensions/command.ts
|
|
583
|
-
function defineCommands(commands
|
|
584
|
-
return defineFacetPayload(commandFacet, [commands
|
|
660
|
+
function defineCommands(commands) {
|
|
661
|
+
return defineFacetPayload(commandFacet, [commands]);
|
|
585
662
|
}
|
|
586
663
|
/**
|
|
587
664
|
* Add some base commands
|
|
@@ -597,8 +674,10 @@ function defineBaseCommands() {
|
|
|
597
674
|
toggleWrap,
|
|
598
675
|
setBlockType,
|
|
599
676
|
setNodeAttrs,
|
|
677
|
+
setNodeAttrsBetween,
|
|
600
678
|
insertDefaultBlock,
|
|
601
679
|
selectAll,
|
|
680
|
+
selectBlock,
|
|
602
681
|
addMark,
|
|
603
682
|
removeMark,
|
|
604
683
|
unsetBlockType,
|
|
@@ -607,37 +686,94 @@ function defineBaseCommands() {
|
|
|
607
686
|
}
|
|
608
687
|
|
|
609
688
|
//#endregion
|
|
610
|
-
//#region src/
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
689
|
+
//#region src/extensions/events/plugin-view.ts
|
|
690
|
+
/**
|
|
691
|
+
* Registers a event handler that is called when the editor view is mounted.
|
|
692
|
+
*
|
|
693
|
+
* @public
|
|
694
|
+
*/
|
|
695
|
+
function defineMountHandler(handler) {
|
|
696
|
+
return definePluginViewFacetPayload(["mount", handler]);
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Registers a event handler that is called when the editor state is updated.
|
|
700
|
+
*
|
|
701
|
+
* @public
|
|
702
|
+
*/
|
|
703
|
+
function defineUpdateHandler(handler) {
|
|
704
|
+
return definePluginViewFacetPayload(["update", handler]);
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Registers a event handler that is called when the editor view is unmounted.
|
|
708
|
+
*
|
|
709
|
+
* @public
|
|
710
|
+
*/
|
|
711
|
+
function defineUnmountHandler(handler) {
|
|
712
|
+
return definePluginViewFacetPayload(["unmount", handler]);
|
|
713
|
+
}
|
|
714
|
+
function definePluginViewFacetPayload(input) {
|
|
715
|
+
return defineFacetPayload(pluginViewFacet, [input]);
|
|
716
|
+
}
|
|
717
|
+
const pluginViewFacet = defineFacet({
|
|
718
|
+
reduce: () => {
|
|
719
|
+
let mountHandlers = [];
|
|
720
|
+
let updateHandlers = [];
|
|
721
|
+
let unmountHandlers = [];
|
|
722
|
+
const plugin = new ProseMirrorPlugin({
|
|
723
|
+
key: pluginKey,
|
|
724
|
+
view: (view) => {
|
|
725
|
+
mountHandlers.forEach((fn) => fn(view));
|
|
726
|
+
return {
|
|
727
|
+
update: (view, prevState) => {
|
|
728
|
+
updateHandlers.forEach((fn) => fn(view, prevState));
|
|
729
|
+
},
|
|
730
|
+
destroy: () => {
|
|
731
|
+
unmountHandlers.forEach((fn) => fn());
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
const register = (input) => {
|
|
737
|
+
mountHandlers = [];
|
|
738
|
+
updateHandlers = [];
|
|
739
|
+
unmountHandlers = [];
|
|
740
|
+
for (const args of input) switch (args[0]) {
|
|
741
|
+
case "mount":
|
|
742
|
+
mountHandlers.push(args[1]);
|
|
743
|
+
break;
|
|
744
|
+
case "update":
|
|
745
|
+
updateHandlers.push(args[1]);
|
|
746
|
+
break;
|
|
747
|
+
case "unmount":
|
|
748
|
+
unmountHandlers.push(args[1]);
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
return function reducer(input) {
|
|
753
|
+
register(input);
|
|
754
|
+
return plugin;
|
|
625
755
|
};
|
|
626
756
|
},
|
|
627
|
-
parent:
|
|
757
|
+
parent: pluginFacet,
|
|
628
758
|
singleton: true
|
|
629
759
|
});
|
|
760
|
+
const pluginKey = new PluginKey("prosekit-plugin-view-handler");
|
|
630
761
|
|
|
631
762
|
//#endregion
|
|
632
|
-
//#region src/
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
return
|
|
763
|
+
//#region src/extensions/events/doc-change.ts
|
|
764
|
+
/**
|
|
765
|
+
* Registers a event handler that is called when the editor document is changed.
|
|
766
|
+
*
|
|
767
|
+
* @public
|
|
768
|
+
*/
|
|
769
|
+
function defineDocChangeHandler(handler) {
|
|
770
|
+
return defineUpdateHandler((view, prevState) => {
|
|
771
|
+
if (!view.state.doc.eq(prevState.doc)) handler(view, prevState);
|
|
772
|
+
});
|
|
640
773
|
}
|
|
774
|
+
|
|
775
|
+
//#endregion
|
|
776
|
+
//#region src/utils/array-grouping.ts
|
|
641
777
|
function groupEntries(entries) {
|
|
642
778
|
const result = {};
|
|
643
779
|
for (const [key, value] of entries) (result[key] ||= []).push(value);
|
|
@@ -645,329 +781,66 @@ function groupEntries(entries) {
|
|
|
645
781
|
}
|
|
646
782
|
|
|
647
783
|
//#endregion
|
|
648
|
-
//#region src/utils/
|
|
649
|
-
function
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
784
|
+
//#region src/utils/combine-event-handlers.ts
|
|
785
|
+
function combineEventHandlers() {
|
|
786
|
+
let handlers = [];
|
|
787
|
+
function setHandlers(eventHandlers) {
|
|
788
|
+
handlers = eventHandlers;
|
|
789
|
+
}
|
|
790
|
+
function combinedEventHandler(...args) {
|
|
791
|
+
for (let i = handlers.length - 1; i >= 0; i--) if (handlers[i](...args)) return true;
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
return [setHandlers, combinedEventHandler];
|
|
653
795
|
}
|
|
654
796
|
|
|
655
797
|
//#endregion
|
|
656
|
-
//#region src/
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
798
|
+
//#region src/extensions/events/dom-event.ts
|
|
799
|
+
/**
|
|
800
|
+
* @internal
|
|
801
|
+
*/
|
|
802
|
+
function defineDomEventFacetPayload(...payloads) {
|
|
803
|
+
return defineFacetPayload(domEventFacet, payloads);
|
|
660
804
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
const attrSpecA = a.attrs?.[name];
|
|
669
|
-
const attrSpecB = b.attrs?.[name];
|
|
670
|
-
const attrSpecMerged = mergeObjects(attrSpecA, attrSpecB);
|
|
671
|
-
if (attrSpecMerged) attrs[name] = attrSpecMerged;
|
|
672
|
-
}
|
|
673
|
-
return mergeObjects(a, b, {
|
|
674
|
-
attrs,
|
|
675
|
-
parseDOM: [...a.parseDOM ?? [], ...b.parseDOM ?? []]
|
|
676
|
-
});
|
|
805
|
+
/**
|
|
806
|
+
* Register a new event handler for the given event type.
|
|
807
|
+
*
|
|
808
|
+
* @public
|
|
809
|
+
*/
|
|
810
|
+
function defineDOMEventHandler(event, handler) {
|
|
811
|
+
return defineDomEventFacetPayload([event, handler]);
|
|
677
812
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
const
|
|
695
|
-
for (const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
else oldAttrs = {};
|
|
710
|
-
const newAttrs = setObjectAttributes(oldAttrs, attrs);
|
|
711
|
-
return [
|
|
712
|
-
dom[0],
|
|
713
|
-
newAttrs,
|
|
714
|
-
...rest
|
|
715
|
-
];
|
|
716
|
-
}
|
|
717
|
-
if (isElementLike(dom)) return setElementAttributes(dom, attrs);
|
|
718
|
-
if (typeof dom === "object" && "dom" in dom && isElementLike(dom.dom)) return {
|
|
719
|
-
...dom,
|
|
720
|
-
dom: setElementAttributes(dom.dom, attrs)
|
|
721
|
-
};
|
|
722
|
-
return dom;
|
|
723
|
-
}
|
|
724
|
-
function setObjectAttributes(obj, attrs) {
|
|
725
|
-
obj = { ...obj };
|
|
726
|
-
for (const [key, value] of attrs) {
|
|
727
|
-
const oldValue = obj[key];
|
|
728
|
-
obj[key] = key === "style" ? joinStyles(value, typeof oldValue === "string" ? oldValue : "") : value;
|
|
729
|
-
}
|
|
730
|
-
return obj;
|
|
731
|
-
}
|
|
732
|
-
function setElementAttributes(element, attrs) {
|
|
733
|
-
element = element.cloneNode(true);
|
|
734
|
-
for (const [key, value] of attrs) {
|
|
735
|
-
const oldValue = element.getAttribute(key);
|
|
736
|
-
const newValue = key === "style" ? joinStyles(value, typeof oldValue === "string" ? oldValue : "") : value;
|
|
737
|
-
element.setAttribute(key, newValue);
|
|
738
|
-
}
|
|
739
|
-
return element;
|
|
740
|
-
}
|
|
741
|
-
function joinStyles(...styles) {
|
|
742
|
-
return styles.map((style) => style.trim().replace(/;$/, "")).filter(Boolean).join("; ");
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
//#endregion
|
|
746
|
-
//#region src/extensions/node-spec.ts
|
|
747
|
-
/**
|
|
748
|
-
* Defines a node type.
|
|
749
|
-
*
|
|
750
|
-
* @public
|
|
751
|
-
*/
|
|
752
|
-
function defineNodeSpec(options) {
|
|
753
|
-
return defineFacetPayload(nodeSpecFacet, [[options, void 0]]);
|
|
754
|
-
}
|
|
755
|
-
/**
|
|
756
|
-
* Defines an attribute for a node type.
|
|
757
|
-
*
|
|
758
|
-
* @public
|
|
759
|
-
*/
|
|
760
|
-
function defineNodeAttr(options) {
|
|
761
|
-
return defineFacetPayload(nodeSpecFacet, [[void 0, options]]);
|
|
762
|
-
}
|
|
763
|
-
const nodeSpecFacet = defineFacet({
|
|
764
|
-
reducer: (payloads) => {
|
|
765
|
-
let specs = OrderedMap.from({});
|
|
766
|
-
let topNodeName = void 0;
|
|
767
|
-
const specPayloads = payloads.map((input) => input[0]).filter(isNotNullish);
|
|
768
|
-
const attrPayloads = payloads.map((input) => input[1]).filter(isNotNullish);
|
|
769
|
-
for (const { name, topNode, ...spec } of specPayloads) {
|
|
770
|
-
if (topNode) topNodeName = name;
|
|
771
|
-
const prevSpec = specs.get(name);
|
|
772
|
-
if (prevSpec) specs = specs.update(name, mergeSpecs(prevSpec, spec));
|
|
773
|
-
else specs = specs.addToStart(name, spec);
|
|
774
|
-
}
|
|
775
|
-
const groupedAttrs = groupBy(attrPayloads, (payload) => payload.type);
|
|
776
|
-
for (const [type, attrs] of Object.entries(groupedAttrs)) {
|
|
777
|
-
if (!attrs) continue;
|
|
778
|
-
const maybeSpec = specs.get(type);
|
|
779
|
-
assert(maybeSpec, `Node type ${type} must be defined`);
|
|
780
|
-
const spec = clone(maybeSpec);
|
|
781
|
-
if (!spec.attrs) spec.attrs = {};
|
|
782
|
-
for (const attr of attrs) spec.attrs[attr.attr] = {
|
|
783
|
-
default: attr.default,
|
|
784
|
-
validate: attr.validate,
|
|
785
|
-
splittable: attr.splittable
|
|
786
|
-
};
|
|
787
|
-
if (spec.toDOM) spec.toDOM = wrapOutputSpecAttrs(spec.toDOM, attrs);
|
|
788
|
-
if (spec.parseDOM) spec.parseDOM = spec.parseDOM.map((rule) => wrapTagParseRuleAttrs(rule, attrs));
|
|
789
|
-
specs = specs.update(type, spec);
|
|
790
|
-
}
|
|
791
|
-
return {
|
|
792
|
-
nodes: specs,
|
|
793
|
-
topNode: topNodeName
|
|
794
|
-
};
|
|
795
|
-
},
|
|
796
|
-
parent: schemaSpecFacet,
|
|
797
|
-
singleton: true
|
|
798
|
-
});
|
|
799
|
-
|
|
800
|
-
//#endregion
|
|
801
|
-
//#region src/extensions/doc.ts
|
|
802
|
-
/**
|
|
803
|
-
* @public
|
|
804
|
-
*
|
|
805
|
-
* @deprecated Use the following import instead:
|
|
806
|
-
*
|
|
807
|
-
* ```ts
|
|
808
|
-
* import { defineDoc } from 'prosekit/extensions/doc'
|
|
809
|
-
* ```
|
|
810
|
-
*/
|
|
811
|
-
function defineDoc() {
|
|
812
|
-
console.warn("[prosekit] The `defineDoc` function from `prosekit/core` is deprecated. Use the following import instead: `import { defineDoc } from \"prosekit/extensions/doc\"`.");
|
|
813
|
-
return defineNodeSpec({
|
|
814
|
-
name: "doc",
|
|
815
|
-
content: "block+",
|
|
816
|
-
topNode: true
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
//#endregion
|
|
821
|
-
//#region src/extensions/events/plugin-view.ts
|
|
822
|
-
/**
|
|
823
|
-
* Registers a event handler that is called when the editor view is mounted.
|
|
824
|
-
*
|
|
825
|
-
* @public
|
|
826
|
-
*/
|
|
827
|
-
function defineMountHandler(handler) {
|
|
828
|
-
return definePluginViewFacetPayload(["mount", handler]);
|
|
829
|
-
}
|
|
830
|
-
/**
|
|
831
|
-
* Registers a event handler that is called when the editor state is updated.
|
|
832
|
-
*
|
|
833
|
-
* @public
|
|
834
|
-
*/
|
|
835
|
-
function defineUpdateHandler(handler) {
|
|
836
|
-
return definePluginViewFacetPayload(["update", handler]);
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Registers a event handler that is called when the editor view is unmounted.
|
|
840
|
-
*
|
|
841
|
-
* @public
|
|
842
|
-
*/
|
|
843
|
-
function defineUnmountHandler(handler) {
|
|
844
|
-
return definePluginViewFacetPayload(["unmount", handler]);
|
|
845
|
-
}
|
|
846
|
-
function definePluginViewFacetPayload(input) {
|
|
847
|
-
return defineFacetPayload(pluginViewFacet, [input]);
|
|
848
|
-
}
|
|
849
|
-
const pluginViewFacet = defineFacet({
|
|
850
|
-
reduce: () => {
|
|
851
|
-
let mountHandlers = [];
|
|
852
|
-
let updateHandlers = [];
|
|
853
|
-
let unmountHandlers = [];
|
|
854
|
-
const plugin = new ProseMirrorPlugin({
|
|
855
|
-
key: pluginKey,
|
|
856
|
-
view: (view) => {
|
|
857
|
-
mountHandlers.forEach((fn) => fn(view));
|
|
858
|
-
return {
|
|
859
|
-
update: (view$1, prevState) => {
|
|
860
|
-
updateHandlers.forEach((fn) => fn(view$1, prevState));
|
|
861
|
-
},
|
|
862
|
-
destroy: () => {
|
|
863
|
-
unmountHandlers.forEach((fn) => fn());
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
});
|
|
868
|
-
const register = (input) => {
|
|
869
|
-
mountHandlers = [];
|
|
870
|
-
updateHandlers = [];
|
|
871
|
-
unmountHandlers = [];
|
|
872
|
-
for (const args of input) switch (args[0]) {
|
|
873
|
-
case "mount":
|
|
874
|
-
mountHandlers.push(args[1]);
|
|
875
|
-
break;
|
|
876
|
-
case "update":
|
|
877
|
-
updateHandlers.push(args[1]);
|
|
878
|
-
break;
|
|
879
|
-
case "unmount":
|
|
880
|
-
unmountHandlers.push(args[1]);
|
|
881
|
-
break;
|
|
882
|
-
}
|
|
883
|
-
};
|
|
884
|
-
return function reducer(input) {
|
|
885
|
-
register(input);
|
|
886
|
-
return plugin;
|
|
887
|
-
};
|
|
888
|
-
},
|
|
889
|
-
parent: pluginFacet,
|
|
890
|
-
singleton: true
|
|
891
|
-
});
|
|
892
|
-
const pluginKey = new PluginKey("prosekit-plugin-view-handler");
|
|
893
|
-
|
|
894
|
-
//#endregion
|
|
895
|
-
//#region src/extensions/events/doc-change.ts
|
|
896
|
-
/**
|
|
897
|
-
* Registers a event handler that is called when the editor document is changed.
|
|
898
|
-
*
|
|
899
|
-
* @public
|
|
900
|
-
*/
|
|
901
|
-
function defineDocChangeHandler(handler) {
|
|
902
|
-
return defineUpdateHandler((view, prevState) => {
|
|
903
|
-
if (!view.state.doc.eq(prevState.doc)) handler(view, prevState);
|
|
904
|
-
});
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
//#endregion
|
|
908
|
-
//#region src/utils/combine-event-handlers.ts
|
|
909
|
-
function combineEventHandlers() {
|
|
910
|
-
let handlers = [];
|
|
911
|
-
function setHandlers(eventHandlers) {
|
|
912
|
-
handlers = toReversed(eventHandlers);
|
|
913
|
-
}
|
|
914
|
-
function combinedEventHandler(...args) {
|
|
915
|
-
for (const handler of handlers) if (handler(...args)) return true;
|
|
916
|
-
return false;
|
|
917
|
-
}
|
|
918
|
-
return [setHandlers, combinedEventHandler];
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
//#endregion
|
|
922
|
-
//#region src/extensions/events/dom-event.ts
|
|
923
|
-
/**
|
|
924
|
-
* @internal
|
|
925
|
-
*/
|
|
926
|
-
function defineDomEventFacetPayload(...payloads) {
|
|
927
|
-
return defineFacetPayload(domEventFacet, payloads);
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* Register a new event handler for the given event type.
|
|
931
|
-
*
|
|
932
|
-
* @public
|
|
933
|
-
*/
|
|
934
|
-
function defineDOMEventHandler(event, handler) {
|
|
935
|
-
return defineDomEventFacetPayload([event, handler]);
|
|
936
|
-
}
|
|
937
|
-
/**
|
|
938
|
-
* @internal
|
|
939
|
-
*/
|
|
940
|
-
const domEventFacet = defineFacet({
|
|
941
|
-
reduce: () => {
|
|
942
|
-
const setHandlersMap = {};
|
|
943
|
-
const combinedHandlerMap = {};
|
|
944
|
-
let plugin;
|
|
945
|
-
const update = (payloads) => {
|
|
946
|
-
let hasNewEvent = false;
|
|
947
|
-
for (const [event] of payloads) if (!setHandlersMap[event]) {
|
|
948
|
-
hasNewEvent = true;
|
|
949
|
-
const [setHandlers, combinedHandler] = combineEventHandlers();
|
|
950
|
-
setHandlersMap[event] = setHandlers;
|
|
951
|
-
const e = (view, eventObject) => {
|
|
952
|
-
return combinedHandler(view, eventObject);
|
|
953
|
-
};
|
|
954
|
-
combinedHandlerMap[event] = e;
|
|
955
|
-
}
|
|
956
|
-
const map = groupEntries(payloads);
|
|
957
|
-
for (const [event, setHandlers] of Object.entries(setHandlersMap)) setHandlers(map[event] ?? []);
|
|
958
|
-
if (hasNewEvent) plugin = new ProseMirrorPlugin({
|
|
959
|
-
key: new PluginKey("prosekit-dom-event-handler"),
|
|
960
|
-
props: { handleDOMEvents: combinedHandlerMap }
|
|
961
|
-
});
|
|
962
|
-
};
|
|
963
|
-
return function reducer(inputs) {
|
|
964
|
-
update(inputs);
|
|
965
|
-
return plugin ?? [];
|
|
966
|
-
};
|
|
967
|
-
},
|
|
968
|
-
parent: pluginFacet,
|
|
969
|
-
singleton: true
|
|
970
|
-
});
|
|
813
|
+
/**
|
|
814
|
+
* @internal
|
|
815
|
+
*/
|
|
816
|
+
const domEventFacet = defineFacet({
|
|
817
|
+
reduce: () => {
|
|
818
|
+
const setHandlersMap = {};
|
|
819
|
+
const combinedHandlerMap = {};
|
|
820
|
+
let plugin;
|
|
821
|
+
const update = (payloads) => {
|
|
822
|
+
let hasNewEvent = false;
|
|
823
|
+
for (const [event] of payloads) if (!setHandlersMap[event]) {
|
|
824
|
+
hasNewEvent = true;
|
|
825
|
+
const [setHandlers, combinedHandler] = combineEventHandlers();
|
|
826
|
+
setHandlersMap[event] = setHandlers;
|
|
827
|
+
combinedHandlerMap[event] = combinedHandler;
|
|
828
|
+
}
|
|
829
|
+
const map = groupEntries(payloads);
|
|
830
|
+
for (const [event, setHandlers] of Object.entries(setHandlersMap)) setHandlers(map[event] ?? []);
|
|
831
|
+
if (hasNewEvent) plugin = new ProseMirrorPlugin({
|
|
832
|
+
key: new PluginKey("prosekit-dom-event-handler"),
|
|
833
|
+
props: { handleDOMEvents: combinedHandlerMap }
|
|
834
|
+
});
|
|
835
|
+
};
|
|
836
|
+
return function reducer(inputs) {
|
|
837
|
+
update(inputs);
|
|
838
|
+
return plugin ?? [];
|
|
839
|
+
};
|
|
840
|
+
},
|
|
841
|
+
parent: pluginFacet,
|
|
842
|
+
singleton: true
|
|
843
|
+
});
|
|
971
844
|
|
|
972
845
|
//#endregion
|
|
973
846
|
//#region src/extensions/events/editor-event.ts
|
|
@@ -1161,69 +1034,38 @@ const isApple = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(nav
|
|
|
1161
1034
|
*
|
|
1162
1035
|
* @public
|
|
1163
1036
|
*/
|
|
1164
|
-
function defineKeymap(keymap
|
|
1165
|
-
return defineFacetPayload(keymapFacet, [keymap
|
|
1037
|
+
function defineKeymap(keymap) {
|
|
1038
|
+
return defineFacetPayload(keymapFacet, [keymap]);
|
|
1166
1039
|
}
|
|
1167
1040
|
/**
|
|
1168
1041
|
* @internal
|
|
1169
1042
|
*/
|
|
1170
1043
|
const keymapFacet = defineFacet({
|
|
1171
1044
|
reduce: () => {
|
|
1172
|
-
let
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1045
|
+
let subHandlers = [];
|
|
1046
|
+
const rootHandler = (view, event) => {
|
|
1047
|
+
for (const handler of subHandlers) if (handler(view, event)) return true;
|
|
1175
1048
|
return false;
|
|
1176
1049
|
};
|
|
1177
1050
|
const plugin = new Plugin({
|
|
1178
1051
|
key: keymapPluginKey,
|
|
1179
|
-
props: { handleKeyDown:
|
|
1052
|
+
props: { handleKeyDown: rootHandler }
|
|
1180
1053
|
});
|
|
1181
1054
|
return (keymaps) => {
|
|
1182
|
-
|
|
1055
|
+
subHandlers = keymaps.map(keydownHandler).reverse();
|
|
1183
1056
|
return plugin;
|
|
1184
1057
|
};
|
|
1185
1058
|
},
|
|
1186
1059
|
parent: pluginFacet,
|
|
1187
1060
|
singleton: true
|
|
1188
1061
|
});
|
|
1189
|
-
function mergeKeymaps(keymaps) {
|
|
1190
|
-
const bindings = {};
|
|
1191
|
-
for (const keymap$1 of keymaps) for (const [key, command] of Object.entries(keymap$1)) {
|
|
1192
|
-
const normalizedKey = normalizeKeyName(key);
|
|
1193
|
-
(bindings[normalizedKey] ||= []).push(command);
|
|
1194
|
-
}
|
|
1195
|
-
return mapValues(bindings, mergeCommands);
|
|
1196
|
-
}
|
|
1197
|
-
function mergeCommands(commands$1) {
|
|
1198
|
-
return chainCommands(...commands$1);
|
|
1199
|
-
}
|
|
1200
|
-
function normalizeKeyName(name) {
|
|
1201
|
-
let parts = name.split(/-(?!$)/), result = parts[parts.length - 1];
|
|
1202
|
-
if (result == "Space") result = " ";
|
|
1203
|
-
let alt, ctrl, shift, meta;
|
|
1204
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
1205
|
-
let mod = parts[i];
|
|
1206
|
-
if (/^(cmd|meta|m)$/i.test(mod)) meta = true;
|
|
1207
|
-
else if (/^a(lt)?$/i.test(mod)) alt = true;
|
|
1208
|
-
else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
|
|
1209
|
-
else if (/^s(hift)?$/i.test(mod)) shift = true;
|
|
1210
|
-
else if (/^mod$/i.test(mod)) if (isApple) meta = true;
|
|
1211
|
-
else ctrl = true;
|
|
1212
|
-
else throw new Error("Unrecognized modifier name: " + mod);
|
|
1213
|
-
}
|
|
1214
|
-
if (alt) result = "Alt-" + result;
|
|
1215
|
-
if (ctrl) result = "Ctrl-" + result;
|
|
1216
|
-
if (meta) result = "Meta-" + result;
|
|
1217
|
-
if (shift) result = "Shift-" + result;
|
|
1218
|
-
return result;
|
|
1219
|
-
}
|
|
1220
1062
|
const keymapPluginKey = new PluginKey("prosekit-keymap");
|
|
1221
1063
|
|
|
1222
1064
|
//#endregion
|
|
1223
1065
|
//#region src/extensions/history.ts
|
|
1224
1066
|
const keymap = {
|
|
1225
1067
|
"Mod-z": undo,
|
|
1226
|
-
"
|
|
1068
|
+
"Mod-Z": redo
|
|
1227
1069
|
};
|
|
1228
1070
|
if (!isApple) keymap["Mod-y"] = redo;
|
|
1229
1071
|
const commands = {
|
|
@@ -1248,25 +1090,168 @@ function defineHistory({ depth = 200, newGroupDelay = 250 } = {}) {
|
|
|
1248
1090
|
//#region src/extensions/keymap-base.ts
|
|
1249
1091
|
const customEnter = chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitSplittableBlock);
|
|
1250
1092
|
const customBackspace = chainCommands(deleteSelection, joinTextblockBackward, selectNodeBackward);
|
|
1251
|
-
const customBaseKeymap = {
|
|
1252
|
-
...baseKeymap,
|
|
1253
|
-
Enter: customEnter,
|
|
1254
|
-
Backspace: customBackspace
|
|
1255
|
-
};
|
|
1256
1093
|
/**
|
|
1257
1094
|
* Defines some basic key bindings.
|
|
1258
1095
|
*
|
|
1096
|
+
* @param options
|
|
1097
|
+
*
|
|
1259
1098
|
* @public
|
|
1260
1099
|
*/
|
|
1261
|
-
function defineBaseKeymap(
|
|
1262
|
-
|
|
1263
|
-
|
|
1100
|
+
function defineBaseKeymap({ priority = Priority.low, preferBlockSelection = true } = {}) {
|
|
1101
|
+
return withPriority(defineKeymap({
|
|
1102
|
+
...baseKeymap,
|
|
1103
|
+
"Mod-a": preferBlockSelection ? chainCommands(selectBlockCommand, selectAll$1) : selectAll$1,
|
|
1104
|
+
"Enter": customEnter,
|
|
1105
|
+
"Backspace": customBackspace
|
|
1106
|
+
}), priority);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
//#endregion
|
|
1110
|
+
//#region src/facets/schema-spec.ts
|
|
1111
|
+
const schemaSpecFacet = defineFacet({
|
|
1112
|
+
reducer: (specs) => {
|
|
1113
|
+
let nodes = OrderedMap.from({});
|
|
1114
|
+
let marks = OrderedMap.from({});
|
|
1115
|
+
let topNode = void 0;
|
|
1116
|
+
for (const spec of specs) {
|
|
1117
|
+
nodes = nodes.append(spec.nodes);
|
|
1118
|
+
marks = marks.append(spec.marks ?? {});
|
|
1119
|
+
topNode = topNode ?? spec.topNode;
|
|
1120
|
+
}
|
|
1121
|
+
return {
|
|
1122
|
+
nodes,
|
|
1123
|
+
marks,
|
|
1124
|
+
topNode
|
|
1125
|
+
};
|
|
1126
|
+
},
|
|
1127
|
+
parent: schemaFacet,
|
|
1128
|
+
singleton: true
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
//#endregion
|
|
1132
|
+
//#region src/utils/remove-undefined-values.ts
|
|
1133
|
+
function removeUndefinedValues(obj) {
|
|
1134
|
+
const result = {};
|
|
1135
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0) result[key] = value;
|
|
1136
|
+
return result;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
//#endregion
|
|
1140
|
+
//#region src/utils/merge-objects.ts
|
|
1141
|
+
function mergeObjects(...objects) {
|
|
1142
|
+
const filteredObjects = objects.filter(isNotNullish).map(removeUndefinedValues);
|
|
1143
|
+
return Object.assign({}, ...filteredObjects);
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
//#endregion
|
|
1147
|
+
//#region src/utils/merge-specs.ts
|
|
1148
|
+
function mergeSpecs(a, b) {
|
|
1149
|
+
const attrs = {};
|
|
1150
|
+
const attrNames = new Set([...Object.keys(a.attrs ?? {}), ...Object.keys(b.attrs ?? {})]);
|
|
1151
|
+
for (const name of attrNames) {
|
|
1152
|
+
const attrSpecA = a.attrs?.[name];
|
|
1153
|
+
const attrSpecB = b.attrs?.[name];
|
|
1154
|
+
const attrSpecMerged = mergeObjects(attrSpecA, attrSpecB);
|
|
1155
|
+
if (attrSpecMerged) attrs[name] = attrSpecMerged;
|
|
1156
|
+
}
|
|
1157
|
+
return mergeObjects(a, b, {
|
|
1158
|
+
attrs,
|
|
1159
|
+
parseDOM: [...a.parseDOM ?? [], ...b.parseDOM ?? []]
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region src/utils/output-spec.ts
|
|
1165
|
+
function wrapOutputSpecAttrs(toDOM, options) {
|
|
1166
|
+
return (node, ...args) => {
|
|
1167
|
+
return insertOutputSpecAttrs(toDOM(node, ...args), options.map((option) => option.toDOM?.(node.attrs[option.attr])).filter(isNotNullish));
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
function wrapTagParseRuleAttrs(rule, options) {
|
|
1171
|
+
const existingGetAttrs = rule.getAttrs;
|
|
1172
|
+
const existingAttrs = rule.attrs;
|
|
1173
|
+
return {
|
|
1174
|
+
...rule,
|
|
1175
|
+
getAttrs: (dom) => {
|
|
1176
|
+
const baseAttrs = existingGetAttrs?.(dom) ?? existingAttrs ?? {};
|
|
1177
|
+
if (baseAttrs === false || !dom || !isElementLike(dom)) return baseAttrs ?? null;
|
|
1178
|
+
const insertedAttrs = {};
|
|
1179
|
+
for (const option of options) if (option.parseDOM) insertedAttrs[option.attr] = option.parseDOM(dom);
|
|
1180
|
+
return {
|
|
1181
|
+
...baseAttrs,
|
|
1182
|
+
...insertedAttrs
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
function wrapParseRuleAttrs(rule, attrs) {
|
|
1188
|
+
if (rule.tag) return wrapTagParseRuleAttrs(rule, attrs);
|
|
1189
|
+
return rule;
|
|
1190
|
+
}
|
|
1191
|
+
function insertOutputSpecAttrs(dom, attrs) {
|
|
1192
|
+
if (!dom) return dom;
|
|
1193
|
+
if (Array.isArray(dom)) {
|
|
1194
|
+
const rest = dom.slice(1);
|
|
1195
|
+
let oldAttrs;
|
|
1196
|
+
if (rest.length > 0 && (rest[0] == null || typeof rest[0] === "object")) oldAttrs = rest.shift();
|
|
1197
|
+
else oldAttrs = {};
|
|
1198
|
+
const newAttrs = setObjectAttributes(oldAttrs, attrs);
|
|
1199
|
+
return [
|
|
1200
|
+
dom[0],
|
|
1201
|
+
newAttrs,
|
|
1202
|
+
...rest
|
|
1203
|
+
];
|
|
1204
|
+
}
|
|
1205
|
+
if (isElementLike(dom)) return setElementAttributes(dom, attrs);
|
|
1206
|
+
if (typeof dom === "object" && "dom" in dom && isElementLike(dom.dom)) return {
|
|
1207
|
+
...dom,
|
|
1208
|
+
dom: setElementAttributes(dom.dom, attrs)
|
|
1209
|
+
};
|
|
1210
|
+
return dom;
|
|
1211
|
+
}
|
|
1212
|
+
function setObjectAttributes(obj, attrs) {
|
|
1213
|
+
obj = { ...obj };
|
|
1214
|
+
for (const [key, value] of attrs) {
|
|
1215
|
+
const oldValue = obj[key];
|
|
1216
|
+
const newValue = key === "style" ? joinStyles(value, typeof oldValue === "string" ? oldValue : "") : value;
|
|
1217
|
+
obj[key] = newValue;
|
|
1218
|
+
}
|
|
1219
|
+
return obj;
|
|
1220
|
+
}
|
|
1221
|
+
function setElementAttributes(element, attrs) {
|
|
1222
|
+
element = element.cloneNode(true);
|
|
1223
|
+
for (const [key, value] of attrs) {
|
|
1224
|
+
const oldValue = element.getAttribute(key);
|
|
1225
|
+
const newValue = key === "style" ? joinStyles(value, typeof oldValue === "string" ? oldValue : "") : value;
|
|
1226
|
+
element.setAttribute(key, newValue);
|
|
1227
|
+
}
|
|
1228
|
+
return element;
|
|
1229
|
+
}
|
|
1230
|
+
function joinStyles(...styles) {
|
|
1231
|
+
return styles.map((style) => style.trim().replace(/;$/, "")).filter(Boolean).join("; ");
|
|
1264
1232
|
}
|
|
1265
1233
|
|
|
1266
1234
|
//#endregion
|
|
1267
1235
|
//#region src/extensions/mark-spec.ts
|
|
1268
1236
|
/**
|
|
1237
|
+
* Defines a mark type into the editor schema.
|
|
1238
|
+
*
|
|
1269
1239
|
* @public
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
*
|
|
1243
|
+
* ```ts
|
|
1244
|
+
* const extension = defineMarkSpec({
|
|
1245
|
+
* name: 'bold',
|
|
1246
|
+
* parseDOM: [
|
|
1247
|
+
* { tag: 'strong' },
|
|
1248
|
+
* { tag: 'b' },
|
|
1249
|
+
* ],
|
|
1250
|
+
* toDOM() {
|
|
1251
|
+
* return ['strong', 0]
|
|
1252
|
+
* },
|
|
1253
|
+
* })
|
|
1254
|
+
* ```
|
|
1270
1255
|
*/
|
|
1271
1256
|
function defineMarkSpec(options) {
|
|
1272
1257
|
return defineFacetPayload(markSpecFacet, [[options, void 0]]);
|
|
@@ -1287,20 +1272,22 @@ const markSpecFacet = defineFacet({
|
|
|
1287
1272
|
if (prevSpec) specs = specs.update(name, mergeSpecs(prevSpec, spec));
|
|
1288
1273
|
else specs = specs.addToStart(name, spec);
|
|
1289
1274
|
}
|
|
1290
|
-
const groupedAttrs =
|
|
1291
|
-
for (const [type, attrs] of
|
|
1275
|
+
const groupedAttrs = mapGroupBy(attrPayloads, (payload) => payload.type);
|
|
1276
|
+
for (const [type, attrs] of groupedAttrs.entries()) {
|
|
1292
1277
|
if (!attrs) continue;
|
|
1293
|
-
const
|
|
1294
|
-
assert(
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1297
|
-
|
|
1278
|
+
const oldSpec = specs.get(type);
|
|
1279
|
+
assert(oldSpec, `Mark type ${type} must be defined`);
|
|
1280
|
+
const newSpec = {
|
|
1281
|
+
...oldSpec,
|
|
1282
|
+
attrs: { ...oldSpec.attrs }
|
|
1283
|
+
};
|
|
1284
|
+
for (const attr of attrs) newSpec.attrs[attr.attr] = {
|
|
1298
1285
|
default: attr.default,
|
|
1299
1286
|
validate: attr.validate
|
|
1300
1287
|
};
|
|
1301
|
-
if (
|
|
1302
|
-
if (
|
|
1303
|
-
specs = specs.update(type,
|
|
1288
|
+
if (oldSpec.toDOM) newSpec.toDOM = wrapOutputSpecAttrs(oldSpec.toDOM, attrs);
|
|
1289
|
+
if (oldSpec.parseDOM) newSpec.parseDOM = oldSpec.parseDOM.map((rule) => wrapParseRuleAttrs(rule, attrs));
|
|
1290
|
+
specs = specs.update(type, newSpec);
|
|
1304
1291
|
}
|
|
1305
1292
|
return {
|
|
1306
1293
|
marks: specs,
|
|
@@ -1310,10 +1297,6 @@ const markSpecFacet = defineFacet({
|
|
|
1310
1297
|
parent: schemaSpecFacet,
|
|
1311
1298
|
singleton: true
|
|
1312
1299
|
});
|
|
1313
|
-
function wrapParseRuleAttrs(rule, attrs) {
|
|
1314
|
-
if (rule.tag) return wrapTagParseRuleAttrs(rule, attrs);
|
|
1315
|
-
return rule;
|
|
1316
|
-
}
|
|
1317
1300
|
|
|
1318
1301
|
//#endregion
|
|
1319
1302
|
//#region src/extensions/mark-view.ts
|
|
@@ -1354,7 +1337,7 @@ const markViewFactoryFacet = defineFacet({
|
|
|
1354
1337
|
const factories = inputs.map((x) => x[0]).filter(isNotNullish);
|
|
1355
1338
|
const options = inputs.map((x) => x[1]).filter(isNotNullish);
|
|
1356
1339
|
for (const { group, name, args } of options) {
|
|
1357
|
-
const factory = factories.find((factory
|
|
1340
|
+
const factory = factories.find((factory) => factory.group === group);
|
|
1358
1341
|
if (!factory) continue;
|
|
1359
1342
|
markViews[name] = factory.factory(args);
|
|
1360
1343
|
}
|
|
@@ -1366,6 +1349,77 @@ const markViewFactoryFacet = defineFacet({
|
|
|
1366
1349
|
parent: pluginFacet
|
|
1367
1350
|
});
|
|
1368
1351
|
|
|
1352
|
+
//#endregion
|
|
1353
|
+
//#region src/extensions/node-spec.ts
|
|
1354
|
+
/**
|
|
1355
|
+
* Defines a node type into the editor schema.
|
|
1356
|
+
*
|
|
1357
|
+
* @public
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
*
|
|
1361
|
+
* ```ts
|
|
1362
|
+
* const extension = defineNodeSpec({
|
|
1363
|
+
* name: 'fancyParagraph',
|
|
1364
|
+
* content: 'inline*',
|
|
1365
|
+
* group: 'block',
|
|
1366
|
+
* parseDOM: [{ tag: 'p.fancy' }],
|
|
1367
|
+
* toDOM() {
|
|
1368
|
+
* return ['p', { 'class': 'fancy' }, 0]
|
|
1369
|
+
* },
|
|
1370
|
+
* })
|
|
1371
|
+
* ```
|
|
1372
|
+
*/
|
|
1373
|
+
function defineNodeSpec(options) {
|
|
1374
|
+
return defineFacetPayload(nodeSpecFacet, [[options, void 0]]);
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Defines an attribute for a node type.
|
|
1378
|
+
*
|
|
1379
|
+
* @public
|
|
1380
|
+
*/
|
|
1381
|
+
function defineNodeAttr(options) {
|
|
1382
|
+
return defineFacetPayload(nodeSpecFacet, [[void 0, options]]);
|
|
1383
|
+
}
|
|
1384
|
+
const nodeSpecFacet = defineFacet({
|
|
1385
|
+
reducer: (payloads) => {
|
|
1386
|
+
let specs = OrderedMap.from({});
|
|
1387
|
+
let topNodeName = void 0;
|
|
1388
|
+
const specPayloads = payloads.map((input) => input[0]).filter(isNotNullish);
|
|
1389
|
+
const attrPayloads = payloads.map((input) => input[1]).filter(isNotNullish);
|
|
1390
|
+
for (const { name, topNode, ...spec } of specPayloads) {
|
|
1391
|
+
if (topNode) topNodeName = name;
|
|
1392
|
+
const prevSpec = specs.get(name);
|
|
1393
|
+
if (prevSpec) specs = specs.update(name, mergeSpecs(prevSpec, spec));
|
|
1394
|
+
else specs = specs.addToStart(name, spec);
|
|
1395
|
+
}
|
|
1396
|
+
const groupedAttrs = mapGroupBy(attrPayloads, (payload) => payload.type);
|
|
1397
|
+
for (const [type, attrs] of groupedAttrs.entries()) {
|
|
1398
|
+
if (!attrs) continue;
|
|
1399
|
+
const oldSpec = specs.get(type);
|
|
1400
|
+
assert(oldSpec, `Node type ${type} must be defined`);
|
|
1401
|
+
const newSpec = {
|
|
1402
|
+
...oldSpec,
|
|
1403
|
+
attrs: { ...oldSpec.attrs }
|
|
1404
|
+
};
|
|
1405
|
+
for (const attr of attrs) newSpec.attrs[attr.attr] = {
|
|
1406
|
+
default: attr.default,
|
|
1407
|
+
validate: attr.validate,
|
|
1408
|
+
splittable: attr.splittable
|
|
1409
|
+
};
|
|
1410
|
+
if (oldSpec.toDOM) newSpec.toDOM = wrapOutputSpecAttrs(oldSpec.toDOM, attrs);
|
|
1411
|
+
if (oldSpec.parseDOM) newSpec.parseDOM = oldSpec.parseDOM.map((rule) => wrapTagParseRuleAttrs(rule, attrs));
|
|
1412
|
+
specs = specs.update(type, newSpec);
|
|
1413
|
+
}
|
|
1414
|
+
return {
|
|
1415
|
+
nodes: specs,
|
|
1416
|
+
topNode: topNodeName
|
|
1417
|
+
};
|
|
1418
|
+
},
|
|
1419
|
+
parent: schemaSpecFacet,
|
|
1420
|
+
singleton: true
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1369
1423
|
//#endregion
|
|
1370
1424
|
//#region src/extensions/node-view.ts
|
|
1371
1425
|
function defineNodeView(options) {
|
|
@@ -1405,7 +1459,7 @@ const nodeViewFactoryFacet = defineFacet({
|
|
|
1405
1459
|
const factories = inputs.map((x) => x[0]).filter(isNotNullish);
|
|
1406
1460
|
const options = inputs.map((x) => x[1]).filter(isNotNullish);
|
|
1407
1461
|
for (const { group, name, args } of options) {
|
|
1408
|
-
const factory = factories.find((factory
|
|
1462
|
+
const factory = factories.find((factory) => factory.group === group);
|
|
1409
1463
|
if (!factory) continue;
|
|
1410
1464
|
nodeViews[name] = factory.factory(args);
|
|
1411
1465
|
}
|
|
@@ -1417,57 +1471,6 @@ const nodeViewFactoryFacet = defineFacet({
|
|
|
1417
1471
|
parent: pluginFacet
|
|
1418
1472
|
});
|
|
1419
1473
|
|
|
1420
|
-
//#endregion
|
|
1421
|
-
//#region src/extensions/paragraph.ts
|
|
1422
|
-
/**
|
|
1423
|
-
* Defines a paragraph node spec.
|
|
1424
|
-
*/
|
|
1425
|
-
function defineParagraphSpec() {
|
|
1426
|
-
return defineNodeSpec({
|
|
1427
|
-
name: "paragraph",
|
|
1428
|
-
content: "inline*",
|
|
1429
|
-
group: "block",
|
|
1430
|
-
parseDOM: [{ tag: "p" }],
|
|
1431
|
-
toDOM() {
|
|
1432
|
-
return ["p", 0];
|
|
1433
|
-
}
|
|
1434
|
-
});
|
|
1435
|
-
}
|
|
1436
|
-
/**
|
|
1437
|
-
* @public
|
|
1438
|
-
*
|
|
1439
|
-
* Defines a paragraph node spec as the highest priority, because it should be the default block node for most cases.
|
|
1440
|
-
*
|
|
1441
|
-
* @deprecated Use the following import instead:
|
|
1442
|
-
*
|
|
1443
|
-
* ```ts
|
|
1444
|
-
* import { defineParagraph } from 'prosekit/extensions/paragraph'
|
|
1445
|
-
* ```
|
|
1446
|
-
*/
|
|
1447
|
-
function defineParagraph() {
|
|
1448
|
-
console.warn("[prosekit] The `defineParagraph` function from `prosekit/core` is deprecated. Use the following import instead: `import { defineParagraph } from \"prosekit/extensions/paragraph\"`.");
|
|
1449
|
-
return withPriority(defineParagraphSpec(), Priority.highest);
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
//#endregion
|
|
1453
|
-
//#region src/extensions/text.ts
|
|
1454
|
-
/**
|
|
1455
|
-
* @public
|
|
1456
|
-
*
|
|
1457
|
-
* @deprecated Use the following import instead:
|
|
1458
|
-
*
|
|
1459
|
-
* ```ts
|
|
1460
|
-
* import { defineText } from 'prosekit/extensions/text'
|
|
1461
|
-
* ```
|
|
1462
|
-
*/
|
|
1463
|
-
function defineText() {
|
|
1464
|
-
console.warn("[prosekit] The `defineText` function from `prosekit/core` is deprecated. Use the following import instead: `import { defineText } from \"prosekit/extensions/text\"`.");
|
|
1465
|
-
return defineNodeSpec({
|
|
1466
|
-
name: "text",
|
|
1467
|
-
group: "inline"
|
|
1468
|
-
});
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
1474
|
//#endregion
|
|
1472
1475
|
//#region src/utils/can-use-regex-lookbehind.ts
|
|
1473
1476
|
/**
|
|
@@ -1475,7 +1478,7 @@ function defineText() {
|
|
|
1475
1478
|
*/
|
|
1476
1479
|
const canUseRegexLookbehind = once(() => {
|
|
1477
1480
|
try {
|
|
1478
|
-
return "ab".replace(new RegExp("(?<=a)b", "g"), "c") === "ac";
|
|
1481
|
+
return "ab".replace(/* @__PURE__ */ new RegExp("(?<=a)b", "g"), "c") === "ac";
|
|
1479
1482
|
} catch {
|
|
1480
1483
|
return false;
|
|
1481
1484
|
}
|
|
@@ -1492,41 +1495,6 @@ const canUseRegexLookbehind = once(() => {
|
|
|
1492
1495
|
*/
|
|
1493
1496
|
const clsx = clsxLite;
|
|
1494
1497
|
|
|
1495
|
-
//#endregion
|
|
1496
|
-
//#region src/utils/collect-children.ts
|
|
1497
|
-
/**
|
|
1498
|
-
* Collects all children of a node or a fragment, and returns them as an array.
|
|
1499
|
-
*
|
|
1500
|
-
* @deprecated Use `node.children` or `fragment.content` instead.
|
|
1501
|
-
*
|
|
1502
|
-
* @hidden
|
|
1503
|
-
*/
|
|
1504
|
-
function collectChildren(parent) {
|
|
1505
|
-
const children = [];
|
|
1506
|
-
for (let i = 0; i < parent.childCount; i++) children.push(parent.child(i));
|
|
1507
|
-
return children;
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
//#endregion
|
|
1511
|
-
//#region src/utils/collect-nodes.ts
|
|
1512
|
-
/**
|
|
1513
|
-
* Collects all nodes from a given content.
|
|
1514
|
-
*
|
|
1515
|
-
* @deprecated Use `collectChildren` instead.
|
|
1516
|
-
*
|
|
1517
|
-
* @hidden
|
|
1518
|
-
*/
|
|
1519
|
-
function collectNodes(content) {
|
|
1520
|
-
if (Array.isArray(content)) return content.flatMap(collectNodes);
|
|
1521
|
-
if (content instanceof ProseMirrorNode) return [content];
|
|
1522
|
-
if (content instanceof ProseMirrorFragment) {
|
|
1523
|
-
const nodes = [];
|
|
1524
|
-
for (let i = 0; i < content.childCount; i++) nodes.push(content.child(i));
|
|
1525
|
-
return nodes;
|
|
1526
|
-
}
|
|
1527
|
-
throw new ProseKitError(`Invalid node content: ${typeof content}`);
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
1498
|
//#endregion
|
|
1531
1499
|
//#region src/utils/contains-inline-node.ts
|
|
1532
1500
|
/**
|
|
@@ -1542,18 +1510,44 @@ function containsInlineNode(doc, from, to) {
|
|
|
1542
1510
|
}
|
|
1543
1511
|
|
|
1544
1512
|
//#endregion
|
|
1545
|
-
//#region src/utils/
|
|
1546
|
-
let id = 0;
|
|
1513
|
+
//#region src/utils/find-node.ts
|
|
1547
1514
|
/**
|
|
1548
|
-
*
|
|
1515
|
+
* Finds the first node that satisfies the predicate from the given document.
|
|
1549
1516
|
*
|
|
1550
1517
|
* @internal
|
|
1518
|
+
*/
|
|
1519
|
+
function findNode(doc, predicate) {
|
|
1520
|
+
let found;
|
|
1521
|
+
doc.descendants((node, pos, parent, index) => {
|
|
1522
|
+
if (found) return false;
|
|
1523
|
+
if (predicate(node)) {
|
|
1524
|
+
found = {
|
|
1525
|
+
node,
|
|
1526
|
+
pos,
|
|
1527
|
+
parent,
|
|
1528
|
+
index
|
|
1529
|
+
};
|
|
1530
|
+
return false;
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
return found;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Finds all nodes that satisfy the predicate from the given document.
|
|
1551
1537
|
*
|
|
1552
|
-
* @
|
|
1538
|
+
* @internal
|
|
1553
1539
|
*/
|
|
1554
|
-
function
|
|
1555
|
-
|
|
1556
|
-
|
|
1540
|
+
function findNodes(doc, predicate) {
|
|
1541
|
+
const results = [];
|
|
1542
|
+
doc.descendants((node, pos, parent, index) => {
|
|
1543
|
+
if (predicate(node)) results.push({
|
|
1544
|
+
node,
|
|
1545
|
+
pos,
|
|
1546
|
+
parent,
|
|
1547
|
+
index
|
|
1548
|
+
});
|
|
1549
|
+
});
|
|
1550
|
+
return results;
|
|
1557
1551
|
}
|
|
1558
1552
|
|
|
1559
1553
|
//#endregion
|
|
@@ -1612,5 +1606,5 @@ function withSkipCodeBlock(command) {
|
|
|
1612
1606
|
}
|
|
1613
1607
|
|
|
1614
1608
|
//#endregion
|
|
1615
|
-
export { Editor, EditorNotFoundError, OBJECT_REPLACEMENT_CHARACTER, Priority, ProseKitError,
|
|
1609
|
+
export { Editor, EditorNotFoundError, OBJECT_REPLACEMENT_CHARACTER, Priority, ProseKitError, addMark, assert, canUseRegexLookbehind, clsx, containsInlineNode, createEditor, defaultBlockAt, defineBaseCommands, defineBaseKeymap, defineClickHandler, defineClickOnHandler, defineClipboardSerializer, defineCommands, defineDOMEventHandler, defineDefaultState, defineDocChangeHandler, defineDoubleClickHandler, defineDoubleClickOnHandler, defineDropHandler, defineFacet, defineFacetPayload, defineFocusChangeHandler, defineHistory, defineKeyDownHandler, defineKeyPressHandler, defineKeymap, defineMarkAttr, defineMarkSpec, defineMarkView, defineMarkViewComponent, defineMarkViewFactory, defineMountHandler, defineNodeAttr, defineNodeSpec, defineNodeView, defineNodeViewComponent, defineNodeViewFactory, definePasteHandler, definePlugin, defineScrollToSelectionHandler, defineTextInputHandler, defineTripleClickHandler, defineTripleClickOnHandler, defineUnmountHandler, defineUpdateHandler, editorEventFacet, elementFromJSON, elementFromNode, expandMark, findNode, findNodes, findParentNode, findParentNodeOfType, getMarkType, getNodeType, htmlFromJSON, htmlFromNode, insertDefaultBlock, insertNode, isAllSelection, isApple, isAtBlockStart, isFragment, isInCodeBlock, isMark, isMarkAbsent, isMarkActive, isNodeSelection, isProseMirrorNode, isSelection, isSlice, isTextSelection, jsonFromHTML, jsonFromNode, jsonFromState, keymapFacet, maybeRun, nodeFromElement, nodeFromHTML, nodeFromJSON, pluginFacet, removeMark, removeNode, selectAll, selectBlock, setBlockType, setNodeAttrs, setNodeAttrsBetween, setSelectionAround, stateFromJSON, toggleMark, toggleNode, toggleWrap, union, unsetBlockType, unsetMark, withPriority, withSkipCodeBlock, wrap };
|
|
1616
1610
|
//# sourceMappingURL=prosekit-core.js.map
|