@prosekit/extensions 0.0.0-next-20240626133927 → 0.0.0-next-20240707065442

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.
@@ -25,6 +25,7 @@ import { MarkType } from '@prosekit/pm/model';
25
25
  import { MarkType as MarkType_2 } from 'prosemirror-model';
26
26
  import { Node as Node_2 } from 'prosemirror-model';
27
27
  import { NodeBuilder } from '@prosekit/core';
28
+ import { NodeJSON } from '@prosekit/core';
28
29
  import { NodeRange } from 'prosemirror-model';
29
30
  import { NodeType } from '@prosekit/pm/model';
30
31
  import { NodeType as NodeType_2 } from 'prosemirror-model';
@@ -34,6 +35,7 @@ import { Plugin as Plugin_2 } from '@prosekit/pm/state';
34
35
  import { PluginKey } from '@prosekit/pm/state';
35
36
  import { ProseMirrorNode } from '@prosekit/pm/model';
36
37
  import type { SpecialLanguage } from 'shiki';
38
+ import { StepJSON } from '@prosekit/core';
37
39
  import { TestEditor } from '@prosekit/core/test';
38
40
  import { ToggleCollapsedOptions } from 'prosemirror-flat-list';
39
41
  import { Transaction } from '@prosekit/pm/state';
@@ -120,6 +122,44 @@ export declare interface CodeBlockShikiOptions {
120
122
  langAlias?: Record<string, BundledLanguage>;
121
123
  }
122
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
+
123
163
  export declare function createAutocompletePlugin({ getRules, }: {
124
164
  getRules: () => AutocompleteRule[];
125
165
  }): Plugin_2;
@@ -327,6 +367,20 @@ Nodes: never;
327
367
  Commands: never;
328
368
  }>;
329
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
+
330
384
  /**
331
385
  * Show up a decoration at the drop position when something is dragged over the editor.
332
386
  *
@@ -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.0.0-next-20240626133927",
4
+ "version": "0.0.0-next-20240707065442",
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,20 +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/pm": "^0.0.0-next-20240626133927",
180
- "@prosekit/core": "^0.0.0-next-20240626133927"
187
+ "shiki": "^1.10.1",
188
+ "@prosekit/core": "^0.0.0-next-20240707065442",
189
+ "@prosekit/pm": "^0.0.0-next-20240707065442"
181
190
  },
182
191
  "devDependencies": {
183
- "@vitest/browser": "^2.0.0-beta.12",
192
+ "@vitest/browser": "^2.0.0-beta.13",
184
193
  "tsup": "^8.1.0",
185
- "typescript": "^5.5.2",
186
- "vitest": "^2.0.0-beta.12",
194
+ "typescript": "^5.5.3",
195
+ "vitest": "^2.0.0-beta.13",
187
196
  "@prosekit/dev": "0.0.0"
188
197
  },
189
198
  "scripts": {
@@ -211,6 +220,9 @@
211
220
  "code-block": [
212
221
  "./dist/prosekit-extensions-code-block.d.ts"
213
222
  ],
223
+ "commit": [
224
+ "./dist/prosekit-extensions-commit.d.ts"
225
+ ],
214
226
  "drop-cursor": [
215
227
  "./dist/prosekit-extensions-drop-cursor.d.ts"
216
228
  ],