@beyondwork/docx-react-component 1.0.45 → 1.0.46
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/README.md
CHANGED
|
@@ -708,7 +708,21 @@ Fired when a comment is resolved (via `resolveComment` or the sidebar).
|
|
|
708
708
|
}
|
|
709
709
|
```
|
|
710
710
|
|
|
711
|
-
|
|
711
|
+
For a general-purpose "something about comments changed" signal (covering deletions, reply appends, body edits, reopen, and every other mutation — including Yjs-driven mutations that route through the editor's imperative ref), subscribe to `comments_changed`.
|
|
712
|
+
|
|
713
|
+
#### `comments_changed`
|
|
714
|
+
|
|
715
|
+
Fired once per commit whenever the runtime's comment snapshot differs from the previous commit. Use this when you render comments in a sibling component and need to know when to re-fetch via `editorRef.current.getComments()`.
|
|
716
|
+
|
|
717
|
+
```ts
|
|
718
|
+
{
|
|
719
|
+
type: "comments_changed";
|
|
720
|
+
documentId: string;
|
|
721
|
+
changedCommentIds: string[]; // always non-empty
|
|
722
|
+
}
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
Covers: `addComment`, `deleteComment`, `resolveComment`, `reopenComment`, `addCommentReply`, `editCommentBody`, and any remote-origin mutation that funnels through the same runtime APIs. Does NOT fire on selection/focus changes.
|
|
712
726
|
|
|
713
727
|
#### `change_accepted`
|
|
714
728
|
|
|
@@ -944,6 +958,9 @@ function CommentButton({ editorRef }: { editorRef: React.RefObject<WordReviewEdi
|
|
|
944
958
|
case "comment_resolved":
|
|
945
959
|
console.log("comment resolved:", event.commentId);
|
|
946
960
|
break;
|
|
961
|
+
case "comments_changed":
|
|
962
|
+
console.log("comments changed:", event.changedCommentIds);
|
|
963
|
+
break;
|
|
947
964
|
case "change_accepted":
|
|
948
965
|
console.log("change accepted:", event.changeId);
|
|
949
966
|
break;
|
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.46",
|
|
5
5
|
"description": "Embeddable React Word (docx) editor with review, comments, tracked changes, and round-trip OOXML fidelity.",
|
|
6
6
|
"packageManager": "pnpm@10.30.3",
|
|
7
7
|
"type": "module",
|
package/src/api/public-types.ts
CHANGED
|
@@ -2416,6 +2416,23 @@ export type WordReviewEditorEvent =
|
|
|
2416
2416
|
documentId: string;
|
|
2417
2417
|
commentId: string;
|
|
2418
2418
|
}
|
|
2419
|
+
| {
|
|
2420
|
+
type: "comments_changed";
|
|
2421
|
+
documentId: string;
|
|
2422
|
+
/**
|
|
2423
|
+
* Stable ids of the comment threads whose state differs between
|
|
2424
|
+
* the previous and current runtime render snapshot. Includes
|
|
2425
|
+
* additions, deletions, body edits, reply appends, and
|
|
2426
|
+
* resolution-state transitions. Consumers can call
|
|
2427
|
+
* `editorRef.current.getComments()` to obtain the full updated
|
|
2428
|
+
* `CommentSidebarSnapshot`.
|
|
2429
|
+
*
|
|
2430
|
+
* The array is always non-empty when this event fires. When the
|
|
2431
|
+
* snapshot's `comments` reference is unchanged between commits,
|
|
2432
|
+
* no event fires.
|
|
2433
|
+
*/
|
|
2434
|
+
changedCommentIds: string[];
|
|
2435
|
+
}
|
|
2419
2436
|
| {
|
|
2420
2437
|
type: "change_accepted";
|
|
2421
2438
|
documentId: string;
|
|
@@ -3071,6 +3071,20 @@ export function createDocumentRuntime(
|
|
|
3071
3071
|
});
|
|
3072
3072
|
}
|
|
3073
3073
|
|
|
3074
|
+
if (previous.document.review.comments !== next.document.review.comments) {
|
|
3075
|
+
const changedCommentIds = diffCommentMapKeys(
|
|
3076
|
+
previous.document.review.comments,
|
|
3077
|
+
next.document.review.comments,
|
|
3078
|
+
);
|
|
3079
|
+
if (changedCommentIds.length > 0) {
|
|
3080
|
+
emit({
|
|
3081
|
+
type: "comments_changed",
|
|
3082
|
+
documentId: next.documentId,
|
|
3083
|
+
changedCommentIds,
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3074
3088
|
if (transaction.effects.changeAccepted) {
|
|
3075
3089
|
emit({
|
|
3076
3090
|
type: "change_accepted",
|
|
@@ -3988,6 +4002,27 @@ function createSelectionFromPublicAnchor(
|
|
|
3988
4002
|
}
|
|
3989
4003
|
}
|
|
3990
4004
|
|
|
4005
|
+
/**
|
|
4006
|
+
* Collect the stable ids of comment threads whose entry differs
|
|
4007
|
+
* (present in one side but not the other, OR present in both but
|
|
4008
|
+
* referencing a different object — which indicates any mutation to
|
|
4009
|
+
* the thread, since the runtime treats `review.comments` as
|
|
4010
|
+
* immutable per commit). Used by the `comments_changed` event.
|
|
4011
|
+
*/
|
|
4012
|
+
function diffCommentMapKeys(
|
|
4013
|
+
previous: CanonicalDocumentEnvelope["review"]["comments"],
|
|
4014
|
+
next: CanonicalDocumentEnvelope["review"]["comments"],
|
|
4015
|
+
): string[] {
|
|
4016
|
+
const changed = new Set<string>();
|
|
4017
|
+
for (const id of Object.keys(previous)) {
|
|
4018
|
+
if (previous[id] !== next[id]) changed.add(id);
|
|
4019
|
+
}
|
|
4020
|
+
for (const id of Object.keys(next)) {
|
|
4021
|
+
if (previous[id] !== next[id]) changed.add(id);
|
|
4022
|
+
}
|
|
4023
|
+
return Array.from(changed);
|
|
4024
|
+
}
|
|
4025
|
+
|
|
3991
4026
|
function toPublicCompatibilityReport(
|
|
3992
4027
|
report: InternalCompatibilityReport,
|
|
3993
4028
|
): CompatibilityReport {
|
|
@@ -45,12 +45,35 @@ export interface DocxFontLoader {
|
|
|
45
45
|
refresh(input: FontLoaderInput): void;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
interface MinimalFontFace {
|
|
49
|
+
load(): Promise<MinimalFontFace>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface MinimalFontFaceDescriptors {
|
|
53
|
+
weight?: string;
|
|
54
|
+
style?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface MinimalFontFaceConstructor {
|
|
58
|
+
new (
|
|
59
|
+
family: string,
|
|
60
|
+
source: ArrayBuffer | ArrayBufferView | string,
|
|
61
|
+
descriptors?: MinimalFontFaceDescriptors,
|
|
62
|
+
): MinimalFontFace;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface MinimalFontFaceSet {
|
|
66
|
+
add(face: MinimalFontFace): void;
|
|
67
|
+
check(font: string): boolean;
|
|
68
|
+
ready: Promise<MinimalFontFaceSet>;
|
|
69
|
+
}
|
|
70
|
+
|
|
48
71
|
export function createDocxFontLoader(initial: FontLoaderInput): DocxFontLoader {
|
|
72
|
+
const globalDocument = (globalThis as unknown as { document?: { fonts?: unknown } }).document;
|
|
49
73
|
const supported =
|
|
50
|
-
|
|
74
|
+
globalDocument !== undefined &&
|
|
51
75
|
typeof (globalThis as { FontFace?: unknown }).FontFace !== "undefined" &&
|
|
52
|
-
|
|
53
|
-
Boolean((document as Document & { fonts?: FontFaceSet }).fonts);
|
|
76
|
+
Boolean(globalDocument.fonts);
|
|
54
77
|
|
|
55
78
|
let current: FontLoaderInput = initial;
|
|
56
79
|
let readyPromise: Promise<void>;
|
|
@@ -58,7 +81,7 @@ export function createDocxFontLoader(initial: FontLoaderInput): DocxFontLoader {
|
|
|
58
81
|
|
|
59
82
|
function run(input: FontLoaderInput): Promise<void> {
|
|
60
83
|
if (!supported) return Promise.resolve();
|
|
61
|
-
const fontSet =
|
|
84
|
+
const fontSet = globalDocument?.fonts as MinimalFontFaceSet | undefined;
|
|
62
85
|
if (!fontSet) return Promise.resolve();
|
|
63
86
|
|
|
64
87
|
const pending: Array<Promise<unknown>> = [];
|
|
@@ -70,10 +93,8 @@ export function createDocxFontLoader(initial: FontLoaderInput): DocxFontLoader {
|
|
|
70
93
|
|
|
71
94
|
for (const [descriptor, data] of variantsOf(variants)) {
|
|
72
95
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
new (family: string, source: BufferSource, descriptors?: FontFaceDescriptors): FontFace;
|
|
76
|
-
};
|
|
96
|
+
const FontFaceCtor = (globalThis as { FontFace?: MinimalFontFaceConstructor }).FontFace;
|
|
97
|
+
if (!FontFaceCtor) continue;
|
|
77
98
|
const face = new FontFaceCtor(family, data, descriptor);
|
|
78
99
|
pending.push(
|
|
79
100
|
face.load().then((loaded) => {
|
|
@@ -88,8 +109,6 @@ export function createDocxFontLoader(initial: FontLoaderInput): DocxFontLoader {
|
|
|
88
109
|
}
|
|
89
110
|
}
|
|
90
111
|
|
|
91
|
-
// Mark declared families as registered if the browser already resolves
|
|
92
|
-
// them (e.g. system fonts like Calibri, Arial).
|
|
93
112
|
for (const family of input.families) {
|
|
94
113
|
try {
|
|
95
114
|
const probe = `12px "${family.replace(/"/g, "'")}", serif`;
|
|
@@ -127,7 +146,7 @@ export function createDocxFontLoader(initial: FontLoaderInput): DocxFontLoader {
|
|
|
127
146
|
|
|
128
147
|
function* variantsOf(
|
|
129
148
|
variants: EmbeddedFontBytes,
|
|
130
|
-
): IterableIterator<[
|
|
149
|
+
): IterableIterator<[MinimalFontFaceDescriptors, ArrayBuffer]> {
|
|
131
150
|
if (variants.regular) {
|
|
132
151
|
yield [{ weight: "400", style: "normal" }, variants.regular];
|
|
133
152
|
}
|