@arbidocs/blocks 0.4.95 → 0.4.97
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/dist/agents/index.cjs +283 -283
- package/dist/agents/index.js +7 -7
- package/dist/chat/index.cjs +127 -127
- package/dist/chat/index.js +4 -4
- package/dist/{chunk-DCZGYCN2.cjs → chunk-3US5OIDQ.cjs} +5 -5
- package/dist/{chunk-DCZGYCN2.cjs.map → chunk-3US5OIDQ.cjs.map} +1 -1
- package/dist/{chunk-QQH2NI5U.js → chunk-5NQIBJPP.js} +8 -8
- package/dist/{chunk-QQH2NI5U.js.map → chunk-5NQIBJPP.js.map} +1 -1
- package/dist/{chunk-KBPHLW2R.cjs → chunk-B4SRYJLM.cjs} +3 -3
- package/dist/{chunk-KBPHLW2R.cjs.map → chunk-B4SRYJLM.cjs.map} +1 -1
- package/dist/chunk-D54JXTPG.cjs +164 -0
- package/dist/chunk-D54JXTPG.cjs.map +1 -0
- package/dist/{chunk-VQ65UHTV.cjs → chunk-DDYXFALG.cjs} +47 -47
- package/dist/{chunk-VQ65UHTV.cjs.map → chunk-DDYXFALG.cjs.map} +1 -1
- package/dist/{chunk-RZGVMV6B.cjs → chunk-EHB7J6SR.cjs} +5 -5
- package/dist/{chunk-RZGVMV6B.cjs.map → chunk-EHB7J6SR.cjs.map} +1 -1
- package/dist/{chunk-EJAYB7PP.js → chunk-EWSEQEPL.js} +4 -4
- package/dist/{chunk-EJAYB7PP.js.map → chunk-EWSEQEPL.js.map} +1 -1
- package/dist/{chunk-3OXWJ3CZ.cjs → chunk-GVOTXXZG.cjs} +5 -5
- package/dist/{chunk-3OXWJ3CZ.cjs.map → chunk-GVOTXXZG.cjs.map} +1 -1
- package/dist/{chunk-CKYA2IG5.cjs → chunk-HBF4BDRU.cjs} +3 -3
- package/dist/{chunk-CKYA2IG5.cjs.map → chunk-HBF4BDRU.cjs.map} +1 -1
- package/dist/{chunk-E2AAIMXO.cjs → chunk-HGJGALLN.cjs} +832 -219
- package/dist/chunk-HGJGALLN.cjs.map +1 -0
- package/dist/{chunk-24CS7JWU.js → chunk-HOXKR26S.js} +3 -3
- package/dist/{chunk-24CS7JWU.js.map → chunk-HOXKR26S.js.map} +1 -1
- package/dist/{chunk-PDEHIGJ5.js → chunk-ICBAFX5B.js} +3 -3
- package/dist/{chunk-PDEHIGJ5.js.map → chunk-ICBAFX5B.js.map} +1 -1
- package/dist/{chunk-OYMYNYFV.cjs → chunk-IF6VAYIA.cjs} +5 -5
- package/dist/{chunk-OYMYNYFV.cjs.map → chunk-IF6VAYIA.cjs.map} +1 -1
- package/dist/{chunk-TOVSTC2M.cjs → chunk-LENXDIMY.cjs} +5 -5
- package/dist/{chunk-TOVSTC2M.cjs.map → chunk-LENXDIMY.cjs.map} +1 -1
- package/dist/{chunk-VYKMBLDX.cjs → chunk-MP6FK43E.cjs} +8 -8
- package/dist/{chunk-VYKMBLDX.cjs.map → chunk-MP6FK43E.cjs.map} +1 -1
- package/dist/{chunk-HUFLBZWI.js → chunk-PGDL26TQ.js} +4 -4
- package/dist/{chunk-HUFLBZWI.js.map → chunk-PGDL26TQ.js.map} +1 -1
- package/dist/{chunk-WXLKMEMB.js → chunk-QIEEFBZ5.js} +834 -221
- package/dist/chunk-QIEEFBZ5.js.map +1 -0
- package/dist/{chunk-YPKSLTL5.js → chunk-RSUOOMPT.js} +3 -3
- package/dist/{chunk-YPKSLTL5.js.map → chunk-RSUOOMPT.js.map} +1 -1
- package/dist/{chunk-UMY6Y6BM.js → chunk-VLOPZHFH.js} +3 -3
- package/dist/{chunk-UMY6Y6BM.js.map → chunk-VLOPZHFH.js.map} +1 -1
- package/dist/{chunk-GNHOB2ZB.cjs → chunk-XMBYDLZQ.cjs} +4 -4
- package/dist/{chunk-GNHOB2ZB.cjs.map → chunk-XMBYDLZQ.cjs.map} +1 -1
- package/dist/{chunk-YG7DGGCA.js → chunk-XQDM6T6C.js} +3 -3
- package/dist/{chunk-YG7DGGCA.js.map → chunk-XQDM6T6C.js.map} +1 -1
- package/dist/{chunk-ZNDAXSDP.js → chunk-YH6SSJDW.js} +3 -3
- package/dist/{chunk-ZNDAXSDP.js.map → chunk-YH6SSJDW.js.map} +1 -1
- package/dist/{chunk-EOEDGJ75.js → chunk-Z3G65XHZ.js} +3 -3
- package/dist/{chunk-EOEDGJ75.js.map → chunk-Z3G65XHZ.js.map} +1 -1
- package/dist/chunk-ZCOVDK2E.js +153 -0
- package/dist/chunk-ZCOVDK2E.js.map +1 -0
- package/dist/components/DetailPanel.d.ts +106 -0
- package/dist/connect/docx.cjs +6 -6
- package/dist/connect/docx.js +4 -4
- package/dist/connect/index.cjs +47 -47
- package/dist/connect/index.js +17 -17
- package/dist/databases/DatabaseRowDetail.d.ts +32 -0
- package/dist/databases/DatabaseTable.d.ts +3 -1
- package/dist/databases/DatabaseToolbar.d.ts +9 -1
- package/dist/databases/PickCellEditor.d.ts +8 -1
- package/dist/databases/SelectCellEditor.d.ts +6 -1
- package/dist/databases/column-types.d.ts +5 -0
- package/dist/databases/databaseColumns.d.ts +7 -0
- package/dist/databases/index.cjs +381 -11
- package/dist/databases/index.cjs.map +1 -1
- package/dist/databases/index.d.ts +7 -5
- package/dist/databases/index.js +379 -14
- package/dist/databases/index.js.map +1 -1
- package/dist/databases/linkCells.d.ts +4 -2
- package/dist/docx/NativeDocxEditor.d.ts +3 -1
- package/dist/docx/RibbonMenu.d.ts +15 -0
- package/dist/docx/StyleGallery.d.ts +9 -0
- package/dist/docx/WordReferences.d.ts +21 -0
- package/dist/docx/index.cjs +24 -24
- package/dist/docx/index.js +3 -3
- package/dist/docx/review/DocxEditorReview.d.ts +4 -2
- package/dist/docx/review/commentText.d.ts +7 -0
- package/dist/docx/wordStyles.d.ts +21 -0
- package/dist/facts/index.cjs +5 -5
- package/dist/facts/index.js +2 -2
- package/dist/files/index.cjs +308 -0
- package/dist/files/index.cjs.map +1 -1
- package/dist/files/index.js +298 -2
- package/dist/files/index.js.map +1 -1
- package/dist/files/views/gridViews.d.ts +80 -0
- package/dist/files/views/index.d.ts +2 -0
- package/dist/files/views/useGridViews.d.ts +38 -0
- package/dist/index.cjs +1237 -1237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +100 -139
- package/dist/index.js.map +1 -1
- package/dist/settings/index.cjs +1 -1
- package/dist/settings/index.js +1 -1
- package/dist/shell/index.cjs +67 -67
- package/dist/shell/index.js +3 -3
- package/dist/studio/index.cjs +7 -7
- package/dist/studio/index.js +6 -6
- package/dist/tags/TagDetail.d.ts +1 -0
- package/dist/workflow-canvas/index.cjs +51 -51
- package/dist/workflow-canvas/index.js +8 -8
- package/package.json +4 -4
- package/src/docx/styles.css +564 -91
- package/dist/chunk-E2AAIMXO.cjs.map +0 -1
- package/dist/chunk-WXLKMEMB.js.map +0 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { stylesXml, definitionBookmark, DEFINITION_BOOKMARK_PREFIX, compareTerms, groupDefinitions, definitionLabels, filterTermGroups, toDefinition, definitionIdOfBookmark, esc, parseDefinition, docxPackage, documentXml } from './chunk-D3QPYKZG.js';
|
|
3
|
-
import { filterMentionCandidates, MentionMenu, findMentionQuery, listOptionId, extractMentions } from './chunk-AA3PT6KR.js';
|
|
3
|
+
import { filterMentionCandidates, MentionMenu, findMentionQuery, listOptionId, extractMentions, useListKeyNav } from './chunk-AA3PT6KR.js';
|
|
4
4
|
import { unzipSync, strFromU8, strToU8, zipSync } from 'fflate';
|
|
5
5
|
import { collectReviewItems, revisionItemsOf } from '@docx-editor.dev/core/store';
|
|
6
6
|
import React3, { createContext, useContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
|
|
7
|
-
import { useDocxEditor, ReviewRailContext, useEditorSnapshot, useChromeTranslate, DocxEditor, createFontSource } from '@docx-editor.dev/react';
|
|
7
|
+
import { useDocxEditor, ReviewRailContext, useEditorSnapshot, useChromeTranslate, DocxEditor, createFontSource, useParagraphStyle, useEditorCommand } from '@docx-editor.dev/react';
|
|
8
|
+
import { AiMarkdown, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, DialogFooter, cn, splitMarkdownBlocks } from '@arbidocs/react/ui';
|
|
9
|
+
import { MessageSquarePlus, MessageSquare, PencilLine, ChevronLeft, ChevronRight, X, ChevronUp, ChevronDown, CheckCheck, RotateCcw, CircleCheck, Trash2, Check, SendHorizontal, Type, Ellipsis, RefreshCw, WifiOff, Download, Save, BookA, ListRestart, Superscript, NotebookText } from 'lucide-react';
|
|
8
10
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
9
11
|
import { createPortal } from 'react-dom';
|
|
10
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, DialogFooter, cn, splitMarkdownBlocks, AiMarkdown } from '@arbidocs/react/ui';
|
|
11
12
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
12
13
|
import * as Y from 'yjs';
|
|
13
14
|
import { DOCUMENT_COLLABORATION_VERSIONS, collaborationModule } from '@arbidocs/coedit';
|
|
14
15
|
import { createHocuspocusCollaboration } from '@arbidocs/coedit/hocuspocus';
|
|
15
|
-
import { Type, Ellipsis, RefreshCw, WifiOff, Check, Download, Save, BookA, ListRestart } from 'lucide-react';
|
|
16
16
|
|
|
17
17
|
function normalizeDocxExport(data) {
|
|
18
18
|
const files = unzipSync(new Uint8Array(data));
|
|
@@ -136,7 +136,25 @@ var ReviewItemContext = createContext(null);
|
|
|
136
136
|
function useReviewItem() {
|
|
137
137
|
return useContext(ReviewItemContext);
|
|
138
138
|
}
|
|
139
|
+
|
|
140
|
+
// src/docx/review/commentText.ts
|
|
141
|
+
var SKIP = /* @__PURE__ */ new Set(["delText", "instrText", "delInstrText", "pPr", "rPr"]);
|
|
142
|
+
function inline(node) {
|
|
143
|
+
if (node.kind === "textValue") return node.value ?? "";
|
|
144
|
+
if (node.localName && SKIP.has(node.localName)) return "";
|
|
145
|
+
if (node.localName === "br" || node.localName === "cr") return "\n";
|
|
146
|
+
if (node.localName === "tab") return " ";
|
|
147
|
+
return (node.children ?? []).map(inline).join("");
|
|
148
|
+
}
|
|
149
|
+
function commentText(entry) {
|
|
150
|
+
if (entry.kind !== "comment") return entry.text;
|
|
151
|
+
const blocks = entry.item?.comment?.blocks ?? [];
|
|
152
|
+
const text = blocks.map(inline).join("\n").trim();
|
|
153
|
+
return text || entry.text;
|
|
154
|
+
}
|
|
139
155
|
var CARD_GAP = 8;
|
|
156
|
+
var CLUSTER_GAP = 24;
|
|
157
|
+
var REVIEW_MARGIN_MIN_WIDTH = 900;
|
|
140
158
|
var REVISION_LABELS = {
|
|
141
159
|
insert: "Inserted",
|
|
142
160
|
delete: "Deleted",
|
|
@@ -152,33 +170,102 @@ function isTopLevel(entry) {
|
|
|
152
170
|
if (entry.kind === "custom") return entry.item.carded;
|
|
153
171
|
return true;
|
|
154
172
|
}
|
|
155
|
-
function
|
|
156
|
-
if (
|
|
173
|
+
function kindLabel(entry) {
|
|
174
|
+
if (entry.kind === "revision") return REVISION_LABELS[entry.revisionKind] ?? "Change";
|
|
175
|
+
if (entry.kind === "comment") return entry.resolved ? "Resolved" : "Comment";
|
|
176
|
+
return "Note";
|
|
177
|
+
}
|
|
178
|
+
function parseDate(value) {
|
|
179
|
+
if (!value) return null;
|
|
157
180
|
const date = new Date(value);
|
|
158
|
-
return Number.isNaN(date.getTime()) ?
|
|
181
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
182
|
+
}
|
|
183
|
+
function relativeDate(date) {
|
|
184
|
+
const seconds = (Date.now() - date.getTime()) / 1e3;
|
|
185
|
+
if (seconds < 45) return "just now";
|
|
186
|
+
if (seconds < 45 * 60) return `${Math.round(seconds / 60)}m ago`;
|
|
187
|
+
if (seconds < 22 * 3600) return `${Math.round(seconds / 3600)}h ago`;
|
|
188
|
+
if (seconds < 7 * 86400) return `${Math.round(seconds / 86400)}d ago`;
|
|
189
|
+
const sameYear = date.getFullYear() === (/* @__PURE__ */ new Date()).getFullYear();
|
|
190
|
+
return date.toLocaleDateString(void 0, {
|
|
191
|
+
day: "numeric",
|
|
192
|
+
month: "short",
|
|
193
|
+
year: sameYear ? void 0 : "numeric"
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function authorHue(author) {
|
|
197
|
+
let hash = 0;
|
|
198
|
+
for (const char of author) hash = hash * 31 + char.charCodeAt(0) | 0;
|
|
199
|
+
return Math.abs(hash) % 360;
|
|
159
200
|
}
|
|
160
201
|
function Avatar({ entry }) {
|
|
161
|
-
return /* @__PURE__ */ jsx(
|
|
202
|
+
return /* @__PURE__ */ jsx(
|
|
203
|
+
"span",
|
|
204
|
+
{
|
|
205
|
+
className: "native-docx-review-avatar",
|
|
206
|
+
"aria-hidden": "true",
|
|
207
|
+
style: { "--review-author-hue": authorHue(entry.author || "") },
|
|
208
|
+
children: entry.initials
|
|
209
|
+
}
|
|
210
|
+
);
|
|
162
211
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
212
|
+
function Byline({ entry, children }) {
|
|
213
|
+
const date = parseDate(entry.date);
|
|
214
|
+
return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-byline", children: [
|
|
215
|
+
/* @__PURE__ */ jsx(Avatar, { entry }),
|
|
216
|
+
/* @__PURE__ */ jsxs("div", { className: "native-docx-review-who", children: [
|
|
167
217
|
/* @__PURE__ */ jsx("span", { className: "native-docx-review-author", children: entry.author || "Reviewer" }),
|
|
168
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ jsxs("span", { className: "native-docx-review-meta", children: [
|
|
219
|
+
kindLabel(entry),
|
|
220
|
+
date && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
221
|
+
" \xB7 ",
|
|
222
|
+
/* @__PURE__ */ jsx(
|
|
223
|
+
"time",
|
|
224
|
+
{
|
|
225
|
+
className: "native-docx-review-date",
|
|
226
|
+
dateTime: date.toISOString(),
|
|
227
|
+
title: date.toLocaleString(),
|
|
228
|
+
children: relativeDate(date)
|
|
229
|
+
}
|
|
230
|
+
)
|
|
231
|
+
] })
|
|
232
|
+
] })
|
|
233
|
+
] }),
|
|
234
|
+
children
|
|
235
|
+
] });
|
|
236
|
+
}
|
|
237
|
+
function ChangeText({ entry }) {
|
|
238
|
+
const removed = entry.revisionKind === "replace" ? entry.replacedText : void 0;
|
|
239
|
+
const struck = entry.revisionKind === "delete" || entry.revisionKind === "moveFrom";
|
|
240
|
+
const added = entry.revisionKind === "insert" || entry.revisionKind === "moveTo" || removed !== void 0;
|
|
241
|
+
return /* @__PURE__ */ jsxs("p", { className: "native-docx-review-change", "data-testid": "review-text", children: [
|
|
242
|
+
removed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
243
|
+
/* @__PURE__ */ jsx("del", { children: removed }),
|
|
244
|
+
/* @__PURE__ */ jsx("span", { className: "native-docx-review-arrow", "aria-hidden": "true", children: "\u2192" })
|
|
169
245
|
] }),
|
|
170
|
-
/* @__PURE__ */ jsx("
|
|
246
|
+
struck ? /* @__PURE__ */ jsx("del", { children: entry.text }) : added ? /* @__PURE__ */ jsx("ins", { children: entry.text }) : /* @__PURE__ */ jsx("span", { children: entry.text })
|
|
247
|
+
] });
|
|
248
|
+
}
|
|
249
|
+
function CommentText({ text, testId }) {
|
|
250
|
+
return /* @__PURE__ */ jsx("div", { className: "native-docx-review-text", "data-testid": testId, children: /* @__PURE__ */ jsx(AiMarkdown, { className: "native-docx-review-markdown", allowHtml: false, children: text }) });
|
|
251
|
+
}
|
|
252
|
+
function Reply({ entry }) {
|
|
253
|
+
return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-message", children: [
|
|
254
|
+
/* @__PURE__ */ jsx(Byline, { entry }),
|
|
255
|
+
/* @__PURE__ */ jsx(CommentText, { text: commentText(entry) })
|
|
171
256
|
] });
|
|
172
257
|
}
|
|
173
258
|
function ReplyForm({
|
|
174
259
|
entry,
|
|
175
|
-
review
|
|
260
|
+
review,
|
|
261
|
+
onDismiss
|
|
176
262
|
}) {
|
|
177
263
|
const [text, setText] = useState("");
|
|
178
264
|
return /* @__PURE__ */ jsxs(
|
|
179
265
|
"form",
|
|
180
266
|
{
|
|
181
267
|
className: "native-docx-review-reply",
|
|
268
|
+
onClick: (event) => event.stopPropagation(),
|
|
182
269
|
onSubmit: (event) => {
|
|
183
270
|
event.preventDefault();
|
|
184
271
|
const value = text.trim();
|
|
@@ -190,25 +277,39 @@ function ReplyForm({
|
|
|
190
277
|
{
|
|
191
278
|
"data-testid": "review-reply-input",
|
|
192
279
|
"aria-label": "Reply",
|
|
193
|
-
placeholder: "Reply",
|
|
280
|
+
placeholder: "Reply\u2026",
|
|
194
281
|
value: text,
|
|
195
282
|
onChange: (event) => setText(event.target.value),
|
|
196
283
|
onKeyDown: (event) => {
|
|
197
284
|
if (event.key === "Escape") {
|
|
285
|
+
event.preventDefault();
|
|
198
286
|
event.stopPropagation();
|
|
199
|
-
|
|
287
|
+
onDismiss();
|
|
200
288
|
}
|
|
201
289
|
}
|
|
202
290
|
}
|
|
203
291
|
),
|
|
204
|
-
/* @__PURE__ */ jsx(
|
|
292
|
+
/* @__PURE__ */ jsx(
|
|
293
|
+
"button",
|
|
294
|
+
{
|
|
295
|
+
type: "submit",
|
|
296
|
+
className: "native-docx-review-icon native-docx-review-send",
|
|
297
|
+
"aria-label": "Reply",
|
|
298
|
+
title: "Reply",
|
|
299
|
+
disabled: !text.trim(),
|
|
300
|
+
children: /* @__PURE__ */ jsx(SendHorizontal, { size: 14 })
|
|
301
|
+
}
|
|
302
|
+
),
|
|
205
303
|
/* @__PURE__ */ jsx(
|
|
206
304
|
"button",
|
|
207
305
|
{
|
|
208
306
|
type: "button",
|
|
307
|
+
className: "native-docx-review-icon",
|
|
209
308
|
"data-testid": "review-reply-cancel",
|
|
210
|
-
|
|
211
|
-
|
|
309
|
+
"aria-label": "Cancel",
|
|
310
|
+
title: "Cancel",
|
|
311
|
+
onClick: onDismiss,
|
|
312
|
+
children: /* @__PURE__ */ jsx(X, { size: 14 })
|
|
212
313
|
}
|
|
213
314
|
)
|
|
214
315
|
]
|
|
@@ -221,7 +322,8 @@ function Card({
|
|
|
221
322
|
review,
|
|
222
323
|
extra,
|
|
223
324
|
cardRef,
|
|
224
|
-
top
|
|
325
|
+
top,
|
|
326
|
+
onDismiss
|
|
225
327
|
}) {
|
|
226
328
|
const resolved = entry.kind === "comment" && entry.resolved;
|
|
227
329
|
return /* @__PURE__ */ jsx(ReviewItemContext.Provider, { value: entry, children: /* @__PURE__ */ jsxs(
|
|
@@ -240,60 +342,85 @@ function Card({
|
|
|
240
342
|
},
|
|
241
343
|
"data-testid": "review-card",
|
|
242
344
|
"data-kind": entry.kind,
|
|
345
|
+
"data-change": entry.kind === "revision" ? entry.revisionKind : void 0,
|
|
243
346
|
"data-active": entry.isActive || void 0,
|
|
244
347
|
"data-resolved": resolved || void 0,
|
|
245
|
-
|
|
348
|
+
"data-floating": top === void 0 || void 0,
|
|
349
|
+
style: top === void 0 ? void 0 : { top },
|
|
246
350
|
onClick: () => {
|
|
247
351
|
if (entry.activatable && !entry.isActive) review.setActive(entry.key);
|
|
248
352
|
},
|
|
249
353
|
children: [
|
|
250
|
-
entry.kind === "
|
|
251
|
-
|
|
252
|
-
|
|
354
|
+
/* @__PURE__ */ jsx(Byline, { entry, children: entry.kind === "comment" && /* @__PURE__ */ jsxs("div", { className: "native-docx-review-tools", children: [
|
|
355
|
+
/* @__PURE__ */ jsx(
|
|
356
|
+
"button",
|
|
357
|
+
{
|
|
358
|
+
type: "button",
|
|
359
|
+
className: "native-docx-review-icon",
|
|
360
|
+
"data-testid": "review-resolve",
|
|
361
|
+
"aria-label": entry.resolved ? "Reopen" : "Resolve",
|
|
362
|
+
title: entry.resolved ? "Reopen" : "Resolve",
|
|
363
|
+
onClick: (event) => {
|
|
364
|
+
event.stopPropagation();
|
|
365
|
+
review.resolve(entry, !entry.resolved);
|
|
366
|
+
},
|
|
367
|
+
children: entry.resolved ? /* @__PURE__ */ jsx(RotateCcw, { size: 14 }) : /* @__PURE__ */ jsx(CircleCheck, { size: 14 })
|
|
368
|
+
}
|
|
369
|
+
),
|
|
370
|
+
/* @__PURE__ */ jsx(
|
|
371
|
+
"button",
|
|
372
|
+
{
|
|
373
|
+
type: "button",
|
|
374
|
+
className: "native-docx-review-icon",
|
|
375
|
+
"data-testid": "review-delete",
|
|
376
|
+
"aria-label": "Delete",
|
|
377
|
+
title: "Delete",
|
|
378
|
+
onClick: (event) => {
|
|
379
|
+
event.stopPropagation();
|
|
380
|
+
review.remove(entry);
|
|
381
|
+
},
|
|
382
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
] }) }),
|
|
386
|
+
entry.kind === "revision" ? /* @__PURE__ */ jsx(ChangeText, { entry }) : /* @__PURE__ */ jsx(CommentText, { text: commentText(entry), testId: "review-text" }),
|
|
387
|
+
replies.length > 0 && /* @__PURE__ */ jsx("div", { className: "native-docx-review-thread", children: replies.map((reply) => /* @__PURE__ */ jsx(Reply, { entry: reply }, reply.key)) }),
|
|
253
388
|
extra,
|
|
254
|
-
/* @__PURE__ */ jsxs("div", { className: "native-docx-review-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
{
|
|
288
|
-
type: "button",
|
|
289
|
-
"data-testid": "review-delete",
|
|
290
|
-
onClick: () => review.remove(entry),
|
|
291
|
-
children: "Delete"
|
|
292
|
-
}
|
|
293
|
-
)
|
|
294
|
-
] })
|
|
389
|
+
entry.kind === "revision" && !entry.readOnly && /* @__PURE__ */ jsxs("div", { className: "native-docx-review-decide", children: [
|
|
390
|
+
/* @__PURE__ */ jsxs(
|
|
391
|
+
"button",
|
|
392
|
+
{
|
|
393
|
+
type: "button",
|
|
394
|
+
className: "native-docx-review-accept",
|
|
395
|
+
"data-testid": "review-accept",
|
|
396
|
+
onClick: (event) => {
|
|
397
|
+
event.stopPropagation();
|
|
398
|
+
review.accept(entry);
|
|
399
|
+
},
|
|
400
|
+
children: [
|
|
401
|
+
/* @__PURE__ */ jsx(Check, { size: 14 }),
|
|
402
|
+
"Accept"
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
),
|
|
406
|
+
/* @__PURE__ */ jsxs(
|
|
407
|
+
"button",
|
|
408
|
+
{
|
|
409
|
+
type: "button",
|
|
410
|
+
className: "native-docx-review-reject",
|
|
411
|
+
"data-testid": "review-reject",
|
|
412
|
+
onClick: (event) => {
|
|
413
|
+
event.stopPropagation();
|
|
414
|
+
review.reject(entry);
|
|
415
|
+
},
|
|
416
|
+
children: [
|
|
417
|
+
/* @__PURE__ */ jsx(X, { size: 14 }),
|
|
418
|
+
"Reject"
|
|
419
|
+
]
|
|
420
|
+
}
|
|
421
|
+
)
|
|
295
422
|
] }),
|
|
296
|
-
entry.isActive && entry.kind !== "custom" && /* @__PURE__ */ jsx(ReplyForm, { entry, review })
|
|
423
|
+
entry.isActive && entry.kind !== "custom" && /* @__PURE__ */ jsx(ReplyForm, { entry, review, onDismiss })
|
|
297
424
|
]
|
|
298
425
|
}
|
|
299
426
|
) });
|
|
@@ -313,7 +440,8 @@ function Draft({
|
|
|
313
440
|
ref: formRef,
|
|
314
441
|
className: "native-docx-review-card native-docx-review-draft",
|
|
315
442
|
"data-testid": "review-draft",
|
|
316
|
-
|
|
443
|
+
"data-floating": top === void 0 || void 0,
|
|
444
|
+
style: top === void 0 ? void 0 : { top },
|
|
317
445
|
onSubmit: (event) => {
|
|
318
446
|
event.preventDefault();
|
|
319
447
|
if (text.trim()) onSubmit(text.trim());
|
|
@@ -325,22 +453,53 @@ function Draft({
|
|
|
325
453
|
ref: input,
|
|
326
454
|
"data-testid": "review-draft-input",
|
|
327
455
|
"aria-label": "Comment",
|
|
328
|
-
placeholder: "Add a comment",
|
|
456
|
+
placeholder: "Add a comment\u2026",
|
|
329
457
|
value: text,
|
|
330
458
|
onChange: (event) => setText(event.target.value),
|
|
331
459
|
onKeyDown: (event) => {
|
|
332
|
-
if (event.key === "Escape")
|
|
460
|
+
if (event.key === "Escape") {
|
|
461
|
+
event.preventDefault();
|
|
462
|
+
event.stopPropagation();
|
|
463
|
+
onCancel();
|
|
464
|
+
}
|
|
333
465
|
}
|
|
334
466
|
}
|
|
335
467
|
),
|
|
336
|
-
/* @__PURE__ */ jsxs("div", { className: "native-docx-review-
|
|
337
|
-
/* @__PURE__ */ jsx("button", { type: "submit", disabled: !text.trim(), children: "Comment" }),
|
|
338
|
-
/* @__PURE__ */ jsx(
|
|
468
|
+
/* @__PURE__ */ jsxs("div", { className: "native-docx-review-decide", children: [
|
|
469
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "native-docx-review-accept", disabled: !text.trim(), children: "Comment" }),
|
|
470
|
+
/* @__PURE__ */ jsx(
|
|
471
|
+
"button",
|
|
472
|
+
{
|
|
473
|
+
type: "button",
|
|
474
|
+
className: "native-docx-review-plain",
|
|
475
|
+
"data-testid": "review-draft-cancel",
|
|
476
|
+
onClick: onCancel,
|
|
477
|
+
children: "Cancel"
|
|
478
|
+
}
|
|
479
|
+
)
|
|
339
480
|
] })
|
|
340
481
|
]
|
|
341
482
|
}
|
|
342
483
|
);
|
|
343
484
|
}
|
|
485
|
+
function useScrollArea(anchor, ready) {
|
|
486
|
+
const [area, setArea] = useState({
|
|
487
|
+
element: null,
|
|
488
|
+
width: 0
|
|
489
|
+
});
|
|
490
|
+
useLayoutEffect(() => {
|
|
491
|
+
const element = anchor.current?.closest(".docx-editor__scroll-container") ?? null;
|
|
492
|
+
const measure = () => setArea(
|
|
493
|
+
(previous) => previous.element === element && previous.width === (element?.clientWidth ?? 0) ? previous : { element, width: element?.clientWidth ?? 0 }
|
|
494
|
+
);
|
|
495
|
+
measure();
|
|
496
|
+
if (!element || typeof ResizeObserver === "undefined") return;
|
|
497
|
+
const observer = new ResizeObserver(measure);
|
|
498
|
+
observer.observe(element);
|
|
499
|
+
return () => observer.disconnect();
|
|
500
|
+
}, [anchor, ready]);
|
|
501
|
+
return area;
|
|
502
|
+
}
|
|
344
503
|
function DocxEditorReviewRail({
|
|
345
504
|
children
|
|
346
505
|
}) {
|
|
@@ -351,6 +510,10 @@ function DocxEditorReviewRail({
|
|
|
351
510
|
const [tops, setTops] = useState({});
|
|
352
511
|
const [showResolved, setShowResolved] = useState(true);
|
|
353
512
|
const elements = useRef(/* @__PURE__ */ new Map());
|
|
513
|
+
const anchor = useRef(null);
|
|
514
|
+
const toolbar = useRef(null);
|
|
515
|
+
const area = useScrollArea(anchor, review.ready);
|
|
516
|
+
const layout = area.width === 0 || area.width >= REVIEW_MARGIN_MIN_WIDTH ? "margin" : "compact";
|
|
354
517
|
const openDraft = useCallback(() => {
|
|
355
518
|
const placement = editor?.getSelectionPlacement();
|
|
356
519
|
if (!placement) return;
|
|
@@ -359,9 +522,22 @@ function DocxEditorReviewRail({
|
|
|
359
522
|
}, [editor, review.setPaneOpen]);
|
|
360
523
|
useEffect(() => registry?.register(), [registry]);
|
|
361
524
|
useEffect(() => registry?.registerCommentDraft(openDraft), [registry, openDraft]);
|
|
525
|
+
const shownLayout = useRef(null);
|
|
526
|
+
useEffect(() => {
|
|
527
|
+
if (!review.ready || area.width === 0 || shownLayout.current === layout) return;
|
|
528
|
+
editor?.setReviewPaneOptions({ opening: layout === "margin" ? "auto" : "manual" });
|
|
529
|
+
const deepLinked = shownLayout.current === null && review.activeKey !== null;
|
|
530
|
+
shownLayout.current = layout;
|
|
531
|
+
if (layout === "margin") review.setPaneOpen(true);
|
|
532
|
+
else if (!deepLinked) {
|
|
533
|
+
setDraft(null);
|
|
534
|
+
review.setPaneOpen(false);
|
|
535
|
+
}
|
|
536
|
+
}, [editor, layout, area.width, review.ready, review.setPaneOpen]);
|
|
362
537
|
const scale = editor?.getRenderScale() ?? 1;
|
|
363
538
|
const top = review.items.filter(isTopLevel).filter((entry) => entry.anchorY !== null).filter((entry) => showResolved || entry.kind !== "comment" || !entry.resolved);
|
|
364
|
-
const
|
|
539
|
+
const changes = review.items.filter((entry) => entry.kind === "revision").length;
|
|
540
|
+
const comments = top.filter((entry) => entry.kind === "comment").length;
|
|
365
541
|
const hasResolved = review.items.some((entry) => entry.kind === "comment" && entry.resolved);
|
|
366
542
|
const repliesOf = useCallback(
|
|
367
543
|
(entry) => review.items.filter(
|
|
@@ -369,10 +545,49 @@ function DocxEditorReviewRail({
|
|
|
369
545
|
),
|
|
370
546
|
[review.items]
|
|
371
547
|
);
|
|
548
|
+
const column = layout === "margin" && review.paneOpen && (top.length > 0 || draft !== null);
|
|
549
|
+
const bubbleOpen = layout === "compact" && (review.paneOpen || draft !== null);
|
|
550
|
+
useEffect(() => {
|
|
551
|
+
const element = area.element;
|
|
552
|
+
if (!element) return;
|
|
553
|
+
if (column) element.setAttribute("data-review-margin", "");
|
|
554
|
+
else element.removeAttribute("data-review-margin");
|
|
555
|
+
return () => element.removeAttribute("data-review-margin");
|
|
556
|
+
}, [area.element, column]);
|
|
557
|
+
const dismiss = useCallback(() => {
|
|
558
|
+
setDraft(null);
|
|
559
|
+
if (layout === "compact") review.setPaneOpen(false);
|
|
560
|
+
else review.setActive(null);
|
|
561
|
+
}, [layout, review.setPaneOpen, review.setActive]);
|
|
562
|
+
useEffect(() => {
|
|
563
|
+
const element = area.element;
|
|
564
|
+
if (!element || !bubbleOpen) return;
|
|
565
|
+
const close = (event) => {
|
|
566
|
+
const target = event.target;
|
|
567
|
+
if (target instanceof Element && target.closest(
|
|
568
|
+
".native-docx-review-bubble, .native-docx-review-marker, .native-docx-review-add"
|
|
569
|
+
))
|
|
570
|
+
return;
|
|
571
|
+
dismiss();
|
|
572
|
+
};
|
|
573
|
+
const escape = (event) => {
|
|
574
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
575
|
+
if (!(event.target instanceof Node) || !element.contains(event.target)) return;
|
|
576
|
+
event.preventDefault();
|
|
577
|
+
dismiss();
|
|
578
|
+
};
|
|
579
|
+
const document2 = element.ownerDocument;
|
|
580
|
+
element.addEventListener("pointerdown", close);
|
|
581
|
+
document2.addEventListener("keydown", escape);
|
|
582
|
+
return () => {
|
|
583
|
+
element.removeEventListener("pointerdown", close);
|
|
584
|
+
document2.removeEventListener("keydown", escape);
|
|
585
|
+
};
|
|
586
|
+
}, [area.element, bubbleOpen, dismiss]);
|
|
372
587
|
useLayoutEffect(() => {
|
|
373
|
-
if (!
|
|
588
|
+
if (!column) return;
|
|
374
589
|
const next = {};
|
|
375
|
-
let floor = 0;
|
|
590
|
+
let floor = (toolbar.current?.offsetHeight ?? 0) + CARD_GAP;
|
|
376
591
|
const rows = top.map((entry) => ({
|
|
377
592
|
key: entry.key,
|
|
378
593
|
y: (entry.anchorY ?? 0) * scale
|
|
@@ -390,7 +605,7 @@ function DocxEditorReviewRail({
|
|
|
390
605
|
return same ? previous : next;
|
|
391
606
|
});
|
|
392
607
|
});
|
|
393
|
-
if (!review.ready) return
|
|
608
|
+
if (!review.ready) return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review" });
|
|
394
609
|
const selection = editor?.getSelectionPlacement();
|
|
395
610
|
const addComment = selection && /* @__PURE__ */ jsx(
|
|
396
611
|
"button",
|
|
@@ -399,108 +614,254 @@ function DocxEditorReviewRail({
|
|
|
399
614
|
className: "native-docx-review-add",
|
|
400
615
|
"data-testid": "review-add-comment",
|
|
401
616
|
"aria-label": "Add comment",
|
|
617
|
+
title: "Add comment",
|
|
402
618
|
style: { top: selection.anchorY * scale },
|
|
403
619
|
onMouseDown: (event) => event.preventDefault(),
|
|
404
620
|
onClick: openDraft,
|
|
405
|
-
children:
|
|
621
|
+
children: /* @__PURE__ */ jsx(MessageSquarePlus, { size: 14 })
|
|
406
622
|
}
|
|
407
623
|
);
|
|
408
|
-
if (
|
|
409
|
-
return /* @__PURE__ */
|
|
624
|
+
if (column) {
|
|
625
|
+
return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review", children: /* @__PURE__ */ jsxs("aside", { className: "native-docx-review-pane", "data-testid": "review-pane", "aria-label": "Review", children: [
|
|
410
626
|
addComment,
|
|
627
|
+
/* @__PURE__ */ jsxs("div", { ref: toolbar, className: "native-docx-review-toolbar", "data-testid": "review-toolbar", children: [
|
|
628
|
+
/* @__PURE__ */ jsx("span", { className: "native-docx-review-summary", children: [
|
|
629
|
+
changes && `${changes} ${changes === 1 ? "change" : "changes"}`,
|
|
630
|
+
comments && `${comments} ${comments === 1 ? "comment" : "comments"}`
|
|
631
|
+
].filter(Boolean).join(" \xB7 ") || "Review" }),
|
|
632
|
+
hasResolved && /* @__PURE__ */ jsxs("label", { className: "native-docx-review-switch", children: [
|
|
633
|
+
/* @__PURE__ */ jsx(
|
|
634
|
+
"input",
|
|
635
|
+
{
|
|
636
|
+
type: "checkbox",
|
|
637
|
+
"data-testid": "review-show-resolved",
|
|
638
|
+
checked: showResolved,
|
|
639
|
+
onChange: (event) => setShowResolved(event.target.checked)
|
|
640
|
+
}
|
|
641
|
+
),
|
|
642
|
+
"Resolved"
|
|
643
|
+
] }),
|
|
644
|
+
changes > 0 && /* @__PURE__ */ jsx(BulkActions, { review, navigate: true })
|
|
645
|
+
] }),
|
|
646
|
+
draft && /* @__PURE__ */ jsx(
|
|
647
|
+
Draft,
|
|
648
|
+
{
|
|
649
|
+
top: tops.__draft ?? draft.anchorY * scale,
|
|
650
|
+
formRef: (element) => {
|
|
651
|
+
if (element) elements.current.set("__draft", element);
|
|
652
|
+
},
|
|
653
|
+
onCancel: () => setDraft(null),
|
|
654
|
+
onSubmit: (text) => {
|
|
655
|
+
if (review.addComment(text)) setDraft(null);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
),
|
|
411
659
|
top.map((entry) => /* @__PURE__ */ jsx(
|
|
660
|
+
Card,
|
|
661
|
+
{
|
|
662
|
+
entry,
|
|
663
|
+
replies: repliesOf(entry),
|
|
664
|
+
review,
|
|
665
|
+
extra: children?.(entry),
|
|
666
|
+
top: tops[entry.key] ?? (entry.anchorY ?? 0) * scale,
|
|
667
|
+
onDismiss: dismiss,
|
|
668
|
+
cardRef: (element) => {
|
|
669
|
+
if (element) elements.current.set(entry.key, element);
|
|
670
|
+
else elements.current.delete(entry.key);
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
entry.key
|
|
674
|
+
))
|
|
675
|
+
] }) });
|
|
676
|
+
}
|
|
677
|
+
const clusters = [];
|
|
678
|
+
for (const entry of [...top].sort((a, b) => (a.anchorY ?? 0) - (b.anchorY ?? 0))) {
|
|
679
|
+
const y = (entry.anchorY ?? 0) * scale;
|
|
680
|
+
const last = clusters[clusters.length - 1];
|
|
681
|
+
if (last && y - last.y < CLUSTER_GAP) last.entries.push(entry);
|
|
682
|
+
else clusters.push({ y, entries: [entry] });
|
|
683
|
+
}
|
|
684
|
+
const shown = bubbleOpen ? draft ? null : clusters.find((cluster) => cluster.entries.some((entry) => entry.isActive)) ?? clusters[0] : void 0;
|
|
685
|
+
const focus = shown?.entries.find((entry) => entry.isActive) ?? shown?.entries[0];
|
|
686
|
+
const position = focus ? top.indexOf(focus) : -1;
|
|
687
|
+
const step = (offset) => {
|
|
688
|
+
const next = top[position + offset];
|
|
689
|
+
if (next) review.setActive(next.key);
|
|
690
|
+
};
|
|
691
|
+
return /* @__PURE__ */ jsx("div", { ref: anchor, className: "native-docx-review", children: /* @__PURE__ */ jsxs("div", { className: "native-docx-review-markers", "data-testid": "review-markers", children: [
|
|
692
|
+
addComment,
|
|
693
|
+
clusters.map((cluster) => {
|
|
694
|
+
const [first] = cluster.entries;
|
|
695
|
+
const comment = cluster.entries.some((entry) => entry.kind === "comment");
|
|
696
|
+
return /* @__PURE__ */ jsxs(
|
|
412
697
|
"button",
|
|
413
698
|
{
|
|
414
699
|
type: "button",
|
|
415
700
|
className: "native-docx-review-marker",
|
|
416
701
|
"data-testid": "review-marker",
|
|
417
|
-
"data-kind":
|
|
418
|
-
"
|
|
419
|
-
|
|
702
|
+
"data-kind": comment ? "comment" : first.kind,
|
|
703
|
+
"data-active": cluster === shown || void 0,
|
|
704
|
+
"aria-label": cluster.entries.length === 1 ? `${first.author}: ${first.text.slice(0, 60)}` : `${cluster.entries.length} comments and changes`,
|
|
705
|
+
"aria-expanded": layout === "compact" ? cluster === shown : void 0,
|
|
706
|
+
style: { top: cluster.y },
|
|
420
707
|
onClick: () => {
|
|
708
|
+
if (layout === "compact" && cluster === shown) return dismiss();
|
|
709
|
+
setDraft(null);
|
|
421
710
|
review.setPaneOpen(true);
|
|
422
|
-
review.setActive(
|
|
423
|
-
}
|
|
711
|
+
review.setActive(first.key);
|
|
712
|
+
},
|
|
713
|
+
children: [
|
|
714
|
+
comment ? /* @__PURE__ */ jsx(MessageSquare, { size: 13 }) : /* @__PURE__ */ jsx(PencilLine, { size: 13 }),
|
|
715
|
+
cluster.entries.length > 1 && /* @__PURE__ */ jsx("span", { className: "native-docx-review-count", children: cluster.entries.length })
|
|
716
|
+
]
|
|
424
717
|
},
|
|
425
|
-
|
|
426
|
-
)
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
{
|
|
446
|
-
type: "button",
|
|
447
|
-
"data-testid": "review-accept-all",
|
|
448
|
-
onClick: () => review.resolveAll("accept"),
|
|
449
|
-
children: "Accept all"
|
|
450
|
-
}
|
|
451
|
-
),
|
|
452
|
-
/* @__PURE__ */ jsx(
|
|
453
|
-
"button",
|
|
454
|
-
{
|
|
455
|
-
type: "button",
|
|
456
|
-
"data-testid": "review-reject-all",
|
|
457
|
-
onClick: () => review.resolveAll("reject"),
|
|
458
|
-
children: "Reject all"
|
|
718
|
+
first.key
|
|
719
|
+
);
|
|
720
|
+
}),
|
|
721
|
+
bubbleOpen && (draft || shown || top.length === 0) && /* @__PURE__ */ jsx(
|
|
722
|
+
"div",
|
|
723
|
+
{
|
|
724
|
+
className: "native-docx-review-bubble",
|
|
725
|
+
"data-testid": "review-bubble",
|
|
726
|
+
role: "dialog",
|
|
727
|
+
"data-state": "open",
|
|
728
|
+
"aria-label": "Review",
|
|
729
|
+
style: {
|
|
730
|
+
top: draft ? draft.anchorY * scale : shown?.y ?? 0,
|
|
731
|
+
width: Math.max(220, Math.min(340, area.width - 56))
|
|
732
|
+
},
|
|
733
|
+
onKeyDown: (event) => {
|
|
734
|
+
if (event.key === "Escape") {
|
|
735
|
+
event.preventDefault();
|
|
736
|
+
event.stopPropagation();
|
|
737
|
+
dismiss();
|
|
459
738
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
/* @__PURE__ */ jsx(
|
|
464
|
-
"input",
|
|
739
|
+
},
|
|
740
|
+
children: draft ? /* @__PURE__ */ jsx(
|
|
741
|
+
Draft,
|
|
465
742
|
{
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
743
|
+
onCancel: dismiss,
|
|
744
|
+
onSubmit: (text) => {
|
|
745
|
+
if (review.addComment(text)) setDraft(null);
|
|
746
|
+
}
|
|
470
747
|
}
|
|
471
|
-
),
|
|
472
|
-
|
|
473
|
-
|
|
748
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
749
|
+
/* @__PURE__ */ jsxs("div", { className: "native-docx-review-bubble-head", children: [
|
|
750
|
+
top.length > 1 && position >= 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
751
|
+
/* @__PURE__ */ jsx(
|
|
752
|
+
"button",
|
|
753
|
+
{
|
|
754
|
+
type: "button",
|
|
755
|
+
className: "native-docx-review-icon",
|
|
756
|
+
"data-testid": "review-bubble-previous",
|
|
757
|
+
"aria-label": "Previous",
|
|
758
|
+
disabled: position === 0,
|
|
759
|
+
onClick: () => step(-1),
|
|
760
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
761
|
+
}
|
|
762
|
+
),
|
|
763
|
+
/* @__PURE__ */ jsxs("span", { className: "native-docx-review-summary", children: [
|
|
764
|
+
position + 1,
|
|
765
|
+
" of ",
|
|
766
|
+
top.length
|
|
767
|
+
] }),
|
|
768
|
+
/* @__PURE__ */ jsx(
|
|
769
|
+
"button",
|
|
770
|
+
{
|
|
771
|
+
type: "button",
|
|
772
|
+
className: "native-docx-review-icon",
|
|
773
|
+
"data-testid": "review-bubble-next",
|
|
774
|
+
"aria-label": "Next",
|
|
775
|
+
disabled: position === top.length - 1,
|
|
776
|
+
onClick: () => step(1),
|
|
777
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
778
|
+
}
|
|
779
|
+
)
|
|
780
|
+
] }),
|
|
781
|
+
/* @__PURE__ */ jsx(
|
|
782
|
+
"button",
|
|
783
|
+
{
|
|
784
|
+
type: "button",
|
|
785
|
+
className: "native-docx-review-icon native-docx-review-close",
|
|
786
|
+
"data-testid": "review-bubble-close",
|
|
787
|
+
"aria-label": "Close",
|
|
788
|
+
onClick: dismiss,
|
|
789
|
+
children: /* @__PURE__ */ jsx(X, { size: 14 })
|
|
790
|
+
}
|
|
791
|
+
)
|
|
792
|
+
] }),
|
|
793
|
+
shown?.entries.map((entry) => /* @__PURE__ */ jsx(
|
|
794
|
+
Card,
|
|
795
|
+
{
|
|
796
|
+
entry,
|
|
797
|
+
replies: repliesOf(entry),
|
|
798
|
+
review,
|
|
799
|
+
extra: children?.(entry),
|
|
800
|
+
onDismiss: dismiss
|
|
801
|
+
},
|
|
802
|
+
entry.key
|
|
803
|
+
)),
|
|
804
|
+
!shown && /* @__PURE__ */ jsx("p", { className: "native-docx-review-empty", "data-testid": "review-empty", children: "No comments or changes." }),
|
|
805
|
+
changes > 1 && /* @__PURE__ */ jsx("div", { className: "native-docx-review-bubble-foot", children: /* @__PURE__ */ jsx(BulkActions, { review }) })
|
|
806
|
+
] })
|
|
807
|
+
}
|
|
808
|
+
)
|
|
809
|
+
] }) });
|
|
810
|
+
}
|
|
811
|
+
function BulkActions({ review, navigate }) {
|
|
812
|
+
return /* @__PURE__ */ jsxs("div", { className: "native-docx-review-bulk", children: [
|
|
813
|
+
navigate && /* @__PURE__ */ jsxs("span", { className: "native-docx-review-segment", children: [
|
|
814
|
+
/* @__PURE__ */ jsx(
|
|
815
|
+
"button",
|
|
816
|
+
{
|
|
817
|
+
type: "button",
|
|
818
|
+
className: "native-docx-review-icon",
|
|
819
|
+
"data-testid": "review-previous",
|
|
820
|
+
"aria-label": "Previous change",
|
|
821
|
+
title: "Previous change",
|
|
822
|
+
onClick: () => review.navigate("previous"),
|
|
823
|
+
children: /* @__PURE__ */ jsx(ChevronUp, { size: 14 })
|
|
824
|
+
}
|
|
825
|
+
),
|
|
826
|
+
/* @__PURE__ */ jsx(
|
|
827
|
+
"button",
|
|
828
|
+
{
|
|
829
|
+
type: "button",
|
|
830
|
+
className: "native-docx-review-icon",
|
|
831
|
+
"data-testid": "review-next",
|
|
832
|
+
"aria-label": "Next change",
|
|
833
|
+
title: "Next change",
|
|
834
|
+
onClick: () => review.navigate("next"),
|
|
835
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { size: 14 })
|
|
836
|
+
}
|
|
837
|
+
)
|
|
474
838
|
] }),
|
|
475
|
-
|
|
476
|
-
|
|
839
|
+
/* @__PURE__ */ jsxs(
|
|
840
|
+
"button",
|
|
477
841
|
{
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
842
|
+
type: "button",
|
|
843
|
+
className: "native-docx-review-accept",
|
|
844
|
+
"data-testid": "review-accept-all",
|
|
845
|
+
onClick: () => review.resolveAll("accept"),
|
|
846
|
+
children: [
|
|
847
|
+
/* @__PURE__ */ jsx(CheckCheck, { size: 14 }),
|
|
848
|
+
"Accept all"
|
|
849
|
+
]
|
|
486
850
|
}
|
|
487
851
|
),
|
|
488
|
-
|
|
489
|
-
|
|
852
|
+
/* @__PURE__ */ jsxs(
|
|
853
|
+
"button",
|
|
490
854
|
{
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
review,
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
entry.key
|
|
502
|
-
)),
|
|
503
|
-
top.length === 0 && !draft && /* @__PURE__ */ jsx("p", { className: "native-docx-review-empty", "data-testid": "review-empty", children: "No comments or changes." })
|
|
855
|
+
type: "button",
|
|
856
|
+
className: "native-docx-review-reject",
|
|
857
|
+
"data-testid": "review-reject-all",
|
|
858
|
+
onClick: () => review.resolveAll("reject"),
|
|
859
|
+
children: [
|
|
860
|
+
/* @__PURE__ */ jsx(X, { size: 14 }),
|
|
861
|
+
"Reject all"
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
)
|
|
504
865
|
] });
|
|
505
866
|
}
|
|
506
867
|
function ReviewCardSlot({ children }) {
|
|
@@ -582,14 +943,7 @@ function DocxCommentActivity() {
|
|
|
582
943
|
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Document comment" }) }),
|
|
583
944
|
thread.map((entry) => /* @__PURE__ */ jsxs("div", { className: "space-y-1 border-b pb-4 last:border-0", children: [
|
|
584
945
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: entry.author || "Reviewer" }),
|
|
585
|
-
/* @__PURE__ */ jsx(
|
|
586
|
-
"p",
|
|
587
|
-
{
|
|
588
|
-
className: "whitespace-pre-wrap break-words text-sm",
|
|
589
|
-
"data-testid": "docx-full-comment-text",
|
|
590
|
-
children: entry.text
|
|
591
|
-
}
|
|
592
|
-
)
|
|
946
|
+
/* @__PURE__ */ jsx("div", { "data-testid": "docx-full-comment-text", children: /* @__PURE__ */ jsx(AiMarkdown, { allowHtml: false, children: commentText(entry) }) })
|
|
593
947
|
] }, entry.key)),
|
|
594
948
|
statuses.map(([id, run]) => /* @__PURE__ */ jsxs("p", { role: "status", className: "text-sm", children: [
|
|
595
949
|
run.label,
|
|
@@ -1855,57 +2209,12 @@ var WordDraftStream = class {
|
|
|
1855
2209
|
}
|
|
1856
2210
|
}
|
|
1857
2211
|
};
|
|
1858
|
-
function contentPath(documentId) {
|
|
1859
|
-
const match = /^(doc-[A-Za-z0-9]+)@v([1-9][0-9]*)$/.exec(documentId);
|
|
1860
|
-
return match ? `/${encodeURIComponent(match[1])}/content?version=${match[2]}` : `/${encodeURIComponent(documentId)}/content`;
|
|
1861
|
-
}
|
|
1862
|
-
var drafts = /* @__PURE__ */ new Map();
|
|
1863
|
-
var stateBytes = (room) => Y.encodeStateAsUpdate(room.ydoc);
|
|
1864
|
-
var encodeState = (room) => {
|
|
1865
|
-
let binary = "";
|
|
1866
|
-
for (const byte of stateBytes(room)) binary += String.fromCharCode(byte);
|
|
1867
|
-
return btoa(binary);
|
|
1868
|
-
};
|
|
1869
|
-
function covered(room, vector, receipt) {
|
|
1870
|
-
const decode = (value) => Uint8Array.from(atob(value), (c) => c.charCodeAt(0));
|
|
1871
|
-
const server = Y.decodeStateVector(decode(vector)), local = Y.decodeStateVector(Y.encodeStateVector(room.ydoc));
|
|
1872
|
-
for (const [client, clock] of local) if ((server.get(client) || 0) < clock) return false;
|
|
1873
|
-
const deleted = Y.decodeUpdate(stateBytes(room)).ds.clients;
|
|
1874
|
-
const saved = Y.decodeUpdate(decode(receipt)).ds.clients;
|
|
1875
|
-
for (const [client, ranges] of deleted)
|
|
1876
|
-
for (const range of ranges) {
|
|
1877
|
-
if (!(saved.get(client) || []).some(
|
|
1878
|
-
(s) => s.clock <= range.clock && s.clock + s.len >= range.clock + range.len
|
|
1879
|
-
))
|
|
1880
|
-
return false;
|
|
1881
|
-
}
|
|
1882
|
-
return true;
|
|
1883
|
-
}
|
|
1884
|
-
var EditorBoundary = class extends React3.Component {
|
|
1885
|
-
state = {};
|
|
1886
|
-
static getDerivedStateFromError(error) {
|
|
1887
|
-
return { error };
|
|
1888
|
-
}
|
|
1889
|
-
render() {
|
|
1890
|
-
return this.state.error ? /* @__PURE__ */ jsxs("div", { role: "alert", className: "native-docx-error", children: [
|
|
1891
|
-
"Could not render this Word document: ",
|
|
1892
|
-
this.state.error.message
|
|
1893
|
-
] }) : this.props.children;
|
|
1894
|
-
}
|
|
1895
|
-
};
|
|
1896
|
-
function DocxParticipants({ session }) {
|
|
1897
|
-
const [people, setPeople] = useState([]);
|
|
1898
|
-
useEffect(() => {
|
|
1899
|
-
if (!session) return;
|
|
1900
|
-
setPeople(session.participants());
|
|
1901
|
-
return session.subscribeParticipants(setPeople);
|
|
1902
|
-
}, [session]);
|
|
1903
|
-
return /* @__PURE__ */ jsx("div", { className: "native-docx-presence", "aria-label": "People viewing this document", children: people.map((p) => /* @__PURE__ */ jsx("span", { className: "native-docx-avatar", title: p.name, children: p.name.split(" ").map((s) => s[0]).slice(0, 2).join("") }, p.actorId)) });
|
|
1904
|
-
}
|
|
1905
2212
|
function RibbonMenu({
|
|
1906
2213
|
label,
|
|
1907
2214
|
icon,
|
|
1908
|
-
children
|
|
2215
|
+
children,
|
|
2216
|
+
className,
|
|
2217
|
+
testId
|
|
1909
2218
|
}) {
|
|
1910
2219
|
const [open, setOpen] = useState(false);
|
|
1911
2220
|
const element = useRef(null);
|
|
@@ -1929,10 +2238,11 @@ function RibbonMenu({
|
|
|
1929
2238
|
"button",
|
|
1930
2239
|
{
|
|
1931
2240
|
type: "button",
|
|
1932
|
-
className: "native-docx-ribbon-trigger",
|
|
2241
|
+
className: ["native-docx-ribbon-trigger", className].filter(Boolean).join(" "),
|
|
1933
2242
|
"aria-label": label,
|
|
1934
2243
|
title: label,
|
|
1935
2244
|
"aria-expanded": open,
|
|
2245
|
+
"data-testid": testId,
|
|
1936
2246
|
onMouseDown: (event) => event.preventDefault(),
|
|
1937
2247
|
onClick: () => setOpen((value) => !value),
|
|
1938
2248
|
children: icon
|
|
@@ -1948,11 +2258,295 @@ function RibbonMenu({
|
|
|
1948
2258
|
if (!(event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement))
|
|
1949
2259
|
event.preventDefault();
|
|
1950
2260
|
},
|
|
1951
|
-
children
|
|
2261
|
+
children: typeof children === "function" ? children(() => setOpen(false)) : children
|
|
2262
|
+
}
|
|
2263
|
+
)
|
|
2264
|
+
] });
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
// src/docx/wordStyles.ts
|
|
2268
|
+
var QUICK_STYLES = ["Normal", "Title", "heading 1", "heading 2", "heading 3"];
|
|
2269
|
+
function findStyle(options, name) {
|
|
2270
|
+
const wanted = name.toLowerCase();
|
|
2271
|
+
const id = name.replace(/(^|\s)(\w)/g, (_, _s, c) => c.toUpperCase());
|
|
2272
|
+
return options.find((o) => o.name.toLowerCase() === wanted) ?? options.find((o) => o.styleId.toLowerCase() === id.toLowerCase());
|
|
2273
|
+
}
|
|
2274
|
+
function styleLabel(name) {
|
|
2275
|
+
return name === name.toLowerCase() ? name.replace(/(^|\s)(\w)/g, (m) => m.toUpperCase()) : name;
|
|
2276
|
+
}
|
|
2277
|
+
function wordShortcut(event) {
|
|
2278
|
+
const mod = event.ctrlKey || event.metaKey;
|
|
2279
|
+
if (!mod) return null;
|
|
2280
|
+
if (event.altKey && !event.shiftKey) {
|
|
2281
|
+
switch (event.code) {
|
|
2282
|
+
case "KeyF":
|
|
2283
|
+
return "footnote";
|
|
2284
|
+
case "KeyD":
|
|
2285
|
+
return "endnote";
|
|
2286
|
+
case "Digit1":
|
|
2287
|
+
case "Numpad1":
|
|
2288
|
+
return "heading 1";
|
|
2289
|
+
case "Digit2":
|
|
2290
|
+
case "Numpad2":
|
|
2291
|
+
return "heading 2";
|
|
2292
|
+
case "Digit3":
|
|
2293
|
+
case "Numpad3":
|
|
2294
|
+
return "heading 3";
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
if (event.shiftKey && !event.altKey && event.code === "KeyN") return "Normal";
|
|
2298
|
+
return null;
|
|
2299
|
+
}
|
|
2300
|
+
var FILTER_FROM = 8;
|
|
2301
|
+
function previewStyle(option) {
|
|
2302
|
+
const { fontFamily, fontSizePt, bold, italic, color } = option.preview;
|
|
2303
|
+
return {
|
|
2304
|
+
fontFamily: fontFamily ? `"${fontFamily}", serif` : void 0,
|
|
2305
|
+
// In the face of the style, but within a row: 9-18pt.
|
|
2306
|
+
fontSize: fontSizePt ? `${Math.min(18, Math.max(9, fontSizePt))}pt` : void 0,
|
|
2307
|
+
fontWeight: bold ? 700 : void 0,
|
|
2308
|
+
fontStyle: italic ? "italic" : void 0,
|
|
2309
|
+
color: color ? `#${color}` : void 0
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
function Gallery({ close }) {
|
|
2313
|
+
const { value, setValue, options, isEnabled } = useParagraphStyle();
|
|
2314
|
+
const editor = useDocxEditor();
|
|
2315
|
+
const [query, setQuery] = useState("");
|
|
2316
|
+
const quick = useMemo(
|
|
2317
|
+
() => QUICK_STYLES.map((name) => findStyle(options, name)).filter(
|
|
2318
|
+
(o) => !!o
|
|
2319
|
+
),
|
|
2320
|
+
[options]
|
|
2321
|
+
);
|
|
2322
|
+
const shown = useMemo(() => {
|
|
2323
|
+
const q = query.trim().toLowerCase();
|
|
2324
|
+
return q ? options.filter(
|
|
2325
|
+
(o) => o.name.toLowerCase().includes(q) || o.styleId.toLowerCase().includes(q)
|
|
2326
|
+
) : options;
|
|
2327
|
+
}, [options, query]);
|
|
2328
|
+
const apply = (option) => {
|
|
2329
|
+
setValue(option.styleId);
|
|
2330
|
+
close();
|
|
2331
|
+
editor?.surface?.focus();
|
|
2332
|
+
};
|
|
2333
|
+
const nav = useListKeyNav({
|
|
2334
|
+
open: true,
|
|
2335
|
+
items: shown,
|
|
2336
|
+
onPick: apply,
|
|
2337
|
+
onDismiss: close,
|
|
2338
|
+
resetKey: query
|
|
2339
|
+
});
|
|
2340
|
+
return /* @__PURE__ */ jsxs("div", { className: "native-docx-style-gallery", "data-testid": "docx-style-gallery", children: [
|
|
2341
|
+
quick.length > 0 && /* @__PURE__ */ jsx("div", { className: "native-docx-style-quick", role: "group", "aria-label": "Quick styles", children: quick.map((option) => /* @__PURE__ */ jsx(
|
|
2342
|
+
"button",
|
|
2343
|
+
{
|
|
2344
|
+
type: "button",
|
|
2345
|
+
"aria-pressed": value === option.styleId,
|
|
2346
|
+
disabled: !isEnabled,
|
|
2347
|
+
"data-style-id": option.styleId,
|
|
2348
|
+
title: styleLabel(option.name),
|
|
2349
|
+
onClick: () => apply(option),
|
|
2350
|
+
children: /* @__PURE__ */ jsx("span", { style: previewStyle(option), children: styleLabel(option.name) })
|
|
2351
|
+
},
|
|
2352
|
+
option.styleId
|
|
2353
|
+
)) }),
|
|
2354
|
+
options.length > FILTER_FROM && /* @__PURE__ */ jsx(
|
|
2355
|
+
"input",
|
|
2356
|
+
{
|
|
2357
|
+
className: "native-docx-style-filter",
|
|
2358
|
+
placeholder: "Find a style",
|
|
2359
|
+
"aria-label": "Find a style",
|
|
2360
|
+
value: query,
|
|
2361
|
+
autoFocus: true,
|
|
2362
|
+
onChange: (event) => setQuery(event.target.value),
|
|
2363
|
+
onKeyDown: (event) => {
|
|
2364
|
+
nav.handleKeyDown(event);
|
|
2365
|
+
},
|
|
2366
|
+
...nav.comboboxProps
|
|
2367
|
+
}
|
|
2368
|
+
),
|
|
2369
|
+
/* @__PURE__ */ jsxs(
|
|
2370
|
+
"ul",
|
|
2371
|
+
{
|
|
2372
|
+
className: "native-docx-style-list",
|
|
2373
|
+
role: "listbox",
|
|
2374
|
+
id: nav.listboxId,
|
|
2375
|
+
"aria-label": "Document styles",
|
|
2376
|
+
children: [
|
|
2377
|
+
shown.map((option, index) => /* @__PURE__ */ jsx(
|
|
2378
|
+
"li",
|
|
2379
|
+
{
|
|
2380
|
+
id: listOptionId(nav.listboxId, index),
|
|
2381
|
+
role: "option",
|
|
2382
|
+
"aria-selected": value === option.styleId,
|
|
2383
|
+
"aria-disabled": !isEnabled,
|
|
2384
|
+
"data-active": index === nav.selectedIndex || void 0,
|
|
2385
|
+
"data-style-id": option.styleId,
|
|
2386
|
+
onMouseEnter: () => nav.setSelectedIndex(index),
|
|
2387
|
+
onClick: () => isEnabled && apply(option),
|
|
2388
|
+
children: /* @__PURE__ */ jsx("span", { style: previewStyle(option), children: styleLabel(option.name) })
|
|
2389
|
+
},
|
|
2390
|
+
option.styleId
|
|
2391
|
+
)),
|
|
2392
|
+
shown.length === 0 && /* @__PURE__ */ jsx("li", { className: "native-docx-style-empty", children: "No matching style" })
|
|
2393
|
+
]
|
|
2394
|
+
}
|
|
2395
|
+
)
|
|
2396
|
+
] });
|
|
2397
|
+
}
|
|
2398
|
+
function StyleGallery() {
|
|
2399
|
+
const { value, options } = useParagraphStyle();
|
|
2400
|
+
const current = options.find((o) => o.styleId === value);
|
|
2401
|
+
const name = current ? styleLabel(current.name) : "Styles";
|
|
2402
|
+
return /* @__PURE__ */ jsx(
|
|
2403
|
+
RibbonMenu,
|
|
2404
|
+
{
|
|
2405
|
+
label: "Styles",
|
|
2406
|
+
className: "native-docx-style-trigger",
|
|
2407
|
+
testId: "docx-style-trigger",
|
|
2408
|
+
icon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2409
|
+
/* @__PURE__ */ jsx("span", { className: "native-docx-style-current", "data-testid": "docx-current-style", children: name }),
|
|
2410
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 12, "aria-hidden": true })
|
|
2411
|
+
] }),
|
|
2412
|
+
children: (close) => /* @__PURE__ */ jsx(Gallery, { close })
|
|
2413
|
+
}
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
function useInsertNote(kind) {
|
|
2417
|
+
const command = useEditorCommand(kind === "footnote" ? "insert.footnote" : "insert.endnote");
|
|
2418
|
+
const { options } = useParagraphStyle();
|
|
2419
|
+
const editor = useDocxEditor();
|
|
2420
|
+
const insert = () => {
|
|
2421
|
+
if (!command.execute()) return false;
|
|
2422
|
+
const text = findStyle(options, `${kind} text`);
|
|
2423
|
+
if (text && editor)
|
|
2424
|
+
withDirectEditing(
|
|
2425
|
+
editor,
|
|
2426
|
+
() => editor.exec({ type: "setParagraphStyle", styleId: text.styleId })
|
|
2427
|
+
);
|
|
2428
|
+
return true;
|
|
2429
|
+
};
|
|
2430
|
+
return { insert, isEnabled: command.isEnabled, disabledReason: command.disabledReason };
|
|
2431
|
+
}
|
|
2432
|
+
function NoteAction({
|
|
2433
|
+
kind,
|
|
2434
|
+
label,
|
|
2435
|
+
shortcut,
|
|
2436
|
+
icon
|
|
2437
|
+
}) {
|
|
2438
|
+
const note = useInsertNote(kind);
|
|
2439
|
+
return /* @__PURE__ */ jsx(
|
|
2440
|
+
DocxEditor.Toolbar.Action,
|
|
2441
|
+
{
|
|
2442
|
+
label: `${label} (${shortcut})`,
|
|
2443
|
+
icon,
|
|
2444
|
+
disabled: !note.isEnabled,
|
|
2445
|
+
disabledReason: note.disabledReason ?? void 0,
|
|
2446
|
+
onSelect: () => void note.insert(),
|
|
2447
|
+
className: `native-docx-insert-${kind}`
|
|
2448
|
+
}
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
function NoteButtons() {
|
|
2452
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2453
|
+
/* @__PURE__ */ jsx(
|
|
2454
|
+
NoteAction,
|
|
2455
|
+
{
|
|
2456
|
+
kind: "footnote",
|
|
2457
|
+
label: "Insert footnote",
|
|
2458
|
+
shortcut: "Ctrl+Alt+F",
|
|
2459
|
+
icon: /* @__PURE__ */ jsx(Superscript, { size: 16 })
|
|
2460
|
+
}
|
|
2461
|
+
),
|
|
2462
|
+
/* @__PURE__ */ jsx(
|
|
2463
|
+
NoteAction,
|
|
2464
|
+
{
|
|
2465
|
+
kind: "endnote",
|
|
2466
|
+
label: "Insert endnote",
|
|
2467
|
+
shortcut: "Ctrl+Alt+D",
|
|
2468
|
+
icon: /* @__PURE__ */ jsx(NotebookText, { size: 16 })
|
|
1952
2469
|
}
|
|
1953
2470
|
)
|
|
1954
2471
|
] });
|
|
1955
2472
|
}
|
|
2473
|
+
function WordShortcuts({ scope }) {
|
|
2474
|
+
const footnote = useInsertNote("footnote");
|
|
2475
|
+
const endnote = useInsertNote("endnote");
|
|
2476
|
+
const styles = useParagraphStyle();
|
|
2477
|
+
const editor = useDocxEditor();
|
|
2478
|
+
const latest = useRef({ footnote, endnote, styles, editor });
|
|
2479
|
+
latest.current = { footnote, endnote, styles, editor };
|
|
2480
|
+
useEffect(() => {
|
|
2481
|
+
const element = scope.current;
|
|
2482
|
+
if (!element) return;
|
|
2483
|
+
const onKeyDown = (event) => {
|
|
2484
|
+
const action = wordShortcut(event);
|
|
2485
|
+
if (!action) return;
|
|
2486
|
+
const { footnote: footnote2, endnote: endnote2, styles: styles2, editor: editor2 } = latest.current;
|
|
2487
|
+
if (action === "footnote" || action === "endnote") {
|
|
2488
|
+
if (!(action === "footnote" ? footnote2 : endnote2).insert()) return;
|
|
2489
|
+
} else {
|
|
2490
|
+
const style = findStyle(styles2.options, action);
|
|
2491
|
+
if (!style) return;
|
|
2492
|
+
styles2.setValue(style.styleId);
|
|
2493
|
+
}
|
|
2494
|
+
event.preventDefault();
|
|
2495
|
+
event.stopPropagation();
|
|
2496
|
+
editor2?.surface?.focus();
|
|
2497
|
+
};
|
|
2498
|
+
element.addEventListener("keydown", onKeyDown, true);
|
|
2499
|
+
return () => element.removeEventListener("keydown", onKeyDown, true);
|
|
2500
|
+
}, [scope]);
|
|
2501
|
+
return null;
|
|
2502
|
+
}
|
|
2503
|
+
function contentPath(documentId) {
|
|
2504
|
+
const match = /^(doc-[A-Za-z0-9]+)@v([1-9][0-9]*)$/.exec(documentId);
|
|
2505
|
+
return match ? `/${encodeURIComponent(match[1])}/content?version=${match[2]}` : `/${encodeURIComponent(documentId)}/content`;
|
|
2506
|
+
}
|
|
2507
|
+
var drafts = /* @__PURE__ */ new Map();
|
|
2508
|
+
var stateBytes = (room) => Y.encodeStateAsUpdate(room.ydoc);
|
|
2509
|
+
var encodeState = (room) => {
|
|
2510
|
+
let binary = "";
|
|
2511
|
+
for (const byte of stateBytes(room)) binary += String.fromCharCode(byte);
|
|
2512
|
+
return btoa(binary);
|
|
2513
|
+
};
|
|
2514
|
+
function covered(room, vector, receipt) {
|
|
2515
|
+
const decode = (value) => Uint8Array.from(atob(value), (c) => c.charCodeAt(0));
|
|
2516
|
+
const server = Y.decodeStateVector(decode(vector)), local = Y.decodeStateVector(Y.encodeStateVector(room.ydoc));
|
|
2517
|
+
for (const [client, clock] of local) if ((server.get(client) || 0) < clock) return false;
|
|
2518
|
+
const deleted = Y.decodeUpdate(stateBytes(room)).ds.clients;
|
|
2519
|
+
const saved = Y.decodeUpdate(decode(receipt)).ds.clients;
|
|
2520
|
+
for (const [client, ranges] of deleted)
|
|
2521
|
+
for (const range of ranges) {
|
|
2522
|
+
if (!(saved.get(client) || []).some(
|
|
2523
|
+
(s) => s.clock <= range.clock && s.clock + s.len >= range.clock + range.len
|
|
2524
|
+
))
|
|
2525
|
+
return false;
|
|
2526
|
+
}
|
|
2527
|
+
return true;
|
|
2528
|
+
}
|
|
2529
|
+
var EditorBoundary = class extends React3.Component {
|
|
2530
|
+
state = {};
|
|
2531
|
+
static getDerivedStateFromError(error) {
|
|
2532
|
+
return { error };
|
|
2533
|
+
}
|
|
2534
|
+
render() {
|
|
2535
|
+
return this.state.error ? /* @__PURE__ */ jsxs("div", { role: "alert", className: "native-docx-error", children: [
|
|
2536
|
+
"Could not render this Word document: ",
|
|
2537
|
+
this.state.error.message
|
|
2538
|
+
] }) : this.props.children;
|
|
2539
|
+
}
|
|
2540
|
+
};
|
|
2541
|
+
function DocxParticipants({ session }) {
|
|
2542
|
+
const [people, setPeople] = useState([]);
|
|
2543
|
+
useEffect(() => {
|
|
2544
|
+
if (!session) return;
|
|
2545
|
+
setPeople(session.participants());
|
|
2546
|
+
return session.subscribeParticipants(setPeople);
|
|
2547
|
+
}, [session]);
|
|
2548
|
+
return /* @__PURE__ */ jsx("div", { className: "native-docx-presence", "aria-label": "People viewing this document", children: people.map((p) => /* @__PURE__ */ jsx("span", { className: "native-docx-avatar", title: p.name, children: p.name.split(" ").map((s) => s[0]).slice(0, 2).join("") }, p.actorId)) });
|
|
2549
|
+
}
|
|
1956
2550
|
function DefinedTermButtons() {
|
|
1957
2551
|
const terms = useDefinedTerms();
|
|
1958
2552
|
if (!terms) return null;
|
|
@@ -1985,13 +2579,17 @@ function DefinedTermButtons() {
|
|
|
1985
2579
|
)
|
|
1986
2580
|
] });
|
|
1987
2581
|
}
|
|
1988
|
-
function DocxRibbon({
|
|
2582
|
+
function DocxRibbon({
|
|
2583
|
+
onSave,
|
|
2584
|
+
badge
|
|
2585
|
+
}) {
|
|
1989
2586
|
const [tab, setTab] = useState("Home");
|
|
1990
2587
|
const t = useChromeTranslate();
|
|
1991
2588
|
return /* @__PURE__ */ jsxs("div", { className: "native-docx-ribbon", children: [
|
|
1992
2589
|
/* @__PURE__ */ jsxs("select", { "aria-label": "Ribbon tab", value: tab, onChange: (event) => setTab(event.target.value), children: [
|
|
1993
2590
|
/* @__PURE__ */ jsx("option", { children: "Home" }),
|
|
1994
2591
|
/* @__PURE__ */ jsx("option", { children: "Insert" }),
|
|
2592
|
+
/* @__PURE__ */ jsx("option", { children: "References" }),
|
|
1995
2593
|
/* @__PURE__ */ jsx("option", { children: "Review" })
|
|
1996
2594
|
] }),
|
|
1997
2595
|
/* @__PURE__ */ jsxs(DocxEditor.Toolbar, { t, preset: false, onSave, children: [
|
|
@@ -1999,6 +2597,7 @@ function DocxRibbon({ onSave }) {
|
|
|
1999
2597
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Redo, {}),
|
|
2000
2598
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Save, {}),
|
|
2001
2599
|
tab === "Home" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2600
|
+
/* @__PURE__ */ jsx(StyleGallery, {}),
|
|
2002
2601
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Bold, {}),
|
|
2003
2602
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Italic, {}),
|
|
2004
2603
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Underline, {}),
|
|
@@ -2009,7 +2608,6 @@ function DocxRibbon({ onSave }) {
|
|
|
2009
2608
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Highlight, {})
|
|
2010
2609
|
] }),
|
|
2011
2610
|
/* @__PURE__ */ jsxs(RibbonMenu, { label: "More formatting", icon: /* @__PURE__ */ jsx(Ellipsis, { size: 16 }), children: [
|
|
2012
|
-
/* @__PURE__ */ jsx(DocxEditor.Toolbar.StylePicker, {}),
|
|
2013
2611
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Alignment, {}),
|
|
2014
2612
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.BulletList, {}),
|
|
2015
2613
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.NumberedList, {}),
|
|
@@ -2026,12 +2624,14 @@ function DocxRibbon({ onSave }) {
|
|
|
2026
2624
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Link, {}),
|
|
2027
2625
|
/* @__PURE__ */ jsx(DefinedTermButtons, {})
|
|
2028
2626
|
] }),
|
|
2627
|
+
tab === "References" && /* @__PURE__ */ jsx(NoteButtons, {}),
|
|
2029
2628
|
tab === "Review" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2030
2629
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.EditingMode, {}),
|
|
2031
2630
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Comments, {}),
|
|
2032
2631
|
/* @__PURE__ */ jsx(RibbonMenu, { label: "Review options", icon: /* @__PURE__ */ jsx(Ellipsis, { size: 16 }), children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Reviewers, {}) })
|
|
2033
2632
|
] })
|
|
2034
|
-
] })
|
|
2633
|
+
] }),
|
|
2634
|
+
badge && /* @__PURE__ */ jsx("span", { className: "native-docx-ribbon-badge", "data-testid": "docx-ribbon-badge", children: badge })
|
|
2035
2635
|
] });
|
|
2036
2636
|
}
|
|
2037
2637
|
var fixedZoomMode = { type: "fixed" };
|
|
@@ -2296,7 +2896,10 @@ function NativeDocxEditor({
|
|
|
2296
2896
|
const resize = new ResizeObserver(fit);
|
|
2297
2897
|
const chrome = new MutationObserver(fit);
|
|
2298
2898
|
resize.observe(viewport);
|
|
2299
|
-
chrome.observe(viewport, {
|
|
2899
|
+
chrome.observe(viewport, {
|
|
2900
|
+
attributes: true,
|
|
2901
|
+
attributeFilter: ["style", "data-review-pane", "data-review-margin"]
|
|
2902
|
+
});
|
|
2300
2903
|
fit();
|
|
2301
2904
|
fitCleanup.current = () => {
|
|
2302
2905
|
resize.disconnect();
|
|
@@ -2378,7 +2981,17 @@ function NativeDocxEditor({
|
|
|
2378
2981
|
trackMoves: true
|
|
2379
2982
|
}
|
|
2380
2983
|
),
|
|
2381
|
-
!stream && /* @__PURE__ */ jsx(
|
|
2984
|
+
!stream && /* @__PURE__ */ jsx(
|
|
2985
|
+
DocxRibbon,
|
|
2986
|
+
{
|
|
2987
|
+
onSave: () => void saveVersion(),
|
|
2988
|
+
badge: (
|
|
2989
|
+
// Says the document is shared live, in place of a title row above the ribbon.
|
|
2990
|
+
ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
|
|
2991
|
+
)
|
|
2992
|
+
}
|
|
2993
|
+
),
|
|
2994
|
+
!stream && /* @__PURE__ */ jsx(WordShortcuts, { scope: stageRef }),
|
|
2382
2995
|
/* @__PURE__ */ jsxs(
|
|
2383
2996
|
"div",
|
|
2384
2997
|
{
|
|
@@ -2510,5 +3123,5 @@ async function loadFonts(baseUrl) {
|
|
|
2510
3123
|
}
|
|
2511
3124
|
|
|
2512
3125
|
export { DEFAULT_DEFINED_TERMS_LABELS, DEFINED_TERM_TRIGGER, DefinedTermsProvider, DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, NativeDocxEditor, editorPort, findDefinitionsSection, insertDefinedTerm, loadDocxFonts, normalizeDocxExport, reviewModule, updateDefinitions, useDefinedTerms, useReview, useReviewItem, withDirectEditing };
|
|
2513
|
-
//# sourceMappingURL=chunk-
|
|
2514
|
-
//# sourceMappingURL=chunk-
|
|
3126
|
+
//# sourceMappingURL=chunk-QIEEFBZ5.js.map
|
|
3127
|
+
//# sourceMappingURL=chunk-QIEEFBZ5.js.map
|