@prosekit/extensions 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/_tsup-dts-rollup.d.ts +100 -120
  2. package/dist/chunk-GPSAJOJA.js +188 -0
  3. package/dist/{chunk-PYT3MOTF.js → chunk-LVMTQOWG.js} +31 -14
  4. package/dist/{chunk-2JYT2MT7.js → chunk-OJCMRVEY.js} +36 -21
  5. package/dist/list/style.css +9 -5
  6. package/dist/placeholder/style.css +1 -1
  7. package/dist/prosekit-extensions-autocomplete.js +62 -33
  8. package/dist/prosekit-extensions-blockquote.js +2 -2
  9. package/dist/prosekit-extensions-bold.js +7 -3
  10. package/dist/prosekit-extensions-code-block.js +77 -41
  11. package/dist/prosekit-extensions-code.js +1 -1
  12. package/dist/prosekit-extensions-commit.js +70 -30
  13. package/dist/prosekit-extensions-enter-rule.js +1 -1
  14. package/dist/prosekit-extensions-heading.d.ts +4 -4
  15. package/dist/prosekit-extensions-heading.js +66 -36
  16. package/dist/prosekit-extensions-image.js +14 -5
  17. package/dist/prosekit-extensions-input-rule.js +1 -1
  18. package/dist/prosekit-extensions-italic.js +1 -1
  19. package/dist/prosekit-extensions-link.js +27 -14
  20. package/dist/prosekit-extensions-list.d.ts +8 -2
  21. package/dist/prosekit-extensions-list.js +64 -35
  22. package/dist/prosekit-extensions-mark-rule.js +1 -1
  23. package/dist/prosekit-extensions-mention.js +6 -4
  24. package/dist/prosekit-extensions-placeholder.js +16 -7
  25. package/dist/prosekit-extensions-readonly.js +1 -1
  26. package/dist/prosekit-extensions-search.js +8 -5
  27. package/dist/prosekit-extensions-strike.js +1 -1
  28. package/dist/prosekit-extensions-table.js +68 -30
  29. package/dist/prosekit-extensions-text-align.js +4 -2
  30. package/dist/prosekit-extensions-virtual-selection.js +11 -6
  31. package/package.json +8 -8
  32. package/dist/chunk-ZPEMHYTU.js +0 -140
@@ -1,5 +1,5 @@
1
+ import { AddMarkOptions } from '@prosekit/core';
1
2
  import { Attrs } from '@prosekit/pm/model';
2
- import { Attrs as Attrs_2 } from 'prosemirror-model';
3
3
  import { BundledLanguage } from 'shiki';
4
4
  import { BundledLanguageInfo } from 'shiki';
5
5
  import { bundledLanguagesInfo } from 'shiki';
@@ -18,28 +18,33 @@ import { getSingletonHighlighter } from 'shiki/bundle/full';
18
18
  import type { Highlighter } from 'shiki';
19
19
  import { IndentListOptions } from 'prosemirror-flat-list';
20
20
  import { InputRule } from '@prosekit/pm/inputrules';
21
+ import { InsertNodeOptions } from '@prosekit/core';
21
22
  import { ListAttributes } from 'prosemirror-flat-list';
22
23
  import { ListDOMSerializer } from 'prosemirror-flat-list';
23
24
  import { MarkBuilder } from '@prosekit/core';
24
25
  import { MarkType } from '@prosekit/pm/model';
25
- import { MarkType as MarkType_2 } from 'prosemirror-model';
26
- import { Node as Node_2 } from 'prosemirror-model';
27
26
  import { NodeBuilder } from '@prosekit/core';
28
27
  import { NodeJSON } from '@prosekit/core';
29
- import { NodeRange } from 'prosemirror-model';
30
28
  import { NodeType } from '@prosekit/pm/model';
31
- import { NodeType as NodeType_2 } from 'prosemirror-model';
32
29
  import { Options } from 'tsup';
33
30
  import { Parser } from 'prosemirror-highlight';
34
31
  import { Plugin as Plugin_2 } from '@prosekit/pm/state';
35
32
  import { PluginKey } from '@prosekit/pm/state';
36
33
  import { ProseMirrorNode } from '@prosekit/pm/model';
34
+ import { RemoveMarkOptions } from '@prosekit/core';
35
+ import { RemoveNodeOptions } from '@prosekit/core';
36
+ import { SetBlockTypeOptions } from '@prosekit/core';
37
+ import { SetNodeAttrsOptions } from '@prosekit/core';
37
38
  import type { SpecialLanguage } from 'shiki';
38
39
  import { StepJSON } from '@prosekit/core';
39
40
  import { TestEditor } from '@prosekit/core/test';
40
41
  import { ToggleCollapsedOptions } from 'prosemirror-flat-list';
41
42
  import { Transaction } from '@prosekit/pm/state';
43
+ import { UnsetBlockTypeOptions } from '@prosekit/core';
44
+ import { UnsetMarkOptions } from '@prosekit/core';
42
45
  import { UnwrapListOptions } from 'prosemirror-flat-list';
46
+ import { WrapInListGetAttrs } from 'prosemirror-flat-list';
47
+ import { WrapOptions } from '@prosekit/core';
43
48
 
44
49
  export declare function applyMarkRules(rules: MarkRuleOptions[], transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Transaction | null;
45
50
 
@@ -174,6 +179,8 @@ export declare function createLazyParser(highlighterOptions: HighlighterOptions)
174
179
  */
175
180
  export declare function createMarkInputRule({ regex, type, attrs, }: MarkInputRuleOptions): InputRule;
176
181
 
182
+ export { DedentListOptions }
183
+
177
184
  export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
178
185
 
179
186
  export { default_alias_1 }
@@ -412,7 +419,7 @@ toggleHeading: [attrs?: HeadingAttrs | undefined];
412
419
  };
413
420
  }>;
414
421
 
415
- export declare function defineHeadingCommands(): Extension< {
422
+ declare function defineHeadingCommands(): Extension< {
416
423
  Commands: {
417
424
  setHeading: [attrs?: HeadingAttrs | undefined];
418
425
  insertHeading: [attrs?: HeadingAttrs | undefined];
@@ -421,20 +428,28 @@ toggleHeading: [attrs?: HeadingAttrs | undefined];
421
428
  Nodes: never;
422
429
  Marks: never;
423
430
  }>;
431
+ export { defineHeadingCommands }
432
+ export { defineHeadingCommands as defineHeadingCommands_alias_1 }
424
433
 
425
434
  /**
426
435
  * Converts the text block to a heading when `#` is typed at the start of a new
427
436
  * line followed by a space.
428
437
  */
429
- export declare function defineHeadingInputRule(): Extension<ExtensionTyping<any, any, any>>;
438
+ declare function defineHeadingInputRule(): Extension<ExtensionTyping<any, any, any>>;
439
+ export { defineHeadingInputRule }
440
+ export { defineHeadingInputRule as defineHeadingInputRule_alias_1 }
430
441
 
431
- export declare function defineHeadingKeymap(): Extension<ExtensionTyping<any, any, any>>;
442
+ declare function defineHeadingKeymap(): Extension<ExtensionTyping<any, any, any>>;
443
+ export { defineHeadingKeymap }
444
+ export { defineHeadingKeymap as defineHeadingKeymap_alias_1 }
432
445
 
433
- export declare function defineHeadingSpec(): Extension< {
446
+ declare function defineHeadingSpec(): Extension< {
434
447
  Nodes: "heading";
435
448
  Marks: never;
436
449
  Commands: never;
437
450
  }>;
451
+ export { defineHeadingSpec }
452
+ export { defineHeadingSpec as defineHeadingSpec_alias_1 }
438
453
 
439
454
  /**
440
455
  * @public
@@ -559,26 +574,31 @@ export declare function defineList(): Extension<{
559
574
  toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
560
575
  toggleList: [attrs: ListAttributes];
561
576
  unwrapList: [options?: UnwrapListOptions | undefined];
562
- wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
577
+ wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
563
578
  insertList: [attrs?: ListAttributes | undefined];
564
579
  };
565
580
  }>;
566
581
 
567
- export declare function defineListCommands(): Extension<{
568
- Commands: {
569
- dedentList: [options?: DedentListOptions | undefined];
570
- indentList: [options?: IndentListOptions | undefined];
571
- moveList: [direction: "up" | "down"];
572
- splitList: [];
573
- toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
574
- toggleList: [attrs: ListAttributes];
575
- unwrapList: [options?: UnwrapListOptions | undefined];
576
- wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
577
- insertList: [attrs?: ListAttributes | undefined];
578
- };
579
- Nodes: never;
580
- Marks: never;
582
+ /**
583
+ * Defines list commands
584
+ */
585
+ declare function defineListCommands(): Extension< {
586
+ Commands: {
587
+ dedentList: [options?: DedentListOptions | undefined];
588
+ indentList: [options?: IndentListOptions | undefined];
589
+ moveList: [direction: "up" | "down"];
590
+ splitList: [];
591
+ toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
592
+ toggleList: [attrs: ListAttributes];
593
+ unwrapList: [options?: UnwrapListOptions | undefined];
594
+ wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
595
+ insertList: [attrs?: ListAttributes | undefined];
596
+ };
597
+ Nodes: never;
598
+ Marks: never;
581
599
  }>;
600
+ export { defineListCommands }
601
+ export { defineListCommands as defineListCommands_alias_1 }
582
602
 
583
603
  export declare function defineListInputRules(): Extension;
584
604
 
@@ -587,7 +607,9 @@ export declare function defineListInputRules(): Extension;
587
607
  *
588
608
  * @public
589
609
  */
590
- export declare function defineListKeymap(): Extension<ExtensionTyping<any, any, any>>;
610
+ declare function defineListKeymap(): Extension<ExtensionTyping<any, any, any>>;
611
+ export { defineListKeymap }
612
+ export { defineListKeymap as defineListKeymap_alias_1 }
591
613
 
592
614
  export declare function defineListPlugins(): Extension<ExtensionTyping<any, any, any>>;
593
615
 
@@ -803,58 +825,25 @@ export declare function defineTestExtension(): Extension<{
803
825
  from?: number;
804
826
  to?: number;
805
827
  }];
806
- insertNode: [options: {
807
- node: Node_2;
808
- pos?: number;
809
- type?: undefined;
810
- attrs?: undefined;
811
- } | {
812
- node?: undefined;
813
- pos?: number;
814
- type: string;
815
- attrs?: Attrs_2;
816
- }];
817
- removeNode: [options: {
818
- type: string | NodeType_2;
819
- pos?: number;
820
- }];
821
- wrap: [{
822
- nodeType: NodeType_2;
823
- attrs?: Attrs_2 | null;
824
- }];
825
- setBlockType: [options: {
826
- type: NodeType_2 | string;
827
- attrs?: Attrs_2 | null;
828
- from?: number;
829
- to?: number;
830
- }];
831
- setNodeAttrs: [options: {
832
- type: string | NodeType_2 | string[] | NodeType_2[];
833
- attrs: Attrs_2;
834
- pos?: number;
835
- }];
828
+ insertNode: [options: InsertNodeOptions];
829
+ removeNode: [options: RemoveNodeOptions];
830
+ wrap: [WrapOptions];
831
+ setBlockType: [options: SetBlockTypeOptions];
832
+ setNodeAttrs: [options: SetNodeAttrsOptions];
836
833
  selectAll: [];
837
- addMark: [options: {
838
- type: string | MarkType_2;
839
- attrs?: Attrs_2 | null;
840
- from?: number;
841
- to?: number;
842
- }];
843
- removeMark: [options: {
844
- type: string | MarkType_2;
845
- attrs?: Attrs_2 | null;
846
- from?: number;
847
- to?: number;
848
- }];
849
- toggleItalic: [];
850
- undo: [];
851
- redo: [];
834
+ addMark: [options: AddMarkOptions];
835
+ removeMark: [options: RemoveMarkOptions];
836
+ unsetBlockType: [options?: UnsetBlockTypeOptions | undefined];
837
+ unsetMark: [options?: UnsetMarkOptions | undefined];
838
+ readonly undo: [];
839
+ readonly redo: [];
852
840
  toggleBold: [];
853
841
  toggleCode: [];
854
842
  setHeading: [attrs?: HeadingAttrs | undefined];
855
843
  insertHeading: [attrs?: HeadingAttrs | undefined];
856
844
  toggleHeading: [attrs?: HeadingAttrs | undefined];
857
845
  insertImage: [attrs?: ImageAttrs | undefined];
846
+ toggleItalic: [];
858
847
  addLink: [attrs: LinkAttrs];
859
848
  removeLink: [];
860
849
  toggleLink: [attrs: LinkAttrs];
@@ -866,7 +855,7 @@ export declare function defineTestExtension(): Extension<{
866
855
  toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
867
856
  toggleList: [attrs: ListAttributes];
868
857
  unwrapList: [options?: UnwrapListOptions | undefined];
869
- wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
858
+ wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
870
859
  insertList: [attrs?: ListAttributes | undefined];
871
860
  toggleStrike: [];
872
861
  insertTable: [{
@@ -1095,9 +1084,11 @@ export { getSingletonHighlighter }
1095
1084
 
1096
1085
  export declare function getTrMeta(tr: Transaction): PredictionPluginState;
1097
1086
 
1098
- export declare interface HeadingAttrs {
1087
+ declare interface HeadingAttrs {
1099
1088
  level: number;
1100
1089
  }
1090
+ export { HeadingAttrs }
1091
+ export { HeadingAttrs as HeadingAttrs_alias_1 }
1101
1092
 
1102
1093
  export declare type HighlighterOptions = {
1103
1094
  themes: BundledTheme[];
@@ -1126,6 +1117,8 @@ export declare interface ImageAttrs {
1126
1117
  src?: string | null;
1127
1118
  }
1128
1119
 
1120
+ export { IndentListOptions }
1121
+
1129
1122
  /**
1130
1123
  * Insert a table node with the given number of rows and columns, and optionally
1131
1124
  * a header row.
@@ -1151,6 +1144,8 @@ export declare interface LinkAttrs {
1151
1144
  href: string;
1152
1145
  }
1153
1146
 
1147
+ export { ListAttributes }
1148
+
1154
1149
  export { ListDOMSerializer }
1155
1150
 
1156
1151
  /**
@@ -1248,6 +1243,18 @@ export declare interface PredictionPluginState {
1248
1243
 
1249
1244
  export declare function prepareHighlighter(options: HighlighterOptions): HighlighterResult;
1250
1245
 
1246
+ /**
1247
+ * @example
1248
+ *
1249
+ * ```ts
1250
+ * await pressKey('mod-1')
1251
+ * await pressKey('Backspace')
1252
+ * ```
1253
+ *
1254
+ * @internal
1255
+ */
1256
+ export declare function pressKey(input: string): Promise<void>;
1257
+
1251
1258
  /**
1252
1259
  * Options for {@link defineSearchQuery}
1253
1260
  *
@@ -1303,7 +1310,7 @@ export declare function setTrMeta(tr: Transaction, meta: PredictionPluginState):
1303
1310
  /**
1304
1311
  * @internal
1305
1312
  */
1306
- export declare function setupDefaultTest(): {
1313
+ export declare function setupTest(): {
1307
1314
  editor: TestEditor<Extension<{
1308
1315
  Nodes: "blockquote" | "table" | "text" | "doc" | "paragraph" | "heading" | "image" | "list" | "tableRow" | "tableCell" | "tableHeaderCell";
1309
1316
  Marks: "code" | "link" | "bold" | "strike" | "italic" | "underline";
@@ -1313,58 +1320,25 @@ export declare function setupDefaultTest(): {
1313
1320
  from?: number;
1314
1321
  to?: number;
1315
1322
  }];
1316
- insertNode: [options: {
1317
- node: Node_2;
1318
- pos?: number;
1319
- type?: undefined;
1320
- attrs?: undefined;
1321
- } | {
1322
- node?: undefined;
1323
- pos?: number;
1324
- type: string;
1325
- attrs?: Attrs_2;
1326
- }];
1327
- removeNode: [options: {
1328
- type: string | NodeType_2;
1329
- pos?: number;
1330
- }];
1331
- wrap: [{
1332
- nodeType: NodeType_2;
1333
- attrs?: Attrs_2 | null;
1334
- }];
1335
- setBlockType: [options: {
1336
- type: NodeType_2 | string;
1337
- attrs?: Attrs_2 | null;
1338
- from?: number;
1339
- to?: number;
1340
- }];
1341
- setNodeAttrs: [options: {
1342
- type: string | NodeType_2 | string[] | NodeType_2[];
1343
- attrs: Attrs_2;
1344
- pos?: number;
1345
- }];
1323
+ insertNode: [options: InsertNodeOptions];
1324
+ removeNode: [options: RemoveNodeOptions];
1325
+ wrap: [WrapOptions];
1326
+ setBlockType: [options: SetBlockTypeOptions];
1327
+ setNodeAttrs: [options: SetNodeAttrsOptions];
1346
1328
  selectAll: [];
1347
- addMark: [options: {
1348
- type: string | MarkType_2;
1349
- attrs?: Attrs_2 | null;
1350
- from?: number;
1351
- to?: number;
1352
- }];
1353
- removeMark: [options: {
1354
- type: string | MarkType_2;
1355
- attrs?: Attrs_2 | null;
1356
- from?: number;
1357
- to?: number;
1358
- }];
1359
- toggleItalic: [];
1360
- undo: [];
1361
- redo: [];
1329
+ addMark: [options: AddMarkOptions];
1330
+ removeMark: [options: RemoveMarkOptions];
1331
+ unsetBlockType: [options?: UnsetBlockTypeOptions | undefined];
1332
+ unsetMark: [options?: UnsetMarkOptions | undefined];
1333
+ readonly undo: [];
1334
+ readonly redo: [];
1362
1335
  toggleBold: [];
1363
1336
  toggleCode: [];
1364
1337
  setHeading: [attrs?: HeadingAttrs | undefined];
1365
1338
  insertHeading: [attrs?: HeadingAttrs | undefined];
1366
1339
  toggleHeading: [attrs?: HeadingAttrs | undefined];
1367
1340
  insertImage: [attrs?: ImageAttrs | undefined];
1341
+ toggleItalic: [];
1368
1342
  addLink: [attrs: LinkAttrs];
1369
1343
  removeLink: [];
1370
1344
  toggleLink: [attrs: LinkAttrs];
@@ -1376,7 +1350,7 @@ export declare function setupDefaultTest(): {
1376
1350
  toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
1377
1351
  toggleList: [attrs: ListAttributes];
1378
1352
  unwrapList: [options?: UnwrapListOptions | undefined];
1379
- wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
1353
+ wrapInList: [getAttrs: WrapInListGetAttrs<ListAttributes>];
1380
1354
  insertList: [attrs?: ListAttributes | undefined];
1381
1355
  toggleStrike: [];
1382
1356
  insertTable: [{
@@ -1395,7 +1369,7 @@ export declare function setupDefaultTest(): {
1395
1369
  /**
1396
1370
  * @internal
1397
1371
  */
1398
- export declare function setupTest<E extends Extension>(extension: E): {
1372
+ export declare function setupTestFromExtension<E extends Extension>(extension: E): {
1399
1373
  editor: TestEditor<E>;
1400
1374
  n: Record<ExtractNodes<E>, NodeBuilder>;
1401
1375
  m: Record<ExtractMarks<E>, MarkBuilder>;
@@ -1445,4 +1419,10 @@ export declare type TextBlockEnterRuleOptions = {
1445
1419
  stop?: boolean;
1446
1420
  };
1447
1421
 
1422
+ export { ToggleCollapsedOptions }
1423
+
1424
+ export { UnwrapListOptions }
1425
+
1426
+ export { WrapInListGetAttrs }
1427
+
1448
1428
  export { }
@@ -0,0 +1,188 @@
1
+ // src/mark-rule/extension.ts
2
+ import {
3
+ defineFacet,
4
+ defineFacetPayload,
5
+ pluginFacet
6
+ } from "@prosekit/core";
7
+ import {
8
+ PluginKey,
9
+ ProseMirrorPlugin
10
+ } from "@prosekit/pm/state";
11
+
12
+ // src/mark-rule/apply.ts
13
+ import {
14
+ OBJECT_REPLACEMENT_CHARACTER,
15
+ getMarkType,
16
+ maybeRun
17
+ } from "@prosekit/core";
18
+ import "@prosekit/pm/model";
19
+ import "@prosekit/pm/state";
20
+
21
+ // src/mark-rule/range.ts
22
+ import "@prosekit/pm/state";
23
+ function getSpanTextRanges($from, $to) {
24
+ const nodeRange = $from.blockRange($to);
25
+ if (!nodeRange) {
26
+ return [];
27
+ }
28
+ const stack = [];
29
+ let start = nodeRange.start;
30
+ for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {
31
+ const child = nodeRange.parent.child(i);
32
+ stack.push([start, child]);
33
+ start += child.nodeSize;
34
+ }
35
+ const ranges = [];
36
+ while (stack.length > 0) {
37
+ const [start2, node] = stack.pop();
38
+ if (node.type.spec.code) {
39
+ continue;
40
+ }
41
+ if (node.type.isTextblock) {
42
+ ranges.push([start2 + 1, start2 + 1 + node.content.size]);
43
+ continue;
44
+ }
45
+ node.forEach((child, offset) => {
46
+ stack.push([start2 + offset + 1, child]);
47
+ });
48
+ }
49
+ return ranges;
50
+ }
51
+ function getInlineTextRange($from, $to) {
52
+ return [$from.start(), $to.end()];
53
+ }
54
+ function getTextRanges(doc, from, to) {
55
+ const $from = doc.resolve(from);
56
+ const $to = doc.resolve(to);
57
+ if ($from.sameParent($to) && $from.parent.isTextblock) {
58
+ return [getInlineTextRange($from, $to)];
59
+ } else {
60
+ const nodeRange = $from.blockRange($to);
61
+ if (!nodeRange) {
62
+ return [];
63
+ }
64
+ return getSpanTextRanges($from, $to);
65
+ }
66
+ }
67
+ function getMapRange(transactions, oldState, newState) {
68
+ let lo = oldState.selection.from;
69
+ let hi = oldState.selection.to;
70
+ for (const tr of transactions) {
71
+ for (const map of tr.mapping.maps) {
72
+ lo = map.map(lo);
73
+ hi = map.map(hi);
74
+ map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
75
+ lo = Math.min(lo, hi, newStart);
76
+ hi = Math.max(lo, hi, newEnd);
77
+ });
78
+ }
79
+ }
80
+ lo = Math.min(lo, hi, newState.selection.from);
81
+ hi = Math.min(lo, hi, newState.selection.to);
82
+ return [lo, hi];
83
+ }
84
+ function getCheckRanges(transactions, oldState, newState) {
85
+ const [from, to] = getMapRange(transactions, oldState, newState);
86
+ return getTextRanges(newState.doc, from, to);
87
+ }
88
+
89
+ // src/mark-rule/apply.ts
90
+ function getExpectedMarkings(rules, doc, from, to) {
91
+ const text = doc.textBetween(from, to, null, OBJECT_REPLACEMENT_CHARACTER);
92
+ const ranges = [];
93
+ for (const rule of rules) {
94
+ rule.regex.lastIndex = 0;
95
+ const matches = text.matchAll(rule.regex);
96
+ const markType = getMarkType(doc.type.schema, rule.type);
97
+ for (const match of matches) {
98
+ const index = match.index;
99
+ if (index == null) continue;
100
+ const attrs = maybeRun(rule.attrs, match);
101
+ const mark = markType.create(attrs);
102
+ ranges.push([from + index, from + index + match[0].length, mark]);
103
+ }
104
+ }
105
+ ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
106
+ const result = [];
107
+ let freeIndex = 0;
108
+ for (const range of ranges) {
109
+ if (range[0] >= freeIndex) {
110
+ result.push(range);
111
+ freeIndex = range[1];
112
+ }
113
+ }
114
+ return result;
115
+ }
116
+ function getReceivedMarkings(rules, doc, from, to) {
117
+ const result = [];
118
+ const schema = doc.type.schema;
119
+ const markTypes = rules.map((rule) => getMarkType(schema, rule.type));
120
+ doc.nodesBetween(from, to, (node, pos) => {
121
+ if (!node.isInline) {
122
+ return;
123
+ }
124
+ for (const markType of markTypes) {
125
+ const mark = node.marks.find((mark2) => mark2.type === markType);
126
+ if (mark) {
127
+ result.push([pos, pos + node.nodeSize, mark]);
128
+ }
129
+ }
130
+ });
131
+ return result;
132
+ }
133
+ function markRangeEquals(a, b) {
134
+ return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2]);
135
+ }
136
+ function markRangeDiffs(a, b) {
137
+ return a.filter((x) => !b.some((y) => markRangeEquals(x, y)));
138
+ }
139
+ function applyMarkRules(rules, transactions, oldState, newState) {
140
+ if (transactions.length === 0 || transactions.every((tr2) => !tr2.docChanged)) {
141
+ return null;
142
+ }
143
+ const ranges = getCheckRanges(transactions, oldState, newState);
144
+ const toRemove = [];
145
+ const toCreate = [];
146
+ for (const [from, to] of ranges) {
147
+ const expected = getExpectedMarkings(rules, newState.doc, from, to);
148
+ const received = getReceivedMarkings(rules, newState.doc, from, to);
149
+ toRemove.push(...markRangeDiffs(received, expected));
150
+ toCreate.push(...markRangeDiffs(expected, received));
151
+ }
152
+ if (toCreate.length === 0 && toRemove.length === 0) {
153
+ return null;
154
+ }
155
+ const tr = newState.tr;
156
+ for (const [from, to, mark] of toRemove) {
157
+ tr.removeMark(from, to, mark);
158
+ }
159
+ for (const [from, to, mark] of toCreate) {
160
+ tr.addMark(from, to, mark);
161
+ }
162
+ return tr;
163
+ }
164
+
165
+ // src/mark-rule/extension.ts
166
+ function defineMarkRule(options) {
167
+ return defineFacetPayload(markRuleFacet, [options]);
168
+ }
169
+ var markRuleFacet = defineFacet({
170
+ reduce: () => {
171
+ let rules = [];
172
+ const plugin = new ProseMirrorPlugin({
173
+ key: new PluginKey("prosekit-mark-rule"),
174
+ appendTransaction: (transactions, oldState, newState) => {
175
+ return applyMarkRules(rules, transactions, oldState, newState);
176
+ }
177
+ });
178
+ return function reducer(input) {
179
+ rules = input;
180
+ return plugin;
181
+ };
182
+ },
183
+ parent: pluginFacet
184
+ });
185
+
186
+ export {
187
+ defineMarkRule
188
+ };
@@ -24,20 +24,35 @@ function createMarkInputRule({
24
24
  type,
25
25
  attrs = null
26
26
  }) {
27
- return new InputRule(regex, (state, match, start, end) => {
27
+ const rule = new InputRule(regex, (state, match, start, end) => {
28
28
  var _a;
29
- let { tr, schema } = state, [fullText, markText] = match;
30
- if (!markText)
29
+ const { tr, schema } = state;
30
+ const [fullText, markText] = match;
31
+ if (!markText) {
31
32
  return null;
32
- let markStart = start + fullText.indexOf(markText), markEnd = markStart + markText.length;
33
- if (!(start <= markStart && markStart < markEnd && markEnd <= end))
33
+ }
34
+ const markStart = start + fullText.indexOf(markText);
35
+ const markEnd = markStart + markText.length;
36
+ if (!(start <= markStart && markStart < markEnd && markEnd <= end)) {
34
37
  return null;
35
- let markType = getMarkType(schema, type), mark = markType.create(maybeRun(attrs, match));
36
- if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs))
38
+ }
39
+ const markType = getMarkType(schema, type);
40
+ const mark = markType.create(maybeRun(attrs, match));
41
+ if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) {
37
42
  return null;
38
- let initialStoredMarks = (_a = tr.storedMarks) != null ? _a : [];
39
- return tr.addMark(markStart, markEnd, mark), markEnd < end && tr.delete(markEnd, end), start < markStart && tr.delete(start, markStart), tr.setStoredMarks(initialStoredMarks), tr;
43
+ }
44
+ const initialStoredMarks = (_a = tr.storedMarks) != null ? _a : [];
45
+ tr.addMark(markStart, markEnd, mark);
46
+ if (markEnd < end) {
47
+ tr.delete(markEnd, end);
48
+ }
49
+ if (start < markStart) {
50
+ tr.delete(start, markStart);
51
+ }
52
+ tr.setStoredMarks(initialStoredMarks);
53
+ return tr;
40
54
  });
55
+ return rule;
41
56
  }
42
57
  function defineMarkInputRule(options) {
43
58
  return defineInputRule(createMarkInputRule(options));
@@ -49,7 +64,7 @@ function defineTextBlockInputRule({
49
64
  }) {
50
65
  return defineFacetPayload(inputRuleFacet, [
51
66
  ({ schema }) => {
52
- let nodeType = getNodeType(schema, type);
67
+ const nodeType = getNodeType(schema, type);
53
68
  return textblockTypeInputRule(regex, nodeType, attrs);
54
69
  }
55
70
  ]);
@@ -62,15 +77,17 @@ function defineWrappingInputRule({
62
77
  }) {
63
78
  return defineFacetPayload(inputRuleFacet, [
64
79
  ({ schema }) => {
65
- let nodeType = getNodeType(schema, type);
80
+ const nodeType = getNodeType(schema, type);
66
81
  return wrappingInputRule(regex, nodeType, attrs, join);
67
82
  }
68
83
  ]);
69
84
  }
70
85
  var inputRuleFacet = defineFacet({
71
- reducer: (inputs) => (context) => {
72
- let rules = inputs.flatMap((callback) => callback(context));
73
- return [inputRules({ rules })];
86
+ reducer: (inputs) => {
87
+ return (context) => {
88
+ const rules = inputs.flatMap((callback) => callback(context));
89
+ return [inputRules({ rules })];
90
+ };
74
91
  },
75
92
  parent: pluginFacet
76
93
  });