@liveblocks/react-tiptap 3.19.5-rc1 → 3.20.0-exp2

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 (52) hide show
  1. package/dist/LiveblocksExtension.cjs +51 -5
  2. package/dist/LiveblocksExtension.cjs.map +1 -1
  3. package/dist/LiveblocksExtension.js +51 -5
  4. package/dist/LiveblocksExtension.js.map +1 -1
  5. package/dist/ai/AiExtension.cjs +2 -1
  6. package/dist/ai/AiExtension.cjs.map +1 -1
  7. package/dist/ai/AiExtension.js +2 -1
  8. package/dist/ai/AiExtension.js.map +1 -1
  9. package/dist/collaboration-liveblocks/cursors.cjs +267 -0
  10. package/dist/collaboration-liveblocks/cursors.cjs.map +1 -0
  11. package/dist/collaboration-liveblocks/cursors.js +264 -0
  12. package/dist/collaboration-liveblocks/cursors.js.map +1 -0
  13. package/dist/collaboration-liveblocks/mapping.cjs +218 -0
  14. package/dist/collaboration-liveblocks/mapping.cjs.map +1 -0
  15. package/dist/collaboration-liveblocks/mapping.js +207 -0
  16. package/dist/collaboration-liveblocks/mapping.js.map +1 -0
  17. package/dist/collaboration-liveblocks/plugin.cjs +249 -0
  18. package/dist/collaboration-liveblocks/plugin.cjs.map +1 -0
  19. package/dist/collaboration-liveblocks/plugin.js +246 -0
  20. package/dist/collaboration-liveblocks/plugin.js.map +1 -0
  21. package/dist/collaboration-liveblocks/remote.cjs +210 -0
  22. package/dist/collaboration-liveblocks/remote.cjs.map +1 -0
  23. package/dist/collaboration-liveblocks/remote.js +207 -0
  24. package/dist/collaboration-liveblocks/remote.js.map +1 -0
  25. package/dist/collaboration-liveblocks/schema.cjs +150 -0
  26. package/dist/collaboration-liveblocks/schema.cjs.map +1 -0
  27. package/dist/collaboration-liveblocks/schema.js +135 -0
  28. package/dist/collaboration-liveblocks/schema.js.map +1 -0
  29. package/dist/collaboration-liveblocks/steps.cjs +359 -0
  30. package/dist/collaboration-liveblocks/steps.cjs.map +1 -0
  31. package/dist/collaboration-liveblocks/steps.js +356 -0
  32. package/dist/collaboration-liveblocks/steps.js.map +1 -0
  33. package/dist/comments/CommentsExtension.cjs +7 -1
  34. package/dist/comments/CommentsExtension.cjs.map +1 -1
  35. package/dist/comments/CommentsExtension.js +7 -1
  36. package/dist/comments/CommentsExtension.js.map +1 -1
  37. package/dist/index.d.cts +5 -0
  38. package/dist/index.d.ts +5 -0
  39. package/dist/mentions/MentionExtension.cjs +4 -1
  40. package/dist/mentions/MentionExtension.cjs.map +1 -1
  41. package/dist/mentions/MentionExtension.js +4 -1
  42. package/dist/mentions/MentionExtension.js.map +1 -1
  43. package/dist/types.cjs.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/dist/version.cjs +1 -1
  46. package/dist/version.cjs.map +1 -1
  47. package/dist/version.js +1 -1
  48. package/dist/version.js.map +1 -1
  49. package/package.json +6 -6
  50. package/src/styles/index.css +12 -4
  51. package/styles.css +1 -1
  52. package/styles.css.map +1 -1
@@ -0,0 +1,356 @@
1
+ import { LiveText } from '@liveblocks/client';
2
+ import { findTextRangeAtPositionInDocument, findTextRangeAtPosition, buildLiveblocksTreeIndex } from './mapping.js';
3
+ import { marksToAttributes, marksToAttributesPatch, createLiveblocksTiptapNode, getLiveblocksNodeContent, updateLiveblocksNodeAttrs } from './schema.js';
4
+
5
+ function isObject(value) {
6
+ return typeof value === "object" && value !== null;
7
+ }
8
+ function isJsonObject(value) {
9
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10
+ }
11
+ function parseMarks(value) {
12
+ if (!Array.isArray(value)) {
13
+ return void 0;
14
+ }
15
+ const marks = [];
16
+ for (const mark of value) {
17
+ if (!isObject(mark) || typeof mark.type !== "string") {
18
+ return void 0;
19
+ }
20
+ marks.push({
21
+ type: mark.type,
22
+ ...isJsonObject(mark.attrs) ? { attrs: mark.attrs } : {}
23
+ });
24
+ }
25
+ return marks.length > 0 ? marks : void 0;
26
+ }
27
+ function parseProseMirrorJsonNode(value) {
28
+ if (!isObject(value) || typeof value.type !== "string") {
29
+ return void 0;
30
+ }
31
+ const node = { type: value.type };
32
+ if (isJsonObject(value.attrs)) {
33
+ node.attrs = value.attrs;
34
+ }
35
+ if (typeof value.text === "string") {
36
+ node.text = value.text;
37
+ }
38
+ const marks = parseMarks(value.marks);
39
+ if (marks !== void 0) {
40
+ node.marks = marks;
41
+ }
42
+ if (Array.isArray(value.content)) {
43
+ const content = [];
44
+ for (const child of value.content) {
45
+ const parsedChild = parseProseMirrorJsonNode(child);
46
+ if (parsedChild === void 0) {
47
+ return void 0;
48
+ }
49
+ content.push(parsedChild);
50
+ }
51
+ node.content = content;
52
+ }
53
+ return node;
54
+ }
55
+ function prosemirrorNodeToJson(node) {
56
+ return parseProseMirrorJsonNode(node.toJSON());
57
+ }
58
+ function getNodeAttrs(node) {
59
+ return prosemirrorNodeToJson(node)?.attrs;
60
+ }
61
+ function isReplaceStepJson(value) {
62
+ return isObject(value) && value.stepType === "replace" && typeof value.from === "number" && typeof value.to === "number";
63
+ }
64
+ function isMarkStepJson(value) {
65
+ return isObject(value) && (value.stepType === "addMark" || value.stepType === "removeMark") && typeof value.from === "number" && typeof value.to === "number";
66
+ }
67
+ function getTextContentFromSlice(slice) {
68
+ const content = slice?.content;
69
+ if (content === void 0 || content.length === 0) {
70
+ return { text: "" };
71
+ }
72
+ let text = "";
73
+ let marks;
74
+ for (const node of content) {
75
+ if (!isObject(node) || node.type !== "text") {
76
+ return void 0;
77
+ }
78
+ const nodeText = node.text;
79
+ if (typeof nodeText !== "string") {
80
+ return void 0;
81
+ }
82
+ const nodeMarks = parseMarks(node.marks);
83
+ if (text.length === 0) {
84
+ marks = nodeMarks;
85
+ } else if (JSON.stringify(marks ?? []) !== JSON.stringify(nodeMarks ?? [])) {
86
+ return void 0;
87
+ }
88
+ text += nodeText;
89
+ }
90
+ return { text, marks };
91
+ }
92
+ function classifyReplaceStep(step, oldDoc, liveRoot) {
93
+ const inserted = getTextContentFromSlice(step.slice);
94
+ if (inserted === void 0) {
95
+ return void 0;
96
+ }
97
+ const operations = [];
98
+ if (step.from !== step.to) {
99
+ const fromRange = findTextRangeAtPositionInDocument(
100
+ oldDoc,
101
+ liveRoot,
102
+ step.from
103
+ );
104
+ const toRange = findTextRangeAtPositionInDocument(
105
+ oldDoc,
106
+ liveRoot,
107
+ step.to
108
+ );
109
+ if (fromRange === void 0 || toRange === void 0 || fromRange.nodeId !== toRange.nodeId) {
110
+ return void 0;
111
+ }
112
+ operations.push({
113
+ type: "delete",
114
+ node: fromRange.node,
115
+ index: fromRange.liveOffset + step.from - fromRange.from,
116
+ length: step.to - step.from
117
+ });
118
+ }
119
+ if (inserted.text.length > 0) {
120
+ const range = findTextRangeAtPositionInDocument(
121
+ oldDoc,
122
+ liveRoot,
123
+ step.from
124
+ );
125
+ if (range === void 0) {
126
+ return void 0;
127
+ }
128
+ operations.push({
129
+ type: "insert",
130
+ node: range.node,
131
+ index: range.liveOffset + step.from - range.from,
132
+ text: inserted.text,
133
+ attributes: marksToAttributes(inserted.marks)
134
+ });
135
+ }
136
+ return operations.length > 0 ? operations : void 0;
137
+ }
138
+ function marksFromNode(node) {
139
+ const marks = node.marks.map((mark) => {
140
+ const json = mark.toJSON();
141
+ if (!isObject(json) || typeof json.type !== "string") {
142
+ return void 0;
143
+ }
144
+ return {
145
+ type: json.type,
146
+ ...isJsonObject(json.attrs) ? { attrs: json.attrs } : {}
147
+ };
148
+ });
149
+ const parsedMarks = marks.filter((mark) => mark !== void 0);
150
+ return parsedMarks.length > 0 ? parsedMarks : void 0;
151
+ }
152
+ function classifyMarkStep(step, oldIndex, newDoc) {
153
+ const operations = [];
154
+ newDoc.nodesBetween(step.from, step.to, (node, pos) => {
155
+ if (!node.isText || node.nodeSize === 0) {
156
+ return true;
157
+ }
158
+ const from = Math.max(step.from, pos);
159
+ const to = Math.min(step.to, pos + node.nodeSize);
160
+ const range = findTextRangeAtPosition(oldIndex, from);
161
+ if (range === void 0 || to <= from) {
162
+ operations.length = 0;
163
+ return false;
164
+ }
165
+ operations.push({
166
+ type: "format",
167
+ node: range.node,
168
+ index: range.liveOffset + from - range.from,
169
+ length: to - from,
170
+ attributes: marksToAttributesPatch(marksFromNode(node))
171
+ });
172
+ return true;
173
+ });
174
+ return operations.length > 0 ? operations : void 0;
175
+ }
176
+ function createNodeOperation(type, content, index, node) {
177
+ const jsonNode = prosemirrorNodeToJson(node);
178
+ if (jsonNode === void 0) {
179
+ return void 0;
180
+ }
181
+ return {
182
+ type,
183
+ content,
184
+ index,
185
+ node: createLiveblocksTiptapNode(jsonNode)
186
+ };
187
+ }
188
+ function classifyAttrsChange(oldNode, newNode, liveNode) {
189
+ if (oldNode.isText || oldNode.type !== newNode.type || !oldNode.content.eq(newNode.content) || oldNode.sameMarkup(newNode)) {
190
+ return void 0;
191
+ }
192
+ return [
193
+ { type: "updateAttrs", node: liveNode, attrs: getNodeAttrs(newNode) }
194
+ ];
195
+ }
196
+ function findCommonPrefix(oldParent, newParent) {
197
+ const max = Math.min(oldParent.childCount, newParent.childCount);
198
+ let prefix = 0;
199
+ while (prefix < max && oldParent.child(prefix).eq(newParent.child(prefix))) {
200
+ prefix++;
201
+ }
202
+ return prefix;
203
+ }
204
+ function findCommonSuffix(oldParent, newParent, prefix) {
205
+ const max = Math.min(
206
+ oldParent.childCount - prefix,
207
+ newParent.childCount - prefix
208
+ );
209
+ let suffix = 0;
210
+ while (suffix < max && oldParent.child(oldParent.childCount - suffix - 1).eq(newParent.child(newParent.childCount - suffix - 1))) {
211
+ suffix++;
212
+ }
213
+ return suffix;
214
+ }
215
+ function classifyChildrenChange(oldParent, newParent, liveParent) {
216
+ const content = getLiveblocksNodeContent(liveParent);
217
+ if (content === void 0) {
218
+ return void 0;
219
+ }
220
+ if (oldParent.childCount === newParent.childCount) {
221
+ const operations = [];
222
+ for (let index = 0; index < oldParent.childCount; index++) {
223
+ const oldChild = oldParent.child(index);
224
+ const newChild = newParent.child(index);
225
+ if (oldChild.eq(newChild)) {
226
+ continue;
227
+ }
228
+ const liveChild = content.get(index);
229
+ if (liveChild === void 0) {
230
+ return void 0;
231
+ }
232
+ const childOperations = classifyAttrsChange(oldChild, newChild, liveChild) ?? classifyNodeChange(oldChild, newChild, liveChild);
233
+ if (childOperations !== void 0) {
234
+ operations.push(...childOperations);
235
+ continue;
236
+ }
237
+ const operation = createNodeOperation(
238
+ "setNode",
239
+ content,
240
+ index,
241
+ newChild
242
+ );
243
+ if (operation === void 0) {
244
+ return void 0;
245
+ }
246
+ operations.push(operation);
247
+ }
248
+ return operations.length > 0 ? operations : void 0;
249
+ }
250
+ const prefix = findCommonPrefix(oldParent, newParent);
251
+ const suffix = findCommonSuffix(oldParent, newParent, prefix);
252
+ if (oldParent.childCount + 1 === newParent.childCount && prefix + suffix === oldParent.childCount) {
253
+ const operation = createNodeOperation(
254
+ "insertNode",
255
+ content,
256
+ prefix,
257
+ newParent.child(prefix)
258
+ );
259
+ return operation === void 0 ? void 0 : [operation];
260
+ }
261
+ if (oldParent.childCount + 1 === newParent.childCount && prefix + suffix + 1 === oldParent.childCount) {
262
+ const setOperation = createNodeOperation(
263
+ "setNode",
264
+ content,
265
+ prefix,
266
+ newParent.child(prefix)
267
+ );
268
+ const insertOperation = createNodeOperation(
269
+ "insertNode",
270
+ content,
271
+ prefix + 1,
272
+ newParent.child(prefix + 1)
273
+ );
274
+ return setOperation === void 0 || insertOperation === void 0 ? void 0 : [setOperation, insertOperation];
275
+ }
276
+ if (oldParent.childCount - 1 === newParent.childCount && prefix + suffix === newParent.childCount) {
277
+ return [{ type: "deleteNode", content, index: prefix }];
278
+ }
279
+ if (oldParent.childCount - 1 === newParent.childCount && prefix + suffix + 1 === newParent.childCount) {
280
+ const operation = createNodeOperation(
281
+ "setNode",
282
+ content,
283
+ prefix,
284
+ newParent.child(prefix)
285
+ );
286
+ return operation === void 0 ? void 0 : [operation, { type: "deleteNode", content, index: prefix + 1 }];
287
+ }
288
+ return void 0;
289
+ }
290
+ function classifyNodeChange(oldNode, newNode, liveNode) {
291
+ const attrOperations = classifyAttrsChange(oldNode, newNode, liveNode) ?? [];
292
+ const childOperations = oldNode.type === newNode.type ? classifyChildrenChange(oldNode, newNode, liveNode) : void 0;
293
+ const operations = [...attrOperations, ...childOperations ?? []];
294
+ return operations.length > 0 ? operations : void 0;
295
+ }
296
+ function classifyStructuralChange(oldDoc, newDoc, liveRoot) {
297
+ return classifyNodeChange(oldDoc, newDoc, liveRoot);
298
+ }
299
+ function classifyTransaction(transactions, oldDoc, newDoc, liveRoot) {
300
+ const changedTransactions = transactions.filter(
301
+ (transaction2) => transaction2.docChanged
302
+ );
303
+ if (changedTransactions.length !== 1) {
304
+ return { type: "unsupported" };
305
+ }
306
+ const [transaction] = changedTransactions;
307
+ if (transaction === void 0 || transaction.steps.length !== 1) {
308
+ return { type: "unsupported" };
309
+ }
310
+ const [step] = transaction.steps;
311
+ const stepJson = step?.toJSON();
312
+ const operations = isReplaceStepJson(stepJson) ? classifyReplaceStep(stepJson, oldDoc, liveRoot) : isMarkStepJson(stepJson) ? classifyMarkStep(
313
+ stepJson,
314
+ buildLiveblocksTreeIndex(oldDoc, liveRoot),
315
+ newDoc
316
+ ) : void 0;
317
+ const structuralOperations = operations ?? classifyStructuralChange(oldDoc, newDoc, liveRoot);
318
+ if (structuralOperations === void 0) {
319
+ return { type: "unsupported" };
320
+ }
321
+ return { type: "incremental", operations: structuralOperations };
322
+ }
323
+ function applyIncrementalOperations(operations) {
324
+ for (const operation of operations) {
325
+ if (operation.type === "insert") {
326
+ const text = operation.node.get("text");
327
+ if (!(text instanceof LiveText)) {
328
+ continue;
329
+ }
330
+ text.insert(operation.index, operation.text, operation.attributes);
331
+ } else if (operation.type === "delete") {
332
+ const text = operation.node.get("text");
333
+ if (!(text instanceof LiveText)) {
334
+ continue;
335
+ }
336
+ text.delete(operation.index, operation.length);
337
+ } else if (operation.type === "format") {
338
+ const text = operation.node.get("text");
339
+ if (!(text instanceof LiveText)) {
340
+ continue;
341
+ }
342
+ text.format(operation.index, operation.length, operation.attributes);
343
+ } else if (operation.type === "insertNode") {
344
+ operation.content.insert(operation.node, operation.index);
345
+ } else if (operation.type === "deleteNode") {
346
+ operation.content.delete(operation.index);
347
+ } else if (operation.type === "setNode") {
348
+ operation.content.set(operation.index, operation.node);
349
+ } else {
350
+ updateLiveblocksNodeAttrs(operation.node, operation.attrs);
351
+ }
352
+ }
353
+ }
354
+
355
+ export { applyIncrementalOperations, classifyTransaction };
356
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sources":["../../src/collaboration-liveblocks/steps.ts"],"sourcesContent":["import { type JsonObject, type LiveList, LiveText } from \"@liveblocks/client\";\nimport type { Node as ProseMirrorNode } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\n\nimport {\n buildLiveblocksTreeIndex,\n findTextRangeAtPosition,\n findTextRangeAtPositionInDocument,\n type LiveblocksTreeIndex,\n} from \"./mapping\";\nimport {\n createLiveblocksTiptapNode,\n getLiveblocksNodeContent,\n type LiveblocksTiptapNode,\n marksToAttributes,\n marksToAttributesPatch,\n type ProseMirrorJsonMark,\n type ProseMirrorJsonNode,\n updateLiveblocksNodeAttrs,\n} from \"./schema\";\n\nexport type IncrementalOperation =\n | {\n type: \"insert\";\n text: string;\n index: number;\n attributes?: ReturnType<typeof marksToAttributes>;\n node: LiveblocksTiptapNode;\n }\n | {\n type: \"delete\";\n index: number;\n length: number;\n node: LiveblocksTiptapNode;\n }\n | {\n type: \"format\";\n index: number;\n length: number;\n attributes: ReturnType<typeof marksToAttributesPatch>;\n node: LiveblocksTiptapNode;\n }\n | {\n type: \"insertNode\";\n content: LiveList<LiveblocksTiptapNode>;\n index: number;\n node: LiveblocksTiptapNode;\n }\n | {\n type: \"deleteNode\";\n content: LiveList<LiveblocksTiptapNode>;\n index: number;\n }\n | {\n type: \"setNode\";\n content: LiveList<LiveblocksTiptapNode>;\n index: number;\n node: LiveblocksTiptapNode;\n }\n | {\n type: \"updateAttrs\";\n attrs: JsonObject | undefined;\n node: LiveblocksTiptapNode;\n };\n\nexport type ClassifiedTransaction =\n | {\n type: \"incremental\";\n operations: IncrementalOperation[];\n }\n | {\n type: \"unsupported\";\n };\n\ntype ReplaceStepJson = {\n stepType: \"replace\";\n from: number;\n to: number;\n slice?: {\n content?: unknown[];\n };\n};\n\ntype MarkStepJson = {\n stepType: \"addMark\" | \"removeMark\";\n from: number;\n to: number;\n};\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseMarks(value: unknown): ProseMirrorJsonMark[] | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const marks: ProseMirrorJsonMark[] = [];\n\n for (const mark of value) {\n if (!isObject(mark) || typeof mark.type !== \"string\") {\n return undefined;\n }\n\n marks.push({\n type: mark.type,\n ...(isJsonObject(mark.attrs) ? { attrs: mark.attrs } : {}),\n });\n }\n\n return marks.length > 0 ? marks : undefined;\n}\n\nfunction parseProseMirrorJsonNode(\n value: unknown\n): ProseMirrorJsonNode | undefined {\n if (!isObject(value) || typeof value.type !== \"string\") {\n return undefined;\n }\n\n const node: ProseMirrorJsonNode = { type: value.type };\n\n if (isJsonObject(value.attrs)) {\n node.attrs = value.attrs;\n }\n\n if (typeof value.text === \"string\") {\n node.text = value.text;\n }\n\n const marks = parseMarks(value.marks);\n if (marks !== undefined) {\n node.marks = marks;\n }\n\n if (Array.isArray(value.content)) {\n const content: ProseMirrorJsonNode[] = [];\n for (const child of value.content) {\n const parsedChild = parseProseMirrorJsonNode(child);\n if (parsedChild === undefined) {\n return undefined;\n }\n\n content.push(parsedChild);\n }\n\n node.content = content;\n }\n\n return node;\n}\n\nfunction prosemirrorNodeToJson(\n node: ProseMirrorNode\n): ProseMirrorJsonNode | undefined {\n return parseProseMirrorJsonNode(node.toJSON());\n}\n\nfunction getNodeAttrs(node: ProseMirrorNode): JsonObject | undefined {\n return prosemirrorNodeToJson(node)?.attrs;\n}\n\nfunction isReplaceStepJson(value: unknown): value is ReplaceStepJson {\n return (\n isObject(value) &&\n value.stepType === \"replace\" &&\n typeof value.from === \"number\" &&\n typeof value.to === \"number\"\n );\n}\n\nfunction isMarkStepJson(value: unknown): value is MarkStepJson {\n return (\n isObject(value) &&\n (value.stepType === \"addMark\" || value.stepType === \"removeMark\") &&\n typeof value.from === \"number\" &&\n typeof value.to === \"number\"\n );\n}\n\nfunction getTextContentFromSlice(\n slice: ReplaceStepJson[\"slice\"]\n): { text: string; marks?: ProseMirrorJsonMark[] } | undefined {\n const content = slice?.content;\n if (content === undefined || content.length === 0) {\n return { text: \"\" };\n }\n\n let text = \"\";\n let marks: ProseMirrorJsonMark[] | undefined;\n\n for (const node of content) {\n if (!isObject(node) || node.type !== \"text\") {\n return undefined;\n }\n\n const nodeText = node.text;\n if (typeof nodeText !== \"string\") {\n return undefined;\n }\n\n const nodeMarks = parseMarks(node.marks);\n if (text.length === 0) {\n marks = nodeMarks;\n } else if (\n JSON.stringify(marks ?? []) !== JSON.stringify(nodeMarks ?? [])\n ) {\n return undefined;\n }\n\n text += nodeText;\n }\n\n return { text, marks };\n}\n\nfunction classifyReplaceStep(\n step: ReplaceStepJson,\n oldDoc: ProseMirrorNode,\n liveRoot: LiveblocksTiptapNode\n): IncrementalOperation[] | undefined {\n const inserted = getTextContentFromSlice(step.slice);\n if (inserted === undefined) {\n return undefined;\n }\n\n const operations: IncrementalOperation[] = [];\n\n if (step.from !== step.to) {\n const fromRange = findTextRangeAtPositionInDocument(\n oldDoc,\n liveRoot,\n step.from\n );\n const toRange = findTextRangeAtPositionInDocument(\n oldDoc,\n liveRoot,\n step.to\n );\n\n if (\n fromRange === undefined ||\n toRange === undefined ||\n fromRange.nodeId !== toRange.nodeId\n ) {\n return undefined;\n }\n\n operations.push({\n type: \"delete\",\n node: fromRange.node,\n index: fromRange.liveOffset + step.from - fromRange.from,\n length: step.to - step.from,\n });\n }\n\n if (inserted.text.length > 0) {\n const range = findTextRangeAtPositionInDocument(\n oldDoc,\n liveRoot,\n step.from\n );\n if (range === undefined) {\n return undefined;\n }\n\n operations.push({\n type: \"insert\",\n node: range.node,\n index: range.liveOffset + step.from - range.from,\n text: inserted.text,\n attributes: marksToAttributes(inserted.marks),\n });\n }\n\n return operations.length > 0 ? operations : undefined;\n}\n\nfunction marksFromNode(\n node: ProseMirrorNode\n): ProseMirrorJsonMark[] | undefined {\n const marks = node.marks.map((mark) => {\n const json: unknown = mark.toJSON();\n if (!isObject(json) || typeof json.type !== \"string\") {\n return undefined;\n }\n\n return {\n type: json.type,\n ...(isJsonObject(json.attrs) ? { attrs: json.attrs } : {}),\n };\n });\n\n const parsedMarks = marks.filter((mark) => mark !== undefined);\n return parsedMarks.length > 0 ? parsedMarks : undefined;\n}\n\nfunction classifyMarkStep(\n step: MarkStepJson,\n oldIndex: LiveblocksTreeIndex,\n newDoc: ProseMirrorNode\n): IncrementalOperation[] | undefined {\n const operations: IncrementalOperation[] = [];\n\n newDoc.nodesBetween(step.from, step.to, (node, pos) => {\n if (!node.isText || node.nodeSize === 0) {\n return true;\n }\n\n const from = Math.max(step.from, pos);\n const to = Math.min(step.to, pos + node.nodeSize);\n const range = findTextRangeAtPosition(oldIndex, from);\n\n if (range === undefined || to <= from) {\n operations.length = 0;\n return false;\n }\n\n operations.push({\n type: \"format\",\n node: range.node,\n index: range.liveOffset + from - range.from,\n length: to - from,\n attributes: marksToAttributesPatch(marksFromNode(node)),\n });\n\n return true;\n });\n\n return operations.length > 0 ? operations : undefined;\n}\n\nfunction createNodeOperation(\n type: \"insertNode\" | \"setNode\",\n content: LiveList<LiveblocksTiptapNode>,\n index: number,\n node: ProseMirrorNode\n): IncrementalOperation | undefined {\n const jsonNode = prosemirrorNodeToJson(node);\n if (jsonNode === undefined) {\n return undefined;\n }\n\n return {\n type,\n content,\n index,\n node: createLiveblocksTiptapNode(jsonNode),\n };\n}\n\nfunction classifyAttrsChange(\n oldNode: ProseMirrorNode,\n newNode: ProseMirrorNode,\n liveNode: LiveblocksTiptapNode\n): IncrementalOperation[] | undefined {\n if (\n oldNode.isText ||\n oldNode.type !== newNode.type ||\n !oldNode.content.eq(newNode.content) ||\n oldNode.sameMarkup(newNode)\n ) {\n return undefined;\n }\n\n return [\n { type: \"updateAttrs\", node: liveNode, attrs: getNodeAttrs(newNode) },\n ];\n}\n\nfunction findCommonPrefix(\n oldParent: ProseMirrorNode,\n newParent: ProseMirrorNode\n): number {\n const max = Math.min(oldParent.childCount, newParent.childCount);\n let prefix = 0;\n\n while (prefix < max && oldParent.child(prefix).eq(newParent.child(prefix))) {\n prefix++;\n }\n\n return prefix;\n}\n\nfunction findCommonSuffix(\n oldParent: ProseMirrorNode,\n newParent: ProseMirrorNode,\n prefix: number\n): number {\n const max = Math.min(\n oldParent.childCount - prefix,\n newParent.childCount - prefix\n );\n let suffix = 0;\n\n while (\n suffix < max &&\n oldParent\n .child(oldParent.childCount - suffix - 1)\n .eq(newParent.child(newParent.childCount - suffix - 1))\n ) {\n suffix++;\n }\n\n return suffix;\n}\n\nfunction classifyChildrenChange(\n oldParent: ProseMirrorNode,\n newParent: ProseMirrorNode,\n liveParent: LiveblocksTiptapNode\n): IncrementalOperation[] | undefined {\n const content = getLiveblocksNodeContent(liveParent);\n if (content === undefined) {\n return undefined;\n }\n\n if (oldParent.childCount === newParent.childCount) {\n const operations: IncrementalOperation[] = [];\n\n for (let index = 0; index < oldParent.childCount; index++) {\n const oldChild = oldParent.child(index);\n const newChild = newParent.child(index);\n if (oldChild.eq(newChild)) {\n continue;\n }\n\n const liveChild = content.get(index);\n if (liveChild === undefined) {\n return undefined;\n }\n\n const childOperations =\n classifyAttrsChange(oldChild, newChild, liveChild) ??\n classifyNodeChange(oldChild, newChild, liveChild);\n\n if (childOperations !== undefined) {\n operations.push(...childOperations);\n continue;\n }\n\n const operation = createNodeOperation(\n \"setNode\",\n content,\n index,\n newChild\n );\n if (operation === undefined) {\n return undefined;\n }\n\n operations.push(operation);\n }\n\n return operations.length > 0 ? operations : undefined;\n }\n\n const prefix = findCommonPrefix(oldParent, newParent);\n const suffix = findCommonSuffix(oldParent, newParent, prefix);\n\n if (\n oldParent.childCount + 1 === newParent.childCount &&\n prefix + suffix === oldParent.childCount\n ) {\n const operation = createNodeOperation(\n \"insertNode\",\n content,\n prefix,\n newParent.child(prefix)\n );\n return operation === undefined ? undefined : [operation];\n }\n\n if (\n oldParent.childCount + 1 === newParent.childCount &&\n prefix + suffix + 1 === oldParent.childCount\n ) {\n const setOperation = createNodeOperation(\n \"setNode\",\n content,\n prefix,\n newParent.child(prefix)\n );\n const insertOperation = createNodeOperation(\n \"insertNode\",\n content,\n prefix + 1,\n newParent.child(prefix + 1)\n );\n\n return setOperation === undefined || insertOperation === undefined\n ? undefined\n : [setOperation, insertOperation];\n }\n\n if (\n oldParent.childCount - 1 === newParent.childCount &&\n prefix + suffix === newParent.childCount\n ) {\n return [{ type: \"deleteNode\", content, index: prefix }];\n }\n\n if (\n oldParent.childCount - 1 === newParent.childCount &&\n prefix + suffix + 1 === newParent.childCount\n ) {\n const operation = createNodeOperation(\n \"setNode\",\n content,\n prefix,\n newParent.child(prefix)\n );\n\n return operation === undefined\n ? undefined\n : [operation, { type: \"deleteNode\", content, index: prefix + 1 }];\n }\n\n return undefined;\n}\n\nfunction classifyNodeChange(\n oldNode: ProseMirrorNode,\n newNode: ProseMirrorNode,\n liveNode: LiveblocksTiptapNode\n): IncrementalOperation[] | undefined {\n const attrOperations = classifyAttrsChange(oldNode, newNode, liveNode) ?? [];\n const childOperations =\n oldNode.type === newNode.type\n ? classifyChildrenChange(oldNode, newNode, liveNode)\n : undefined;\n const operations = [...attrOperations, ...(childOperations ?? [])];\n\n return operations.length > 0 ? operations : undefined;\n}\n\nfunction classifyStructuralChange(\n oldDoc: ProseMirrorNode,\n newDoc: ProseMirrorNode,\n liveRoot: LiveblocksTiptapNode\n): IncrementalOperation[] | undefined {\n return classifyNodeChange(oldDoc, newDoc, liveRoot);\n}\n\nexport function classifyTransaction(\n transactions: readonly Transaction[],\n oldDoc: ProseMirrorNode,\n newDoc: ProseMirrorNode,\n liveRoot: LiveblocksTiptapNode\n): ClassifiedTransaction {\n const changedTransactions = transactions.filter(\n (transaction) => transaction.docChanged\n );\n\n if (changedTransactions.length !== 1) {\n return { type: \"unsupported\" };\n }\n\n const [transaction] = changedTransactions;\n if (transaction === undefined || transaction.steps.length !== 1) {\n return { type: \"unsupported\" };\n }\n\n const [step] = transaction.steps;\n const stepJson: unknown = step?.toJSON();\n\n const operations = isReplaceStepJson(stepJson)\n ? classifyReplaceStep(stepJson, oldDoc, liveRoot)\n : isMarkStepJson(stepJson)\n ? classifyMarkStep(\n stepJson,\n buildLiveblocksTreeIndex(oldDoc, liveRoot),\n newDoc\n )\n : undefined;\n\n const structuralOperations =\n operations ?? classifyStructuralChange(oldDoc, newDoc, liveRoot);\n\n if (structuralOperations === undefined) {\n return { type: \"unsupported\" };\n }\n\n return { type: \"incremental\", operations: structuralOperations };\n}\n\nexport function applyIncrementalOperations(\n operations: readonly IncrementalOperation[]\n): void {\n for (const operation of operations) {\n if (operation.type === \"insert\") {\n const text = operation.node.get(\"text\");\n if (!(text instanceof LiveText)) {\n continue;\n }\n\n text.insert(operation.index, operation.text, operation.attributes);\n } else if (operation.type === \"delete\") {\n const text = operation.node.get(\"text\");\n if (!(text instanceof LiveText)) {\n continue;\n }\n\n text.delete(operation.index, operation.length);\n } else if (operation.type === \"format\") {\n const text = operation.node.get(\"text\");\n if (!(text instanceof LiveText)) {\n continue;\n }\n\n text.format(operation.index, operation.length, operation.attributes);\n } else if (operation.type === \"insertNode\") {\n operation.content.insert(operation.node, operation.index);\n } else if (operation.type === \"deleteNode\") {\n operation.content.delete(operation.index);\n } else if (operation.type === \"setNode\") {\n operation.content.set(operation.index, operation.node);\n } else {\n updateLiveblocksNodeAttrs(operation.node, operation.attrs);\n }\n }\n}\n"],"names":["transaction"],"mappings":"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"}
@@ -6,6 +6,7 @@ var model = require('@tiptap/pm/model');
6
6
  var state = require('@tiptap/pm/state');
7
7
  var view = require('@tiptap/pm/view');
8
8
  var yProsemirror = require('y-prosemirror');
9
+ var plugin = require('../collaboration-liveblocks/plugin.cjs');
9
10
  var types = require('../types.cjs');
10
11
  var utils = require('../utils.cjs');
11
12
 
@@ -258,7 +259,12 @@ const CommentsExtension = core.Extension.create({
258
259
  };
259
260
  },
260
261
  onSelectionUpdate({ transaction }) {
261
- if (this.storage.pendingComment && !transaction.getMeta(yProsemirror.ySyncPluginKey)) {
262
+ const yjsMeta = transaction.getMeta(yProsemirror.ySyncPluginKey);
263
+ const liveblocksMeta = transaction.getMeta(
264
+ plugin.LIVEBLOCKS_COLLABORATION_PLUGIN_KEY
265
+ );
266
+ const isRemoteCollaborationUpdate = yjsMeta || liveblocksMeta;
267
+ if (this.storage.pendingComment && !isRemoteCollaborationUpdate) {
262
268
  this.storage.pendingComment = false;
263
269
  }
264
270
  if (this.storage.pendingComment) return;
@@ -1 +1 @@
1
- {"version":3,"file":"CommentsExtension.cjs","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { shallow } from \"@liveblocks/core\";\nimport { type Editor, Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type {\n Mark as ProseMirrorMark,\n MarkType,\n Node,\n ResolvedPos,\n} from \"@tiptap/pm/model\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { EditorState, Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\nimport { areSetsEqual } from \"../utils\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string[];\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\nfunction getFilteredThreads(state: EditorState): Set<string> | undefined {\n return FILTERED_THREADS_PLUGIN_KEY.getState(state)?.filteredThreads;\n}\n\nfunction getVisibleThreadIdsFromMarks(\n marks: readonly ProseMirrorMark[],\n markType: MarkType,\n filteredThreads: Set<string> | undefined\n): string[] {\n const ids = new Set<string>();\n for (const mark of marks) {\n if (mark.type !== markType || mark.attrs.orphan) continue;\n const threadId = mark.attrs.threadId as string | undefined;\n if (!threadId) continue;\n if (filteredThreads && !filteredThreads.has(threadId)) continue;\n ids.add(threadId);\n }\n return [...ids];\n}\n\nfunction getVisibleThreadIdsAtPos(\n state: EditorState,\n $pos: ResolvedPos,\n markType: MarkType\n): string[] {\n return getVisibleThreadIdsFromMarks(\n $pos.marks(),\n markType,\n getFilteredThreads(state)\n );\n}\n\nfunction dispatchSetActiveThreadIds(view: EditorView, ids: string[]): void {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_ACTIVE_THREAD_IDS,\n data: ids,\n } satisfies ThreadPluginAction)\n );\n}\n\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (\n doc: Node,\n activeThreadIds: string[],\n { scroll }: { scroll: boolean }\n ): ThreadPluginState => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n const activeSet = new Set(activeThreadIds);\n\n doc.descendants((node, pos) => {\n for (const mark of node.marks) {\n if (mark.type !== this.type) continue;\n\n const threadId = (mark.attrs as { threadId?: string }).threadId;\n if (!threadId) continue;\n\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so we always store the largest \"to\" found.\n // AnchoredThreads component uses \"from\" as the position, so we always store the smallest \"from\" found.\n const current = threadPositions.get(threadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(threadId, {\n from: Math.min(from, current.from),\n to: Math.max(to, current.to),\n });\n\n if (activeSet.has(threadId)) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n }\n }\n });\n\n // Only scroll when the active selection explicitly changes.\n if (scroll && activeThreadIds.length > 0) {\n const [scrollTargetId] = activeThreadIds;\n const element = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${scrollTargetId}\"]`\n );\n element?.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }\n\n return {\n decorations: DecorationSet.create(doc, decorations),\n activeThreadIds,\n threadPositions,\n };\n };\n\n // Recursively walks a Fragment and removes only this extension's comment mark from every node it finds.\n const stripCommentMarks = (slice: Slice): Slice => {\n const stripFragment = (fragment: Fragment): Fragment => {\n let changed = false;\n const nodes: Node[] = [];\n\n fragment.forEach((node) => {\n // Filter out this extension's comment mark from the node's marks so that it is not copied to the clipboard\n const nextMarks = node.marks.filter(\n (mark) => mark.type !== this.type\n );\n const marksChanged = nextMarks.length !== node.marks.length;\n\n // Recursively strip comment marks from child content (e.g. inline content inside paragraphs, list items)\n const nextContent =\n node.content.childCount > 0\n ? stripFragment(node.content)\n : node.content;\n const contentChanged = nextContent !== node.content;\n\n if (marksChanged || contentChanged) {\n changed = true;\n nodes.push(\n node.isText\n ? node.mark(nextMarks)\n : node.type.create(node.attrs, nextContent, nextMarks)\n );\n } else {\n nodes.push(node);\n }\n });\n\n return changed ? Fragment.fromArray(nodes) : fragment;\n };\n\n const content = stripFragment(slice.content);\n return content === slice.content\n ? slice\n : new Slice(content, slice.openStart, slice.openEnd);\n };\n\n return [\n new Plugin({\n key: new PluginKey(\"lb-comment-clipboard\"),\n props: {\n transformCopied: (slice) => stripCommentMarks(slice),\n transformPasted: (slice) => stripCommentMarks(slice),\n },\n }),\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init(): ThreadPluginState {\n return {\n threadPositions: new Map(),\n activeThreadIds: [],\n decorations: DecorationSet.empty,\n };\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as\n | ThreadPluginAction\n | undefined;\n\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n return updateState(tr.doc, state.activeThreadIds, {\n scroll: false,\n });\n }\n\n if (action.name === ThreadPluginActions.SET_ACTIVE_THREAD_IDS) {\n const idsChanged = !shallow(action.data, state.activeThreadIds);\n if (!tr.docChanged && !idsChanged) {\n return state;\n }\n return updateState(tr.doc, action.data, { scroll: idsChanged });\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) return;\n\n const $pos = view.state.doc.resolve(pos);\n const ids = getVisibleThreadIdsAtPos(view.state, $pos, this.type);\n dispatchSetActiveThreadIds(view, ids);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // Unselect any open threads.\n dispatchSetActiveThreadIds(this.editor.view, []);\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n // If the target thread is filtered out, clear the active selection\n // instead of selecting an invisible thread.\n const filtered = getFilteredThreads(this.editor.state);\n const nextIds =\n id === null || (filtered && !filtered.has(id)) ? [] : [id];\n\n dispatchSetActiveThreadIds(this.editor.view, nextIds);\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage; editor: Editor },\n { transaction }: { transaction: Transaction }\n ) {\n // Close any pending composer when the user moves the selection locally\n // (but ignore remote Yjs-driven selection changes).\n if (this.storage.pendingComment && !transaction.getMeta(ySyncPluginKey)) {\n this.storage.pendingComment = false;\n }\n\n if (this.storage.pendingComment) return;\n\n const { state } = this.editor;\n const markType = state.schema.marks[LIVEBLOCKS_COMMENT_MARK_TYPE];\n if (!markType) return;\n\n const ids = getVisibleThreadIdsAtPos(\n state,\n state.selection.$from,\n markType\n );\n const current = THREADS_PLUGIN_KEY.getState(state)?.activeThreadIds ?? [];\n if (shallow(ids, current)) return;\n\n dispatchSetActiveThreadIds(this.editor.view, ids);\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const active =\n THREADS_PLUGIN_KEY.getState(view.state)?.activeThreadIds ??\n [];\n\n if (active.length && curr) {\n const next = active.filter((id) => curr.has(id));\n if (next.length !== active.length) {\n dispatchSetActiveThreadIds(view, next);\n }\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n"],"names":["PluginKey","THREADS_PLUGIN_KEY","ThreadPluginActions","Mark","LIVEBLOCKS_COMMENT_MARK_TYPE","mergeAttributes","Decoration","DecorationSet","Fragment","Slice","Plugin","shallow","Extension","ySyncPluginKey","THREADS_ACTIVE_SELECTION_PLUGIN","view","areSetsEqual"],"mappings":"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"}
1
+ {"version":3,"file":"CommentsExtension.cjs","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { shallow } from \"@liveblocks/core\";\nimport { type Editor, Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type {\n Mark as ProseMirrorMark,\n MarkType,\n Node,\n ResolvedPos,\n} from \"@tiptap/pm/model\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { EditorState, Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY } from \"../collaboration-liveblocks/plugin\";\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\nimport { areSetsEqual } from \"../utils\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string[];\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\nfunction getFilteredThreads(state: EditorState): Set<string> | undefined {\n return FILTERED_THREADS_PLUGIN_KEY.getState(state)?.filteredThreads;\n}\n\nfunction getVisibleThreadIdsFromMarks(\n marks: readonly ProseMirrorMark[],\n markType: MarkType,\n filteredThreads: Set<string> | undefined\n): string[] {\n const ids = new Set<string>();\n for (const mark of marks) {\n if (mark.type !== markType || mark.attrs.orphan) continue;\n const threadId = mark.attrs.threadId as string | undefined;\n if (!threadId) continue;\n if (filteredThreads && !filteredThreads.has(threadId)) continue;\n ids.add(threadId);\n }\n return [...ids];\n}\n\nfunction getVisibleThreadIdsAtPos(\n state: EditorState,\n $pos: ResolvedPos,\n markType: MarkType\n): string[] {\n return getVisibleThreadIdsFromMarks(\n $pos.marks(),\n markType,\n getFilteredThreads(state)\n );\n}\n\nfunction dispatchSetActiveThreadIds(view: EditorView, ids: string[]): void {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_ACTIVE_THREAD_IDS,\n data: ids,\n } satisfies ThreadPluginAction)\n );\n}\n\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (\n doc: Node,\n activeThreadIds: string[],\n { scroll }: { scroll: boolean }\n ): ThreadPluginState => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n const activeSet = new Set(activeThreadIds);\n\n doc.descendants((node, pos) => {\n for (const mark of node.marks) {\n if (mark.type !== this.type) continue;\n\n const threadId = (mark.attrs as { threadId?: string }).threadId;\n if (!threadId) continue;\n\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so we always store the largest \"to\" found.\n // AnchoredThreads component uses \"from\" as the position, so we always store the smallest \"from\" found.\n const current = threadPositions.get(threadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(threadId, {\n from: Math.min(from, current.from),\n to: Math.max(to, current.to),\n });\n\n if (activeSet.has(threadId)) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n }\n }\n });\n\n // Only scroll when the active selection explicitly changes.\n if (scroll && activeThreadIds.length > 0) {\n const [scrollTargetId] = activeThreadIds;\n const element = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${scrollTargetId}\"]`\n );\n element?.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }\n\n return {\n decorations: DecorationSet.create(doc, decorations),\n activeThreadIds,\n threadPositions,\n };\n };\n\n // Recursively walks a Fragment and removes only this extension's comment mark from every node it finds.\n const stripCommentMarks = (slice: Slice): Slice => {\n const stripFragment = (fragment: Fragment): Fragment => {\n let changed = false;\n const nodes: Node[] = [];\n\n fragment.forEach((node) => {\n // Filter out this extension's comment mark from the node's marks so that it is not copied to the clipboard\n const nextMarks = node.marks.filter(\n (mark) => mark.type !== this.type\n );\n const marksChanged = nextMarks.length !== node.marks.length;\n\n // Recursively strip comment marks from child content (e.g. inline content inside paragraphs, list items)\n const nextContent =\n node.content.childCount > 0\n ? stripFragment(node.content)\n : node.content;\n const contentChanged = nextContent !== node.content;\n\n if (marksChanged || contentChanged) {\n changed = true;\n nodes.push(\n node.isText\n ? node.mark(nextMarks)\n : node.type.create(node.attrs, nextContent, nextMarks)\n );\n } else {\n nodes.push(node);\n }\n });\n\n return changed ? Fragment.fromArray(nodes) : fragment;\n };\n\n const content = stripFragment(slice.content);\n return content === slice.content\n ? slice\n : new Slice(content, slice.openStart, slice.openEnd);\n };\n\n return [\n new Plugin({\n key: new PluginKey(\"lb-comment-clipboard\"),\n props: {\n transformCopied: (slice) => stripCommentMarks(slice),\n transformPasted: (slice) => stripCommentMarks(slice),\n },\n }),\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init(): ThreadPluginState {\n return {\n threadPositions: new Map(),\n activeThreadIds: [],\n decorations: DecorationSet.empty,\n };\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as\n | ThreadPluginAction\n | undefined;\n\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n return updateState(tr.doc, state.activeThreadIds, {\n scroll: false,\n });\n }\n\n if (action.name === ThreadPluginActions.SET_ACTIVE_THREAD_IDS) {\n const idsChanged = !shallow(action.data, state.activeThreadIds);\n if (!tr.docChanged && !idsChanged) {\n return state;\n }\n return updateState(tr.doc, action.data, { scroll: idsChanged });\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) return;\n\n const $pos = view.state.doc.resolve(pos);\n const ids = getVisibleThreadIdsAtPos(view.state, $pos, this.type);\n dispatchSetActiveThreadIds(view, ids);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // Unselect any open threads.\n dispatchSetActiveThreadIds(this.editor.view, []);\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n // If the target thread is filtered out, clear the active selection\n // instead of selecting an invisible thread.\n const filtered = getFilteredThreads(this.editor.state);\n const nextIds =\n id === null || (filtered && !filtered.has(id)) ? [] : [id];\n\n dispatchSetActiveThreadIds(this.editor.view, nextIds);\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage; editor: Editor },\n { transaction }: { transaction: Transaction }\n ) {\n const yjsMeta: unknown = transaction.getMeta(ySyncPluginKey);\n const liveblocksMeta: unknown = transaction.getMeta(\n LIVEBLOCKS_COLLABORATION_PLUGIN_KEY\n );\n const isRemoteCollaborationUpdate = yjsMeta || liveblocksMeta;\n\n // Close any pending composer when the user moves the selection locally\n // (but ignore remote collaboration-driven selection changes).\n if (this.storage.pendingComment && !isRemoteCollaborationUpdate) {\n this.storage.pendingComment = false;\n }\n\n if (this.storage.pendingComment) return;\n\n const { state } = this.editor;\n const markType = state.schema.marks[LIVEBLOCKS_COMMENT_MARK_TYPE];\n if (!markType) return;\n\n const ids = getVisibleThreadIdsAtPos(\n state,\n state.selection.$from,\n markType\n );\n const current = THREADS_PLUGIN_KEY.getState(state)?.activeThreadIds ?? [];\n if (shallow(ids, current)) return;\n\n dispatchSetActiveThreadIds(this.editor.view, ids);\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const active =\n THREADS_PLUGIN_KEY.getState(view.state)?.activeThreadIds ??\n [];\n\n if (active.length && curr) {\n const next = active.filter((id) => curr.has(id));\n if (next.length !== active.length) {\n dispatchSetActiveThreadIds(view, next);\n }\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n"],"names":["PluginKey","THREADS_PLUGIN_KEY","ThreadPluginActions","Mark","LIVEBLOCKS_COMMENT_MARK_TYPE","mergeAttributes","Decoration","DecorationSet","Fragment","Slice","Plugin","shallow","Extension","ySyncPluginKey","LIVEBLOCKS_COLLABORATION_PLUGIN_KEY","THREADS_ACTIVE_SELECTION_PLUGIN","view","areSetsEqual"],"mappings":"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"}
@@ -4,6 +4,7 @@ import { Fragment, Slice } from '@tiptap/pm/model';
4
4
  import { PluginKey, Plugin } from '@tiptap/pm/state';
5
5
  import { Decoration, DecorationSet } from '@tiptap/pm/view';
6
6
  import { ySyncPluginKey } from 'y-prosemirror';
7
+ import { LIVEBLOCKS_COLLABORATION_PLUGIN_KEY } from '../collaboration-liveblocks/plugin.js';
7
8
  import { THREADS_PLUGIN_KEY, ThreadPluginActions, LIVEBLOCKS_COMMENT_MARK_TYPE, THREADS_ACTIVE_SELECTION_PLUGIN } from '../types.js';
8
9
  import { areSetsEqual } from '../utils.js';
9
10
 
@@ -256,7 +257,12 @@ const CommentsExtension = Extension.create({
256
257
  };
257
258
  },
258
259
  onSelectionUpdate({ transaction }) {
259
- if (this.storage.pendingComment && !transaction.getMeta(ySyncPluginKey)) {
260
+ const yjsMeta = transaction.getMeta(ySyncPluginKey);
261
+ const liveblocksMeta = transaction.getMeta(
262
+ LIVEBLOCKS_COLLABORATION_PLUGIN_KEY
263
+ );
264
+ const isRemoteCollaborationUpdate = yjsMeta || liveblocksMeta;
265
+ if (this.storage.pendingComment && !isRemoteCollaborationUpdate) {
260
266
  this.storage.pendingComment = false;
261
267
  }
262
268
  if (this.storage.pendingComment) return;