@prosekit/core 0.2.6 → 0.3.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.
@@ -9,7 +9,6 @@ import { EditorState } from '@prosekit/pm/state';
9
9
  import type { EditorStateConfig } from '@prosekit/pm/state';
10
10
  import { EditorView } from '@prosekit/pm/view';
11
11
  import type { EmptyObject } from 'type-fest';
12
- import { InputRule } from '@prosekit/pm/inputrules';
13
12
  import type { IsEqual } from 'type-fest';
14
13
  import { Mark } from '@prosekit/pm/model';
15
14
  import type { MarkSpec } from '@prosekit/pm/model';
@@ -333,22 +332,6 @@ redo: [];
333
332
  export { defineHistory }
334
333
  export { defineHistory as defineHistory_alias_1 }
335
334
 
336
- /**
337
- * Defines an input rule extension.
338
- *
339
- * @param rule - The ProseMirror input rule to add, or an array of input rules,
340
- * or a function that returns one or multiple input rules.
341
- *
342
- * @public
343
- *
344
- * @deprecated Use `prosekit/extensions/input-rule` instead.
345
- */
346
- declare function defineInputRule(rule: InputRule | InputRule[] | ((context: {
347
- schema: Schema;
348
- }) => InputRule | InputRule[])): Extension;
349
- export { defineInputRule }
350
- export { defineInputRule as defineInputRule_alias_1 }
351
-
352
335
  /**
353
336
  * @public
354
337
  */
@@ -513,7 +496,14 @@ declare class Editor<E extends Extension = any> {
513
496
  * Whether the editor is focused.
514
497
  */
515
498
  get focused(): boolean;
516
- mount(place: HTMLElement | null | undefined | void): void;
499
+ /**
500
+ * Mount the editor to the given HTML element.
501
+ * Pass `null` or `undefined` to unmount the editor.
502
+ */
503
+ mount(place: HTMLElement | null | undefined): void;
504
+ /**
505
+ * Unmount the editor. This is equivalent to `mount(null)`.
506
+ */
517
507
  unmount(): void;
518
508
  /**
519
509
  * Focus the editor.
@@ -531,6 +521,15 @@ declare class Editor<E extends Extension = any> {
531
521
  export { Editor }
532
522
  export { Editor as Editor_alias_1 }
533
523
 
524
+ /**
525
+ * @internal
526
+ */
527
+ declare class EditorNotFoundError extends ProseKitError {
528
+ constructor();
529
+ }
530
+ export { EditorNotFoundError }
531
+ export { EditorNotFoundError as EditorNotFoundError_alias_1 }
532
+
534
533
  /**
535
534
  * @public
536
535
  */
@@ -569,6 +568,20 @@ declare type EmptyValue = undefined | null | EmptyObject;
569
568
 
570
569
  export declare type ExceptEmptyValue<T> = ConditionalExcept<T, EmptyValue>;
571
570
 
571
+ /**
572
+ * Expands the selection to include the entire mark at the current position.
573
+ *
574
+ * @public
575
+ */
576
+ declare function expandMark(options: {
577
+ /**
578
+ * The type of the mark to expand.
579
+ */
580
+ type: string | MarkType;
581
+ }): Command;
582
+ export { expandMark }
583
+ export { expandMark as expandMark_alias_1 }
584
+
572
585
  /**
573
586
  * @public
574
587
  */
@@ -818,6 +831,9 @@ declare function isMark(mark: unknown): mark is Mark;
818
831
  export { isMark }
819
832
  export { isMark as isMark_alias_1 }
820
833
 
834
+ /**
835
+ * @internal
836
+ */
821
837
  export declare function isMarkActive(state: EditorState, type: string | MarkType, attrs?: Attrs | null): boolean;
822
838
 
823
839
  export declare function isNodeActive(state: EditorState, type: string | NodeType, attrs?: Attrs | null): boolean;
@@ -1122,6 +1138,8 @@ export { Priority as Priority_alias_1 }
1122
1138
 
1123
1139
  /**
1124
1140
  * Base class for all ProseKit errors.
1141
+ *
1142
+ * @internal
1125
1143
  */
1126
1144
  declare class ProseKitError extends Error {
1127
1145
  }
@@ -1,4 +1,5 @@
1
1
  export { addMark } from './_tsup-dts-rollup';
2
+ export { expandMark } from './_tsup-dts-rollup';
2
3
  export { insertNode } from './_tsup-dts-rollup';
3
4
  export { removeMark } from './_tsup-dts-rollup';
4
5
  export { setBlockType } from './_tsup-dts-rollup';
@@ -10,6 +11,7 @@ export { createEditor } from './_tsup-dts-rollup';
10
11
  export { EditorOptions } from './_tsup-dts-rollup';
11
12
  export { union } from './_tsup-dts-rollup';
12
13
  export { withPriority } from './_tsup-dts-rollup';
14
+ export { EditorNotFoundError_alias_1 as EditorNotFoundError } from './_tsup-dts-rollup';
13
15
  export { ProseKitError_alias_1 as ProseKitError } from './_tsup-dts-rollup';
14
16
  export { defineBaseCommands } from './_tsup-dts-rollup';
15
17
  export { defineCommands } from './_tsup-dts-rollup';
@@ -27,7 +29,6 @@ export { MountHandler } from './_tsup-dts-rollup';
27
29
  export { UnmountHandler } from './_tsup-dts-rollup';
28
30
  export { UpdateHandler } from './_tsup-dts-rollup';
29
31
  export { defineHistory } from './_tsup-dts-rollup';
30
- export { defineInputRule } from './_tsup-dts-rollup';
31
32
  export { defineBaseKeymap } from './_tsup-dts-rollup';
32
33
  export { defineKeymap } from './_tsup-dts-rollup';
33
34
  export { keymapFacet } from './_tsup-dts-rollup';
@@ -8,6 +8,13 @@ import "@prosekit/pm/model";
8
8
  // src/error.ts
9
9
  var ProseKitError = class extends Error {
10
10
  };
11
+ var EditorNotFoundError = class extends ProseKitError {
12
+ constructor() {
13
+ super(
14
+ "Unable to find editor. Pass it as an argument or call this function inside a ProseKit component."
15
+ );
16
+ }
17
+ };
11
18
 
12
19
  // src/utils/get-mark-type.ts
13
20
  function getMarkType(schema, type) {
@@ -36,6 +43,59 @@ function addMark(options) {
36
43
  };
37
44
  }
38
45
 
46
+ // src/commands/expand-mark.ts
47
+ import { TextSelection } from "@prosekit/pm/state";
48
+ function expandMark(options) {
49
+ return (state, dispatch) => {
50
+ const markType = getMarkType(state.schema, options.type);
51
+ const predicate = (mark) => mark.type === markType;
52
+ const from = expandMarkBefore(state.selection.$from, predicate);
53
+ const to = expandMarkAfter(state.selection.$to, predicate);
54
+ if (from === state.selection.from && to === state.selection.to) {
55
+ return false;
56
+ }
57
+ if (dispatch) {
58
+ dispatch(state.tr.setSelection(TextSelection.create(state.doc, from, to)));
59
+ }
60
+ return true;
61
+ };
62
+ }
63
+ function expandMarkBefore($pos, predicate) {
64
+ const { parent } = $pos;
65
+ if (!$pos.marks().some(predicate)) {
66
+ return $pos.pos;
67
+ }
68
+ const index = $pos.index();
69
+ let boundaryIndex = index;
70
+ for (let i = index; i >= 0; i--) {
71
+ const node = parent.child(i);
72
+ if (node.marks.some(predicate)) {
73
+ boundaryIndex = i;
74
+ } else {
75
+ break;
76
+ }
77
+ }
78
+ return $pos.posAtIndex(boundaryIndex);
79
+ }
80
+ function expandMarkAfter($pos, predicate) {
81
+ const { parent } = $pos;
82
+ if (!$pos.marks().some(predicate)) {
83
+ return $pos.pos;
84
+ }
85
+ const index = Math.max(0, $pos.indexAfter() - 1);
86
+ const childCount = parent.childCount;
87
+ let boundaryIndex = index;
88
+ for (let i = index; i < childCount; i++) {
89
+ const node = parent.child(i);
90
+ if (node.marks.some(predicate)) {
91
+ boundaryIndex = i;
92
+ } else {
93
+ break;
94
+ }
95
+ }
96
+ return $pos.posAtIndex(boundaryIndex) + parent.child(boundaryIndex).nodeSize;
97
+ }
98
+
39
99
  // src/commands/insert-node.ts
40
100
  import "@prosekit/pm/state";
41
101
  import { insertPoint } from "@prosekit/pm/transform";
@@ -54,11 +114,11 @@ function getNodeType(schema, type) {
54
114
  }
55
115
 
56
116
  // src/utils/set-selection-around.ts
57
- import { TextSelection } from "@prosekit/pm/state";
117
+ import { TextSelection as TextSelection2 } from "@prosekit/pm/state";
58
118
  function setSelectionAround(tr, pos) {
59
119
  const docSize = tr.doc.content.size;
60
120
  const $pos = tr.doc.resolve(pos > docSize ? docSize : pos < 0 ? 0 : pos);
61
- const selection = TextSelection.between($pos, $pos);
121
+ const selection = TextSelection2.between($pos, $pos);
62
122
  tr.setSelection(selection);
63
123
  }
64
124
 
@@ -108,13 +168,13 @@ function removeMark(options) {
108
168
  import "@prosekit/pm/state";
109
169
 
110
170
  // src/utils/get-custom-selection.ts
111
- import { TextSelection as TextSelection2 } from "@prosekit/pm/state";
171
+ import { TextSelection as TextSelection3 } from "@prosekit/pm/state";
112
172
  function getCustomSelection(state, from, to) {
113
173
  const pos = from != null ? from : to;
114
174
  if (pos != null) {
115
175
  const $from = state.doc.resolve(from != null ? from : pos);
116
176
  const $to = state.doc.resolve(to != null ? to : pos);
117
- return TextSelection2.between($from, $to);
177
+ return TextSelection3.between($from, $to);
118
178
  }
119
179
  return state.selection;
120
180
  }
@@ -689,12 +749,25 @@ function updateExtension(prevInputs, prevConverters, extension, mode) {
689
749
  // src/editor/builder.ts
690
750
  import "@prosekit/pm/model";
691
751
 
752
+ // src/utils/is-mark-active.ts
753
+ function isMarkActive(state, type, attrs) {
754
+ const { from, $from, to, empty } = state.selection;
755
+ const markType = getMarkType(state.schema, type);
756
+ if (empty) {
757
+ const mark = attrs ? markType.create(attrs) : markType;
758
+ return !!mark.isInSet(state.storedMarks || $from.marks());
759
+ } else {
760
+ const markOrType = attrs ? markType.create(attrs) : markType;
761
+ return state.doc.rangeHasMark(from, to, markOrType);
762
+ }
763
+ }
764
+
692
765
  // src/utils/type-assertion.ts
693
766
  import { Mark, ProseMirrorNode } from "@prosekit/pm/model";
694
767
  import {
695
768
  AllSelection,
696
769
  NodeSelection,
697
- TextSelection as TextSelection3
770
+ TextSelection as TextSelection4
698
771
  } from "@prosekit/pm/state";
699
772
  function isProseMirrorNode(node) {
700
773
  return node instanceof ProseMirrorNode;
@@ -703,7 +776,7 @@ function isMark(mark) {
703
776
  return mark instanceof Mark;
704
777
  }
705
778
  function isTextSelection(sel) {
706
- return sel instanceof TextSelection3;
779
+ return sel instanceof TextSelection4;
707
780
  }
708
781
  function isNodeSelection(sel) {
709
782
  return sel instanceof NodeSelection;
@@ -712,28 +785,6 @@ function isAllSelection(sel) {
712
785
  return sel instanceof AllSelection;
713
786
  }
714
787
 
715
- // src/utils/is-mark-active.ts
716
- function isMarkActive(state, type, attrs) {
717
- const markType = getMarkType(state.schema, type);
718
- const mark = attrs ? markType.create(attrs) : markType;
719
- const { from, $from, to, empty } = state.selection;
720
- if (empty) {
721
- return hasMark(state.storedMarks || $from.marks(), mark);
722
- } else {
723
- return state.doc.rangeHasMark(from, to, mark);
724
- }
725
- }
726
- function hasMark(marks, mark) {
727
- if (marks.length === 0) {
728
- return false;
729
- }
730
- if (isMark(mark)) {
731
- return marks.some((m) => m.eq(mark));
732
- } else {
733
- return marks.some((m) => m.type === mark);
734
- }
735
- }
736
-
737
788
  // src/editor/builder.ts
738
789
  function createNodeBuilder(getState, type) {
739
790
  const builder = (...args) => buildNode(type, args);
@@ -1038,6 +1089,10 @@ var Editor = class _Editor {
1038
1089
  var _a, _b;
1039
1090
  return (_b = (_a = this.instance.view) == null ? void 0 : _a.hasFocus()) != null ? _b : false;
1040
1091
  }
1092
+ /**
1093
+ * Mount the editor to the given HTML element.
1094
+ * Pass `null` or `undefined` to unmount the editor.
1095
+ */
1041
1096
  mount(place) {
1042
1097
  if (!place) {
1043
1098
  return this.unmount();
@@ -1045,6 +1100,9 @@ var Editor = class _Editor {
1045
1100
  this.instance.mount(place);
1046
1101
  this.afterMounted.forEach((callback) => callback());
1047
1102
  }
1103
+ /**
1104
+ * Unmount the editor. This is equivalent to `mount(null)`.
1105
+ */
1048
1106
  unmount() {
1049
1107
  if (this.mounted) {
1050
1108
  this.instance.unmount();
@@ -1391,16 +1449,11 @@ function defineFocusChangeHandler(handler) {
1391
1449
  const handleBlur = () => handler(false);
1392
1450
  const plugin = new ProseMirrorPlugin2({
1393
1451
  key: new PluginKey2("prosekit-focus-handler"),
1394
- view: (view) => {
1395
- const dom = view.dom;
1396
- dom.addEventListener("focus", handleFocus);
1397
- dom.addEventListener("blur", handleBlur);
1398
- return {
1399
- destroy: () => {
1400
- dom.removeEventListener("focus", handleFocus);
1401
- dom.removeEventListener("blur", handleBlur);
1402
- }
1403
- };
1452
+ props: {
1453
+ handleDOMEvents: {
1454
+ focus: handleFocus,
1455
+ blur: handleBlur
1456
+ }
1404
1457
  }
1405
1458
  });
1406
1459
  return definePlugin(plugin);
@@ -1487,32 +1540,6 @@ function defineHistory() {
1487
1540
  ]);
1488
1541
  }
1489
1542
 
1490
- // src/extensions/input-rules.ts
1491
- import { InputRule, inputRules } from "@prosekit/pm/inputrules";
1492
- import "@prosekit/pm/model";
1493
- import "@prosekit/pm/state";
1494
- function defineInputRule(rule) {
1495
- if (rule instanceof InputRule) {
1496
- return inputRuleFacet.extension([() => rule]);
1497
- }
1498
- if (Array.isArray(rule) && rule.every((r) => r instanceof InputRule)) {
1499
- return inputRuleFacet.extension([() => rule]);
1500
- }
1501
- if (typeof rule === "function") {
1502
- return inputRuleFacet.extension([rule]);
1503
- }
1504
- throw new TypeError("Invalid input rule");
1505
- }
1506
- var inputRuleFacet = Facet.define({
1507
- convert: (inputs) => {
1508
- return (context) => {
1509
- const rules = inputs.flatMap((callback) => callback(context));
1510
- return [inputRules({ rules })];
1511
- };
1512
- },
1513
- next: pluginFacet
1514
- });
1515
-
1516
1543
  // src/extensions/mark-spec.ts
1517
1544
  function defineMarkSpec(options) {
1518
1545
  const payload = [options, void 0];
@@ -1724,6 +1751,7 @@ function withSkipCodeBlock(command) {
1724
1751
  }
1725
1752
  export {
1726
1753
  Editor,
1754
+ EditorNotFoundError,
1727
1755
  Facet,
1728
1756
  OBJECT_REPLACEMENT_CHARACTER,
1729
1757
  Priority,
@@ -1741,7 +1769,6 @@ export {
1741
1769
  defineDocChangeHandler,
1742
1770
  defineFocusChangeHandler,
1743
1771
  defineHistory,
1744
- defineInputRule,
1745
1772
  defineKeymap,
1746
1773
  defineMarkAttr,
1747
1774
  defineMarkSpec,
@@ -1755,6 +1782,7 @@ export {
1755
1782
  defineText,
1756
1783
  defineUnmountHandler,
1757
1784
  defineUpdateHandler,
1785
+ expandMark,
1758
1786
  getMarkType,
1759
1787
  getNodeType,
1760
1788
  insertNode,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.2.6",
4
+ "version": "0.3.0",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -38,13 +38,13 @@
38
38
  "@prosekit/pm": "^0.1.1",
39
39
  "clsx": "^2.1.0",
40
40
  "orderedmap": "^2.1.1",
41
- "type-fest": "^4.9.0"
41
+ "type-fest": "^4.10.2"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@prosekit/dev": "*",
45
45
  "tsup": "^8.0.1",
46
46
  "typescript": "^5.3.3",
47
- "vitest": "^1.2.0"
47
+ "vitest": "^1.2.2"
48
48
  },
49
49
  "scripts": {
50
50
  "build:tsup": "tsup",
package/src/index.ts DELETED
@@ -1,106 +0,0 @@
1
- export { addMark } from './commands/add-mark'
2
- export { insertNode } from './commands/insert-node'
3
- export { removeMark } from './commands/remove-mark'
4
- export { setBlockType } from './commands/set-block-type'
5
- export { setNodeAttrs } from './commands/set-node-attrs'
6
- export { toggleMark } from './commands/toggle-mark'
7
- export { toggleNode } from './commands/toggle-node'
8
- export { Editor, createEditor, type EditorOptions } from './editor/editor'
9
- export { union } from './editor/union'
10
- export { withPriority } from './editor/with-priority'
11
- export { ProseKitError } from './error'
12
- export { defineBaseCommands, defineCommands } from './extensions/command'
13
- export {
14
- defineDefaultState,
15
- type DefaultStateOptions,
16
- } from './extensions/default-state'
17
- export { defineDoc } from './extensions/doc'
18
- export {
19
- defineDocChangeHandler,
20
- type DocChangeHandler,
21
- } from './extensions/events/doc-change'
22
- export {
23
- defineFocusChangeHandler,
24
- type FocusChangeHandler,
25
- } from './extensions/events/focus'
26
- export {
27
- defineMountHandler,
28
- defineUnmountHandler,
29
- defineUpdateHandler,
30
- type MountHandler,
31
- type UnmountHandler,
32
- type UpdateHandler,
33
- } from './extensions/events/plugin-view'
34
- export { defineHistory } from './extensions/history'
35
- export { defineInputRule } from './extensions/input-rules'
36
- export {
37
- defineBaseKeymap,
38
- defineKeymap,
39
- keymapFacet,
40
- type Keymap,
41
- type KeymapPayload,
42
- } from './extensions/keymap'
43
- export {
44
- defineMarkAttr,
45
- defineMarkSpec,
46
- type MarkAttrOptions,
47
- type MarkSpecOptions,
48
- } from './extensions/mark-spec'
49
- export {
50
- defineNodeAttr,
51
- defineNodeSpec,
52
- type NodeAttrOptions,
53
- type NodeSpecOptions,
54
- } from './extensions/node-spec'
55
- export { defineNodeView, type NodeViewOptions } from './extensions/node-view'
56
- export {
57
- defineNodeViewFactory,
58
- type NodeViewFactoryOptions,
59
- } from './extensions/node-view-effect'
60
- export { defineParagraph } from './extensions/paragraph'
61
- export {
62
- definePlugin,
63
- pluginFacet,
64
- type PluginPayload,
65
- } from './extensions/plugin'
66
- export { defineText } from './extensions/text'
67
- export { Facet, type FacetOptions } from './facets/facet'
68
- export type { BaseNodeViewOptions } from './types/base-node-view-options'
69
- export { type CommandArgs } from './types/command'
70
- export {
71
- type Extension,
72
- type ExtractCommandAppliers,
73
- type ExtractCommandCreators,
74
- type ExtractMarks,
75
- type ExtractNodes,
76
- type SimplifyExtension,
77
- } from './types/extension'
78
- export { type ExtensionTyping } from './types/extension-typing'
79
- export type { NodeJSON, SelectionJSON, StateJSON } from './types/model'
80
- export { Priority } from './types/priority'
81
- export { type SimplifyUnion } from './types/simplify-union'
82
- export { clsx } from './utils/clsx'
83
- export { defaultBlockAt } from './utils/default-block-at'
84
- export { getId as _getId } from './utils/get-id'
85
- export { getMarkType } from './utils/get-mark-type'
86
- export { getNodeType } from './utils/get-node-type'
87
- export { isInCodeBlock } from './utils/is-in-code-block'
88
- export {
89
- jsonFromElement,
90
- jsonFromHTML,
91
- jsonFromNode,
92
- jsonFromState,
93
- nodeFromElement,
94
- nodeFromHTML,
95
- nodeFromJSON,
96
- stateFromJSON,
97
- } from './utils/parse'
98
- export {
99
- isAllSelection,
100
- isMark,
101
- isNodeSelection,
102
- isProseMirrorNode,
103
- isTextSelection,
104
- } from './utils/type-assertion'
105
- export * from './utils/unicode'
106
- export { withSkipCodeBlock } from './utils/with-skip-code-block'