@prosekit/extensions 0.6.1 → 0.7.1

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.
@@ -1,4 +1,5 @@
1
1
  import { Attrs } from '@prosekit/pm/model';
2
+ import { Attrs as Attrs_2 } from 'prosemirror-model';
2
3
  import { BundledLanguage } from 'shiki';
3
4
  import { BundledLanguageInfo } from 'shiki';
4
5
  import { bundledLanguagesInfo } from 'shiki';
@@ -7,23 +8,35 @@ import { BundledThemeInfo } from 'shiki';
7
8
  import { bundledThemesInfo } from 'shiki';
8
9
  import { Command } from '@prosekit/pm/state';
9
10
  import { DedentListOptions } from 'prosemirror-flat-list';
11
+ import { config as default_alias_1 } from '@prosekit/dev/config-vitest';
10
12
  import { EditorState } from '@prosekit/pm/state';
11
13
  import { Extension } from '@prosekit/core';
14
+ import { ExtensionTyping } from '@prosekit/core';
15
+ import { ExtractMarks } from '@prosekit/core';
16
+ import { ExtractNodes } from '@prosekit/core';
12
17
  import { getSingletonHighlighter } from 'shiki/bundle/full';
13
18
  import type { Highlighter } from 'shiki';
14
19
  import { IndentListOptions } from 'prosemirror-flat-list';
15
20
  import { InputRule } from '@prosekit/pm/inputrules';
16
21
  import { ListAttributes } from 'prosemirror-flat-list';
17
22
  import { ListDOMSerializer } from 'prosemirror-flat-list';
23
+ import { MarkBuilder } from '@prosekit/core';
18
24
  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
+ import { NodeBuilder } from '@prosekit/core';
28
+ import { NodeJSON } from '@prosekit/core';
19
29
  import { NodeRange } from 'prosemirror-model';
20
30
  import { NodeType } from '@prosekit/pm/model';
31
+ import { NodeType as NodeType_2 } from 'prosemirror-model';
21
32
  import { Options } from 'tsup';
22
33
  import { Parser } from 'prosemirror-highlight';
23
34
  import { Plugin as Plugin_2 } from '@prosekit/pm/state';
24
35
  import { PluginKey } from '@prosekit/pm/state';
25
36
  import { ProseMirrorNode } from '@prosekit/pm/model';
26
37
  import type { SpecialLanguage } from 'shiki';
38
+ import { StepJSON } from '@prosekit/core';
39
+ import { TestEditor } from '@prosekit/core/test';
27
40
  import { ToggleCollapsedOptions } from 'prosemirror-flat-list';
28
41
  import { Transaction } from '@prosekit/pm/state';
29
42
  import { UnwrapListOptions } from 'prosemirror-flat-list';
@@ -109,6 +122,44 @@ export declare interface CodeBlockShikiOptions {
109
122
  langAlias?: Record<string, BundledLanguage>;
110
123
  }
111
124
 
125
+ /**
126
+ * A JSON representation of a commit.
127
+ */
128
+ export declare interface Commit {
129
+ /**
130
+ * The current doc node in the JSON format
131
+ */
132
+ doc: NodeJSON;
133
+ /**
134
+ * The parent node in the JSON format
135
+ */
136
+ parent: NodeJSON;
137
+ /**
138
+ * An array of steps in the JSON format that transform the parent node to the
139
+ * current doc node.
140
+ */
141
+ steps: StepJSON[];
142
+ }
143
+
144
+ export declare class CommitRecorder {
145
+ private parent;
146
+ private doc;
147
+ private steps;
148
+ /**
149
+ * Return a commit object including all changes since the last commit. `null`
150
+ * will be returned if there is no change.
151
+ */
152
+ commit(): Commit | null;
153
+ /**
154
+ * @internal
155
+ */
156
+ init(doc: ProseMirrorNode): void;
157
+ /**
158
+ * @internal
159
+ */
160
+ apply(tr: Transaction): void;
161
+ }
162
+
112
163
  export declare function createAutocompletePlugin({ getRules, }: {
113
164
  getRules: () => AutocompleteRule[];
114
165
  }): Plugin_2;
@@ -125,11 +176,7 @@ export declare function createMarkInputRule({ regex, type, attrs, }: MarkInputRu
125
176
 
126
177
  export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
127
178
 
128
- export declare const default_alias_1: {
129
- test: {
130
- environment: "jsdom";
131
- };
132
- };
179
+ export { default_alias_1 }
133
180
 
134
181
  export declare function defaultCanMatch({ state }: {
135
182
  state: EditorState;
@@ -150,7 +197,7 @@ Commands: never;
150
197
  * Wraps the text block in a blockquote when `>` is typed at the start of a new
151
198
  * line followed by a space.
152
199
  */
153
- export declare function defineBlockquoteInputRule(): Extension<any>;
200
+ export declare function defineBlockquoteInputRule(): Extension<ExtensionTyping<any, any, any>>;
154
201
 
155
202
  export declare function defineBlockquoteSpec(): Extension< {
156
203
  Nodes: "blockquote";
@@ -177,9 +224,9 @@ Nodes: never;
177
224
  Marks: never;
178
225
  }>;
179
226
 
180
- export declare function defineBoldInputRule(): Extension<any>;
227
+ export declare function defineBoldInputRule(): Extension<ExtensionTyping<any, any, any>>;
181
228
 
182
- export declare function defineBoldKeymap(): Extension<any>;
229
+ export declare function defineBoldKeymap(): Extension<ExtensionTyping<any, any, any>>;
183
230
 
184
231
  export declare function defineBoldSpec(): Extension< {
185
232
  Marks: "bold";
@@ -245,7 +292,7 @@ export { defineCodeBlockCommands as defineCodeBlockCommands_alias_1 }
245
292
  *
246
293
  * @public
247
294
  */
248
- declare function defineCodeBlockEnterRule(): Extension<any>;
295
+ declare function defineCodeBlockEnterRule(): Extension<ExtensionTyping<any, any, any>>;
249
296
  export { defineCodeBlockEnterRule }
250
297
  export { defineCodeBlockEnterRule as defineCodeBlockEnterRule_alias_1 }
251
298
 
@@ -268,14 +315,14 @@ export { defineCodeBlockHighlight as defineCodeBlockHighlight_alias_1 }
268
315
  *
269
316
  * @public
270
317
  */
271
- declare function defineCodeBlockInputRule(): Extension<any>;
318
+ declare function defineCodeBlockInputRule(): Extension<ExtensionTyping<any, any, any>>;
272
319
  export { defineCodeBlockInputRule }
273
320
  export { defineCodeBlockInputRule as defineCodeBlockInputRule_alias_1 }
274
321
 
275
322
  /**
276
323
  * Defines the keymap for code blocks.
277
324
  */
278
- export declare function defineCodeBlockKeymap(): Extension<any>;
325
+ export declare function defineCodeBlockKeymap(): Extension<ExtensionTyping<any, any, any>>;
279
326
 
280
327
  /**
281
328
  * Adds syntax highlighting to code blocks using the [shiki](https://github.com/shikijs/shiki) package.
@@ -307,9 +354,9 @@ Nodes: never;
307
354
  Marks: never;
308
355
  }>;
309
356
 
310
- export declare function defineCodeInputRule(): Extension<any>;
357
+ export declare function defineCodeInputRule(): Extension<ExtensionTyping<any, any, any>>;
311
358
 
312
- export declare function defineCodeKeymap(): Extension<any>;
359
+ export declare function defineCodeKeymap(): Extension<ExtensionTyping<any, any, any>>;
313
360
 
314
361
  /**
315
362
  * @public
@@ -320,6 +367,20 @@ Nodes: never;
320
367
  Commands: never;
321
368
  }>;
322
369
 
370
+ /**
371
+ * Define an extension that can record the changes in the editor.
372
+ */
373
+ export declare function defineCommitRecorder(commitRecorder: CommitRecorder): Extension<ExtensionTyping<any, any, any>>;
374
+
375
+ /**
376
+ * Define an extension to display the changes from the given commit in the editor.
377
+ */
378
+ export declare function defineCommitViewer(commit: Commit): Extension< {
379
+ Nodes: never;
380
+ Marks: never;
381
+ Commands: never;
382
+ }>;
383
+
323
384
  /**
324
385
  * Show up a decoration at the drop position when something is dragged over the editor.
325
386
  *
@@ -327,7 +388,7 @@ Commands: never;
327
388
  *
328
389
  * @public
329
390
  */
330
- export declare function defineDropCursor(options?: DropCursorOptions): Extension<any>;
391
+ export declare function defineDropCursor(options?: DropCursorOptions): Extension<ExtensionTyping<any, any, any>>;
331
392
 
332
393
  /**
333
394
  * Defines an enter rule. An enter rule applies when the text directly in front of
@@ -365,9 +426,9 @@ Marks: never;
365
426
  * Converts the text block to a heading when `#` is typed at the start of a new
366
427
  * line followed by a space.
367
428
  */
368
- export declare function defineHeadingInputRule(): Extension<any>;
429
+ export declare function defineHeadingInputRule(): Extension<ExtensionTyping<any, any, any>>;
369
430
 
370
- export declare function defineHeadingKeymap(): Extension<any>;
431
+ export declare function defineHeadingKeymap(): Extension<ExtensionTyping<any, any, any>>;
371
432
 
372
433
  export declare function defineHeadingSpec(): Extension< {
373
434
  Nodes: "heading";
@@ -428,9 +489,9 @@ Nodes: never;
428
489
  Marks: never;
429
490
  }>;
430
491
 
431
- export declare function defineItalicInputRule(): Extension<any>;
492
+ export declare function defineItalicInputRule(): Extension<ExtensionTyping<any, any, any>>;
432
493
 
433
- export declare function defineItalicKeymap(): Extension<any>;
494
+ export declare function defineItalicKeymap(): Extension<ExtensionTyping<any, any, any>>;
434
495
 
435
496
  export declare function defineItalicSpec(): Extension< {
436
497
  Marks: "italic";
@@ -466,17 +527,17 @@ Marks: never;
466
527
  /**
467
528
  * Apply link marks after typing Enter.
468
529
  */
469
- export declare function defineLinkEnterRule(): Extension<any>;
530
+ export declare function defineLinkEnterRule(): Extension<ExtensionTyping<any, any, any>>;
470
531
 
471
532
  /**
472
533
  * Apply link marks after pressing Space.
473
534
  */
474
- export declare function defineLinkInputRule(): Extension<any>;
535
+ export declare function defineLinkInputRule(): Extension<ExtensionTyping<any, any, any>>;
475
536
 
476
537
  /**
477
538
  * Apply and remove link marks to the text during typing.
478
539
  */
479
- export declare function defineLinkMarkRule(): Extension<any>;
540
+ export declare function defineLinkMarkRule(): Extension<ExtensionTyping<any, any, any>>;
480
541
 
481
542
  export declare function defineLinkSpec(): Extension< {
482
543
  Marks: "link";
@@ -526,9 +587,9 @@ export declare function defineListInputRules(): Extension;
526
587
  *
527
588
  * @public
528
589
  */
529
- export declare function defineListKeymap(): Extension<any>;
590
+ export declare function defineListKeymap(): Extension<ExtensionTyping<any, any, any>>;
530
591
 
531
- export declare function defineListPlugins(): Extension<any>;
592
+ export declare function defineListPlugins(): Extension<ExtensionTyping<any, any, any>>;
532
593
 
533
594
  export declare function defineListSpec(): Extension<{
534
595
  Nodes: "list";
@@ -548,7 +609,7 @@ export declare function defineMarkInputRule(options: MarkInputRuleOptions): Exte
548
609
  * A mark rule is something that can automatically apply marks to text if it
549
610
  * matches a certain pattern, and remove them if it doesn't match anymore.
550
611
  */
551
- declare function defineMarkRule(options: MarkRuleOptions): Extension<any>;
612
+ declare function defineMarkRule(options: MarkRuleOptions): Extension<ExtensionTyping<any, any, any>>;
552
613
  export { defineMarkRule }
553
614
  export { defineMarkRule as defineMarkRule_alias_1 }
554
615
 
@@ -592,12 +653,12 @@ export declare function defineModClickPrevention(): Extension;
592
653
  * Add a placeholder text to the editor when the current block or document is
593
654
  * empty.
594
655
  */
595
- export declare function definePlaceholder(options: PlaceholderOptions): Extension<any>;
656
+ export declare function definePlaceholder(options: PlaceholderOptions): Extension<ExtensionTyping<any, any, any>>;
596
657
 
597
658
  /**
598
659
  * Make the editor read-only.
599
660
  */
600
- export declare function defineReadonly(): Extension<any>;
661
+ export declare function defineReadonly(): Extension<ExtensionTyping<any, any, any>>;
601
662
 
602
663
  /**
603
664
  * Defines commands for search and replace.
@@ -624,7 +685,7 @@ Marks: never;
624
685
  *
625
686
  * @public
626
687
  */
627
- export declare function defineSearchQuery(options: SearchQueryOptions): Extension<any>;
688
+ export declare function defineSearchQuery(options: SearchQueryOptions): Extension<ExtensionTyping<any, any, any>>;
628
689
 
629
690
  /**
630
691
  * @public
@@ -645,9 +706,9 @@ Nodes: never;
645
706
  Marks: never;
646
707
  }>;
647
708
 
648
- export declare function defineStrikeInputRule(): Extension<any>;
709
+ export declare function defineStrikeInputRule(): Extension<ExtensionTyping<any, any, any>>;
649
710
 
650
- export declare function defineStrikeKeymap(): Extension<any>;
711
+ export declare function defineStrikeKeymap(): Extension<ExtensionTyping<any, any, any>>;
651
712
 
652
713
  export declare function defineStrikeSpec(): Extension< {
653
714
  Marks: "strike";
@@ -710,7 +771,7 @@ export { defineTableHeaderCellSpec as defineTableHeaderCellSpec_alias_1 }
710
771
  /**
711
772
  * @public
712
773
  */
713
- declare function defineTablePlugins(): Extension<any>;
774
+ declare function defineTablePlugins(): Extension<ExtensionTyping<any, any, any>>;
714
775
  export { defineTablePlugins }
715
776
  export { defineTablePlugins as defineTablePlugins_alias_1 }
716
777
 
@@ -730,6 +791,94 @@ Commands: never;
730
791
  export { defineTableSpec }
731
792
  export { defineTableSpec as defineTableSpec_alias_1 }
732
793
 
794
+ /**
795
+ * @internal
796
+ */
797
+ export declare function defineTestExtension(): Extension<{
798
+ Nodes: "blockquote" | "table" | "text" | "doc" | "paragraph" | "heading" | "image" | "list" | "tableRow" | "tableCell" | "tableHeaderCell";
799
+ Marks: "code" | "link" | "bold" | "strike" | "italic" | "underline";
800
+ Commands: {
801
+ insertText: [{
802
+ text: string;
803
+ from?: number;
804
+ to?: number;
805
+ }];
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
+ }];
836
+ 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: [];
852
+ toggleBold: [];
853
+ toggleCode: [];
854
+ setHeading: [attrs?: HeadingAttrs | undefined];
855
+ insertHeading: [attrs?: HeadingAttrs | undefined];
856
+ toggleHeading: [attrs?: HeadingAttrs | undefined];
857
+ insertImage: [attrs?: ImageAttrs | undefined];
858
+ addLink: [attrs: LinkAttrs];
859
+ removeLink: [];
860
+ toggleLink: [attrs: LinkAttrs];
861
+ expandLink: [];
862
+ dedentList: [options?: DedentListOptions | undefined];
863
+ indentList: [options?: IndentListOptions | undefined];
864
+ moveList: [direction: "up" | "down"];
865
+ splitList: [];
866
+ toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
867
+ toggleList: [attrs: ListAttributes];
868
+ unwrapList: [options?: UnwrapListOptions | undefined];
869
+ wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
870
+ insertList: [attrs?: ListAttributes | undefined];
871
+ toggleStrike: [];
872
+ insertTable: [{
873
+ row: number;
874
+ col: number;
875
+ header: boolean;
876
+ }];
877
+ exitTable: [];
878
+ toggleUnderline: [];
879
+ };
880
+ }>;
881
+
733
882
  /**
734
883
  * Adds a `textAlign` attribute to the specified nodes. This will be rendered as
735
884
  * a CSS `text-align` style.
@@ -758,7 +907,7 @@ export declare function defineTextAlignCommands(types: string[]): Extension<{
758
907
  /**
759
908
  * @internal
760
909
  */
761
- export declare function defineTextAlignKeymap(types: string[]): Extension<any>;
910
+ export declare function defineTextAlignKeymap(types: string[]): Extension<ExtensionTyping<any, any, any>>;
762
911
 
763
912
  /**
764
913
  * Defines an enter rule that replaces the matched text with a block node.
@@ -813,7 +962,7 @@ Nodes: never;
813
962
  Marks: never;
814
963
  }>;
815
964
 
816
- export declare function defineUnderlineKeymap(): Extension<any>;
965
+ export declare function defineUnderlineKeymap(): Extension<ExtensionTyping<any, any, any>>;
817
966
 
818
967
  export declare function defineUnderlineSpec(): Extension< {
819
968
  Marks: "underline";
@@ -1151,6 +1300,107 @@ export declare function setTextAlign({ types, value, }: {
1151
1300
 
1152
1301
  export declare function setTrMeta(tr: Transaction, meta: PredictionPluginState): Transaction;
1153
1302
 
1303
+ /**
1304
+ * @internal
1305
+ */
1306
+ export declare function setupDefaultTest(): {
1307
+ editor: TestEditor<Extension<{
1308
+ Nodes: "blockquote" | "table" | "text" | "doc" | "paragraph" | "heading" | "image" | "list" | "tableRow" | "tableCell" | "tableHeaderCell";
1309
+ Marks: "code" | "link" | "bold" | "strike" | "italic" | "underline";
1310
+ Commands: {
1311
+ insertText: [{
1312
+ text: string;
1313
+ from?: number;
1314
+ to?: number;
1315
+ }];
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
+ }];
1346
+ 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: [];
1362
+ toggleBold: [];
1363
+ toggleCode: [];
1364
+ setHeading: [attrs?: HeadingAttrs | undefined];
1365
+ insertHeading: [attrs?: HeadingAttrs | undefined];
1366
+ toggleHeading: [attrs?: HeadingAttrs | undefined];
1367
+ insertImage: [attrs?: ImageAttrs | undefined];
1368
+ addLink: [attrs: LinkAttrs];
1369
+ removeLink: [];
1370
+ toggleLink: [attrs: LinkAttrs];
1371
+ expandLink: [];
1372
+ dedentList: [options?: DedentListOptions | undefined];
1373
+ indentList: [options?: IndentListOptions | undefined];
1374
+ moveList: [direction: "up" | "down"];
1375
+ splitList: [];
1376
+ toggleCollapsed: [(ToggleCollapsedOptions | undefined)?];
1377
+ toggleList: [attrs: ListAttributes];
1378
+ unwrapList: [options?: UnwrapListOptions | undefined];
1379
+ wrapInList: [getAttrs: ListAttributes | ((range: NodeRange) => ListAttributes | null)];
1380
+ insertList: [attrs?: ListAttributes | undefined];
1381
+ toggleStrike: [];
1382
+ insertTable: [{
1383
+ row: number;
1384
+ col: number;
1385
+ header: boolean;
1386
+ }];
1387
+ exitTable: [];
1388
+ toggleUnderline: [];
1389
+ };
1390
+ }>>;
1391
+ n: Record<"blockquote" | "table" | "text" | "doc" | "paragraph" | "heading" | "image" | "list" | "tableRow" | "tableCell" | "tableHeaderCell", NodeBuilder>;
1392
+ m: Record<"code" | "link" | "bold" | "strike" | "italic" | "underline", MarkBuilder>;
1393
+ };
1394
+
1395
+ /**
1396
+ * @internal
1397
+ */
1398
+ export declare function setupTest<E extends Extension>(extension: E): {
1399
+ editor: TestEditor<E>;
1400
+ n: Record<ExtractNodes<E>, NodeBuilder>;
1401
+ m: Record<ExtractMarks<E>, MarkBuilder>;
1402
+ };
1403
+
1154
1404
  export declare interface TextAlignOptions {
1155
1405
  /**
1156
1406
  * The names of node to add the attribute to.
@@ -0,0 +1,8 @@
1
+ /* src/commit/style.css */
2
+ .prosekit-commit-deletion {
3
+ background-color: #e5534b80;
4
+ text-decoration: line-through;
5
+ }
6
+ .prosekit-commit-addition {
7
+ background-color: #53e54b80;
8
+ }
@@ -1,4 +1,4 @@
1
- /* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.0/node_modules/prosemirror-flat-list/dist/style.css */
1
+ /* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.1/node_modules/prosemirror-flat-list/dist/style.css */
2
2
  .prosemirror-flat-list {
3
3
  padding: 0;
4
4
  margin-top: 0;
@@ -1,9 +1,9 @@
1
- import {
2
- defineTextBlockInputRule
3
- } from "./chunk-PYT3MOTF.js";
4
1
  import {
5
2
  defineTextBlockEnterRule
6
3
  } from "./chunk-2JYT2MT7.js";
4
+ import {
5
+ defineTextBlockInputRule
6
+ } from "./chunk-PYT3MOTF.js";
7
7
 
8
8
  // src/code-block/code-block.ts
9
9
  import { union } from "@prosekit/core";
@@ -0,0 +1,4 @@
1
+ export { CommitRecorder } from './_tsup-dts-rollup';
2
+ export { defineCommitRecorder } from './_tsup-dts-rollup';
3
+ export { defineCommitViewer } from './_tsup-dts-rollup';
4
+ export { Commit } from './_tsup-dts-rollup';
@@ -0,0 +1,160 @@
1
+ // src/commit/index.ts
2
+ import {
3
+ collectNodes,
4
+ defineDefaultState,
5
+ definePlugin,
6
+ jsonFromNode,
7
+ union
8
+ } from "@prosekit/core";
9
+ import {
10
+ DOMSerializer,
11
+ Fragment,
12
+ Slice
13
+ } from "@prosekit/pm/model";
14
+ import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
15
+ import { Step } from "@prosekit/pm/transform";
16
+ import { Decoration, DecorationSet } from "@prosekit/pm/view";
17
+ import { ChangeSet } from "prosemirror-changeset";
18
+ function getChanges(doc, parent, steps) {
19
+ return ChangeSet.create(parent).addSteps(
20
+ doc,
21
+ steps.map((step) => step.getMap()),
22
+ null
23
+ ).changes;
24
+ }
25
+ function renderDivWeight(view) {
26
+ return view.dom.ownerDocument.createElement("div");
27
+ }
28
+ function decorateDeletionSlice(slice) {
29
+ let { openStart, openEnd, content } = slice;
30
+ for (; openStart > 0 && openEnd > 0 && content.childCount === 1; )
31
+ openStart--, openEnd--, content = content.child(0).content;
32
+ if (content.childCount === 0)
33
+ return [];
34
+ if (openStart > 0 && openEnd > 0 && content.childCount === 2) {
35
+ let head = Fragment.from([content.child(0)]), tail = Fragment.from([content.child(1)]);
36
+ return [
37
+ ...decorateDeletionSlice(new Slice(head, openStart, openStart)),
38
+ renderDivWeight,
39
+ ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd))
40
+ ];
41
+ }
42
+ if (openStart > 0 && content.childCount >= 2) {
43
+ let nodes = collectNodes(content), head = Fragment.from(nodes.slice(0, 1)), body = Fragment.from(nodes.slice(1));
44
+ return [
45
+ ...decorateDeletionSlice(new Slice(head, openStart, openStart)),
46
+ ...decorateDeletionSlice(new Slice(body, 0, openEnd))
47
+ ];
48
+ }
49
+ if (openEnd > 0 && content.childCount >= 2) {
50
+ let nodes = collectNodes(content), body = Fragment.from(nodes.slice(0, -1)), tail = Fragment.from(nodes.slice(-1));
51
+ return [
52
+ ...decorateDeletionSlice(new Slice(body, openStart, 0)),
53
+ ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd))
54
+ ];
55
+ }
56
+ let schema = content.child(0).type.schema, isInline = content.child(0).isInline;
57
+ return [(view) => {
58
+ let document = view.dom.ownerDocument, element = document.createElement(isInline ? "span" : "div");
59
+ return DOMSerializer.fromSchema(schema).serializeFragment(content, { document }, element), element.classList.add("prosekit-commit-deletion"), element;
60
+ }];
61
+ }
62
+ function decorateDeletion(doc, from, to, pos) {
63
+ let slice = doc.slice(from, to), renders = decorateDeletionSlice(slice), count = renders.length;
64
+ return renders.map(
65
+ (render, index) => Decoration.widget(pos, render, {
66
+ side: -20 - count + index,
67
+ // Ensure the text in the decoration is able to be selected.
68
+ ignoreSelection: !0
69
+ })
70
+ );
71
+ }
72
+ function decorateAddition(from, to) {
73
+ return Decoration.inline(from, to, { class: "prosekit-commit-addition" });
74
+ }
75
+ function decorateChange(prev, change) {
76
+ let { fromA, toA, fromB, toB } = change, decorations = [];
77
+ return fromA < toA && decorations.push(...decorateDeletion(prev, fromA, toA, fromB)), fromB < toB && decorations.push(decorateAddition(fromB, toB)), decorations;
78
+ }
79
+ function decorateCommit(doc, parent, steps) {
80
+ let decorations = getChanges(doc, parent, steps).flatMap(
81
+ (change) => decorateChange(parent, change)
82
+ );
83
+ return DecorationSet.create(doc, decorations);
84
+ }
85
+ function defineCommitDecoration(commit) {
86
+ let key = new PluginKey("prosekit-commit-decoration");
87
+ return definePlugin(({ schema }) => {
88
+ let parent = schema.nodeFromJSON(commit.parent), steps = commit.steps.map((step) => Step.fromJSON(schema, step));
89
+ return new ProseMirrorPlugin({
90
+ key,
91
+ state: {
92
+ init: (_, instance) => decorateCommit(instance.doc, parent, steps),
93
+ apply: (tr, deco) => deco.map(tr.mapping, tr.doc)
94
+ },
95
+ props: {
96
+ decorations: (state) => key.getState(state)
97
+ }
98
+ });
99
+ });
100
+ }
101
+ function defineCommitViewer(commit) {
102
+ return union([
103
+ defineDefaultState({ defaultDoc: commit.doc }),
104
+ defineCommitDecoration(commit)
105
+ ]);
106
+ }
107
+ var CommitRecorder = class {
108
+ constructor() {
109
+ this.parent = null;
110
+ this.doc = null;
111
+ this.steps = [];
112
+ }
113
+ /**
114
+ * Return a commit object including all changes since the last commit. `null`
115
+ * will be returned if there is no change.
116
+ */
117
+ commit() {
118
+ if (!this.parent || !this.doc || this.steps.length === 0 || this.parent.eq(this.doc))
119
+ return null;
120
+ let commit = {
121
+ doc: jsonFromNode(this.doc),
122
+ parent: jsonFromNode(this.parent),
123
+ steps: this.steps.map((step) => step.toJSON())
124
+ };
125
+ return this.init(this.doc), commit;
126
+ }
127
+ /**
128
+ * @internal
129
+ */
130
+ init(doc) {
131
+ this.doc = doc, this.parent = doc, this.steps = [];
132
+ }
133
+ /**
134
+ * @internal
135
+ */
136
+ apply(tr) {
137
+ this.steps.push(...tr.steps), this.doc = tr.doc;
138
+ }
139
+ };
140
+ function defineCommitRecorder(commitRecorder) {
141
+ let key = new PluginKey("prosekit-commit-recorder");
142
+ return definePlugin(
143
+ new ProseMirrorPlugin({
144
+ key,
145
+ state: {
146
+ init: (_, state) => {
147
+ commitRecorder.init(state.doc);
148
+ },
149
+ apply: (tr) => {
150
+ commitRecorder.apply(tr);
151
+ }
152
+ }
153
+ })
154
+ );
155
+ }
156
+ export {
157
+ CommitRecorder,
158
+ defineCommitRecorder,
159
+ defineCommitViewer
160
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  defineMarkRule
3
3
  } from "./chunk-ZPEMHYTU.js";
4
- import {
5
- defineInputRule
6
- } from "./chunk-PYT3MOTF.js";
7
4
  import {
8
5
  defineEnterRule
9
6
  } from "./chunk-2JYT2MT7.js";
7
+ import {
8
+ defineInputRule
9
+ } from "./chunk-PYT3MOTF.js";
10
10
 
11
11
  // src/link/index.ts
12
12
  import {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.6.1",
4
+ "version": "0.7.1",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -55,6 +55,14 @@
55
55
  "import": "./dist/prosekit-extensions-code-block.js",
56
56
  "default": "./dist/prosekit-extensions-code-block.js"
57
57
  },
58
+ "./commit": {
59
+ "types": "./dist/prosekit-extensions-commit.d.ts",
60
+ "import": "./dist/prosekit-extensions-commit.js",
61
+ "default": "./dist/prosekit-extensions-commit.js"
62
+ },
63
+ "./commit/style.css": {
64
+ "default": "./dist/commit/style.css"
65
+ },
58
66
  "./drop-cursor": {
59
67
  "types": "./dist/prosekit-extensions-drop-cursor.d.ts",
60
68
  "import": "./dist/prosekit-extensions-drop-cursor.js",
@@ -170,19 +178,21 @@
170
178
  "dist"
171
179
  ],
172
180
  "dependencies": {
181
+ "prosemirror-changeset": "^2.2.1",
173
182
  "prosemirror-dropcursor": "^1.8.1",
174
- "prosemirror-flat-list": "^0.5.0",
183
+ "prosemirror-flat-list": "^0.5.1",
175
184
  "prosemirror-highlight": "^0.8.0",
176
185
  "prosemirror-search": "^0.1.0",
177
186
  "prosemirror-tables": "^1.3.7",
178
- "shiki": "^1.9.0",
179
- "@prosekit/core": "^0.6.1",
187
+ "shiki": "^1.10.1",
188
+ "@prosekit/core": "^0.7.1",
180
189
  "@prosekit/pm": "^0.1.5"
181
190
  },
182
191
  "devDependencies": {
192
+ "@vitest/browser": "^2.0.0-beta.13",
183
193
  "tsup": "^8.1.0",
184
- "typescript": "^5.5.2",
185
- "vitest": "^1.6.0",
194
+ "typescript": "^5.5.3",
195
+ "vitest": "^2.0.0-beta.13",
186
196
  "@prosekit/dev": "0.0.0"
187
197
  },
188
198
  "scripts": {
@@ -210,6 +220,9 @@
210
220
  "code-block": [
211
221
  "./dist/prosekit-extensions-code-block.d.ts"
212
222
  ],
223
+ "commit": [
224
+ "./dist/prosekit-extensions-commit.d.ts"
225
+ ],
213
226
  "drop-cursor": [
214
227
  "./dist/prosekit-extensions-drop-cursor.d.ts"
215
228
  ],