@beyondwork/docx-react-component 1.0.9 → 1.0.11
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.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondwork/docx-react-component",
|
|
3
3
|
"publisher": "beyondwork",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.11",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": [
|
package/src/api/public-types.ts
CHANGED
|
@@ -508,6 +508,8 @@ export interface WordReviewEditorRef {
|
|
|
508
508
|
getWarnings(): EditorWarning[];
|
|
509
509
|
getComments(): CommentSidebarSnapshot;
|
|
510
510
|
getTrackedChanges(): TrackedChangesSnapshot;
|
|
511
|
+
scrollToRevision(revisionId: string): void;
|
|
512
|
+
scrollToComment(commentId: string): void;
|
|
511
513
|
}
|
|
512
514
|
|
|
513
515
|
export interface WordReviewEditorProps {
|
|
@@ -48,6 +48,7 @@ export interface CompareDocumentVersionsOptions {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
interface BuildEntry {
|
|
51
|
+
changeId?: string;
|
|
51
52
|
block: BlockNode;
|
|
52
53
|
trackChange?: "insertion" | "deletion";
|
|
53
54
|
tracked: boolean;
|
|
@@ -196,6 +197,7 @@ function addTrackedOrStructuralEntry(
|
|
|
196
197
|
const text = getBlockDisplayText(block);
|
|
197
198
|
|
|
198
199
|
buildEntries.push({
|
|
200
|
+
...(tracked ? { changeId } : {}),
|
|
199
201
|
block: cloned,
|
|
200
202
|
...(tracked ? { trackChange: direction } : {}),
|
|
201
203
|
tracked,
|
|
@@ -243,7 +245,7 @@ function buildComparedDocument(
|
|
|
243
245
|
if (entry.block.type === "paragraph") {
|
|
244
246
|
if (entry.trackChange) {
|
|
245
247
|
pendingRevisions.push({
|
|
246
|
-
changeId: `change-${pendingRevisions.length + 1}`,
|
|
248
|
+
changeId: entry.changeId ?? `change-${pendingRevisions.length + 1}`,
|
|
247
249
|
kind: entry.trackChange,
|
|
248
250
|
paragraphIndex,
|
|
249
251
|
});
|
|
@@ -281,7 +283,7 @@ function buildComparedDocument(
|
|
|
281
283
|
children: contentChildren,
|
|
282
284
|
},
|
|
283
285
|
review: {
|
|
284
|
-
comments:
|
|
286
|
+
comments: projectValue(target.review.comments),
|
|
285
287
|
revisions,
|
|
286
288
|
},
|
|
287
289
|
preservation: mergePreservationStores(base.preservation, target.preservation),
|
|
@@ -321,15 +323,14 @@ function createParagraphRevisionRecords(
|
|
|
321
323
|
}
|
|
322
324
|
|
|
323
325
|
const entries: Array<[string, RevisionRecord]> = [];
|
|
324
|
-
pendingRevisions.forEach((revision
|
|
326
|
+
pendingRevisions.forEach((revision) => {
|
|
325
327
|
const position = positionByParagraphIndex.get(revision.paragraphIndex);
|
|
326
328
|
if (position === undefined) {
|
|
327
329
|
return;
|
|
328
330
|
}
|
|
329
331
|
|
|
330
|
-
const changeId = `change-${index + 1}`;
|
|
331
332
|
const record: RevisionRecord = {
|
|
332
|
-
changeId,
|
|
333
|
+
changeId: revision.changeId,
|
|
333
334
|
kind: revision.kind,
|
|
334
335
|
anchor: {
|
|
335
336
|
kind: "range",
|
|
@@ -346,7 +347,7 @@ function createParagraphRevisionRecords(
|
|
|
346
347
|
revision.kind === "insertion" ? "paragraph-insertion" : "paragraph-deletion",
|
|
347
348
|
},
|
|
348
349
|
};
|
|
349
|
-
entries.push([changeId, record]);
|
|
350
|
+
entries.push([revision.changeId, record]);
|
|
350
351
|
});
|
|
351
352
|
return Object.fromEntries(entries);
|
|
352
353
|
}
|
|
@@ -5,6 +5,12 @@ import {
|
|
|
5
5
|
serializeNumberingXml,
|
|
6
6
|
} from "../io/export/serialize-numbering.ts";
|
|
7
7
|
import { serializeRuntimeRevisionsIntoDocumentXml } from "../io/export/serialize-runtime-revisions.ts";
|
|
8
|
+
import { splitDocumentAtReviewBoundaries } from "../io/export/split-review-boundaries.ts";
|
|
9
|
+
import {
|
|
10
|
+
createCommentExportIdMap,
|
|
11
|
+
serializeCommentAnchorsIntoDocumentXml,
|
|
12
|
+
serializeMergedCommentsXml,
|
|
13
|
+
} from "../io/export/serialize-comments.ts";
|
|
8
14
|
import { createExportSession } from "../io/export/export-session.ts";
|
|
9
15
|
import {
|
|
10
16
|
DOCX_DOCUMENT_CONTENT_TYPE,
|
|
@@ -13,13 +19,34 @@ import {
|
|
|
13
19
|
} from "../io/opc/docx-package.ts";
|
|
14
20
|
import type { OpcPackage } from "../io/opc/package-reader.ts";
|
|
15
21
|
import { readOpcPackage } from "../io/opc/package-reader.ts";
|
|
22
|
+
import { createCommentStoreFromRuntimeComments } from "../review/store/runtime-comment-store.ts";
|
|
16
23
|
import type { RevisionRecord as ReviewRevisionRecord } from "../review/store/revision-types.ts";
|
|
17
24
|
import type { VersionCompareResult } from "./diff-engine.ts";
|
|
18
25
|
|
|
19
26
|
const MAIN_DOCUMENT_PATH = "/word/document.xml";
|
|
20
27
|
const NUMBERING_PART_PATH = "/word/numbering.xml";
|
|
28
|
+
const COMMENTS_PART_PATH = "/word/comments.xml";
|
|
29
|
+
const COMMENTS_EXTENDED_PART_PATH = "/word/commentsExtended.xml";
|
|
30
|
+
const COMMENTS_IDS_PART_PATH = "/word/commentsIds.xml";
|
|
31
|
+
const PEOPLE_PART_PATH = "/word/people.xml";
|
|
21
32
|
const NUMBERING_RELATIONSHIP_TYPE =
|
|
22
33
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
|
|
34
|
+
const COMMENTS_RELATIONSHIP_TYPE =
|
|
35
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
|
36
|
+
const COMMENTS_EXTENDED_RELATIONSHIP_TYPE =
|
|
37
|
+
"http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
|
|
38
|
+
const COMMENTS_IDS_RELATIONSHIP_TYPE =
|
|
39
|
+
"http://schemas.microsoft.com/office/2016/09/relationships/commentsIds";
|
|
40
|
+
const PEOPLE_RELATIONSHIP_TYPE =
|
|
41
|
+
"http://schemas.microsoft.com/office/2011/relationships/people";
|
|
42
|
+
const COMMENTS_CONTENT_TYPE =
|
|
43
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml";
|
|
44
|
+
const COMMENTS_EXTENDED_CONTENT_TYPE =
|
|
45
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml";
|
|
46
|
+
const COMMENTS_IDS_CONTENT_TYPE =
|
|
47
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml";
|
|
48
|
+
const PEOPLE_CONTENT_TYPE =
|
|
49
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml";
|
|
23
50
|
|
|
24
51
|
export interface ExportComparedDocumentOptions {
|
|
25
52
|
fileName?: string;
|
|
@@ -46,15 +73,22 @@ export function exportComparedDocumentRedlines(
|
|
|
46
73
|
const existingRelationships =
|
|
47
74
|
sourcePackage.parts.get(MAIN_DOCUMENT_PATH)?.relationships ?? [];
|
|
48
75
|
|
|
76
|
+
const commentThreads = Object.values(
|
|
77
|
+
createCommentStoreFromRuntimeComments(result.comparedDocument.review.comments).threads,
|
|
78
|
+
);
|
|
79
|
+
const actionableRevisions = toReviewRevisionRecords(result.comparedDocument.review.revisions);
|
|
49
80
|
const serialized = serializeMainDocument(
|
|
50
|
-
|
|
81
|
+
splitDocumentAtReviewBoundaries(
|
|
82
|
+
result.comparedDocument.content as never,
|
|
83
|
+
commentThreads,
|
|
84
|
+
actionableRevisions,
|
|
85
|
+
) as never,
|
|
51
86
|
result.comparedDocument.preservation,
|
|
52
87
|
existingRelationships,
|
|
53
88
|
{
|
|
54
89
|
media: result.comparedDocument.media,
|
|
55
90
|
},
|
|
56
91
|
);
|
|
57
|
-
const actionableRevisions = toReviewRevisionRecords(result.comparedDocument.review.revisions);
|
|
58
92
|
const revisionDocument = serializeRuntimeRevisionsIntoDocumentXml(
|
|
59
93
|
serialized.documentXml,
|
|
60
94
|
actionableRevisions,
|
|
@@ -65,23 +99,70 @@ export function exportComparedDocumentRedlines(
|
|
|
65
99
|
`Compare export skipped ${revisionDocument.skippedRevisionIds.length} revision markers.`,
|
|
66
100
|
);
|
|
67
101
|
}
|
|
102
|
+
const exportCommentIds = createCommentExportIdMap(commentThreads);
|
|
103
|
+
const serializedComments = serializeMergedCommentsXml(commentThreads, {
|
|
104
|
+
exportCommentIds,
|
|
105
|
+
});
|
|
106
|
+
const annotatedDocument = serializeCommentAnchorsIntoDocumentXml(
|
|
107
|
+
revisionDocument.documentXml,
|
|
108
|
+
commentThreads,
|
|
109
|
+
undefined,
|
|
110
|
+
{
|
|
111
|
+
exportCommentIds,
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
if (annotatedDocument.skippedCommentIds.length > 0) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`Compare export skipped ${annotatedDocument.skippedCommentIds.length} comment anchors.`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
68
119
|
|
|
69
120
|
const numberingXml = hasNumberingEntries(result.comparedDocument.numbering)
|
|
70
121
|
? serializeNumberingXml(result.comparedDocument.numbering)
|
|
71
122
|
: undefined;
|
|
72
|
-
const relationships =
|
|
73
|
-
|
|
123
|
+
const relationships = withOptionalRelatedPart(
|
|
124
|
+
withOptionalRelatedPart(
|
|
125
|
+
withOptionalRelatedPart(
|
|
126
|
+
withOptionalRelatedPart(
|
|
127
|
+
withOptionalRelatedPart(
|
|
128
|
+
serialized.relationships,
|
|
129
|
+
existingRelationships,
|
|
130
|
+
NUMBERING_RELATIONSHIP_TYPE,
|
|
131
|
+
"numbering.xml",
|
|
132
|
+
Boolean(numberingXml),
|
|
133
|
+
),
|
|
134
|
+
existingRelationships,
|
|
135
|
+
COMMENTS_RELATIONSHIP_TYPE,
|
|
136
|
+
"comments.xml",
|
|
137
|
+
serializedComments.serializedCommentIds.length > 0,
|
|
138
|
+
),
|
|
139
|
+
existingRelationships,
|
|
140
|
+
COMMENTS_EXTENDED_RELATIONSHIP_TYPE,
|
|
141
|
+
"commentsExtended.xml",
|
|
142
|
+
Boolean(serializedComments.commentsExtendedXml),
|
|
143
|
+
),
|
|
144
|
+
existingRelationships,
|
|
145
|
+
COMMENTS_IDS_RELATIONSHIP_TYPE,
|
|
146
|
+
"commentsIds.xml",
|
|
147
|
+
Boolean(serializedComments.commentsIdsXml),
|
|
148
|
+
),
|
|
74
149
|
existingRelationships,
|
|
75
|
-
|
|
150
|
+
PEOPLE_RELATIONSHIP_TYPE,
|
|
151
|
+
"people.xml",
|
|
152
|
+
Boolean(serializedComments.peopleXml),
|
|
76
153
|
);
|
|
77
154
|
const exportSession = createExportSession(sourcePackage, [
|
|
78
155
|
MAIN_DOCUMENT_PATH,
|
|
79
156
|
...(numberingXml ? [NUMBERING_PART_PATH] : []),
|
|
157
|
+
...(serializedComments.serializedCommentIds.length > 0 ? [COMMENTS_PART_PATH] : []),
|
|
158
|
+
...(serializedComments.commentsExtendedXml ? [COMMENTS_EXTENDED_PART_PATH] : []),
|
|
159
|
+
...(serializedComments.commentsIdsXml ? [COMMENTS_IDS_PART_PATH] : []),
|
|
160
|
+
...(serializedComments.peopleXml ? [PEOPLE_PART_PATH] : []),
|
|
80
161
|
]);
|
|
81
162
|
|
|
82
163
|
exportSession.replaceOwnedPart({
|
|
83
164
|
path: MAIN_DOCUMENT_PATH,
|
|
84
|
-
bytes: new TextEncoder().encode(
|
|
165
|
+
bytes: new TextEncoder().encode(annotatedDocument.documentXml),
|
|
85
166
|
contentType: DOCX_DOCUMENT_CONTENT_TYPE,
|
|
86
167
|
relationships,
|
|
87
168
|
});
|
|
@@ -95,6 +176,43 @@ export function exportComparedDocumentRedlines(
|
|
|
95
176
|
});
|
|
96
177
|
}
|
|
97
178
|
|
|
179
|
+
if (serializedComments.serializedCommentIds.length > 0) {
|
|
180
|
+
exportSession.replaceOwnedPart({
|
|
181
|
+
path: COMMENTS_PART_PATH,
|
|
182
|
+
bytes: new TextEncoder().encode(serializedComments.commentsXml),
|
|
183
|
+
contentType:
|
|
184
|
+
sourcePackage.parts.get(COMMENTS_PART_PATH)?.contentType ?? COMMENTS_CONTENT_TYPE,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (serializedComments.commentsExtendedXml) {
|
|
189
|
+
exportSession.replaceOwnedPart({
|
|
190
|
+
path: COMMENTS_EXTENDED_PART_PATH,
|
|
191
|
+
bytes: new TextEncoder().encode(serializedComments.commentsExtendedXml),
|
|
192
|
+
contentType:
|
|
193
|
+
sourcePackage.parts.get(COMMENTS_EXTENDED_PART_PATH)?.contentType ??
|
|
194
|
+
COMMENTS_EXTENDED_CONTENT_TYPE,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (serializedComments.commentsIdsXml) {
|
|
199
|
+
exportSession.replaceOwnedPart({
|
|
200
|
+
path: COMMENTS_IDS_PART_PATH,
|
|
201
|
+
bytes: new TextEncoder().encode(serializedComments.commentsIdsXml),
|
|
202
|
+
contentType:
|
|
203
|
+
sourcePackage.parts.get(COMMENTS_IDS_PART_PATH)?.contentType ?? COMMENTS_IDS_CONTENT_TYPE,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (serializedComments.peopleXml) {
|
|
208
|
+
exportSession.replaceOwnedPart({
|
|
209
|
+
path: PEOPLE_PART_PATH,
|
|
210
|
+
bytes: new TextEncoder().encode(serializedComments.peopleXml),
|
|
211
|
+
contentType:
|
|
212
|
+
sourcePackage.parts.get(PEOPLE_PART_PATH)?.contentType ?? PEOPLE_CONTENT_TYPE,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
98
216
|
return {
|
|
99
217
|
bytes: exportSession.serialize(),
|
|
100
218
|
mimeType: DOCX_MIME_TYPE,
|
|
@@ -132,28 +250,30 @@ function hasNumberingEntries(
|
|
|
132
250
|
);
|
|
133
251
|
}
|
|
134
252
|
|
|
135
|
-
function
|
|
253
|
+
function withOptionalRelatedPart(
|
|
136
254
|
relationships: readonly OpcRelationship[],
|
|
137
255
|
existingRelationships: readonly OpcRelationship[],
|
|
138
|
-
|
|
256
|
+
relationshipType: string,
|
|
257
|
+
target: string,
|
|
258
|
+
includePart: boolean,
|
|
139
259
|
): OpcRelationship[] {
|
|
140
260
|
const next = relationships.map((relationship) => ({ ...relationship }));
|
|
141
|
-
if (!
|
|
261
|
+
if (!includePart) {
|
|
142
262
|
return next;
|
|
143
263
|
}
|
|
144
264
|
|
|
145
|
-
const existing = next.find((relationship) => relationship.type ===
|
|
265
|
+
const existing = next.find((relationship) => relationship.type === relationshipType);
|
|
146
266
|
if (existing) {
|
|
147
267
|
return next;
|
|
148
268
|
}
|
|
149
269
|
|
|
150
270
|
const fallbackId =
|
|
151
|
-
existingRelationships.find((relationship) => relationship.type ===
|
|
271
|
+
existingRelationships.find((relationship) => relationship.type === relationshipType)?.id ??
|
|
152
272
|
`rId${next.length + 1}`;
|
|
153
273
|
next.push({
|
|
154
274
|
id: fallbackId,
|
|
155
|
-
type:
|
|
156
|
-
target
|
|
275
|
+
type: relationshipType,
|
|
276
|
+
target,
|
|
157
277
|
targetMode: "internal",
|
|
158
278
|
});
|
|
159
279
|
return next;
|
package/src/compare/snapshot.ts
CHANGED
|
@@ -20,6 +20,13 @@ export interface CreateDocumentVersionSnapshotOptions {
|
|
|
20
20
|
createdAt?: string;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
export function createDocumentVersionSnapshotId(
|
|
24
|
+
document: Pick<CanonicalDocument, "docId">,
|
|
25
|
+
name: string,
|
|
26
|
+
): string {
|
|
27
|
+
return `${document.docId}:${name}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
export function createDocumentVersionSnapshot(
|
|
24
31
|
document: CanonicalDocument,
|
|
25
32
|
options: CreateDocumentVersionSnapshotOptions,
|
|
@@ -27,7 +34,8 @@ export function createDocumentVersionSnapshot(
|
|
|
27
34
|
const canonicalDocument = projectCanonicalDocument(document);
|
|
28
35
|
return {
|
|
29
36
|
snapshotVersion: "document-version-snapshot/1",
|
|
30
|
-
versionId:
|
|
37
|
+
versionId:
|
|
38
|
+
options.versionId ?? createDocumentVersionSnapshotId(canonicalDocument, options.name),
|
|
31
39
|
name: options.name,
|
|
32
40
|
createdAt: options.createdAt ?? canonicalDocument.updatedAt,
|
|
33
41
|
documentId: canonicalDocument.docId,
|
|
@@ -35,3 +43,24 @@ export function createDocumentVersionSnapshot(
|
|
|
35
43
|
canonicalDocument,
|
|
36
44
|
};
|
|
37
45
|
}
|
|
46
|
+
|
|
47
|
+
export function saveDocumentVersionSnapshot(
|
|
48
|
+
snapshots: readonly DocumentVersionSnapshot[],
|
|
49
|
+
snapshot: DocumentVersionSnapshot,
|
|
50
|
+
): DocumentVersionSnapshot[] {
|
|
51
|
+
const next = snapshots.filter((entry) => entry.versionId !== snapshot.versionId);
|
|
52
|
+
next.push(snapshot);
|
|
53
|
+
return next.sort(compareDocumentVersionSnapshots);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function compareDocumentVersionSnapshots(
|
|
57
|
+
left: DocumentVersionSnapshot,
|
|
58
|
+
right: DocumentVersionSnapshot,
|
|
59
|
+
): number {
|
|
60
|
+
const createdAtComparison = right.createdAt.localeCompare(left.createdAt);
|
|
61
|
+
if (createdAtComparison !== 0) {
|
|
62
|
+
return createdAtComparison;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return left.versionId.localeCompare(right.versionId);
|
|
66
|
+
}
|
|
@@ -114,6 +114,26 @@ export function __createWordReviewEditorRefBridge(
|
|
|
114
114
|
getWarnings: () => runtime.getWarnings(),
|
|
115
115
|
getComments: () => runtime.getRenderSnapshot().comments,
|
|
116
116
|
getTrackedChanges: () => runtime.getRenderSnapshot().trackedChanges,
|
|
117
|
+
scrollToRevision: (revisionId: string) => {
|
|
118
|
+
const revision = runtime.getRenderSnapshot().trackedChanges.revisions.find(
|
|
119
|
+
(r) => r.revisionId === revisionId,
|
|
120
|
+
);
|
|
121
|
+
if (!revision || revision.anchor.kind === "detached") return;
|
|
122
|
+
runtime.dispatch({
|
|
123
|
+
type: "selection.set",
|
|
124
|
+
selection: toRuntimeSelectionSnapshot(createSelectionFromAnchor(revision.anchor)),
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
scrollToComment: (commentId: string) => {
|
|
128
|
+
const comment = runtime.getRenderSnapshot().comments.threads.find(
|
|
129
|
+
(t) => t.commentId === commentId,
|
|
130
|
+
);
|
|
131
|
+
if (!comment || comment.anchor.kind === "detached") return;
|
|
132
|
+
runtime.dispatch({
|
|
133
|
+
type: "selection.set",
|
|
134
|
+
selection: toRuntimeSelectionSnapshot(createSelectionFromAnchor(comment.anchor)),
|
|
135
|
+
});
|
|
136
|
+
},
|
|
117
137
|
};
|
|
118
138
|
}
|
|
119
139
|
|
|
@@ -500,6 +520,26 @@ export const WordReviewEditor = forwardRef<WordReviewEditorRef, WordReviewEditor
|
|
|
500
520
|
getWarnings: () => activeRuntime.getWarnings(),
|
|
501
521
|
getComments: () => activeRuntime.getRenderSnapshot().comments,
|
|
502
522
|
getTrackedChanges: () => activeRuntime.getRenderSnapshot().trackedChanges,
|
|
523
|
+
scrollToRevision: (revisionId: string) => {
|
|
524
|
+
const revision = activeRuntime.getRenderSnapshot().trackedChanges.revisions.find(
|
|
525
|
+
(r) => r.revisionId === revisionId,
|
|
526
|
+
);
|
|
527
|
+
if (!revision || revision.anchor.kind === "detached") return;
|
|
528
|
+
activeRuntime.dispatch({
|
|
529
|
+
type: "selection.set",
|
|
530
|
+
selection: toRuntimeSelectionSnapshot(createSelectionFromAnchor(revision.anchor)),
|
|
531
|
+
});
|
|
532
|
+
},
|
|
533
|
+
scrollToComment: (commentId: string) => {
|
|
534
|
+
const comment = activeRuntime.getRenderSnapshot().comments.threads.find(
|
|
535
|
+
(t) => t.commentId === commentId,
|
|
536
|
+
);
|
|
537
|
+
if (!comment || comment.anchor.kind === "detached") return;
|
|
538
|
+
activeRuntime.dispatch({
|
|
539
|
+
type: "selection.set",
|
|
540
|
+
selection: toRuntimeSelectionSnapshot(createSelectionFromAnchor(comment.anchor)),
|
|
541
|
+
});
|
|
542
|
+
},
|
|
503
543
|
}),
|
|
504
544
|
[activeRuntime, currentUser.userId, documentId, runtime],
|
|
505
545
|
);
|