@arbidocs/blocks 0.4.102 → 0.4.104
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 +207 -207
- package/dist/agents/index.js +2 -2
- package/dist/{chunk-AOFATOT3.cjs → chunk-2A4MDHJR.cjs} +7 -5
- package/dist/chunk-2A4MDHJR.cjs.map +1 -0
- package/dist/{chunk-G5JH2YMQ.js → chunk-4GFB5U3K.js} +3 -3
- package/dist/{chunk-G5JH2YMQ.js.map → chunk-4GFB5U3K.js.map} +1 -1
- package/dist/chunk-5FYU7ZIU.cjs +139 -0
- package/dist/chunk-5FYU7ZIU.cjs.map +1 -0
- package/dist/{chunk-Y5XW57U4.cjs → chunk-7LLLQUM7.cjs} +5 -5
- package/dist/{chunk-Y5XW57U4.cjs.map → chunk-7LLLQUM7.cjs.map} +1 -1
- package/dist/{chunk-D3QPYKZG.js → chunk-EPHGD4YV.js} +7 -6
- package/dist/chunk-EPHGD4YV.js.map +1 -0
- package/dist/chunk-HFZ45FD3.js +133 -0
- package/dist/chunk-HFZ45FD3.js.map +1 -0
- package/dist/{chunk-5NQIBJPP.js → chunk-NJX774HB.js} +3 -3
- package/dist/{chunk-5NQIBJPP.js.map → chunk-NJX774HB.js.map} +1 -1
- package/dist/{chunk-DDYXFALG.cjs → chunk-NW3LFDZL.cjs} +3 -3
- package/dist/{chunk-DDYXFALG.cjs.map → chunk-NW3LFDZL.cjs.map} +1 -1
- package/dist/{chunk-YGREW5TZ.js → chunk-PIT2YZCK.js} +3 -3
- package/dist/{chunk-YGREW5TZ.js.map → chunk-PIT2YZCK.js.map} +1 -1
- package/dist/{chunk-Z3G65XHZ.js → chunk-S55VDTX3.js} +3 -3
- package/dist/{chunk-Z3G65XHZ.js.map → chunk-S55VDTX3.js.map} +1 -1
- package/dist/{chunk-LENXDIMY.cjs → chunk-SKSE4OT6.cjs} +22 -22
- package/dist/{chunk-LENXDIMY.cjs.map → chunk-SKSE4OT6.cjs.map} +1 -1
- package/dist/{chunk-ZT2EBBSC.cjs → chunk-TP3FAP5J.cjs} +5 -5
- package/dist/{chunk-ZT2EBBSC.cjs.map → chunk-TP3FAP5J.cjs.map} +1 -1
- package/dist/{chunk-MYALCKDR.js → chunk-W2RTZOK3.js} +1533 -263
- package/dist/chunk-W2RTZOK3.js.map +1 -0
- package/dist/{chunk-FAGQTB3D.cjs → chunk-ZWWN4CUL.cjs} +1690 -408
- package/dist/chunk-ZWWN4CUL.cjs.map +1 -0
- package/dist/connect/docx.cjs +8 -7
- package/dist/connect/docx.cjs.map +1 -1
- package/dist/connect/docx.js +6 -5
- package/dist/connect/docx.js.map +1 -1
- package/dist/connect/index.cjs +12 -11
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +5 -4
- package/dist/connect/index.js.map +1 -1
- package/dist/docx/LinkHoverCard.d.ts +24 -0
- package/dist/docx/NativeDocxEditor.d.ts +6 -0
- package/dist/docx/RibbonMenu.d.ts +4 -1
- package/dist/docx/RibbonOverflow.d.ts +27 -0
- package/dist/docx/WordReferences.d.ts +3 -2
- package/dist/docx/beforeSave.d.ts +9 -0
- package/dist/docx/definitions/fragment.d.ts +19 -1
- package/dist/docx/definitions/port.d.ts +43 -11
- package/dist/docx/index.cjs +85 -36
- package/dist/docx/index.cjs.map +1 -1
- package/dist/docx/index.d.ts +6 -0
- package/dist/docx/index.js +5 -4
- package/dist/docx/index.js.map +1 -1
- package/dist/docx/noteStyles.d.ts +46 -0
- package/dist/docx/overflowPlan.d.ts +15 -0
- package/dist/docx/references/CrossReferences.d.ts +97 -0
- package/dist/docx/references/EditorMenus.d.ts +10 -0
- package/dist/docx/references/commands.d.ts +119 -0
- package/dist/docx/references/numbering.d.ts +49 -0
- package/dist/docx/references/passages.d.ts +32 -0
- package/dist/docx/references/port.d.ts +20 -0
- package/dist/facts/index.cjs +22 -129
- package/dist/facts/index.cjs.map +1 -1
- package/dist/facts/index.js +3 -125
- package/dist/facts/index.js.map +1 -1
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/home/index.cjs +1 -1
- package/dist/home/index.js +1 -1
- package/dist/index.cjs +314 -314
- package/dist/index.js +8 -8
- package/dist/shell/index.cjs +1 -1
- package/dist/shell/index.js +1 -1
- package/dist/studio/index.cjs +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/tags/ooxml.d.ts +4 -0
- package/dist/workflow-canvas/index.cjs +9 -9
- package/dist/workflow-canvas/index.js +2 -2
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +4 -4
- package/src/docx/README.md +32 -0
- package/src/docx/styles.css +73 -5
- package/dist/chunk-AOFATOT3.cjs.map +0 -1
- package/dist/chunk-D3QPYKZG.js.map +0 -1
- package/dist/chunk-FAGQTB3D.cjs.map +0 -1
- package/dist/chunk-MYALCKDR.js.map +0 -1
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunk5FYU7ZIU_cjs = require('./chunk-5FYU7ZIU.cjs');
|
|
5
|
+
var chunk2A4MDHJR_cjs = require('./chunk-2A4MDHJR.cjs');
|
|
5
6
|
var chunk7UTB4PHM_cjs = require('./chunk-7UTB4PHM.cjs');
|
|
6
7
|
var fflate = require('fflate');
|
|
7
8
|
var store = require('@docx-editor.dev/core/store');
|
|
8
|
-
var
|
|
9
|
+
var React4 = require('react');
|
|
9
10
|
var react = require('@docx-editor.dev/react');
|
|
10
11
|
var ui = require('@arbidocs/react/ui');
|
|
11
12
|
var lucideReact = require('lucide-react');
|
|
12
13
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
14
|
var reactDom = require('react-dom');
|
|
14
15
|
var template = require('@arbidocs/coedit/template');
|
|
16
|
+
var layout = require('@docx-editor.dev/core/layout');
|
|
15
17
|
var editor = require('@docx-editor.dev/core/editor');
|
|
16
18
|
var server = require('react-dom/server');
|
|
17
19
|
var Y = require('yjs');
|
|
@@ -38,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
38
40
|
return Object.freeze(n);
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
var
|
|
43
|
+
var React4__default = /*#__PURE__*/_interopDefault(React4);
|
|
42
44
|
var Y__namespace = /*#__PURE__*/_interopNamespace(Y);
|
|
43
45
|
|
|
44
46
|
function normalizeDocxExport(data) {
|
|
@@ -134,10 +136,10 @@ function useReview() {
|
|
|
134
136
|
const editor = react.useDocxEditor();
|
|
135
137
|
const version = react.useEditorSnapshot(editor);
|
|
136
138
|
const revision = editor?.getReviewRevision() ?? 0;
|
|
137
|
-
const items =
|
|
139
|
+
const items = React4.useMemo(() => editor ? editor.getReviewItems() : NONE, [editor, revision]);
|
|
138
140
|
const paneOpen = editor?.isReviewPaneOpen() ?? false;
|
|
139
141
|
const activeKey = items.find((item) => item.isActive)?.key ?? null;
|
|
140
|
-
return
|
|
142
|
+
return React4.useMemo(
|
|
141
143
|
() => ({
|
|
142
144
|
ready: editor !== null,
|
|
143
145
|
items,
|
|
@@ -159,9 +161,9 @@ function useReview() {
|
|
|
159
161
|
[editor, items, activeKey, paneOpen, version]
|
|
160
162
|
);
|
|
161
163
|
}
|
|
162
|
-
var ReviewItemContext =
|
|
164
|
+
var ReviewItemContext = React4.createContext(null);
|
|
163
165
|
function useReviewItem() {
|
|
164
|
-
return
|
|
166
|
+
return React4.useContext(ReviewItemContext);
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
// src/docx/review/commentText.ts
|
|
@@ -287,7 +289,7 @@ function ReplyForm({
|
|
|
287
289
|
review,
|
|
288
290
|
onDismiss
|
|
289
291
|
}) {
|
|
290
|
-
const [text, setText] =
|
|
292
|
+
const [text, setText] = React4.useState("");
|
|
291
293
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
292
294
|
"form",
|
|
293
295
|
{
|
|
@@ -458,9 +460,9 @@ function Draft({
|
|
|
458
460
|
onCancel,
|
|
459
461
|
formRef
|
|
460
462
|
}) {
|
|
461
|
-
const [text, setText] =
|
|
462
|
-
const input =
|
|
463
|
-
|
|
463
|
+
const [text, setText] = React4.useState("");
|
|
464
|
+
const input = React4.useRef(null);
|
|
465
|
+
React4.useEffect(() => input.current?.focus(), []);
|
|
464
466
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
465
467
|
"form",
|
|
466
468
|
{
|
|
@@ -510,11 +512,11 @@ function Draft({
|
|
|
510
512
|
);
|
|
511
513
|
}
|
|
512
514
|
function useScrollArea(anchor, ready) {
|
|
513
|
-
const [area, setArea] =
|
|
515
|
+
const [area, setArea] = React4.useState({
|
|
514
516
|
element: null,
|
|
515
517
|
width: 0
|
|
516
518
|
});
|
|
517
|
-
|
|
519
|
+
React4.useLayoutEffect(() => {
|
|
518
520
|
const element = anchor.current?.closest(".docx-editor__scroll-container") ?? null;
|
|
519
521
|
const measure = () => setArea(
|
|
520
522
|
(previous) => previous.element === element && previous.width === (element?.clientWidth ?? 0) ? previous : { element, width: element?.clientWidth ?? 0 }
|
|
@@ -531,26 +533,26 @@ function DocxEditorReviewRail({
|
|
|
531
533
|
children
|
|
532
534
|
}) {
|
|
533
535
|
const editor = react.useDocxEditor();
|
|
534
|
-
const registry =
|
|
536
|
+
const registry = React4.useContext(react.ReviewRailContext);
|
|
535
537
|
const review = useReview();
|
|
536
|
-
const [draft, setDraft] =
|
|
537
|
-
const [tops, setTops] =
|
|
538
|
-
const [showResolved, setShowResolved] =
|
|
539
|
-
const elements =
|
|
540
|
-
const anchor =
|
|
541
|
-
const toolbar =
|
|
538
|
+
const [draft, setDraft] = React4.useState(null);
|
|
539
|
+
const [tops, setTops] = React4.useState({});
|
|
540
|
+
const [showResolved, setShowResolved] = React4.useState(true);
|
|
541
|
+
const elements = React4.useRef(/* @__PURE__ */ new Map());
|
|
542
|
+
const anchor = React4.useRef(null);
|
|
543
|
+
const toolbar = React4.useRef(null);
|
|
542
544
|
const area = useScrollArea(anchor, review.ready);
|
|
543
545
|
const layout = area.width === 0 || area.width >= REVIEW_MARGIN_MIN_WIDTH ? "margin" : "compact";
|
|
544
|
-
const openDraft =
|
|
546
|
+
const openDraft = React4.useCallback(() => {
|
|
545
547
|
const placement = editor?.getSelectionPlacement();
|
|
546
548
|
if (!placement) return;
|
|
547
549
|
review.setPaneOpen(true);
|
|
548
550
|
setDraft({ anchorY: placement.anchorY });
|
|
549
551
|
}, [editor, review.setPaneOpen]);
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const shownLayout =
|
|
553
|
-
|
|
552
|
+
React4.useEffect(() => registry?.register(), [registry]);
|
|
553
|
+
React4.useEffect(() => registry?.registerCommentDraft(openDraft), [registry, openDraft]);
|
|
554
|
+
const shownLayout = React4.useRef(null);
|
|
555
|
+
React4.useEffect(() => {
|
|
554
556
|
if (!review.ready || area.width === 0 || shownLayout.current === layout) return;
|
|
555
557
|
editor?.setReviewPaneOptions({ opening: layout === "margin" ? "auto" : "manual" });
|
|
556
558
|
const deepLinked = shownLayout.current === null && review.activeKey !== null;
|
|
@@ -566,7 +568,7 @@ function DocxEditorReviewRail({
|
|
|
566
568
|
const changes = review.items.filter((entry) => entry.kind === "revision").length;
|
|
567
569
|
const comments = top.filter((entry) => entry.kind === "comment").length;
|
|
568
570
|
const hasResolved = review.items.some((entry) => entry.kind === "comment" && entry.resolved);
|
|
569
|
-
const repliesOf =
|
|
571
|
+
const repliesOf = React4.useCallback(
|
|
570
572
|
(entry) => review.items.filter(
|
|
571
573
|
(other) => other.kind === "comment" && (other.parentId === entry.id || other.parentRevisionId === entry.id)
|
|
572
574
|
),
|
|
@@ -574,19 +576,19 @@ function DocxEditorReviewRail({
|
|
|
574
576
|
);
|
|
575
577
|
const column = layout === "margin" && review.paneOpen && (top.length > 0 || draft !== null);
|
|
576
578
|
const bubbleOpen = layout === "compact" && (review.paneOpen || draft !== null);
|
|
577
|
-
|
|
579
|
+
React4.useEffect(() => {
|
|
578
580
|
const element = area.element;
|
|
579
581
|
if (!element) return;
|
|
580
582
|
if (column) element.setAttribute("data-review-margin", "");
|
|
581
583
|
else element.removeAttribute("data-review-margin");
|
|
582
584
|
return () => element.removeAttribute("data-review-margin");
|
|
583
585
|
}, [area.element, column]);
|
|
584
|
-
const dismiss =
|
|
586
|
+
const dismiss = React4.useCallback(() => {
|
|
585
587
|
setDraft(null);
|
|
586
588
|
if (layout === "compact") review.setPaneOpen(false);
|
|
587
589
|
else review.setActive(null);
|
|
588
590
|
}, [layout, review.setPaneOpen, review.setActive]);
|
|
589
|
-
|
|
591
|
+
React4.useEffect(() => {
|
|
590
592
|
const element = area.element;
|
|
591
593
|
if (!element || !bubbleOpen) return;
|
|
592
594
|
const close = (event) => {
|
|
@@ -611,7 +613,7 @@ function DocxEditorReviewRail({
|
|
|
611
613
|
document2.removeEventListener("keydown", escape);
|
|
612
614
|
};
|
|
613
615
|
}, [area.element, bubbleOpen, dismiss]);
|
|
614
|
-
|
|
616
|
+
React4.useLayoutEffect(() => {
|
|
615
617
|
if (!column) return;
|
|
616
618
|
const next = {};
|
|
617
619
|
let floor = (toolbar.current?.offsetHeight ?? 0) + CARD_GAP;
|
|
@@ -910,18 +912,18 @@ function mentionCandidates(mentions) {
|
|
|
910
912
|
function mentionedDocxRecipients(text, mentions) {
|
|
911
913
|
return chunk7UTB4PHM_cjs.extractMentions(text, mentionCandidates(mentions)).map((person) => person.id);
|
|
912
914
|
}
|
|
913
|
-
var ActivityContext =
|
|
915
|
+
var ActivityContext = React4.createContext({});
|
|
914
916
|
function DocxCommentActivity() {
|
|
915
917
|
const item = useReviewItem();
|
|
916
918
|
const review = useReview();
|
|
917
|
-
const activity =
|
|
918
|
-
const [reading, setReading] =
|
|
919
|
+
const activity = React4.useContext(ActivityContext);
|
|
920
|
+
const [reading, setReading] = React4.useState(false);
|
|
919
921
|
if (!item || item.kind !== "comment") return null;
|
|
920
922
|
const commentId = item.parentId || item.item.id;
|
|
921
923
|
const thread = review.items.filter(
|
|
922
924
|
(entry) => entry.kind === "comment" && (entry.item.id === commentId || entry.parentId === commentId)
|
|
923
925
|
);
|
|
924
|
-
const statuses = Object.entries(activity).filter(([,
|
|
926
|
+
const statuses = Object.entries(activity).filter(([, run2]) => run2.commentId === commentId);
|
|
925
927
|
const labels = {
|
|
926
928
|
delivering: "Delivering mention\u2026",
|
|
927
929
|
queued: "Queued\u2026",
|
|
@@ -933,18 +935,18 @@ function DocxCommentActivity() {
|
|
|
933
935
|
unknown: "Status unavailable"
|
|
934
936
|
};
|
|
935
937
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "native-docx-comment-extra", "data-review-selectable": "", children: [
|
|
936
|
-
statuses.map(([id,
|
|
938
|
+
statuses.map(([id, run2]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
937
939
|
"div",
|
|
938
940
|
{
|
|
939
941
|
role: "status",
|
|
940
942
|
"data-testid": "docx-comment-agent-status",
|
|
941
|
-
"data-status":
|
|
943
|
+
"data-status": run2.status,
|
|
942
944
|
className: "native-docx-comment-activity",
|
|
943
945
|
children: [
|
|
944
|
-
["delivering", "queued", "in_progress"].includes(
|
|
945
|
-
|
|
946
|
+
["delivering", "queued", "in_progress"].includes(run2.status) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-agent-spinner", "aria-hidden": "true" }),
|
|
947
|
+
run2.label,
|
|
946
948
|
": ",
|
|
947
|
-
labels[
|
|
949
|
+
labels[run2.status]
|
|
948
950
|
]
|
|
949
951
|
},
|
|
950
952
|
id
|
|
@@ -972,10 +974,10 @@ function DocxCommentActivity() {
|
|
|
972
974
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: entry.author || "Reviewer" }),
|
|
973
975
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "docx-full-comment-text", children: /* @__PURE__ */ jsxRuntime.jsx(ui.AiMarkdown, { allowHtml: false, children: commentText(entry) }) })
|
|
974
976
|
] }, entry.key)),
|
|
975
|
-
statuses.map(([id,
|
|
976
|
-
|
|
977
|
+
statuses.map(([id, run2]) => /* @__PURE__ */ jsxRuntime.jsxs("p", { role: "status", className: "text-sm", children: [
|
|
978
|
+
run2.label,
|
|
977
979
|
": ",
|
|
978
|
-
labels[
|
|
980
|
+
labels[run2.status]
|
|
979
981
|
] }, id))
|
|
980
982
|
]
|
|
981
983
|
}
|
|
@@ -991,10 +993,10 @@ function DocxMentions({
|
|
|
991
993
|
notify
|
|
992
994
|
}) {
|
|
993
995
|
const review = useReview();
|
|
994
|
-
const [activity, setActivity] =
|
|
995
|
-
const root =
|
|
996
|
-
const [composers, setComposers] =
|
|
997
|
-
|
|
996
|
+
const [activity, setActivity] = React4.useState({});
|
|
997
|
+
const root = React4.useRef(null);
|
|
998
|
+
const [composers, setComposers] = React4.useState([]);
|
|
999
|
+
React4.useEffect(() => {
|
|
998
1000
|
const element = root.current;
|
|
999
1001
|
if (!element || !requestAgent) return;
|
|
1000
1002
|
const discover = () => {
|
|
@@ -1020,15 +1022,15 @@ function DocxMentions({
|
|
|
1020
1022
|
field.setSelectionRange(value.length, value.length);
|
|
1021
1023
|
setSuggestions(null);
|
|
1022
1024
|
};
|
|
1023
|
-
const alive =
|
|
1024
|
-
|
|
1025
|
+
const alive = React4.useRef(true);
|
|
1026
|
+
React4.useEffect(() => {
|
|
1025
1027
|
alive.current = true;
|
|
1026
1028
|
return () => {
|
|
1027
1029
|
alive.current = false;
|
|
1028
1030
|
};
|
|
1029
1031
|
}, []);
|
|
1030
|
-
const activated =
|
|
1031
|
-
|
|
1032
|
+
const activated = React4.useRef(void 0);
|
|
1033
|
+
React4.useEffect(() => {
|
|
1032
1034
|
if (!initialCommentId || activated.current === initialCommentId || !review.ready) return;
|
|
1033
1035
|
const target = review.items.find(
|
|
1034
1036
|
(item) => item.kind === "comment" && item.item.id === initialCommentId
|
|
@@ -1037,16 +1039,16 @@ function DocxMentions({
|
|
|
1037
1039
|
review.setPaneOpen(true);
|
|
1038
1040
|
if (review.setActive(target.key)) activated.current = initialCommentId;
|
|
1039
1041
|
}, [initialCommentId, review]);
|
|
1040
|
-
const input =
|
|
1041
|
-
const replyTarget =
|
|
1042
|
-
const pending =
|
|
1043
|
-
const [suggestions, setSuggestions] =
|
|
1044
|
-
const [selected, setSelected] =
|
|
1042
|
+
const input = React4.useRef(null);
|
|
1043
|
+
const replyTarget = React4.useRef(null);
|
|
1044
|
+
const pending = React4.useRef(null);
|
|
1045
|
+
const [suggestions, setSuggestions] = React4.useState(null);
|
|
1046
|
+
const [selected, setSelected] = React4.useState(0);
|
|
1045
1047
|
const candidates = chunk7UTB4PHM_cjs.filterMentionCandidates(
|
|
1046
1048
|
mentionCandidates(mentions),
|
|
1047
1049
|
suggestions?.query || ""
|
|
1048
1050
|
).slice(0, 8);
|
|
1049
|
-
|
|
1051
|
+
React4.useEffect(() => {
|
|
1050
1052
|
const submission = pending.current;
|
|
1051
1053
|
if (!submission || !requestAgent) return;
|
|
1052
1054
|
const created = review.items.find(
|
|
@@ -1287,26 +1289,36 @@ function DocxMentions({
|
|
|
1287
1289
|
) });
|
|
1288
1290
|
}
|
|
1289
1291
|
var DEFINED_TERM_STYLE = "DefinedTerm";
|
|
1290
|
-
var
|
|
1292
|
+
var CROSS_REFERENCE_STYLE = "CrossReference";
|
|
1293
|
+
var BROKEN_CROSS_REFERENCE_STYLE = "CrossReferenceBroken";
|
|
1294
|
+
var CHARACTER_STYLES = {
|
|
1295
|
+
[DEFINED_TERM_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${DEFINED_TERM_STYLE}"><w:name w:val="Defined Term"/><w:rPr><w:u w:val="dotted" w:color="7F7F7F"/></w:rPr></w:style>`,
|
|
1296
|
+
[CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference"/><w:rPr><w:color w:val="1F4E79"/><w:u w:val="dotted" w:color="8EA9C1"/></w:rPr></w:style>`,
|
|
1297
|
+
[BROKEN_CROSS_REFERENCE_STYLE]: `<w:style w:type="character" w:customStyle="1" w:styleId="${BROKEN_CROSS_REFERENCE_STYLE}"><w:name w:val="Cross Reference Broken"/><w:basedOn w:val="${CROSS_REFERENCE_STYLE}"/><w:rPr><w:color w:val="C00000"/><w:u w:val="wave" w:color="C00000"/></w:rPr></w:style>`
|
|
1298
|
+
};
|
|
1299
|
+
function stylesUsed(body) {
|
|
1300
|
+
return [...new Set([...body.matchAll(/<w:rStyle w:val="([^"]+)"/g)].map((m) => m[1]))];
|
|
1301
|
+
}
|
|
1302
|
+
var fragmentStyles = (ids) => chunk2A4MDHJR_cjs.stylesXml(
|
|
1291
1303
|
"",
|
|
1292
|
-
`<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style
|
|
1304
|
+
`<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style>${ids.map((id) => CHARACTER_STYLES[id] ?? "").join("")}`
|
|
1293
1305
|
);
|
|
1294
|
-
var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${
|
|
1306
|
+
var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(text)}</w:t></w:r>`;
|
|
1295
1307
|
function definitionTooltip(definition) {
|
|
1296
1308
|
const line = `\u201C${definition.term}\u201D${definition.rest}`.replace(/\s+/g, " ").trim();
|
|
1297
1309
|
return line.length > 255 ? `${line.slice(0, 254)}\u2026` : line;
|
|
1298
1310
|
}
|
|
1299
1311
|
function definitionParagraphXml(definition, bookmark, id = 0) {
|
|
1300
|
-
return `<w:p><w:bookmarkStart w:id="${id}" w:name="${
|
|
1312
|
+
return `<w:p><w:bookmarkStart w:id="${id}" w:name="${chunk2A4MDHJR_cjs.esc(bookmark)}"/>${textRun("\u201C")}${textRun(
|
|
1301
1313
|
definition.term,
|
|
1302
1314
|
"<w:b/>"
|
|
1303
1315
|
)}${textRun("\u201D")}<w:bookmarkEnd w:id="${id}"/>${textRun(definition.rest)}</w:p>`;
|
|
1304
1316
|
}
|
|
1305
1317
|
function headingParagraphXml(text, styleId) {
|
|
1306
|
-
return styleId ? `<w:p><w:pPr><w:pStyle w:val="${
|
|
1318
|
+
return styleId ? `<w:p><w:pPr><w:pStyle w:val="${chunk2A4MDHJR_cjs.esc(styleId)}"/></w:pPr>${textRun(text)}</w:p>` : `<w:p><w:pPr><w:keepNext/></w:pPr>${textRun(text, "<w:b/>")}</w:p>`;
|
|
1307
1319
|
}
|
|
1308
1320
|
function termLinkXml(term, bookmark, tooltip) {
|
|
1309
|
-
return `<w:p><w:hyperlink w:anchor="${
|
|
1321
|
+
return `<w:p><w:hyperlink w:anchor="${chunk2A4MDHJR_cjs.esc(bookmark)}" w:tooltip="${chunk2A4MDHJR_cjs.esc(tooltip)}" w:history="1">${textRun(
|
|
1310
1322
|
term,
|
|
1311
1323
|
`<w:rStyle w:val="${DEFINED_TERM_STYLE}"/>`
|
|
1312
1324
|
)}</w:hyperlink></w:p>`;
|
|
@@ -1317,11 +1329,16 @@ function base64(bytes) {
|
|
|
1317
1329
|
binary += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
1318
1330
|
return btoa(binary);
|
|
1319
1331
|
}
|
|
1320
|
-
function fragmentHtml(body, covered2,
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1332
|
+
function fragmentHtml(body, covered2, {
|
|
1333
|
+
revision,
|
|
1334
|
+
relationships,
|
|
1335
|
+
styles = stylesUsed(body)
|
|
1336
|
+
} = {}) {
|
|
1337
|
+
const untracked = chunk2A4MDHJR_cjs.docxPackage({
|
|
1338
|
+
document: chunk2A4MDHJR_cjs.documentXml(body),
|
|
1339
|
+
styles: fragmentStyles(styles),
|
|
1340
|
+
title: "Defined terms",
|
|
1341
|
+
relationships
|
|
1325
1342
|
});
|
|
1326
1343
|
const bytes = revision ? template.trackInsertion(untracked, revision, covered2) : untracked;
|
|
1327
1344
|
return `<div data-docx-fragment="${base64(bytes)}" data-docx-fragment-end="${covered2 ? "covered" : "open"}"></div>`;
|
|
@@ -1343,14 +1360,14 @@ function findDefinitionsSection(paragraphs) {
|
|
|
1343
1360
|
while (end < paragraphs.length && paragraphs[end].topLevel && !paragraphs[end].heading) end++;
|
|
1344
1361
|
return { title, start: title + 1, end };
|
|
1345
1362
|
}
|
|
1346
|
-
var termOf = (paragraph) =>
|
|
1363
|
+
var termOf = (paragraph) => chunk2A4MDHJR_cjs.parseDefinition(paragraph.text)?.term ?? null;
|
|
1347
1364
|
function insertionIndex(paragraphs, section, term, skip = /* @__PURE__ */ new Set()) {
|
|
1348
1365
|
let afterLast = section.start;
|
|
1349
1366
|
for (let i = section.start; i < section.end; i++) {
|
|
1350
1367
|
if (skip.has(paragraphs[i].id)) continue;
|
|
1351
1368
|
const other = termOf(paragraphs[i]);
|
|
1352
1369
|
if (other === null) continue;
|
|
1353
|
-
if (
|
|
1370
|
+
if (chunk2A4MDHJR_cjs.compareTerms(other, term) > 0) return i;
|
|
1354
1371
|
afterLast = i + 1;
|
|
1355
1372
|
}
|
|
1356
1373
|
return afterLast;
|
|
@@ -1377,7 +1394,7 @@ function insertParagraphs(port, index, body, count, keep) {
|
|
|
1377
1394
|
function addDefinition(port, definition, keep) {
|
|
1378
1395
|
const paragraphs = port.paragraphs();
|
|
1379
1396
|
const section = findDefinitionsSection(paragraphs);
|
|
1380
|
-
const paragraph = definitionParagraphXml(definition,
|
|
1397
|
+
const paragraph = definitionParagraphXml(definition, chunk2A4MDHJR_cjs.definitionBookmark(definition.id));
|
|
1381
1398
|
if (section)
|
|
1382
1399
|
return insertParagraphs(
|
|
1383
1400
|
port,
|
|
@@ -1403,7 +1420,7 @@ function insertDefinedTerm(port, definition, options = {}) {
|
|
|
1403
1420
|
caret = { paragraphId: start.paragraphId, offset: Math.max(0, start.offset - options.replace) };
|
|
1404
1421
|
port.deleteRange(caret, start);
|
|
1405
1422
|
}
|
|
1406
|
-
const bookmark =
|
|
1423
|
+
const bookmark = chunk2A4MDHJR_cjs.definitionBookmark(definition.id);
|
|
1407
1424
|
const addedDefinition = !hasBookmark(port.paragraphs(), bookmark);
|
|
1408
1425
|
if (addedDefinition) caret = addDefinition(port, definition, caret) ?? caret;
|
|
1409
1426
|
port.setCaret(caret);
|
|
@@ -1417,12 +1434,96 @@ function insertDefinedTerm(port, definition, options = {}) {
|
|
|
1417
1434
|
return { addedDefinition };
|
|
1418
1435
|
}
|
|
1419
1436
|
function definitionOfAnchor(anchor, definitions) {
|
|
1420
|
-
const id =
|
|
1437
|
+
const id = chunk2A4MDHJR_cjs.definitionIdOfBookmark(anchor.replace(/^#/, ""));
|
|
1421
1438
|
return id ? definitions.get(id) : void 0;
|
|
1422
1439
|
}
|
|
1440
|
+
function LinkHoverCard({
|
|
1441
|
+
root,
|
|
1442
|
+
matches,
|
|
1443
|
+
resolve,
|
|
1444
|
+
onFirstHover,
|
|
1445
|
+
testId
|
|
1446
|
+
}) {
|
|
1447
|
+
const [card, setCard] = React4.useState(null);
|
|
1448
|
+
const hovered = React4.useRef(false);
|
|
1449
|
+
const latest = React4.useRef({ matches, onFirstHover });
|
|
1450
|
+
latest.current = { matches, onFirstHover };
|
|
1451
|
+
React4.useEffect(() => {
|
|
1452
|
+
if (!root) return;
|
|
1453
|
+
const over = (event) => {
|
|
1454
|
+
const link = event.target?.closest?.(
|
|
1455
|
+
"a.docx-hyperlink"
|
|
1456
|
+
);
|
|
1457
|
+
const href = link?.getAttribute("href") ?? "";
|
|
1458
|
+
if (!link || !href || !latest.current.matches(href, link)) return;
|
|
1459
|
+
if (!hovered.current) {
|
|
1460
|
+
hovered.current = true;
|
|
1461
|
+
latest.current.onFirstHover?.();
|
|
1462
|
+
}
|
|
1463
|
+
const title = link.getAttribute("title");
|
|
1464
|
+
if (title) {
|
|
1465
|
+
link.dataset.hoverTitle = title;
|
|
1466
|
+
link.removeAttribute("title");
|
|
1467
|
+
}
|
|
1468
|
+
const rect = link.getBoundingClientRect();
|
|
1469
|
+
setCard({
|
|
1470
|
+
left: rect.left,
|
|
1471
|
+
top: rect.bottom + 6,
|
|
1472
|
+
href,
|
|
1473
|
+
fallback: link.dataset.hoverTitle ?? ""
|
|
1474
|
+
});
|
|
1475
|
+
};
|
|
1476
|
+
const out = (event) => {
|
|
1477
|
+
const link = event.target?.closest?.("a.docx-hyperlink");
|
|
1478
|
+
if (link && !link.contains(event.relatedTarget)) setCard(null);
|
|
1479
|
+
};
|
|
1480
|
+
const hide = () => setCard(null);
|
|
1481
|
+
root.addEventListener("mouseover", over);
|
|
1482
|
+
root.addEventListener("mouseout", out);
|
|
1483
|
+
window.addEventListener("keydown", hide, true);
|
|
1484
|
+
window.addEventListener("pointerdown", hide, true);
|
|
1485
|
+
window.addEventListener("scroll", hide, true);
|
|
1486
|
+
return () => {
|
|
1487
|
+
root.removeEventListener("mouseover", over);
|
|
1488
|
+
root.removeEventListener("mouseout", out);
|
|
1489
|
+
window.removeEventListener("keydown", hide, true);
|
|
1490
|
+
window.removeEventListener("pointerdown", hide, true);
|
|
1491
|
+
window.removeEventListener("scroll", hide, true);
|
|
1492
|
+
};
|
|
1493
|
+
}, [root]);
|
|
1494
|
+
if (!card) return null;
|
|
1495
|
+
const content = resolve(card.href);
|
|
1496
|
+
if (!content && !card.fallback) return null;
|
|
1497
|
+
return reactDom.createPortal(
|
|
1498
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1499
|
+
"div",
|
|
1500
|
+
{
|
|
1501
|
+
role: "tooltip",
|
|
1502
|
+
className: "native-docx-link-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
|
|
1503
|
+
style: {
|
|
1504
|
+
position: "fixed",
|
|
1505
|
+
left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
|
|
1506
|
+
top: card.top,
|
|
1507
|
+
width: 340,
|
|
1508
|
+
zIndex: 1e3,
|
|
1509
|
+
pointerEvents: "none"
|
|
1510
|
+
},
|
|
1511
|
+
"data-testid": testId,
|
|
1512
|
+
children: content ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1513
|
+
content.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: content.title }),
|
|
1514
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: content.title ? "mt-1 text-muted-foreground" : void 0, children: content.body }),
|
|
1515
|
+
content.footer && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: content.footer })
|
|
1516
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: card.fallback })
|
|
1517
|
+
}
|
|
1518
|
+
),
|
|
1519
|
+
document.body
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1423
1522
|
|
|
1424
1523
|
// src/docx/definitions/port.ts
|
|
1524
|
+
var WATCHED_STYLES = /* @__PURE__ */ new Set([BROKEN_CROSS_REFERENCE_STYLE]);
|
|
1425
1525
|
var attr = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
|
|
1526
|
+
var FIELD_ATOM = "\uFFFC";
|
|
1426
1527
|
var HEADING_STYLE = /^(heading|berschrift|titre|t[ií]tulo|titolo|kop)\s*\d/i;
|
|
1427
1528
|
function readParagraphs(root) {
|
|
1428
1529
|
const out = [];
|
|
@@ -1449,8 +1550,44 @@ function readParagraph(node, topLevel, bookmarks) {
|
|
|
1449
1550
|
const links = [];
|
|
1450
1551
|
let styleId;
|
|
1451
1552
|
let outline = false;
|
|
1553
|
+
let fieldDepth = 0;
|
|
1554
|
+
const marks = [];
|
|
1555
|
+
let runStyle;
|
|
1556
|
+
const fields = [];
|
|
1557
|
+
let current = null;
|
|
1558
|
+
const field = (c) => {
|
|
1559
|
+
const type = attr(c, "fldCharType");
|
|
1560
|
+
if (type === "begin") {
|
|
1561
|
+
if (fieldDepth === 0) {
|
|
1562
|
+
current = { offset: text.length, instruction: "", result: "", inResult: false };
|
|
1563
|
+
text += FIELD_ATOM;
|
|
1564
|
+
}
|
|
1565
|
+
fieldDepth++;
|
|
1566
|
+
} else if (type === "separate" && fieldDepth === 1 && current) current.inResult = true;
|
|
1567
|
+
else if (type === "end") {
|
|
1568
|
+
fieldDepth = Math.max(0, fieldDepth - 1);
|
|
1569
|
+
if (fieldDepth === 0 && current) {
|
|
1570
|
+
const { offset, instruction, result } = current;
|
|
1571
|
+
fields.push({ offset, instruction: instruction.trim(), result });
|
|
1572
|
+
current = null;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1452
1576
|
const walk = (n, link) => {
|
|
1453
1577
|
for (const c of n.children ?? []) {
|
|
1578
|
+
if (c.localName === "fldChar") {
|
|
1579
|
+
field(c);
|
|
1580
|
+
continue;
|
|
1581
|
+
}
|
|
1582
|
+
if (c.localName === "fldSimple") {
|
|
1583
|
+
if (fieldDepth === 0) text += FIELD_ATOM;
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
if (c.localName === "instrText") {
|
|
1587
|
+
if (fieldDepth === 1 && current)
|
|
1588
|
+
current.instruction += (c.children ?? []).map((t) => t.value ?? "").join("");
|
|
1589
|
+
continue;
|
|
1590
|
+
}
|
|
1454
1591
|
if (c.kind === "paragraphProperties" || c.localName === "pPr") {
|
|
1455
1592
|
for (const p of c.children ?? []) {
|
|
1456
1593
|
if (p.localName === "pStyle") styleId = attr(p, "val");
|
|
@@ -1459,6 +1596,14 @@ function readParagraph(node, topLevel, bookmarks) {
|
|
|
1459
1596
|
continue;
|
|
1460
1597
|
}
|
|
1461
1598
|
if (c.localName === "delText" || c.localName === "del" || c.localName === "rPr") continue;
|
|
1599
|
+
if (c.localName === "r") {
|
|
1600
|
+
const rStyle = c.children?.find((x) => x.localName === "rPr")?.children?.find((x) => x.localName === "rStyle");
|
|
1601
|
+
const watched = rStyle && attr(rStyle, "val");
|
|
1602
|
+
runStyle = watched && WATCHED_STYLES.has(watched) ? watched : void 0;
|
|
1603
|
+
walk(c, link);
|
|
1604
|
+
runStyle = void 0;
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1462
1607
|
if (c.localName === "bookmarkStart") {
|
|
1463
1608
|
const name = attr(c, "name");
|
|
1464
1609
|
if (name) bookmarks.push(name);
|
|
@@ -1472,11 +1617,22 @@ function readParagraph(node, topLevel, bookmarks) {
|
|
|
1472
1617
|
continue;
|
|
1473
1618
|
}
|
|
1474
1619
|
if (c.kind === "textValue") {
|
|
1620
|
+
if (fieldDepth > 0) {
|
|
1621
|
+
const open = current;
|
|
1622
|
+
if (fieldDepth === 1 && open?.inResult) open.result += c.value ?? "";
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
if (runStyle && c.value) {
|
|
1626
|
+
const last = marks[marks.length - 1];
|
|
1627
|
+
if (last && last.styleId === runStyle && last.offset + last.text.length === text.length)
|
|
1628
|
+
last.text += c.value;
|
|
1629
|
+
else marks.push({ styleId: runStyle, offset: text.length, text: c.value });
|
|
1630
|
+
}
|
|
1475
1631
|
text += c.value ?? "";
|
|
1476
1632
|
if (link) link.text += c.value ?? "";
|
|
1477
1633
|
continue;
|
|
1478
1634
|
}
|
|
1479
|
-
if (c.localName === "tab") text += " ";
|
|
1635
|
+
if (c.localName === "tab" && fieldDepth === 0) text += " ";
|
|
1480
1636
|
walk(c, link);
|
|
1481
1637
|
}
|
|
1482
1638
|
};
|
|
@@ -1488,9 +1644,20 @@ function readParagraph(node, topLevel, bookmarks) {
|
|
|
1488
1644
|
styleId,
|
|
1489
1645
|
topLevel,
|
|
1490
1646
|
bookmarks,
|
|
1491
|
-
links
|
|
1647
|
+
links,
|
|
1648
|
+
...fields.length ? { fields } : {},
|
|
1649
|
+
...marks.length ? { marks } : {}
|
|
1492
1650
|
};
|
|
1493
1651
|
}
|
|
1652
|
+
function documentStyleIds(root) {
|
|
1653
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1654
|
+
for (const style of root?.children ?? [])
|
|
1655
|
+
if (style.localName === "style") {
|
|
1656
|
+
const id = attr(style, "styleId");
|
|
1657
|
+
if (id) ids.add(id);
|
|
1658
|
+
}
|
|
1659
|
+
return ids;
|
|
1660
|
+
}
|
|
1494
1661
|
function editorPort(editor, revision) {
|
|
1495
1662
|
const surface = () => {
|
|
1496
1663
|
const s = editor.surface;
|
|
@@ -1510,8 +1677,17 @@ function editorPort(editor, revision) {
|
|
|
1510
1677
|
surface().setSelection({ anchor: from, head: to });
|
|
1511
1678
|
surface().deleteSelection();
|
|
1512
1679
|
},
|
|
1513
|
-
paste: (body, text, covered2) =>
|
|
1514
|
-
|
|
1680
|
+
paste: (body, text, covered2, relationships) => {
|
|
1681
|
+
const defined = documentStyleIds(surface().session.stylesRoot());
|
|
1682
|
+
const styles = stylesUsed(body).filter((id) => !defined.has(id));
|
|
1683
|
+
return editor.exec({
|
|
1684
|
+
type: "paste",
|
|
1685
|
+
text,
|
|
1686
|
+
html: fragmentHtml(body, covered2, { revision, relationships, styles })
|
|
1687
|
+
}).ok;
|
|
1688
|
+
},
|
|
1689
|
+
splitParagraph: () => surface().splitParagraph(),
|
|
1690
|
+
typeText: (text) => surface().insertPlainText(text)
|
|
1515
1691
|
};
|
|
1516
1692
|
}
|
|
1517
1693
|
function withDirectEditing(editor, fn) {
|
|
@@ -1524,34 +1700,68 @@ function withDirectEditing(editor, fn) {
|
|
|
1524
1700
|
if (mode === "suggesting") editor.setEditingMode("suggesting");
|
|
1525
1701
|
}
|
|
1526
1702
|
}
|
|
1527
|
-
function holdCaret(editor,
|
|
1703
|
+
function holdCaret(editor, { settleMs = 600, maxMs = 2e3 } = {}) {
|
|
1528
1704
|
const surface = editor.surface;
|
|
1529
1705
|
const selection = surface?.state().selection;
|
|
1530
1706
|
if (!surface || !selection) return;
|
|
1531
|
-
const {
|
|
1532
|
-
const paraId = surface.session.paraIdOf(paragraphId);
|
|
1707
|
+
const { offset } = selection.head;
|
|
1708
|
+
const paraId = surface.session.paraIdOf(selection.head.paragraphId);
|
|
1533
1709
|
if (!paraId) return;
|
|
1710
|
+
let typed = "";
|
|
1534
1711
|
let done = false;
|
|
1712
|
+
let settle;
|
|
1535
1713
|
const stop = () => {
|
|
1536
1714
|
done = true;
|
|
1537
1715
|
offChange();
|
|
1538
|
-
|
|
1539
|
-
clearTimeout(
|
|
1716
|
+
clearTimeout(settle);
|
|
1717
|
+
clearTimeout(limit);
|
|
1718
|
+
window.removeEventListener("keydown", key, true);
|
|
1719
|
+
window.removeEventListener("pointerdown", click, true);
|
|
1540
1720
|
};
|
|
1541
|
-
const
|
|
1721
|
+
const finish = () => {
|
|
1542
1722
|
if (done) return;
|
|
1543
|
-
const now = surface.state().selection;
|
|
1544
|
-
const node = surface.session.nodeIdOf(paraId);
|
|
1545
|
-
if (!now || !node) return;
|
|
1546
|
-
if (now.head.offset !== offset || now.head.paragraphId !== paragraphId) return stop();
|
|
1547
|
-
if (node === paragraphId) return;
|
|
1548
1723
|
stop();
|
|
1724
|
+
const node = surface.session.nodeIdOf(paraId);
|
|
1725
|
+
if (!node) return;
|
|
1549
1726
|
const point = { paragraphId: node, offset };
|
|
1550
1727
|
surface.setSelection({ anchor: point, head: point });
|
|
1728
|
+
if (typed) surface.insertPlainText(typed);
|
|
1551
1729
|
};
|
|
1552
|
-
const
|
|
1553
|
-
|
|
1554
|
-
|
|
1730
|
+
const key = (event) => {
|
|
1731
|
+
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
1732
|
+
event.preventDefault();
|
|
1733
|
+
event.stopPropagation();
|
|
1734
|
+
typed += event.key;
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
finish();
|
|
1738
|
+
};
|
|
1739
|
+
const click = () => {
|
|
1740
|
+
if (typed) finish();
|
|
1741
|
+
else stop();
|
|
1742
|
+
};
|
|
1743
|
+
const quiet = () => {
|
|
1744
|
+
clearTimeout(settle);
|
|
1745
|
+
settle = setTimeout(finish, settleMs);
|
|
1746
|
+
};
|
|
1747
|
+
const offChange = editor.on("change", quiet);
|
|
1748
|
+
window.addEventListener("keydown", key, true);
|
|
1749
|
+
window.addEventListener("pointerdown", click, true);
|
|
1750
|
+
settle = setTimeout(finish, settleMs);
|
|
1751
|
+
const limit = setTimeout(finish, maxMs);
|
|
1752
|
+
}
|
|
1753
|
+
function preservingCaret(editor, fn) {
|
|
1754
|
+
const surface = editor.surface;
|
|
1755
|
+
const before = surface?.state().selection?.head;
|
|
1756
|
+
const paraId = before && surface?.session.paraIdOf(before.paragraphId);
|
|
1757
|
+
const result = fn();
|
|
1758
|
+
const node = paraId && surface?.session.nodeIdOf(paraId);
|
|
1759
|
+
if (before && node) {
|
|
1760
|
+
const point = { paragraphId: node, offset: before.offset };
|
|
1761
|
+
surface.setSelection({ anchor: point, head: point });
|
|
1762
|
+
holdCaret(editor);
|
|
1763
|
+
}
|
|
1764
|
+
return result;
|
|
1555
1765
|
}
|
|
1556
1766
|
|
|
1557
1767
|
// src/docx/structural/trackedOrNoted.ts
|
|
@@ -1608,11 +1818,11 @@ function structuralPort(editor) {
|
|
|
1608
1818
|
}
|
|
1609
1819
|
};
|
|
1610
1820
|
}
|
|
1611
|
-
var DocxAuthorContext =
|
|
1821
|
+
var DocxAuthorContext = React4.createContext("You");
|
|
1612
1822
|
function useTrackedOrNoted() {
|
|
1613
1823
|
const editor = react.useDocxEditor();
|
|
1614
|
-
const author =
|
|
1615
|
-
return
|
|
1824
|
+
const author = React4.useContext(DocxAuthorContext);
|
|
1825
|
+
return React4.useCallback(
|
|
1616
1826
|
(spec) => editor ? trackedOrNoted(structuralPort(editor), { ...spec, author }) : void 0,
|
|
1617
1827
|
[editor, author]
|
|
1618
1828
|
);
|
|
@@ -1632,8 +1842,8 @@ var DEFAULT_DEFINED_TERMS_LABELS = {
|
|
|
1632
1842
|
preferred: "Preferred",
|
|
1633
1843
|
alsoIn: (source) => `Also defined${source ? ` in ${source}` : ""}`
|
|
1634
1844
|
};
|
|
1635
|
-
var DefinedTermsContext =
|
|
1636
|
-
var useDefinedTerms = () =>
|
|
1845
|
+
var DefinedTermsContext = React4.createContext(null);
|
|
1846
|
+
var useDefinedTerms = () => React4.useContext(DefinedTermsContext);
|
|
1637
1847
|
function rowsOf(groups) {
|
|
1638
1848
|
return groups.flatMap(
|
|
1639
1849
|
(group) => group.definitions.map((definition, i) => ({ group, definition, variant: i > 0 }))
|
|
@@ -1649,16 +1859,16 @@ function DefinedTermsProvider({
|
|
|
1649
1859
|
}) {
|
|
1650
1860
|
const editor = react.useDocxEditor();
|
|
1651
1861
|
const track = useTrackedOrNoted();
|
|
1652
|
-
const l =
|
|
1653
|
-
const [sources, setSources] =
|
|
1654
|
-
const loadedAt =
|
|
1655
|
-
const loading =
|
|
1656
|
-
const [labelId, setLabelId] =
|
|
1657
|
-
const [picker, setPicker] =
|
|
1658
|
-
const [selected, setSelected] =
|
|
1659
|
-
const marker =
|
|
1660
|
-
const dismissedAt =
|
|
1661
|
-
const refresh =
|
|
1862
|
+
const l = React4.useMemo(() => ({ ...DEFAULT_DEFINED_TERMS_LABELS, ...labels }), [labels]);
|
|
1863
|
+
const [sources, setSources] = React4.useState(null);
|
|
1864
|
+
const loadedAt = React4.useRef(0);
|
|
1865
|
+
const loading = React4.useRef(null);
|
|
1866
|
+
const [labelId, setLabelId] = React4.useState(null);
|
|
1867
|
+
const [picker, setPicker] = React4.useState(null);
|
|
1868
|
+
const [selected, setSelected] = React4.useState(0);
|
|
1869
|
+
const marker = React4.useRef(null);
|
|
1870
|
+
const dismissedAt = React4.useRef(null);
|
|
1871
|
+
const refresh = React4.useCallback(
|
|
1662
1872
|
(force = false) => {
|
|
1663
1873
|
if (!load) return Promise.resolve([]);
|
|
1664
1874
|
if (!force && sources && Date.now() - loadedAt.current < STALE_AFTER_MS)
|
|
@@ -1682,29 +1892,29 @@ function DefinedTermsProvider({
|
|
|
1682
1892
|
},
|
|
1683
1893
|
[load, sources, notify]
|
|
1684
1894
|
);
|
|
1685
|
-
const all =
|
|
1686
|
-
const byId =
|
|
1895
|
+
const all = React4.useMemo(() => chunk2A4MDHJR_cjs.groupDefinitions(sources ?? []).groups, [sources]);
|
|
1896
|
+
const byId = React4.useMemo(
|
|
1687
1897
|
() => new Map(all.flatMap((g) => g.definitions).map((d) => [d.id, d])),
|
|
1688
1898
|
[all]
|
|
1689
1899
|
);
|
|
1690
|
-
const agreements =
|
|
1691
|
-
const groups =
|
|
1692
|
-
() => picker ?
|
|
1900
|
+
const agreements = React4.useMemo(() => chunk2A4MDHJR_cjs.definitionLabels(sources ?? []), [sources]);
|
|
1901
|
+
const groups = React4.useMemo(
|
|
1902
|
+
() => picker ? chunk2A4MDHJR_cjs.filterTermGroups(chunk2A4MDHJR_cjs.groupDefinitions(sources ?? [], { labelId }).groups, picker.query).slice(
|
|
1693
1903
|
0,
|
|
1694
1904
|
MAX_GROUPS
|
|
1695
1905
|
) : [],
|
|
1696
1906
|
[sources, labelId, picker]
|
|
1697
1907
|
);
|
|
1698
|
-
const rows =
|
|
1699
|
-
|
|
1908
|
+
const rows = React4.useMemo(() => rowsOf(groups), [groups]);
|
|
1909
|
+
React4.useEffect(() => setSelected(0), [picker?.query, labelId]);
|
|
1700
1910
|
const container = () => marker.current?.closest(".native-docx-viewer") ?? document.body;
|
|
1701
|
-
const [viewer, setViewer] =
|
|
1702
|
-
|
|
1703
|
-
const refreshRef =
|
|
1911
|
+
const [viewer, setViewer] = React4.useState(null);
|
|
1912
|
+
React4.useEffect(() => setViewer(container()), []);
|
|
1913
|
+
const refreshRef = React4.useRef(refresh);
|
|
1704
1914
|
refreshRef.current = refresh;
|
|
1705
|
-
const firstHover =
|
|
1915
|
+
const firstHover = React4.useCallback(() => void refreshRef.current(), []);
|
|
1706
1916
|
const caretRect = () => container().querySelector(".docx-editor-one-surface__caret")?.getBoundingClientRect();
|
|
1707
|
-
const attempt =
|
|
1917
|
+
const attempt = React4.useCallback(
|
|
1708
1918
|
(fn) => {
|
|
1709
1919
|
try {
|
|
1710
1920
|
return fn();
|
|
@@ -1715,19 +1925,26 @@ function DefinedTermsProvider({
|
|
|
1715
1925
|
},
|
|
1716
1926
|
[notify]
|
|
1717
1927
|
);
|
|
1718
|
-
const
|
|
1928
|
+
const run2 = React4.useCallback(
|
|
1719
1929
|
(fn) => editor ? attempt(() => withDirectEditing(editor, fn)) : void 0,
|
|
1720
1930
|
[editor, attempt]
|
|
1721
1931
|
);
|
|
1722
|
-
const
|
|
1932
|
+
const typedTrigger = (port) => {
|
|
1933
|
+
if (picker?.mode !== "typing") return 0;
|
|
1934
|
+
const caret = port.caret();
|
|
1935
|
+
const paragraph = caret && port.paragraphs().find((p) => p.id === caret.paragraphId);
|
|
1936
|
+
const match = paragraph && TRIGGER_QUERY.exec(paragraph.text.slice(0, caret.offset));
|
|
1937
|
+
return match ? DEFINED_TERM_TRIGGER.length + match[1].length : 0;
|
|
1938
|
+
};
|
|
1939
|
+
const pick = React4.useCallback(
|
|
1723
1940
|
(row) => {
|
|
1724
1941
|
if (!editor || !picker || !row) return;
|
|
1725
1942
|
const port = editorPort(editor);
|
|
1726
|
-
const placed =
|
|
1943
|
+
const placed = run2(() => {
|
|
1727
1944
|
if (picker.mode === "search" && picker.caret) port.setCaret(picker.caret);
|
|
1728
1945
|
const caret = port.caret();
|
|
1729
1946
|
if (!caret) throw new Error("Place the cursor where the term should go.");
|
|
1730
|
-
const typed =
|
|
1947
|
+
const typed = typedTrigger(port);
|
|
1731
1948
|
if (typed) port.deleteRange({ ...caret, offset: Math.max(0, caret.offset - typed) }, caret);
|
|
1732
1949
|
return true;
|
|
1733
1950
|
});
|
|
@@ -1743,9 +1960,9 @@ function DefinedTermsProvider({
|
|
|
1743
1960
|
if (result?.addedDefinition)
|
|
1744
1961
|
notify?.(`\u201C${row.definition.term}\u201D added to the Definitions section.`, "success");
|
|
1745
1962
|
},
|
|
1746
|
-
[editor, picker,
|
|
1963
|
+
[editor, picker, run2, attempt, track, notify]
|
|
1747
1964
|
);
|
|
1748
|
-
const openPicker =
|
|
1965
|
+
const openPicker = React4.useCallback(
|
|
1749
1966
|
(anchor) => {
|
|
1750
1967
|
if (!editor || !editable) return;
|
|
1751
1968
|
const caret = editorPort(editor).caret();
|
|
@@ -1762,7 +1979,7 @@ function DefinedTermsProvider({
|
|
|
1762
1979
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1763
1980
|
[editor, editable, refresh]
|
|
1764
1981
|
);
|
|
1765
|
-
|
|
1982
|
+
React4.useEffect(() => {
|
|
1766
1983
|
if (!editor || !editable || !load) return;
|
|
1767
1984
|
let frame = 0;
|
|
1768
1985
|
const check = () => {
|
|
@@ -1797,7 +2014,7 @@ function DefinedTermsProvider({
|
|
|
1797
2014
|
offSelection();
|
|
1798
2015
|
};
|
|
1799
2016
|
}, [editor, editable, load, refresh]);
|
|
1800
|
-
|
|
2017
|
+
React4.useEffect(() => {
|
|
1801
2018
|
if (picker?.mode !== "typing") return;
|
|
1802
2019
|
const keys = (event) => {
|
|
1803
2020
|
if (event.key === "Escape") {
|
|
@@ -1814,7 +2031,7 @@ function DefinedTermsProvider({
|
|
|
1814
2031
|
window.addEventListener("keydown", keys, true);
|
|
1815
2032
|
return () => window.removeEventListener("keydown", keys, true);
|
|
1816
2033
|
}, [picker, rows, selected, pick]);
|
|
1817
|
-
const value =
|
|
2034
|
+
const value = React4.useMemo(
|
|
1818
2035
|
() => load && editable ? { openPicker, labels: l } : null,
|
|
1819
2036
|
[load, editable, openPicker, l]
|
|
1820
2037
|
);
|
|
@@ -1822,11 +2039,16 @@ function DefinedTermsProvider({
|
|
|
1822
2039
|
/* @__PURE__ */ jsxRuntime.jsx("span", { ref: marker, hidden: true }),
|
|
1823
2040
|
children,
|
|
1824
2041
|
load && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1825
|
-
|
|
2042
|
+
LinkHoverCard,
|
|
1826
2043
|
{
|
|
1827
2044
|
root: viewer,
|
|
1828
|
-
|
|
1829
|
-
|
|
2045
|
+
matches: (href) => href.startsWith("#_dt_"),
|
|
2046
|
+
resolve: (href) => {
|
|
2047
|
+
const definition = definitionOfAnchor(href, byId);
|
|
2048
|
+
return definition ? { title: definition.term, body: definition.meaning, footer: sourceOf(definition) } : null;
|
|
2049
|
+
},
|
|
2050
|
+
onFirstHover: firstHover,
|
|
2051
|
+
testId: "docx-defined-term-card"
|
|
1830
2052
|
}
|
|
1831
2053
|
),
|
|
1832
2054
|
picker && reactDom.createPortal(
|
|
@@ -1868,17 +2090,17 @@ function DefinedTermMenu({
|
|
|
1868
2090
|
onClose,
|
|
1869
2091
|
labels: l
|
|
1870
2092
|
}) {
|
|
1871
|
-
const listboxId =
|
|
1872
|
-
const element =
|
|
2093
|
+
const listboxId = React4__default.default.useId();
|
|
2094
|
+
const element = React4.useRef(null);
|
|
1873
2095
|
const search = picker.mode === "search";
|
|
1874
|
-
|
|
2096
|
+
React4.useEffect(() => {
|
|
1875
2097
|
const dismiss = (event) => {
|
|
1876
2098
|
if (!element.current?.contains(event.target)) onClose();
|
|
1877
2099
|
};
|
|
1878
2100
|
document.addEventListener("pointerdown", dismiss);
|
|
1879
2101
|
return () => document.removeEventListener("pointerdown", dismiss);
|
|
1880
2102
|
}, [onClose]);
|
|
1881
|
-
|
|
2103
|
+
React4.useEffect(() => {
|
|
1882
2104
|
element.current?.querySelector(`[data-index="${selected}"]`)?.scrollIntoView?.({ block: "nearest" });
|
|
1883
2105
|
}, [selected]);
|
|
1884
2106
|
const left = Math.max(8, Math.min(picker.left, window.innerWidth - 368));
|
|
@@ -1979,83 +2201,6 @@ function DefinedTermMenu({
|
|
|
1979
2201
|
}
|
|
1980
2202
|
);
|
|
1981
2203
|
}
|
|
1982
|
-
function DefinedTermHover({
|
|
1983
|
-
root,
|
|
1984
|
-
resolve,
|
|
1985
|
-
onFirstHover
|
|
1986
|
-
}) {
|
|
1987
|
-
const [card, setCard] = React3.useState(null);
|
|
1988
|
-
const hovered = React3.useRef(false);
|
|
1989
|
-
React3.useEffect(() => {
|
|
1990
|
-
if (!root) return;
|
|
1991
|
-
const over = (event) => {
|
|
1992
|
-
const link = event.target?.closest?.(
|
|
1993
|
-
'a.docx-hyperlink[data-docx-link-kind="internal"]'
|
|
1994
|
-
);
|
|
1995
|
-
const href = link?.getAttribute("href") ?? "";
|
|
1996
|
-
if (!link || !href.startsWith("#_dt_")) return;
|
|
1997
|
-
if (!hovered.current) {
|
|
1998
|
-
hovered.current = true;
|
|
1999
|
-
onFirstHover();
|
|
2000
|
-
}
|
|
2001
|
-
const title = link.getAttribute("title");
|
|
2002
|
-
if (title) {
|
|
2003
|
-
link.dataset.definition = title;
|
|
2004
|
-
link.removeAttribute("title");
|
|
2005
|
-
}
|
|
2006
|
-
const rect = link.getBoundingClientRect();
|
|
2007
|
-
setCard({
|
|
2008
|
-
left: rect.left,
|
|
2009
|
-
top: rect.bottom + 6,
|
|
2010
|
-
anchor: href.slice(1),
|
|
2011
|
-
fallback: link.dataset.definition ?? ""
|
|
2012
|
-
});
|
|
2013
|
-
};
|
|
2014
|
-
const out = (event) => {
|
|
2015
|
-
const link = event.target?.closest?.("a.docx-hyperlink");
|
|
2016
|
-
if (link && !link.contains(event.relatedTarget)) setCard(null);
|
|
2017
|
-
};
|
|
2018
|
-
root.addEventListener("mouseover", over);
|
|
2019
|
-
root.addEventListener("mouseout", out);
|
|
2020
|
-
const hide = () => setCard(null);
|
|
2021
|
-
window.addEventListener("keydown", hide, true);
|
|
2022
|
-
window.addEventListener("pointerdown", hide, true);
|
|
2023
|
-
window.addEventListener("scroll", hide, true);
|
|
2024
|
-
return () => {
|
|
2025
|
-
root.removeEventListener("mouseover", over);
|
|
2026
|
-
root.removeEventListener("mouseout", out);
|
|
2027
|
-
window.removeEventListener("keydown", hide, true);
|
|
2028
|
-
window.removeEventListener("pointerdown", hide, true);
|
|
2029
|
-
window.removeEventListener("scroll", hide, true);
|
|
2030
|
-
};
|
|
2031
|
-
}, [root, onFirstHover]);
|
|
2032
|
-
if (!card) return null;
|
|
2033
|
-
const definition = resolve(card.anchor);
|
|
2034
|
-
return reactDom.createPortal(
|
|
2035
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2036
|
-
"div",
|
|
2037
|
-
{
|
|
2038
|
-
role: "tooltip",
|
|
2039
|
-
className: "native-docx-term-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
|
|
2040
|
-
style: {
|
|
2041
|
-
position: "fixed",
|
|
2042
|
-
left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
|
|
2043
|
-
top: card.top,
|
|
2044
|
-
width: 340,
|
|
2045
|
-
zIndex: 1e3,
|
|
2046
|
-
pointerEvents: "none"
|
|
2047
|
-
},
|
|
2048
|
-
"data-testid": "docx-defined-term-card",
|
|
2049
|
-
children: definition ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2050
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: definition.term }),
|
|
2051
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-muted-foreground", children: definition.meaning }),
|
|
2052
|
-
sourceOf(definition) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: sourceOf(definition) })
|
|
2053
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: card.fallback })
|
|
2054
|
-
}
|
|
2055
|
-
),
|
|
2056
|
-
document.body
|
|
2057
|
-
);
|
|
2058
|
-
}
|
|
2059
2204
|
var BUILTIN_TEMPLATE_NAME = "ARBI legal template";
|
|
2060
2205
|
var templateFileName = (t) => /\.(dotx|dotm|docx|docm)$/i.test(t.name) ? t.name : `${t.name}.dotx`;
|
|
2061
2206
|
var builtin;
|
|
@@ -2071,8 +2216,8 @@ async function resolveHouseTemplate(host) {
|
|
|
2071
2216
|
return builtinHouseTemplate();
|
|
2072
2217
|
}
|
|
2073
2218
|
}
|
|
2074
|
-
var HouseTemplateContext =
|
|
2075
|
-
var useHouseTemplate = () =>
|
|
2219
|
+
var HouseTemplateContext = React4.createContext(null);
|
|
2220
|
+
var useHouseTemplate = () => React4.useContext(HouseTemplateContext);
|
|
2076
2221
|
function HouseTemplateProvider({
|
|
2077
2222
|
host,
|
|
2078
2223
|
documentId,
|
|
@@ -2083,26 +2228,26 @@ function HouseTemplateProvider({
|
|
|
2083
2228
|
}) {
|
|
2084
2229
|
const editor = react.useDocxEditor();
|
|
2085
2230
|
const track = useTrackedOrNoted();
|
|
2086
|
-
const [template$1, setTemplate] =
|
|
2087
|
-
const [divergence, setDivergence] =
|
|
2088
|
-
const [basedOnTemplate, setBasedOnTemplate] =
|
|
2089
|
-
const [levels, setLevels] =
|
|
2090
|
-
const [generation, setGeneration] =
|
|
2091
|
-
|
|
2231
|
+
const [template$1, setTemplate] = React4.useState(builtinHouseTemplate);
|
|
2232
|
+
const [divergence, setDivergence] = React4.useState(null);
|
|
2233
|
+
const [basedOnTemplate, setBasedOnTemplate] = React4.useState(false);
|
|
2234
|
+
const [levels, setLevels] = React4.useState({});
|
|
2235
|
+
const [generation, setGeneration] = React4.useState(0);
|
|
2236
|
+
React4.useEffect(() => {
|
|
2092
2237
|
let live = true;
|
|
2093
2238
|
void resolveHouseTemplate(host).then((t) => live && setTemplate(t));
|
|
2094
2239
|
return () => {
|
|
2095
2240
|
live = false;
|
|
2096
2241
|
};
|
|
2097
2242
|
}, [host]);
|
|
2098
|
-
const blocks =
|
|
2243
|
+
const blocks = React4.useMemo(() => {
|
|
2099
2244
|
try {
|
|
2100
2245
|
return template.listBuildingBlocks(template$1.bytes);
|
|
2101
2246
|
} catch {
|
|
2102
2247
|
return [];
|
|
2103
2248
|
}
|
|
2104
2249
|
}, [template$1]);
|
|
2105
|
-
|
|
2250
|
+
React4.useEffect(() => {
|
|
2106
2251
|
if (!editor || !enabled) return;
|
|
2107
2252
|
let live = true;
|
|
2108
2253
|
void editor.save().then((saved) => {
|
|
@@ -2116,8 +2261,8 @@ function HouseTemplateProvider({
|
|
|
2116
2261
|
live = false;
|
|
2117
2262
|
};
|
|
2118
2263
|
}, [editor, template$1, generation, enabled]);
|
|
2119
|
-
const refresh =
|
|
2120
|
-
const insertBlock =
|
|
2264
|
+
const refresh = React4.useCallback(() => setGeneration((g) => g + 1), []);
|
|
2265
|
+
const insertBlock = React4.useCallback(
|
|
2121
2266
|
(name) => {
|
|
2122
2267
|
if (!editor || !editable) return false;
|
|
2123
2268
|
const fragment = template.buildingBlockFragment(template$1.bytes, name);
|
|
@@ -2147,7 +2292,7 @@ function HouseTemplateProvider({
|
|
|
2147
2292
|
},
|
|
2148
2293
|
[editor, editable, template$1, notify, refresh, track]
|
|
2149
2294
|
);
|
|
2150
|
-
const setAsHouseTemplate =
|
|
2295
|
+
const setAsHouseTemplate = React4.useMemo(
|
|
2151
2296
|
() => host?.setFromDocument && documentId ? async () => {
|
|
2152
2297
|
try {
|
|
2153
2298
|
await host.setFromDocument(documentId);
|
|
@@ -2162,7 +2307,7 @@ function HouseTemplateProvider({
|
|
|
2162
2307
|
} : void 0,
|
|
2163
2308
|
[host, documentId, notify]
|
|
2164
2309
|
);
|
|
2165
|
-
const value =
|
|
2310
|
+
const value = React4.useMemo(
|
|
2166
2311
|
() => ({
|
|
2167
2312
|
template: template$1,
|
|
2168
2313
|
blocks,
|
|
@@ -2188,17 +2333,838 @@ function HouseTemplateProvider({
|
|
|
2188
2333
|
);
|
|
2189
2334
|
return /* @__PURE__ */ jsxRuntime.jsx(HouseTemplateContext.Provider, { value: enabled ? value : null, children });
|
|
2190
2335
|
}
|
|
2336
|
+
|
|
2337
|
+
// src/docx/references/numbering.ts
|
|
2338
|
+
var numbers = (level) => !!level && level.numFmt !== "bullet" && level.numFmt !== "none" && (level.lvlText ?? level.markerText ?? "").length > 0;
|
|
2339
|
+
function paragraphNumber(order, items, levelOf, paragraphId) {
|
|
2340
|
+
const item = items.get(paragraphId);
|
|
2341
|
+
if (!item || !numbers(item)) return null;
|
|
2342
|
+
const at = order.indexOf(paragraphId);
|
|
2343
|
+
const markerAt = (ilvl) => {
|
|
2344
|
+
if (ilvl === item.ilvl) return item.markerText;
|
|
2345
|
+
for (let i = at - 1; i >= 0; i--) {
|
|
2346
|
+
const other = items.get(order[i]);
|
|
2347
|
+
if (other && other.numId === item.numId && other.ilvl === ilvl) return other.markerText;
|
|
2348
|
+
}
|
|
2349
|
+
return null;
|
|
2350
|
+
};
|
|
2351
|
+
const chain = [];
|
|
2352
|
+
const texts = [];
|
|
2353
|
+
for (let u = item.ilvl; u >= 0; u--) {
|
|
2354
|
+
const level = levelOf(item.numId, u);
|
|
2355
|
+
if (!level || !numbers(level)) continue;
|
|
2356
|
+
if (u !== item.ilvl && texts.some((t) => t.includes(`%${u + 1}`))) continue;
|
|
2357
|
+
chain.push(u);
|
|
2358
|
+
texts.push(level.lvlText);
|
|
2359
|
+
}
|
|
2360
|
+
const value = chain.reverse().map((u) => markerAt(u) ?? "").join("");
|
|
2361
|
+
if (!value) return null;
|
|
2362
|
+
return value.length > 1 && value.endsWith(".") ? value.slice(0, -1) : value;
|
|
2363
|
+
}
|
|
2364
|
+
function listTargets(paragraphs, items, levelOf) {
|
|
2365
|
+
const order = paragraphs.map((p) => p.id);
|
|
2366
|
+
const out = [];
|
|
2367
|
+
for (const p of paragraphs) {
|
|
2368
|
+
const text = p.text.replace(//g, "").trim();
|
|
2369
|
+
if (!text) continue;
|
|
2370
|
+
const number = paragraphNumber(order, items, levelOf, p.id);
|
|
2371
|
+
const item = items.get(p.id);
|
|
2372
|
+
if (number !== null)
|
|
2373
|
+
out.push({
|
|
2374
|
+
paragraphId: p.id,
|
|
2375
|
+
kind: "numbered",
|
|
2376
|
+
number,
|
|
2377
|
+
marker: item?.markerText ?? "",
|
|
2378
|
+
text,
|
|
2379
|
+
heading: p.heading,
|
|
2380
|
+
level: item?.ilvl ?? 0
|
|
2381
|
+
});
|
|
2382
|
+
else if (p.heading)
|
|
2383
|
+
out.push({
|
|
2384
|
+
paragraphId: p.id,
|
|
2385
|
+
kind: "heading",
|
|
2386
|
+
number: null,
|
|
2387
|
+
marker: "",
|
|
2388
|
+
text,
|
|
2389
|
+
heading: true,
|
|
2390
|
+
level: 0
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
return out;
|
|
2394
|
+
}
|
|
2395
|
+
function filterTargets(targets, query) {
|
|
2396
|
+
const q = query.trim().toLowerCase();
|
|
2397
|
+
if (!q) return [...targets];
|
|
2398
|
+
return targets.filter(
|
|
2399
|
+
(t) => (t.number ?? "").toLowerCase().startsWith(q) || t.text.toLowerCase().includes(q)
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
// src/docx/references/commands.ts
|
|
2404
|
+
var REF_BOOKMARK_PREFIX = "_Ref";
|
|
2405
|
+
function newRefBookmark(taken, random = Math.random) {
|
|
2406
|
+
for (; ; ) {
|
|
2407
|
+
const name = `${REF_BOOKMARK_PREFIX}${String(Math.floor(random() * 9e8) + 1e8)}`;
|
|
2408
|
+
if (!taken.has(name)) return name;
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
var styled = (style) => style ? `<w:rPr><w:rStyle w:val="${style}"/></w:rPr>` : "";
|
|
2412
|
+
var run = (text, style) => `<w:r>${styled(style)}<w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(text)}</w:t></w:r>`;
|
|
2413
|
+
function refFieldXml(instruction, cached) {
|
|
2414
|
+
const r = (inner) => `<w:r>${styled(CROSS_REFERENCE_STYLE)}${inner}</w:r>`;
|
|
2415
|
+
return `${r('<w:fldChar w:fldCharType="begin"/>')}${r(
|
|
2416
|
+
`<w:instrText xml:space="preserve"> ${chunk2A4MDHJR_cjs.esc(instruction)} </w:instrText>`
|
|
2417
|
+
)}${r('<w:fldChar w:fldCharType="separate"/>')}${run(cached, CROSS_REFERENCE_STYLE)}${r(
|
|
2418
|
+
'<w:fldChar w:fldCharType="end"/>'
|
|
2419
|
+
)}`;
|
|
2420
|
+
}
|
|
2421
|
+
var refTooltip = (value, mode) => mode === "number" ? `Cross-reference to clause ${value}` : `Cross-reference to \u201C${value}\u201D`;
|
|
2422
|
+
function crossReferenceXml(bookmark, mode, value) {
|
|
2423
|
+
return `<w:hyperlink w:anchor="${chunk2A4MDHJR_cjs.esc(bookmark)}" w:tooltip="${chunk2A4MDHJR_cjs.esc(
|
|
2424
|
+
refTooltip(value, mode)
|
|
2425
|
+
)}" w:history="1">${refFieldXml(refInstruction(bookmark, mode), value)}</w:hyperlink>`;
|
|
2426
|
+
}
|
|
2427
|
+
var refInstruction = (bookmark, mode) => mode === "number" ? `REF ${bookmark} \\r \\h` : `REF ${bookmark} \\h`;
|
|
2428
|
+
var refResult = (target, mode) => mode === "number" && target.number ? target.number : target.text;
|
|
2429
|
+
var allBookmarks = (port) => new Set(port.paragraphs().flatMap((p) => p.bookmarks));
|
|
2430
|
+
function ensureTargetBookmark(port, target, mode) {
|
|
2431
|
+
const paragraph = port.paragraphs().find((p) => p.id === target.paragraphId);
|
|
2432
|
+
if (!paragraph) throw new Error("That clause is no longer in the document.");
|
|
2433
|
+
const existing = paragraph.bookmarks.find((b) => b.startsWith(REF_BOOKMARK_PREFIX));
|
|
2434
|
+
if (existing && mode === "number") return existing;
|
|
2435
|
+
const name = newRefBookmark(allBookmarks(port));
|
|
2436
|
+
const start = `<w:bookmarkStart w:id="0" w:name="${name}"/>`;
|
|
2437
|
+
const end = '<w:bookmarkEnd w:id="0"/>';
|
|
2438
|
+
if (mode === "number") {
|
|
2439
|
+
port.setCaret({ paragraphId: paragraph.id, offset: 0 });
|
|
2440
|
+
if (!port.paste(`<w:p>${start}${end}</w:p>`, "", false))
|
|
2441
|
+
throw new Error("The cross-reference target could not be marked.");
|
|
2442
|
+
return name;
|
|
2443
|
+
}
|
|
2444
|
+
const runs = port.runsXml(paragraph.id);
|
|
2445
|
+
if (!runs) throw new Error("This heading cannot be referred to by its text; use its number.");
|
|
2446
|
+
port.deleteRange(
|
|
2447
|
+
{ paragraphId: paragraph.id, offset: 0 },
|
|
2448
|
+
{ paragraphId: paragraph.id, offset: paragraph.text.length }
|
|
2449
|
+
);
|
|
2450
|
+
if (!port.paste(`<w:p>${start}${runs}${end}</w:p>`, paragraph.text, false))
|
|
2451
|
+
throw new Error("The cross-reference target could not be marked.");
|
|
2452
|
+
return name;
|
|
2453
|
+
}
|
|
2454
|
+
function pastePoint(port, caret) {
|
|
2455
|
+
const paragraph = port.paragraphs().find((p) => p.id === caret.paragraphId);
|
|
2456
|
+
if (paragraph?.text[caret.offset - 1] !== FIELD_ATOM) return caret;
|
|
2457
|
+
port.setCaret(caret);
|
|
2458
|
+
port.typeText(" ");
|
|
2459
|
+
return { paragraphId: caret.paragraphId, offset: caret.offset + 1 };
|
|
2460
|
+
}
|
|
2461
|
+
function markCrossReferenceTarget(port, target, mode) {
|
|
2462
|
+
if (mode === "number" && !target.number) mode = "text";
|
|
2463
|
+
const bookmark = ensureTargetBookmark(port, target, mode);
|
|
2464
|
+
return { bookmark, mode, value: refResult(target, mode) };
|
|
2465
|
+
}
|
|
2466
|
+
function insertCrossReferenceField(port, { bookmark, mode, value }, caret) {
|
|
2467
|
+
caret = pastePoint(port, caret);
|
|
2468
|
+
port.setCaret(caret);
|
|
2469
|
+
if (!port.paste(`<w:p>${crossReferenceXml(bookmark, mode, value)}</w:p>`, value, false))
|
|
2470
|
+
throw new Error("The cross-reference could not be inserted.");
|
|
2471
|
+
port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + 1 });
|
|
2472
|
+
return { bookmark };
|
|
2473
|
+
}
|
|
2474
|
+
function insertCrossReference(port, target, mode, caret) {
|
|
2475
|
+
return insertCrossReferenceField(port, markCrossReferenceTarget(port, target, mode), caret);
|
|
2476
|
+
}
|
|
2477
|
+
var documentReferenceTooltip = (text, appName = "ARBI") => `Cross-reference: ${text} \u2014 opens in ${appName}`;
|
|
2478
|
+
function insertDocumentReference(port, reference, caret) {
|
|
2479
|
+
const text = reference.text.trim();
|
|
2480
|
+
if (!text) throw new Error("Enter the reference text.");
|
|
2481
|
+
const tooltip = documentReferenceTooltip(text, reference.appName).slice(0, 255);
|
|
2482
|
+
caret = pastePoint(port, caret);
|
|
2483
|
+
port.setCaret(caret);
|
|
2484
|
+
const link = `<w:p><w:hyperlink r:id="rIdRef1"${tooltip ? ` w:tooltip="${chunk2A4MDHJR_cjs.esc(tooltip)}"` : ""} w:history="1">${run(text, CROSS_REFERENCE_STYLE)}</w:hyperlink></w:p>`;
|
|
2485
|
+
if (!port.paste(link, text, false, chunk2A4MDHJR_cjs.hyperlinkRelationship("rIdRef1", reference.url)))
|
|
2486
|
+
throw new Error("The reference could not be inserted.");
|
|
2487
|
+
port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + text.length });
|
|
2488
|
+
}
|
|
2489
|
+
var REF_FIELD = /^REF\s+(\S+)((?:\s+\\[A-Za-z*]+(?:\s+MERGEFORMAT)?)*)\s*$/i;
|
|
2490
|
+
function staleCrossReferences(port) {
|
|
2491
|
+
const paragraphs = port.paragraphs();
|
|
2492
|
+
if (!paragraphs.some((p) => p.fields?.length)) return [];
|
|
2493
|
+
const items = port.listItems();
|
|
2494
|
+
const order = paragraphs.map((p) => p.id);
|
|
2495
|
+
const owner = /* @__PURE__ */ new Map();
|
|
2496
|
+
for (const p of paragraphs) for (const b of p.bookmarks) if (!owner.has(b)) owner.set(b, p.id);
|
|
2497
|
+
const out = [];
|
|
2498
|
+
for (const p of paragraphs)
|
|
2499
|
+
for (const field of p.fields ?? []) {
|
|
2500
|
+
const match = REF_FIELD.exec(field.instruction);
|
|
2501
|
+
if (!match || !match[1].startsWith(REF_BOOKMARK_PREFIX)) continue;
|
|
2502
|
+
const switches = match[2].toLowerCase();
|
|
2503
|
+
const mode = /\\[rwn]\b/.test(switches) ? "number" : "text";
|
|
2504
|
+
const target = owner.get(match[1]);
|
|
2505
|
+
const base = {
|
|
2506
|
+
paragraphId: p.id,
|
|
2507
|
+
offset: field.offset,
|
|
2508
|
+
instruction: field.instruction,
|
|
2509
|
+
cached: field.result,
|
|
2510
|
+
bookmark: match[1],
|
|
2511
|
+
mode
|
|
2512
|
+
};
|
|
2513
|
+
if (!target) {
|
|
2514
|
+
out.push({ ...base, value: null });
|
|
2515
|
+
continue;
|
|
2516
|
+
}
|
|
2517
|
+
const value = /\\[rwn]\b/.test(switches) ? switches.includes("\\r") ? paragraphNumber(order, items, port.levelOf, target) : null : (paragraphs.find((x) => x.id === target)?.text ?? "").replace(//g, "").trim();
|
|
2518
|
+
if (value && value !== field.result.trim()) out.push({ ...base, value });
|
|
2519
|
+
}
|
|
2520
|
+
return out;
|
|
2521
|
+
}
|
|
2522
|
+
function brokenCrossReferences(port) {
|
|
2523
|
+
return port.paragraphs().flatMap(
|
|
2524
|
+
(p) => (p.marks ?? []).filter((m) => m.styleId === BROKEN_CROSS_REFERENCE_STYLE).map((m) => ({ paragraphId: p.id, offset: m.offset, text: m.text }))
|
|
2525
|
+
);
|
|
2526
|
+
}
|
|
2527
|
+
function refreshCrossReferences(port) {
|
|
2528
|
+
const stale = staleCrossReferences(port).sort(
|
|
2529
|
+
(a, b) => a.paragraphId === b.paragraphId ? b.offset - a.offset : 0
|
|
2530
|
+
);
|
|
2531
|
+
let refreshed = 0;
|
|
2532
|
+
for (const ref of stale) {
|
|
2533
|
+
const paragraph = port.paragraphs().find((p) => p.id === ref.paragraphId);
|
|
2534
|
+
if (!paragraph || paragraph.text[ref.offset - 1] === FIELD_ATOM) continue;
|
|
2535
|
+
const at = { paragraphId: ref.paragraphId, offset: ref.offset };
|
|
2536
|
+
port.deleteRange(at, { paragraphId: ref.paragraphId, offset: ref.offset + 1 });
|
|
2537
|
+
port.setCaret(at);
|
|
2538
|
+
const text = ref.value ?? (ref.cached.trim() || ref.bookmark);
|
|
2539
|
+
const body = ref.value === null ? run(text, BROKEN_CROSS_REFERENCE_STYLE) : crossReferenceXml(ref.bookmark, ref.mode, ref.value);
|
|
2540
|
+
if (port.paste(`<w:p>${body}</w:p>`, text, false) && ref.value !== null) refreshed++;
|
|
2541
|
+
}
|
|
2542
|
+
return { refreshed, broken: brokenCrossReferences(port) };
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
// src/docx/references/passages.ts
|
|
2546
|
+
function shortTitle(title) {
|
|
2547
|
+
const base = title.replace(/\.[A-Za-z0-9]{1,5}$/, "").trim();
|
|
2548
|
+
const defined = /\(\s*(?:the\s+)?["“'‘]([^"”'’]{1,30})["”'’]\s*\)/i.exec(base);
|
|
2549
|
+
return defined ? defined[1] : base;
|
|
2550
|
+
}
|
|
2551
|
+
function passageClause(text) {
|
|
2552
|
+
const first = text.trim().split("\n")[0] ?? "";
|
|
2553
|
+
const match = /^(?:#+\s*)?(?:\*\*)?(?:clause|section|article)?\s*(\d+(?:\.\d+)*)[.)]?(?:\*\*)?\s+\S/i.exec(
|
|
2554
|
+
first
|
|
2555
|
+
);
|
|
2556
|
+
return match ? match[1] : null;
|
|
2557
|
+
}
|
|
2558
|
+
function referenceText(title, passage) {
|
|
2559
|
+
const name = shortTitle(title);
|
|
2560
|
+
const clause = passageClause(passage.text);
|
|
2561
|
+
if (clause) return `${name}, clause ${clause}`;
|
|
2562
|
+
if (passage.page) return `${name}, p. ${passage.page}`;
|
|
2563
|
+
return name;
|
|
2564
|
+
}
|
|
2565
|
+
function passageExcerpt(text, max = 280) {
|
|
2566
|
+
const plain = text.replace(/[#*_`>|]+/g, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\s+/g, " ").trim();
|
|
2567
|
+
return plain.length > max ? `${plain.slice(0, max - 1)}\u2026` : plain;
|
|
2568
|
+
}
|
|
2569
|
+
function filterPassages(passages, query) {
|
|
2570
|
+
const q = query.trim().toLowerCase();
|
|
2571
|
+
return q ? passages.filter((p) => p.text.toLowerCase().includes(q)) : [...passages];
|
|
2572
|
+
}
|
|
2573
|
+
var RUN_PARTS = /* @__PURE__ */ new Set(["rPr", "t", "tab", "br", "lastRenderedPageBreak"]);
|
|
2574
|
+
var SKIPPED = /* @__PURE__ */ new Set(["pPr", "bookmarkStart", "bookmarkEnd", "proofErr", "permStart", "permEnd"]);
|
|
2575
|
+
function serialize(node) {
|
|
2576
|
+
if (node.kind === "textValue") return chunk2A4MDHJR_cjs.esc(node.value ?? "");
|
|
2577
|
+
const name = `${node.prefix ?? "w"}:${node.localName}`;
|
|
2578
|
+
const attrs = (node.attributes ?? []).map((a) => ` ${a.prefix ? `${a.prefix}:` : ""}${a.localName}="${chunk2A4MDHJR_cjs.esc(a.value)}"`).join("");
|
|
2579
|
+
const children = (node.children ?? []).map((c) => serialize(c)).join("");
|
|
2580
|
+
return children ? `<${name}${attrs}>${children}</${name}>` : `<${name}${attrs}/>`;
|
|
2581
|
+
}
|
|
2582
|
+
function paragraphRunsXml(paragraph) {
|
|
2583
|
+
const runs = [];
|
|
2584
|
+
for (const child of paragraph.children ?? []) {
|
|
2585
|
+
if (child.localName && SKIPPED.has(child.localName)) continue;
|
|
2586
|
+
if (child.localName !== "r") return null;
|
|
2587
|
+
if ((child.children ?? []).some((c) => !c.localName || !RUN_PARTS.has(c.localName))) return null;
|
|
2588
|
+
runs.push(serialize(child));
|
|
2589
|
+
}
|
|
2590
|
+
return runs.length ? runs.join("") : null;
|
|
2591
|
+
}
|
|
2592
|
+
function findNode2(node, id) {
|
|
2593
|
+
if (node.id === id) return node;
|
|
2594
|
+
for (const child of node.children ?? []) {
|
|
2595
|
+
const found = findNode2(child, id);
|
|
2596
|
+
if (found) return found;
|
|
2597
|
+
}
|
|
2598
|
+
return void 0;
|
|
2599
|
+
}
|
|
2600
|
+
function referencesPort(editor, revision) {
|
|
2601
|
+
const base = editorPort(editor, revision);
|
|
2602
|
+
const session = () => {
|
|
2603
|
+
const s = editor.surface?.session;
|
|
2604
|
+
if (!s) throw new Error("The document is not open.");
|
|
2605
|
+
return s;
|
|
2606
|
+
};
|
|
2607
|
+
const root = () => session().part().root;
|
|
2608
|
+
let numbering;
|
|
2609
|
+
let cascade;
|
|
2610
|
+
const index = () => {
|
|
2611
|
+
if (!numbering) {
|
|
2612
|
+
const s = session();
|
|
2613
|
+
cascade = layout.buildStyleCascadeTable(s.stylesRoot(), void 0, s.settingsRoot());
|
|
2614
|
+
numbering = layout.withNumberingStyleLinks(layout.buildNumberingIndex(s.numberingRoot()), cascade);
|
|
2615
|
+
}
|
|
2616
|
+
return numbering;
|
|
2617
|
+
};
|
|
2618
|
+
return {
|
|
2619
|
+
...base,
|
|
2620
|
+
listItems: () => {
|
|
2621
|
+
const body = root().children?.find((n) => n.kind === "body");
|
|
2622
|
+
const items = layout.resolveStoryListItems(
|
|
2623
|
+
body?.children ?? [],
|
|
2624
|
+
index(),
|
|
2625
|
+
cascade
|
|
2626
|
+
);
|
|
2627
|
+
const out = /* @__PURE__ */ new Map();
|
|
2628
|
+
for (const [id, item] of items)
|
|
2629
|
+
out.set(id, {
|
|
2630
|
+
numId: item.numId,
|
|
2631
|
+
ilvl: item.ilvl,
|
|
2632
|
+
markerText: item.markerText,
|
|
2633
|
+
numFmt: item.numFmt
|
|
2634
|
+
});
|
|
2635
|
+
return out;
|
|
2636
|
+
},
|
|
2637
|
+
levelOf: (numId, ilvl) => {
|
|
2638
|
+
const level = layout.resolveNumberingLevel(index(), numId, ilvl)?.level;
|
|
2639
|
+
return level ? { lvlText: level.lvlText, numFmt: level.numFmt } : null;
|
|
2640
|
+
},
|
|
2641
|
+
runsXml: (paragraphId) => {
|
|
2642
|
+
const node = findNode2(root(), paragraphId);
|
|
2643
|
+
return node ? paragraphRunsXml(node) : null;
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
// src/docx/beforeSave.ts
|
|
2649
|
+
var hooks = /* @__PURE__ */ new WeakMap();
|
|
2650
|
+
function onBeforeSave(editor, fn) {
|
|
2651
|
+
let set = hooks.get(editor);
|
|
2652
|
+
if (!set) hooks.set(editor, set = /* @__PURE__ */ new Set());
|
|
2653
|
+
set.add(fn);
|
|
2654
|
+
return () => set.delete(fn);
|
|
2655
|
+
}
|
|
2656
|
+
function runBeforeSave(editor) {
|
|
2657
|
+
if (!editor) return;
|
|
2658
|
+
for (const fn of hooks.get(editor) ?? [])
|
|
2659
|
+
try {
|
|
2660
|
+
fn();
|
|
2661
|
+
} catch {
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
var DEFAULT_CROSS_REFERENCES_LABELS = {
|
|
2665
|
+
insert: "Insert cross-reference",
|
|
2666
|
+
title: "Insert cross-reference",
|
|
2667
|
+
description: "Refer to a clause of this document, or to a passage of another document.",
|
|
2668
|
+
thisDocument: "This document",
|
|
2669
|
+
otherDocument: "Another document",
|
|
2670
|
+
filterTargets: "Find a clause or heading",
|
|
2671
|
+
noTargets: "This document has no numbered clauses or headings yet.",
|
|
2672
|
+
number: "Paragraph number",
|
|
2673
|
+
text: "Heading text",
|
|
2674
|
+
insertAs: "Insert",
|
|
2675
|
+
chooseDocument: "Choose a document",
|
|
2676
|
+
filterPassages: "Find a passage",
|
|
2677
|
+
loadingPassages: "Loading passages\u2026",
|
|
2678
|
+
noPassages: "No passage matches.",
|
|
2679
|
+
referenceText: "Reference text",
|
|
2680
|
+
insertButton: "Insert",
|
|
2681
|
+
cancel: "Cancel",
|
|
2682
|
+
clause: (number) => `Clause ${number}`,
|
|
2683
|
+
heading: "Heading",
|
|
2684
|
+
update: "Update cross-references",
|
|
2685
|
+
updated: "Cross-references updated",
|
|
2686
|
+
updateSummary: (refreshed) => refreshed ? `${refreshed} cross-reference${refreshed === 1 ? "" : "s"} brought up to date.` : "Every cross-reference is up to date.",
|
|
2687
|
+
brokenTitle: "Broken cross-references",
|
|
2688
|
+
brokenNone: "No cross-reference points at a deleted target.",
|
|
2689
|
+
brokenHelp: "Their target was deleted: the last text is kept and marked. Insert the reference again to repair it.",
|
|
2690
|
+
brokenCard: "Broken cross-reference",
|
|
2691
|
+
brokenCardBody: "Its target was deleted. Update cross-references to mark it.",
|
|
2692
|
+
show: "Show",
|
|
2693
|
+
close: "Close"
|
|
2694
|
+
};
|
|
2695
|
+
var CrossReferencesContext = React4.createContext(null);
|
|
2696
|
+
var useCrossReferences = () => React4.useContext(CrossReferencesContext);
|
|
2697
|
+
function CrossReferencesProvider({
|
|
2698
|
+
children,
|
|
2699
|
+
editable,
|
|
2700
|
+
references,
|
|
2701
|
+
documentId,
|
|
2702
|
+
notify,
|
|
2703
|
+
labels
|
|
2704
|
+
}) {
|
|
2705
|
+
const editor = react.useDocxEditor();
|
|
2706
|
+
const track = useTrackedOrNoted();
|
|
2707
|
+
const l = React4.useMemo(() => ({ ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels }), [labels]);
|
|
2708
|
+
const [dialog, setDialog] = React4.useState(
|
|
2709
|
+
null
|
|
2710
|
+
);
|
|
2711
|
+
const marker = React4.useRef(null);
|
|
2712
|
+
const [viewer, setViewer] = React4.useState(null);
|
|
2713
|
+
React4.useEffect(() => setViewer(marker.current?.closest(".native-docx-viewer") ?? null), []);
|
|
2714
|
+
const openDialog = React4.useCallback(() => {
|
|
2715
|
+
if (!editor || !editable) return;
|
|
2716
|
+
try {
|
|
2717
|
+
const port = referencesPort(editor);
|
|
2718
|
+
const caret = port.caret();
|
|
2719
|
+
if (!caret) return notify?.("Place the cursor where the reference should go.", "error");
|
|
2720
|
+
setDialog({ caret, targets: listTargets(port.paragraphs(), port.listItems(), port.levelOf) });
|
|
2721
|
+
} catch (error) {
|
|
2722
|
+
notify?.(error instanceof Error ? error.message : "Could not read the document.", "error");
|
|
2723
|
+
}
|
|
2724
|
+
}, [editor, editable, notify]);
|
|
2725
|
+
const run2 = React4.useCallback(
|
|
2726
|
+
(label, prepare, insert) => {
|
|
2727
|
+
if (!editor) return;
|
|
2728
|
+
try {
|
|
2729
|
+
const prepared = withDirectEditing(editor, prepare);
|
|
2730
|
+
if (dialog) referencesPort(editor).setCaret(dialog.caret);
|
|
2731
|
+
track({ label, insert: (revision) => insert(prepared, revision), inserted: () => true });
|
|
2732
|
+
setDialog(null);
|
|
2733
|
+
editor.surface?.focus();
|
|
2734
|
+
holdCaret(editor);
|
|
2735
|
+
} catch (error) {
|
|
2736
|
+
notify?.(
|
|
2737
|
+
error instanceof Error ? error.message : "Could not insert the reference.",
|
|
2738
|
+
"error"
|
|
2739
|
+
);
|
|
2740
|
+
}
|
|
2741
|
+
},
|
|
2742
|
+
[editor, dialog, track, notify]
|
|
2743
|
+
);
|
|
2744
|
+
React4.useEffect(() => {
|
|
2745
|
+
if (!editor || !editable) return;
|
|
2746
|
+
const refresh = () => {
|
|
2747
|
+
try {
|
|
2748
|
+
const port = referencesPort(editor);
|
|
2749
|
+
if (!port.paragraphs().some((p) => p.fields?.length)) return;
|
|
2750
|
+
preservingCaret(editor, () => withDirectEditing(editor, () => refreshCrossReferences(port)));
|
|
2751
|
+
} catch {
|
|
2752
|
+
}
|
|
2753
|
+
};
|
|
2754
|
+
const off = onBeforeSave(editor, refresh);
|
|
2755
|
+
const timer = setTimeout(refresh, 1500);
|
|
2756
|
+
return () => {
|
|
2757
|
+
off();
|
|
2758
|
+
clearTimeout(timer);
|
|
2759
|
+
};
|
|
2760
|
+
}, [editor, editable]);
|
|
2761
|
+
const [report, setReport] = React4.useState(null);
|
|
2762
|
+
const update = React4.useCallback(() => {
|
|
2763
|
+
if (!editor || !editable) return;
|
|
2764
|
+
try {
|
|
2765
|
+
const result = preservingCaret(
|
|
2766
|
+
editor,
|
|
2767
|
+
() => withDirectEditing(editor, () => refreshCrossReferences(referencesPort(editor)))
|
|
2768
|
+
);
|
|
2769
|
+
setReport(result);
|
|
2770
|
+
} catch (error) {
|
|
2771
|
+
notify?.(
|
|
2772
|
+
error instanceof Error ? error.message : "Could not update cross-references.",
|
|
2773
|
+
"error"
|
|
2774
|
+
);
|
|
2775
|
+
}
|
|
2776
|
+
}, [editor, editable, notify]);
|
|
2777
|
+
const [passages, setPassages] = React4.useState({});
|
|
2778
|
+
const loadPassages = React4.useCallback(
|
|
2779
|
+
(id) => {
|
|
2780
|
+
if (!references || passages[id]) return;
|
|
2781
|
+
setPassages((p) => ({ ...p, [id]: "loading" }));
|
|
2782
|
+
references.passages(id).then((list) => setPassages((p) => ({ ...p, [id]: list }))).catch(() => setPassages((p) => ({ ...p, [id]: [] })));
|
|
2783
|
+
},
|
|
2784
|
+
[references, passages]
|
|
2785
|
+
);
|
|
2786
|
+
React4.useEffect(() => {
|
|
2787
|
+
if (!viewer || !references) return;
|
|
2788
|
+
const targetOf = (event) => {
|
|
2789
|
+
const link = event.target?.closest?.(
|
|
2790
|
+
'a.docx-hyperlink[data-docx-link-kind="external"]'
|
|
2791
|
+
);
|
|
2792
|
+
if (!link || !viewer.contains(link)) return null;
|
|
2793
|
+
const mouse = event;
|
|
2794
|
+
if (mouse.button !== 0 || mouse.ctrlKey || mouse.metaKey || mouse.shiftKey) return null;
|
|
2795
|
+
return references.targetOf(link.getAttribute("href") ?? "");
|
|
2796
|
+
};
|
|
2797
|
+
const take = (event) => {
|
|
2798
|
+
const target = targetOf(event);
|
|
2799
|
+
if (!target) return;
|
|
2800
|
+
event.preventDefault();
|
|
2801
|
+
event.stopPropagation();
|
|
2802
|
+
if (event.type === "click") references.open(target);
|
|
2803
|
+
};
|
|
2804
|
+
const types = ["pointerdown", "mousedown", "pointerup", "mouseup", "click"];
|
|
2805
|
+
for (const type of types) window.addEventListener(type, take, true);
|
|
2806
|
+
return () => {
|
|
2807
|
+
for (const type of types) window.removeEventListener(type, take, true);
|
|
2808
|
+
};
|
|
2809
|
+
}, [viewer, references]);
|
|
2810
|
+
const value = React4.useMemo(
|
|
2811
|
+
() => editable ? { openDialog, update, labels: l } : null,
|
|
2812
|
+
[editable, openDialog, update, l]
|
|
2813
|
+
);
|
|
2814
|
+
const resolveInternal = (href) => {
|
|
2815
|
+
if (!editor) return null;
|
|
2816
|
+
const name = href.replace(/^#/, "");
|
|
2817
|
+
try {
|
|
2818
|
+
const port = referencesPort(editor);
|
|
2819
|
+
const paragraphs = port.paragraphs();
|
|
2820
|
+
const target = paragraphs.find((p) => p.bookmarks.includes(name));
|
|
2821
|
+
if (!target) return { title: l.brokenCard, body: l.brokenCardBody };
|
|
2822
|
+
const number = paragraphNumber(
|
|
2823
|
+
paragraphs.map((p) => p.id),
|
|
2824
|
+
port.listItems(),
|
|
2825
|
+
port.levelOf,
|
|
2826
|
+
target.id
|
|
2827
|
+
);
|
|
2828
|
+
return {
|
|
2829
|
+
title: number ? l.clause(number) : l.heading,
|
|
2830
|
+
body: passageExcerpt(target.text.replace(//g, ""))
|
|
2831
|
+
};
|
|
2832
|
+
} catch {
|
|
2833
|
+
return null;
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(CrossReferencesContext.Provider, { value, children: [
|
|
2837
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { ref: marker, hidden: true }),
|
|
2838
|
+
children,
|
|
2839
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2840
|
+
LinkHoverCard,
|
|
2841
|
+
{
|
|
2842
|
+
root: viewer,
|
|
2843
|
+
matches: (href) => href.startsWith(`#${REF_BOOKMARK_PREFIX}`),
|
|
2844
|
+
resolve: resolveInternal,
|
|
2845
|
+
testId: "docx-cross-reference-card"
|
|
2846
|
+
}
|
|
2847
|
+
),
|
|
2848
|
+
references && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2849
|
+
LinkHoverCard,
|
|
2850
|
+
{
|
|
2851
|
+
root: viewer,
|
|
2852
|
+
matches: (href) => !!references.targetOf(href),
|
|
2853
|
+
resolve: (href) => {
|
|
2854
|
+
const target = references.targetOf(href);
|
|
2855
|
+
if (!target) return null;
|
|
2856
|
+
const list = passages[target.documentId];
|
|
2857
|
+
if (!list) loadPassages(target.documentId);
|
|
2858
|
+
const passage = Array.isArray(list) ? list.find((p) => p.chunkId === target.chunkId) : void 0;
|
|
2859
|
+
return passage ? {
|
|
2860
|
+
body: passageExcerpt(passage.text),
|
|
2861
|
+
footer: passage.page ? `p. ${passage.page}` : void 0
|
|
2862
|
+
} : null;
|
|
2863
|
+
},
|
|
2864
|
+
testId: "docx-cross-reference-card"
|
|
2865
|
+
}
|
|
2866
|
+
),
|
|
2867
|
+
dialog && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2868
|
+
CrossReferenceDialog,
|
|
2869
|
+
{
|
|
2870
|
+
targets: dialog.targets,
|
|
2871
|
+
references,
|
|
2872
|
+
documentId,
|
|
2873
|
+
passages,
|
|
2874
|
+
loadPassages,
|
|
2875
|
+
labels: l,
|
|
2876
|
+
onCancel: () => setDialog(null),
|
|
2877
|
+
onClosed: () => editor?.surface?.focus(),
|
|
2878
|
+
onInsertTarget: (target, mode) => run2(
|
|
2879
|
+
`Inserted cross-reference: ${refResult(target, mode)}`,
|
|
2880
|
+
() => markCrossReferenceTarget(referencesPort(editor), target, mode),
|
|
2881
|
+
(marked, revision) => insertCrossReferenceField(referencesPort(editor, revision), marked, dialog.caret)
|
|
2882
|
+
),
|
|
2883
|
+
onInsertPassage: (target, text) => run2(
|
|
2884
|
+
`Inserted cross-reference: ${text}`,
|
|
2885
|
+
() => void 0,
|
|
2886
|
+
(_, revision) => insertDocumentReference(
|
|
2887
|
+
referencesPort(editor, revision),
|
|
2888
|
+
{ text, url: references.linkFor(target), appName: references.appName },
|
|
2889
|
+
dialog.caret
|
|
2890
|
+
)
|
|
2891
|
+
)
|
|
2892
|
+
}
|
|
2893
|
+
),
|
|
2894
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: !!report, onOpenChange: (open) => !open && setReport(null), children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2895
|
+
ui.DialogContent,
|
|
2896
|
+
{
|
|
2897
|
+
className: "max-h-[85dvh] overflow-y-auto",
|
|
2898
|
+
"data-testid": "docx-cross-references-report",
|
|
2899
|
+
children: [
|
|
2900
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
|
|
2901
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.updated }),
|
|
2902
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: report && l.updateSummary(report.refreshed) })
|
|
2903
|
+
] }),
|
|
2904
|
+
report && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-1 text-sm", children: [
|
|
2905
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-medium", children: l.brokenTitle }),
|
|
2906
|
+
report.broken.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2907
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: l.brokenHelp }),
|
|
2908
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "space-y-1", "data-testid": "docx-cross-references-broken", children: report.broken.map((b) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2909
|
+
"li",
|
|
2910
|
+
{
|
|
2911
|
+
className: "flex items-center justify-between gap-2",
|
|
2912
|
+
children: [
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-text", children: b.text }),
|
|
2914
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2915
|
+
ui.Button,
|
|
2916
|
+
{
|
|
2917
|
+
size: "sm",
|
|
2918
|
+
variant: "ghost",
|
|
2919
|
+
onClick: () => {
|
|
2920
|
+
const point = { paragraphId: b.paragraphId, offset: b.offset };
|
|
2921
|
+
editor?.surface?.setSelection({ anchor: point, head: point });
|
|
2922
|
+
editor?.surface?.revealParagraph(b.paragraphId);
|
|
2923
|
+
setReport(null);
|
|
2924
|
+
},
|
|
2925
|
+
children: l.show
|
|
2926
|
+
}
|
|
2927
|
+
)
|
|
2928
|
+
]
|
|
2929
|
+
},
|
|
2930
|
+
`${b.paragraphId}:${b.offset}`
|
|
2931
|
+
)) })
|
|
2932
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: l.brokenNone })
|
|
2933
|
+
] }),
|
|
2934
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: () => setReport(null), children: l.close }) })
|
|
2935
|
+
]
|
|
2936
|
+
}
|
|
2937
|
+
) })
|
|
2938
|
+
] });
|
|
2939
|
+
}
|
|
2940
|
+
function CrossReferenceDialog({
|
|
2941
|
+
targets,
|
|
2942
|
+
references,
|
|
2943
|
+
documentId,
|
|
2944
|
+
passages,
|
|
2945
|
+
loadPassages,
|
|
2946
|
+
labels,
|
|
2947
|
+
onCancel,
|
|
2948
|
+
onInsertTarget,
|
|
2949
|
+
onInsertPassage,
|
|
2950
|
+
onClosed
|
|
2951
|
+
}) {
|
|
2952
|
+
const l = { ...DEFAULT_CROSS_REFERENCES_LABELS, ...labels };
|
|
2953
|
+
const [tab, setTab] = React4.useState("this");
|
|
2954
|
+
const [query, setQuery] = React4.useState("");
|
|
2955
|
+
const [chosen, setChosen] = React4.useState(null);
|
|
2956
|
+
const [mode, setMode] = React4.useState("number");
|
|
2957
|
+
const shown = React4.useMemo(() => filterTargets(targets, query), [targets, query]);
|
|
2958
|
+
const effectiveMode = chosen?.number ? mode : "text";
|
|
2959
|
+
const [documents, setDocuments] = React4.useState(null);
|
|
2960
|
+
const [docId, setDocId] = React4.useState(null);
|
|
2961
|
+
const [passageQuery, setPassageQuery] = React4.useState("");
|
|
2962
|
+
const [passage, setPassage] = React4.useState(null);
|
|
2963
|
+
const [text, setText] = React4.useState("");
|
|
2964
|
+
React4.useEffect(() => {
|
|
2965
|
+
if (tab !== "other" || !references || documents) return;
|
|
2966
|
+
references.documents().then((list2) => setDocuments(list2.filter((d) => d.id !== documentId))).catch(() => setDocuments([]));
|
|
2967
|
+
}, [tab, references, documents, documentId]);
|
|
2968
|
+
const chooseDocument = (id) => {
|
|
2969
|
+
setDocId(id);
|
|
2970
|
+
setPassage(null);
|
|
2971
|
+
setText("");
|
|
2972
|
+
loadPassages(id);
|
|
2973
|
+
};
|
|
2974
|
+
const title = documents?.find((d) => d.id === docId)?.title ?? "";
|
|
2975
|
+
const list = docId ? passages[docId] : void 0;
|
|
2976
|
+
const shownPassages = Array.isArray(list) ? filterPassages(list, passageQuery) : [];
|
|
2977
|
+
const canInsert = tab === "this" ? !!chosen : !!(docId && passage && text.trim());
|
|
2978
|
+
const insert = () => {
|
|
2979
|
+
if (tab === "this" && chosen) onInsertTarget(chosen, effectiveMode);
|
|
2980
|
+
if (tab === "other" && docId && passage)
|
|
2981
|
+
onInsertPassage(
|
|
2982
|
+
{ documentId: docId, chunkId: passage.chunkId, page: passage.page ?? null },
|
|
2983
|
+
text
|
|
2984
|
+
);
|
|
2985
|
+
};
|
|
2986
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ui.Dialog, { open: true, onOpenChange: (open) => !open && onCancel(), children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2987
|
+
ui.DialogContent,
|
|
2988
|
+
{
|
|
2989
|
+
className: "max-h-[85dvh] overflow-y-auto",
|
|
2990
|
+
"data-testid": "docx-cross-reference-dialog",
|
|
2991
|
+
onCloseAutoFocus: (event) => {
|
|
2992
|
+
if (!onClosed) return;
|
|
2993
|
+
event.preventDefault();
|
|
2994
|
+
onClosed();
|
|
2995
|
+
},
|
|
2996
|
+
children: [
|
|
2997
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DialogHeader, { children: [
|
|
2998
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: l.title }),
|
|
2999
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DialogDescription, { children: l.description })
|
|
3000
|
+
] }),
|
|
3001
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: tab, onValueChange: (v) => setTab(v), children: [
|
|
3002
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsList, { children: [
|
|
3003
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "this", "data-testid": "docx-cross-reference-this", children: l.thisDocument }),
|
|
3004
|
+
references && /* @__PURE__ */ jsxRuntime.jsx(ui.TabsTrigger, { value: "other", "data-testid": "docx-cross-reference-other", children: l.otherDocument })
|
|
3005
|
+
] }),
|
|
3006
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "this", className: "space-y-3", children: [
|
|
3007
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3008
|
+
ui.Input,
|
|
3009
|
+
{
|
|
3010
|
+
value: query,
|
|
3011
|
+
placeholder: l.filterTargets,
|
|
3012
|
+
"aria-label": l.filterTargets,
|
|
3013
|
+
onChange: (e) => setQuery(e.target.value),
|
|
3014
|
+
"data-testid": "docx-cross-reference-filter"
|
|
3015
|
+
}
|
|
3016
|
+
),
|
|
3017
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3018
|
+
"div",
|
|
3019
|
+
{
|
|
3020
|
+
role: "listbox",
|
|
3021
|
+
"aria-label": l.filterTargets,
|
|
3022
|
+
className: "max-h-64 space-y-0.5 overflow-y-auto rounded-md border border-border p-1",
|
|
3023
|
+
children: [
|
|
3024
|
+
shown.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noTargets }),
|
|
3025
|
+
shown.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3026
|
+
"button",
|
|
3027
|
+
{
|
|
3028
|
+
type: "button",
|
|
3029
|
+
role: "option",
|
|
3030
|
+
"aria-selected": chosen?.paragraphId === t.paragraphId,
|
|
3031
|
+
"data-testid": "docx-cross-reference-target",
|
|
3032
|
+
onClick: () => setChosen(t),
|
|
3033
|
+
onDoubleClick: () => onInsertTarget(t, t.number ? mode : "text"),
|
|
3034
|
+
className: ui.cn(
|
|
3035
|
+
"flex w-full items-baseline gap-2 rounded px-2 py-1 text-left text-sm",
|
|
3036
|
+
chosen?.paragraphId === t.paragraphId ? "bg-accent" : "hover:bg-accent/50"
|
|
3037
|
+
),
|
|
3038
|
+
style: { paddingLeft: 8 + t.level * 16 },
|
|
3039
|
+
children: [
|
|
3040
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-xs text-muted-foreground", children: t.marker || l.heading }),
|
|
3041
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn("truncate", t.heading && "font-medium"), children: t.text })
|
|
3042
|
+
]
|
|
3043
|
+
},
|
|
3044
|
+
t.paragraphId
|
|
3045
|
+
))
|
|
3046
|
+
]
|
|
3047
|
+
}
|
|
3048
|
+
),
|
|
3049
|
+
chosen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 text-sm", children: [
|
|
3050
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: l.insertAs }),
|
|
3051
|
+
chosen.number && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [
|
|
3052
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3053
|
+
"input",
|
|
3054
|
+
{
|
|
3055
|
+
type: "radio",
|
|
3056
|
+
name: "cross-reference-mode",
|
|
3057
|
+
checked: effectiveMode === "number",
|
|
3058
|
+
onChange: () => setMode("number")
|
|
3059
|
+
}
|
|
3060
|
+
),
|
|
3061
|
+
l.number
|
|
3062
|
+
] }),
|
|
3063
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-1", children: [
|
|
3064
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3065
|
+
"input",
|
|
3066
|
+
{
|
|
3067
|
+
type: "radio",
|
|
3068
|
+
name: "cross-reference-mode",
|
|
3069
|
+
checked: effectiveMode === "text",
|
|
3070
|
+
onChange: () => setMode("text")
|
|
3071
|
+
}
|
|
3072
|
+
),
|
|
3073
|
+
l.text
|
|
3074
|
+
] }),
|
|
3075
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3076
|
+
"span",
|
|
3077
|
+
{
|
|
3078
|
+
className: "ml-auto rounded bg-muted px-2 py-0.5",
|
|
3079
|
+
"data-testid": "docx-cross-reference-preview",
|
|
3080
|
+
children: refResult(chosen, effectiveMode)
|
|
3081
|
+
}
|
|
3082
|
+
)
|
|
3083
|
+
] })
|
|
3084
|
+
] }),
|
|
3085
|
+
references && /* @__PURE__ */ jsxRuntime.jsxs(ui.TabsContent, { value: "other", className: "space-y-3", children: [
|
|
3086
|
+
references.renderDocumentPicker ? references.renderDocumentPicker(chooseDocument, docId) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3087
|
+
"select",
|
|
3088
|
+
{
|
|
3089
|
+
className: "h-9 w-full rounded-md border border-border bg-background px-2 text-sm",
|
|
3090
|
+
"aria-label": l.chooseDocument,
|
|
3091
|
+
value: docId ?? "",
|
|
3092
|
+
onChange: (e) => e.target.value && chooseDocument(e.target.value),
|
|
3093
|
+
"data-testid": "docx-cross-reference-document",
|
|
3094
|
+
children: [
|
|
3095
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: l.chooseDocument }),
|
|
3096
|
+
(documents ?? []).map((d) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: d.id, children: d.title }, d.id))
|
|
3097
|
+
]
|
|
3098
|
+
}
|
|
3099
|
+
),
|
|
3100
|
+
docId && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3101
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3102
|
+
ui.Input,
|
|
3103
|
+
{
|
|
3104
|
+
value: passageQuery,
|
|
3105
|
+
placeholder: l.filterPassages,
|
|
3106
|
+
"aria-label": l.filterPassages,
|
|
3107
|
+
onChange: (e) => setPassageQuery(e.target.value),
|
|
3108
|
+
"data-testid": "docx-cross-reference-passage-filter"
|
|
3109
|
+
}
|
|
3110
|
+
),
|
|
3111
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3112
|
+
"div",
|
|
3113
|
+
{
|
|
3114
|
+
className: "max-h-64 space-y-1 overflow-y-auto",
|
|
3115
|
+
"data-testid": "docx-cross-reference-passages",
|
|
3116
|
+
children: list === "loading" || list === void 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.loadingPassages }) : shownPassages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "p-2 text-sm text-muted-foreground", children: l.noPassages }) : shownPassages.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3117
|
+
chunk5FYU7ZIU_cjs.FactPassageItem,
|
|
3118
|
+
{
|
|
3119
|
+
index: i,
|
|
3120
|
+
page: p.page,
|
|
3121
|
+
excerpt: passageExcerpt(p.text, 200),
|
|
3122
|
+
isViewing: passage?.chunkId === p.chunkId,
|
|
3123
|
+
onSelect: () => {
|
|
3124
|
+
setPassage(p);
|
|
3125
|
+
setText(referenceText(title, p));
|
|
3126
|
+
},
|
|
3127
|
+
testId: "docx-cross-reference-passage"
|
|
3128
|
+
},
|
|
3129
|
+
p.chunkId
|
|
3130
|
+
))
|
|
3131
|
+
}
|
|
3132
|
+
),
|
|
3133
|
+
passage && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "block space-y-1 text-sm", children: [
|
|
3134
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: l.referenceText }),
|
|
3135
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3136
|
+
ui.Input,
|
|
3137
|
+
{
|
|
3138
|
+
value: text,
|
|
3139
|
+
onChange: (e) => setText(e.target.value),
|
|
3140
|
+
"data-testid": "docx-cross-reference-text"
|
|
3141
|
+
}
|
|
3142
|
+
)
|
|
3143
|
+
] })
|
|
3144
|
+
] })
|
|
3145
|
+
] })
|
|
3146
|
+
] }),
|
|
3147
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DialogFooter, { children: [
|
|
3148
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "outline", onClick: onCancel, children: l.cancel }),
|
|
3149
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { disabled: !canInsert, onClick: insert, "data-testid": "docx-cross-reference-insert", children: l.insertButton })
|
|
3150
|
+
] })
|
|
3151
|
+
]
|
|
3152
|
+
}
|
|
3153
|
+
) });
|
|
3154
|
+
}
|
|
2191
3155
|
function RibbonMenu({
|
|
2192
3156
|
label,
|
|
2193
3157
|
icon,
|
|
2194
3158
|
children,
|
|
2195
3159
|
className,
|
|
2196
3160
|
testId,
|
|
2197
|
-
title
|
|
3161
|
+
title,
|
|
3162
|
+
keepMounted = false,
|
|
3163
|
+
popoverClassName
|
|
2198
3164
|
}) {
|
|
2199
|
-
const [open, setOpen] =
|
|
2200
|
-
const element =
|
|
2201
|
-
|
|
3165
|
+
const [open, setOpen] = React4.useState(false);
|
|
3166
|
+
const element = React4.useRef(null);
|
|
3167
|
+
React4.useEffect(() => {
|
|
2202
3168
|
if (!open) return;
|
|
2203
3169
|
const dismiss = (event) => {
|
|
2204
3170
|
if (!element.current?.contains(event.target)) setOpen(false);
|
|
@@ -2228,12 +3194,13 @@ function RibbonMenu({
|
|
|
2228
3194
|
children: icon
|
|
2229
3195
|
}
|
|
2230
3196
|
),
|
|
2231
|
-
open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3197
|
+
(open || keepMounted) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2232
3198
|
"div",
|
|
2233
3199
|
{
|
|
2234
|
-
className: "native-docx-ribbon-popover",
|
|
3200
|
+
className: ["native-docx-ribbon-popover", popoverClassName].filter(Boolean).join(" "),
|
|
2235
3201
|
role: "group",
|
|
2236
3202
|
"aria-label": label,
|
|
3203
|
+
hidden: !open,
|
|
2237
3204
|
onMouseDown: (event) => {
|
|
2238
3205
|
if (!(event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement))
|
|
2239
3206
|
event.preventDefault();
|
|
@@ -2306,7 +3273,7 @@ var AUTO = "";
|
|
|
2306
3273
|
function useGenerateImageTarget() {
|
|
2307
3274
|
const editor = react.useDocxEditor();
|
|
2308
3275
|
const loaded2 = react.useEditorState((snapshot) => !snapshot.isLoading);
|
|
2309
|
-
|
|
3276
|
+
React4.useEffect(() => {
|
|
2310
3277
|
if (!editor || !loaded2) return;
|
|
2311
3278
|
mounted.push(editor);
|
|
2312
3279
|
return () => void mounted.splice(mounted.indexOf(editor), 1);
|
|
@@ -2314,16 +3281,16 @@ function useGenerateImageTarget() {
|
|
|
2314
3281
|
}
|
|
2315
3282
|
function GenerateImageButton({ generation }) {
|
|
2316
3283
|
const editor = react.useDocxEditor();
|
|
2317
|
-
const [prompt, setPrompt] =
|
|
2318
|
-
const [aspectRatio, setAspectRatio] =
|
|
2319
|
-
const [busy, setBusy] =
|
|
2320
|
-
const [error, setError] =
|
|
2321
|
-
const abort =
|
|
2322
|
-
const close =
|
|
3284
|
+
const [prompt, setPrompt] = React4.useState("");
|
|
3285
|
+
const [aspectRatio, setAspectRatio] = React4.useState(AUTO);
|
|
3286
|
+
const [busy, setBusy] = React4.useState(false);
|
|
3287
|
+
const [error, setError] = React4.useState("");
|
|
3288
|
+
const abort = React4.useRef(null);
|
|
3289
|
+
const close = React4.useRef(() => {
|
|
2323
3290
|
});
|
|
2324
3291
|
const editable = react.useEditorState((snapshot) => snapshot.editable);
|
|
2325
|
-
const generating =
|
|
2326
|
-
async function
|
|
3292
|
+
const generating = React4.useSyncExternalStore(subscribe, () => running > 0);
|
|
3293
|
+
async function run2() {
|
|
2327
3294
|
if (!editor || !prompt.trim() || busy) return;
|
|
2328
3295
|
const caret = rememberCaret(editor);
|
|
2329
3296
|
const controller = new AbortController();
|
|
@@ -2369,7 +3336,7 @@ function GenerateImageButton({ generation }) {
|
|
|
2369
3336
|
className: "native-docx-form native-docx-generate-image",
|
|
2370
3337
|
onSubmit: (event) => {
|
|
2371
3338
|
event.preventDefault();
|
|
2372
|
-
void
|
|
3339
|
+
void run2();
|
|
2373
3340
|
},
|
|
2374
3341
|
children: [
|
|
2375
3342
|
/* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
@@ -2385,7 +3352,7 @@ function GenerateImageButton({ generation }) {
|
|
|
2385
3352
|
"data-testid": "docx-generate-image-prompt",
|
|
2386
3353
|
onChange: (event) => setPrompt(event.target.value),
|
|
2387
3354
|
onKeyDown: (event) => {
|
|
2388
|
-
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void
|
|
3355
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) void run2();
|
|
2389
3356
|
}
|
|
2390
3357
|
}
|
|
2391
3358
|
)
|
|
@@ -2511,6 +3478,163 @@ var WordDraftStream = class {
|
|
|
2511
3478
|
}
|
|
2512
3479
|
};
|
|
2513
3480
|
|
|
3481
|
+
// src/docx/overflowPlan.ts
|
|
3482
|
+
function planOverflow(items, available, moreWidth) {
|
|
3483
|
+
const collapsed = /* @__PURE__ */ new Set();
|
|
3484
|
+
let used = items.reduce((sum, item) => sum + item.width, 0);
|
|
3485
|
+
if (used <= available) return collapsed;
|
|
3486
|
+
used += moreWidth;
|
|
3487
|
+
const order = items.map((item, index) => ({ item, index })).sort((a, b) => a.item.priority - b.item.priority || b.index - a.index);
|
|
3488
|
+
for (const { item } of order) {
|
|
3489
|
+
if (used <= available) break;
|
|
3490
|
+
collapsed.add(item.id);
|
|
3491
|
+
used -= item.width;
|
|
3492
|
+
}
|
|
3493
|
+
return collapsed;
|
|
3494
|
+
}
|
|
3495
|
+
var Overflow = React4.createContext(null);
|
|
3496
|
+
var MORE_WIDTH = 32;
|
|
3497
|
+
var sameSet = (a, b) => a.size === b.size && [...a].every((id) => b.has(id));
|
|
3498
|
+
function RibbonOverflow({ tab, children }) {
|
|
3499
|
+
const row = React4.useRef(null);
|
|
3500
|
+
const items = React4.useRef(/* @__PURE__ */ new Map());
|
|
3501
|
+
const widths = React4.useRef(/* @__PURE__ */ new Map());
|
|
3502
|
+
const [version, setVersion] = React4.useState(0);
|
|
3503
|
+
const [collapsed, setCollapsed] = React4.useState(() => /* @__PURE__ */ new Set());
|
|
3504
|
+
const [slots, setSlots] = React4.useState({});
|
|
3505
|
+
const [menu, setMenu] = React4.useState([]);
|
|
3506
|
+
const register = React4.useCallback((id, item) => {
|
|
3507
|
+
items.current.set(id, item);
|
|
3508
|
+
setVersion((v) => v + 1);
|
|
3509
|
+
return () => {
|
|
3510
|
+
if (items.current.get(id) === item) items.current.delete(id);
|
|
3511
|
+
setVersion((v) => v + 1);
|
|
3512
|
+
};
|
|
3513
|
+
}, []);
|
|
3514
|
+
const plan = React4.useCallback(() => {
|
|
3515
|
+
const element = row.current;
|
|
3516
|
+
if (!element) return;
|
|
3517
|
+
const gap = parseFloat(getComputedStyle(element).columnGap) || 0;
|
|
3518
|
+
const ordered = Array.from(element.querySelectorAll("[data-ribbon-item]")).map((node) => node.dataset.ribbonItem).filter((id) => items.current.has(id));
|
|
3519
|
+
const measured = ordered.map((id) => {
|
|
3520
|
+
const { element: node, priority } = items.current.get(id);
|
|
3521
|
+
if (!node.hidden) {
|
|
3522
|
+
const width = node.getBoundingClientRect().width;
|
|
3523
|
+
widths.current.set(id, width ? width + gap : 0);
|
|
3524
|
+
}
|
|
3525
|
+
return { id, priority, width: widths.current.get(id) ?? 0 };
|
|
3526
|
+
});
|
|
3527
|
+
const next = planOverflow(measured, element.clientWidth, MORE_WIDTH);
|
|
3528
|
+
setCollapsed((current) => sameSet(current, next) ? current : next);
|
|
3529
|
+
const entries = ordered.filter((id) => next.has(id)).map((id) => ({ id, label: items.current.get(id).label }));
|
|
3530
|
+
setMenu(
|
|
3531
|
+
(current) => current.length === entries.length && current.every((entry, i) => entry.id === entries[i].id && entry.label === entries[i].label) ? current : entries
|
|
3532
|
+
);
|
|
3533
|
+
}, []);
|
|
3534
|
+
React4.useLayoutEffect(plan, [plan, version, tab, collapsed]);
|
|
3535
|
+
React4.useLayoutEffect(() => {
|
|
3536
|
+
const element = row.current;
|
|
3537
|
+
if (!element) return;
|
|
3538
|
+
const observer = new ResizeObserver(() => plan());
|
|
3539
|
+
observer.observe(element);
|
|
3540
|
+
for (const item of items.current.values()) observer.observe(item.element);
|
|
3541
|
+
return () => observer.disconnect();
|
|
3542
|
+
}, [plan, version]);
|
|
3543
|
+
const slotRef = React4.useCallback(
|
|
3544
|
+
(id) => (node) => setSlots((current) => {
|
|
3545
|
+
if (node ? current[id] === node : !(id in current)) return current;
|
|
3546
|
+
const next = { ...current };
|
|
3547
|
+
if (node) next[id] = node;
|
|
3548
|
+
else delete next[id];
|
|
3549
|
+
return next;
|
|
3550
|
+
}),
|
|
3551
|
+
[]
|
|
3552
|
+
);
|
|
3553
|
+
const context = React4.useMemo(() => ({ collapsed, slots, register }), [collapsed, slots, register]);
|
|
3554
|
+
const shown = menu.filter((entry) => collapsed.has(entry.id));
|
|
3555
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Overflow.Provider, { value: context, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "native-docx-ribbon-row", ref: row, "data-testid": "docx-ribbon-row", children: [
|
|
3556
|
+
children,
|
|
3557
|
+
shown.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3558
|
+
RibbonMenu,
|
|
3559
|
+
{
|
|
3560
|
+
label: "More",
|
|
3561
|
+
title: "More commands",
|
|
3562
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { size: 16 }),
|
|
3563
|
+
testId: "docx-ribbon-more",
|
|
3564
|
+
keepMounted: true,
|
|
3565
|
+
popoverClassName: "native-docx-ribbon-more",
|
|
3566
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(MoreRows, { entries: shown, slotRef, close })
|
|
3567
|
+
},
|
|
3568
|
+
tab
|
|
3569
|
+
)
|
|
3570
|
+
] }) });
|
|
3571
|
+
}
|
|
3572
|
+
function MoreRows({
|
|
3573
|
+
entries,
|
|
3574
|
+
slotRef,
|
|
3575
|
+
close
|
|
3576
|
+
}) {
|
|
3577
|
+
const refs = React4.useRef(/* @__PURE__ */ new Map());
|
|
3578
|
+
const refFor = (id) => {
|
|
3579
|
+
let ref = refs.current.get(id);
|
|
3580
|
+
if (!ref) refs.current.set(id, ref = slotRef(id));
|
|
3581
|
+
return ref;
|
|
3582
|
+
};
|
|
3583
|
+
const list = React4.useRef(null);
|
|
3584
|
+
const latest = React4.useRef(close);
|
|
3585
|
+
latest.current = close;
|
|
3586
|
+
React4.useEffect(() => {
|
|
3587
|
+
const element = list.current;
|
|
3588
|
+
if (!element) return;
|
|
3589
|
+
const onClick = (event) => {
|
|
3590
|
+
const target = event.target;
|
|
3591
|
+
const row = target.closest(".native-docx-ribbon-more-row");
|
|
3592
|
+
if (!row) return;
|
|
3593
|
+
const control = row.querySelector(".native-docx-ribbon-more-control");
|
|
3594
|
+
if (!control.contains(target)) {
|
|
3595
|
+
control.querySelector("button:not([disabled])")?.click();
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
const button = target.closest("button");
|
|
3599
|
+
if (button && !button.disabled && !control.querySelector(".native-docx-ribbon-popover")?.contains(button) && !button.hasAttribute("aria-expanded") && !button.hasAttribute("aria-haspopup"))
|
|
3600
|
+
latest.current();
|
|
3601
|
+
};
|
|
3602
|
+
element.addEventListener("click", onClick, true);
|
|
3603
|
+
return () => element.removeEventListener("click", onClick, true);
|
|
3604
|
+
}, []);
|
|
3605
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "native-docx-ribbon-more-list", ref: list, children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "native-docx-ribbon-more-row", "data-ribbon-more": entry.id, children: [
|
|
3606
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-ribbon-more-control", ref: refFor(entry.id) }),
|
|
3607
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-ribbon-more-label", children: entry.label })
|
|
3608
|
+
] }, entry.id)) });
|
|
3609
|
+
}
|
|
3610
|
+
function RibbonItem({
|
|
3611
|
+
id,
|
|
3612
|
+
label,
|
|
3613
|
+
priority = 0,
|
|
3614
|
+
children
|
|
3615
|
+
}) {
|
|
3616
|
+
const context = React4.useContext(Overflow);
|
|
3617
|
+
const element = React4.useRef(null);
|
|
3618
|
+
const register = context?.register;
|
|
3619
|
+
React4.useLayoutEffect(() => {
|
|
3620
|
+
if (!register || !element.current) return;
|
|
3621
|
+
return register(id, { label, priority, element: element.current });
|
|
3622
|
+
}, [register, id, label, priority]);
|
|
3623
|
+
if (!context) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
3624
|
+
const collapsed = context.collapsed.has(id);
|
|
3625
|
+
const slot = context.slots[id];
|
|
3626
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3627
|
+
"span",
|
|
3628
|
+
{
|
|
3629
|
+
ref: element,
|
|
3630
|
+
className: "native-docx-ribbon-item",
|
|
3631
|
+
"data-ribbon-item": id,
|
|
3632
|
+
hidden: collapsed || void 0,
|
|
3633
|
+
children: collapsed ? slot ? reactDom.createPortal(children, slot) : null : children
|
|
3634
|
+
}
|
|
3635
|
+
);
|
|
3636
|
+
}
|
|
3637
|
+
|
|
2514
3638
|
// src/docx/wordStyles.ts
|
|
2515
3639
|
var QUICK_STYLES = ["Normal", "Title", "heading 1", "heading 2", "heading 3"];
|
|
2516
3640
|
function findStyle(options, name) {
|
|
@@ -2574,14 +3698,14 @@ function Gallery({ close }) {
|
|
|
2574
3698
|
const changed = new Set(
|
|
2575
3699
|
house?.basedOnTemplate ? house.divergence?.styles.filter((s) => s.kind === "changed").map((s) => s.styleId) : []
|
|
2576
3700
|
);
|
|
2577
|
-
const [query, setQuery] =
|
|
2578
|
-
const quick =
|
|
3701
|
+
const [query, setQuery] = React4.useState("");
|
|
3702
|
+
const quick = React4.useMemo(
|
|
2579
3703
|
() => QUICK_STYLES.map((name) => findStyle(options, name)).filter(
|
|
2580
3704
|
(o) => !!o
|
|
2581
3705
|
),
|
|
2582
3706
|
[options]
|
|
2583
3707
|
);
|
|
2584
|
-
const shown =
|
|
3708
|
+
const shown = React4.useMemo(() => {
|
|
2585
3709
|
const q = query.trim().toLowerCase();
|
|
2586
3710
|
return q ? options.filter(
|
|
2587
3711
|
(o) => o.name.toLowerCase().includes(q) || o.styleId.toLowerCase().includes(q)
|
|
@@ -2696,18 +3820,87 @@ function StyleGallery() {
|
|
|
2696
3820
|
}
|
|
2697
3821
|
);
|
|
2698
3822
|
}
|
|
3823
|
+
var W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
3824
|
+
var DEFAULT_PARAGRAPH_FONT = {
|
|
3825
|
+
id: "DefaultParagraphFont",
|
|
3826
|
+
type: "character",
|
|
3827
|
+
xml: '<w:style w:type="character" w:default="1" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style>'
|
|
3828
|
+
};
|
|
3829
|
+
function stylesOf(kind) {
|
|
3830
|
+
const Kind = kind === "footnote" ? "Footnote" : "Endnote";
|
|
3831
|
+
const text = `${Kind}Text`;
|
|
3832
|
+
return [
|
|
3833
|
+
{
|
|
3834
|
+
id: text,
|
|
3835
|
+
type: "paragraph",
|
|
3836
|
+
xml: `<w:style w:type="paragraph" w:styleId="${text}"><w:name w:val="${kind} text"/><w:basedOn w:val="Normal"/><w:link w:val="${text}Char"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style>`
|
|
3837
|
+
},
|
|
3838
|
+
{
|
|
3839
|
+
id: `${text}Char`,
|
|
3840
|
+
type: "character",
|
|
3841
|
+
xml: `<w:style w:type="character" w:customStyle="1" w:styleId="${text}Char"><w:name w:val="${Kind} Text Char"/><w:basedOn w:val="DefaultParagraphFont"/><w:link w:val="${text}"/><w:uiPriority w:val="99"/><w:semiHidden/><w:rPr><w:sz w:val="20"/><w:szCs w:val="20"/></w:rPr></w:style>`
|
|
3842
|
+
},
|
|
3843
|
+
{
|
|
3844
|
+
id: `${Kind}Reference`,
|
|
3845
|
+
type: "character",
|
|
3846
|
+
xml: `<w:style w:type="character" w:styleId="${Kind}Reference"><w:name w:val="${kind} reference"/><w:basedOn w:val="DefaultParagraphFont"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val="superscript"/></w:rPr></w:style>`
|
|
3847
|
+
}
|
|
3848
|
+
];
|
|
3849
|
+
}
|
|
3850
|
+
function noteTextStyle(styles, kind) {
|
|
3851
|
+
const paragraph = styles.filter((style) => style.type === "paragraph");
|
|
3852
|
+
const id = kind === "footnote" ? "FootnoteText" : "EndnoteText";
|
|
3853
|
+
return paragraph.find((style) => style.name.toLowerCase() === `${kind} text`)?.styleId ?? paragraph.find((style) => style.styleId === id)?.styleId;
|
|
3854
|
+
}
|
|
3855
|
+
function missingNoteStyles(styles, kind) {
|
|
3856
|
+
const has = (type, id) => styles.some((style) => style.type === type && style.styleId === id);
|
|
3857
|
+
const text = noteTextStyle(styles, kind);
|
|
3858
|
+
const missing = stylesOf(kind).filter(
|
|
3859
|
+
(style) => style.type === "paragraph" ? !text : !has("character", style.id)
|
|
3860
|
+
);
|
|
3861
|
+
if (!missing.length) return [];
|
|
3862
|
+
const base = has("character", DEFAULT_PARAGRAPH_FONT.id) ? [] : [DEFAULT_PARAGRAPH_FONT];
|
|
3863
|
+
return [...base, ...missing].map((style) => style.xml);
|
|
3864
|
+
}
|
|
3865
|
+
var CONTENT_TYPES = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/></Types>';
|
|
3866
|
+
function stylesOnlyClipboardHtml(styles) {
|
|
3867
|
+
const fragment = fflate.zipSync({
|
|
3868
|
+
"[Content_Types].xml": fflate.strToU8(CONTENT_TYPES),
|
|
3869
|
+
"_rels/.rels": fflate.strToU8(
|
|
3870
|
+
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>'
|
|
3871
|
+
),
|
|
3872
|
+
"word/document.xml": fflate.strToU8(
|
|
3873
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3874
|
+
<w:document xmlns:w="${W}"><w:body><w:p/></w:body></w:document>`
|
|
3875
|
+
),
|
|
3876
|
+
"word/_rels/document.xml.rels": fflate.strToU8(
|
|
3877
|
+
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>'
|
|
3878
|
+
),
|
|
3879
|
+
"word/styles.xml": fflate.strToU8(
|
|
3880
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
3881
|
+
<w:styles xmlns:w="${W}">${styles.join("")}</w:styles>`
|
|
3882
|
+
)
|
|
3883
|
+
});
|
|
3884
|
+
return template.fragmentClipboardHtml(fragment, false);
|
|
3885
|
+
}
|
|
3886
|
+
function ensureNoteStyles(editor, kind, direct = (fn) => fn()) {
|
|
3887
|
+
if (!editor.can({ type: "insertNote", noteKind: kind }).ok) return void 0;
|
|
3888
|
+
const missing = missingNoteStyles(editor.getDocumentStyles(), kind);
|
|
3889
|
+
if (missing.length)
|
|
3890
|
+
direct(() => editor.exec({ type: "paste", text: "", html: stylesOnlyClipboardHtml(missing) }));
|
|
3891
|
+
return noteTextStyle(editor.getDocumentStyles(), kind);
|
|
3892
|
+
}
|
|
2699
3893
|
function useInsertNote(kind) {
|
|
2700
3894
|
const command = react.useEditorCommand(kind === "footnote" ? "insert.footnote" : "insert.endnote");
|
|
2701
|
-
const { options } = react.useParagraphStyle();
|
|
2702
3895
|
const editor = react.useDocxEditor();
|
|
2703
3896
|
const insert = () => {
|
|
3897
|
+
const text = editor && ensureNoteStyles(editor, kind, (fn) => withDirectEditing(editor, fn));
|
|
2704
3898
|
if (!command.execute()) return false;
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
);
|
|
3899
|
+
if (editor) {
|
|
3900
|
+
if (text)
|
|
3901
|
+
withDirectEditing(editor, () => editor.exec({ type: "setParagraphStyle", styleId: text }));
|
|
3902
|
+
editor.exec({ type: "insertText", text: " " });
|
|
3903
|
+
}
|
|
2711
3904
|
return true;
|
|
2712
3905
|
};
|
|
2713
3906
|
return { insert, isEnabled: command.isEnabled, disabledReason: command.disabledReason };
|
|
@@ -2719,7 +3912,7 @@ function NoteAction({
|
|
|
2719
3912
|
icon
|
|
2720
3913
|
}) {
|
|
2721
3914
|
const note = useInsertNote(kind);
|
|
2722
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3915
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: `references-${kind}`, label, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2723
3916
|
react.DocxEditor.Toolbar.Action,
|
|
2724
3917
|
{
|
|
2725
3918
|
label: `${label} (${shortcut})`,
|
|
@@ -2729,7 +3922,7 @@ function NoteAction({
|
|
|
2729
3922
|
onSelect: () => void note.insert(),
|
|
2730
3923
|
className: `native-docx-insert-${kind}`
|
|
2731
3924
|
}
|
|
2732
|
-
);
|
|
3925
|
+
) });
|
|
2733
3926
|
}
|
|
2734
3927
|
function NoteButtons() {
|
|
2735
3928
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2759,9 +3952,9 @@ function WordShortcuts({ scope }) {
|
|
|
2759
3952
|
const styles = react.useParagraphStyle();
|
|
2760
3953
|
const editor = react.useDocxEditor();
|
|
2761
3954
|
const levels = useHouseTemplate()?.levels;
|
|
2762
|
-
const latest =
|
|
3955
|
+
const latest = React4.useRef({ footnote, endnote, styles, editor, levels });
|
|
2763
3956
|
latest.current = { footnote, endnote, styles, editor, levels };
|
|
2764
|
-
|
|
3957
|
+
React4.useEffect(() => {
|
|
2765
3958
|
const element = scope.current;
|
|
2766
3959
|
if (!element) return;
|
|
2767
3960
|
const onKeyDown = (event) => {
|
|
@@ -2799,6 +3992,65 @@ function WordShortcuts({ scope }) {
|
|
|
2799
3992
|
}, [scope]);
|
|
2800
3993
|
return null;
|
|
2801
3994
|
}
|
|
3995
|
+
function CrossReferenceButton() {
|
|
3996
|
+
const references = useCrossReferences();
|
|
3997
|
+
if (!references) return null;
|
|
3998
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3999
|
+
"button",
|
|
4000
|
+
{
|
|
4001
|
+
type: "button",
|
|
4002
|
+
className: "native-docx-ribbon-trigger",
|
|
4003
|
+
"aria-label": references.labels.insert,
|
|
4004
|
+
title: references.labels.insert,
|
|
4005
|
+
"data-testid": "docx-insert-cross-reference",
|
|
4006
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
4007
|
+
onClick: () => references.openDialog(),
|
|
4008
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { size: 16 })
|
|
4009
|
+
}
|
|
4010
|
+
);
|
|
4011
|
+
}
|
|
4012
|
+
function UpdateCrossReferencesButton() {
|
|
4013
|
+
const references = useCrossReferences();
|
|
4014
|
+
if (!references) return null;
|
|
4015
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4016
|
+
"button",
|
|
4017
|
+
{
|
|
4018
|
+
type: "button",
|
|
4019
|
+
className: "native-docx-ribbon-trigger",
|
|
4020
|
+
"aria-label": references.labels.update,
|
|
4021
|
+
title: references.labels.update,
|
|
4022
|
+
"data-testid": "docx-update-cross-references",
|
|
4023
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
4024
|
+
onClick: () => references.update(),
|
|
4025
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcw, { size: 16 })
|
|
4026
|
+
}
|
|
4027
|
+
);
|
|
4028
|
+
}
|
|
4029
|
+
function DocxContextMenuExtras() {
|
|
4030
|
+
const terms = useDefinedTerms();
|
|
4031
|
+
const references = useCrossReferences();
|
|
4032
|
+
if (!terms && !references) return null;
|
|
4033
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4034
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu.Separator, {}),
|
|
4035
|
+
terms && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4036
|
+
react.DocxEditor.ContextMenu.Item,
|
|
4037
|
+
{
|
|
4038
|
+
label: "Insert defined term",
|
|
4039
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BookA, { size: 14 }),
|
|
4040
|
+
shortcut: "@@",
|
|
4041
|
+
onSelect: () => terms.openPicker()
|
|
4042
|
+
}
|
|
4043
|
+
),
|
|
4044
|
+
references && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4045
|
+
react.DocxEditor.ContextMenu.Item,
|
|
4046
|
+
{
|
|
4047
|
+
label: references.labels.insert,
|
|
4048
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Link2, { size: 14 }),
|
|
4049
|
+
onSelect: () => references.openDialog()
|
|
4050
|
+
}
|
|
4051
|
+
)
|
|
4052
|
+
] });
|
|
4053
|
+
}
|
|
2802
4054
|
|
|
2803
4055
|
// src/docx/layout/presets.ts
|
|
2804
4056
|
var TWIPS_PER_INCH = 1440;
|
|
@@ -3011,13 +4263,13 @@ function Breaks() {
|
|
|
3011
4263
|
}
|
|
3012
4264
|
function LayoutButtons() {
|
|
3013
4265
|
const { pageSetup, apply } = react.usePageSetup();
|
|
3014
|
-
const [dialog, setDialog] =
|
|
4266
|
+
const [dialog, setDialog] = React4.useState(false);
|
|
3015
4267
|
const props = { setup: pageSetup, apply, openDialog: () => setDialog(true) };
|
|
3016
4268
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3017
|
-
/* @__PURE__ */ jsxRuntime.jsx(Margins, { ...props }),
|
|
3018
|
-
/* @__PURE__ */ jsxRuntime.jsx(Orientation, { ...props }),
|
|
3019
|
-
/* @__PURE__ */ jsxRuntime.jsx(Size, { ...props }),
|
|
3020
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4269
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-margins", label: "Margins", children: /* @__PURE__ */ jsxRuntime.jsx(Margins, { ...props }) }),
|
|
4270
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-orientation", label: "Orientation", children: /* @__PURE__ */ jsxRuntime.jsx(Orientation, { ...props }) }),
|
|
4271
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-size", label: "Size", children: /* @__PURE__ */ jsxRuntime.jsx(Size, { ...props }) }),
|
|
4272
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-columns", label: "Columns", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3021
4273
|
react.DocxEditor.Toolbar.Action,
|
|
3022
4274
|
{
|
|
3023
4275
|
label: "Columns",
|
|
@@ -3026,9 +4278,9 @@ function LayoutButtons() {
|
|
|
3026
4278
|
disabledReason: COLUMNS_UNSUPPORTED,
|
|
3027
4279
|
className: "native-docx-layout-columns"
|
|
3028
4280
|
}
|
|
3029
|
-
),
|
|
3030
|
-
/* @__PURE__ */ jsxRuntime.jsx(Breaks, {}),
|
|
3031
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4281
|
+
) }),
|
|
4282
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-breaks", label: "Breaks", children: /* @__PURE__ */ jsxRuntime.jsx(Breaks, {}) }),
|
|
4283
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "layout-page-setup", label: "Page Setup\u2026", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3032
4284
|
react.DocxEditor.Toolbar.Action,
|
|
3033
4285
|
{
|
|
3034
4286
|
label: "Page Setup\u2026",
|
|
@@ -3036,7 +4288,7 @@ function LayoutButtons() {
|
|
|
3036
4288
|
onSelect: () => setDialog(true),
|
|
3037
4289
|
className: "native-docx-layout-page-setup"
|
|
3038
4290
|
}
|
|
3039
|
-
),
|
|
4291
|
+
) }),
|
|
3040
4292
|
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.PageSetupDialog, { open: dialog, onClose: () => setDialog(false) })
|
|
3041
4293
|
] });
|
|
3042
4294
|
}
|
|
@@ -3063,7 +4315,7 @@ function CommandGallery({
|
|
|
3063
4315
|
rows
|
|
3064
4316
|
}) {
|
|
3065
4317
|
const bound = useRows(rows);
|
|
3066
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label, icon, testId, children: (close) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4318
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: testId, label, children: /* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label, icon, testId, children: (close) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3067
4319
|
RibbonGallery,
|
|
3068
4320
|
{
|
|
3069
4321
|
label,
|
|
@@ -3077,7 +4329,7 @@ function CommandGallery({
|
|
|
3077
4329
|
})),
|
|
3078
4330
|
onPick: (id) => void bound.find((row) => row.id === id)?.state.execute()
|
|
3079
4331
|
}
|
|
3080
|
-
) });
|
|
4332
|
+
) }) });
|
|
3081
4333
|
}
|
|
3082
4334
|
function CommandAction({
|
|
3083
4335
|
command,
|
|
@@ -3086,7 +4338,7 @@ function CommandAction({
|
|
|
3086
4338
|
testId
|
|
3087
4339
|
}) {
|
|
3088
4340
|
const state = react.useEditorCommand(command);
|
|
3089
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4341
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: `table-${testId}`, label, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3090
4342
|
react.DocxEditor.Toolbar.Action,
|
|
3091
4343
|
{
|
|
3092
4344
|
label,
|
|
@@ -3097,7 +4349,7 @@ function CommandAction({
|
|
|
3097
4349
|
onSelect: () => void state.execute(),
|
|
3098
4350
|
className: `native-docx-table-${testId}`
|
|
3099
4351
|
}
|
|
3100
|
-
);
|
|
4352
|
+
) });
|
|
3101
4353
|
}
|
|
3102
4354
|
function TableButtons() {
|
|
3103
4355
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3197,15 +4449,15 @@ function TableButtons() {
|
|
|
3197
4449
|
]
|
|
3198
4450
|
}
|
|
3199
4451
|
),
|
|
3200
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderTarget, {}),
|
|
3201
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderStyle, {}),
|
|
3202
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderWidth, {}),
|
|
3203
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderColor, {}),
|
|
3204
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableCellFill, {})
|
|
4452
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "table-border-target", label: "Borders", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderTarget, {}) }),
|
|
4453
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "table-border-style", label: "Border style", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderStyle, {}) }),
|
|
4454
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "table-border-width", label: "Border width", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderWidth, {}) }),
|
|
4455
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "table-border-color", label: "Border color", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableBorderColor, {}) }),
|
|
4456
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "table-cell-fill", label: "Shading", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableCellFill, {}) })
|
|
3205
4457
|
] });
|
|
3206
4458
|
}
|
|
3207
4459
|
var CAPTION_LABELS = ["Figure", "Table", "Equation"];
|
|
3208
|
-
var CAPTION_STYLES =
|
|
4460
|
+
var CAPTION_STYLES = chunk2A4MDHJR_cjs.stylesXml(
|
|
3209
4461
|
"",
|
|
3210
4462
|
'<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w:style><w:style w:type="paragraph" w:styleId="Caption"><w:name w:val="caption"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:uiPriority w:val="35"/><w:unhideWhenUsed/><w:qFormat/><w:pPr><w:spacing w:after="200" w:line="240" w:lineRule="auto"/></w:pPr><w:rPr><w:i/><w:iCs/><w:color w:val="44546A"/><w:sz w:val="18"/><w:szCs w:val="18"/></w:rPr></w:style>'
|
|
3211
4463
|
);
|
|
@@ -3233,9 +4485,9 @@ function countSeqFields(root, label, throughId) {
|
|
|
3233
4485
|
return count;
|
|
3234
4486
|
}
|
|
3235
4487
|
function captionParagraphXml(label, number, text) {
|
|
3236
|
-
const
|
|
4488
|
+
const run2 = (value) => `<w:r><w:t xml:space="preserve">${chunk2A4MDHJR_cjs.esc(value)}</w:t></w:r>`;
|
|
3237
4489
|
const rest = text.trim() ? `: ${text.trim()}` : "";
|
|
3238
|
-
return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${
|
|
4490
|
+
return `<w:p><w:pPr><w:pStyle w:val="Caption"/></w:pPr>${run2(`${label} `)}<w:fldSimple w:instr=" SEQ ${chunk2A4MDHJR_cjs.esc(label)} \\* ARABIC "><w:r><w:t>${number}</w:t></w:r></w:fldSimple>${rest ? run2(rest) : ""}</w:p>`;
|
|
3239
4491
|
}
|
|
3240
4492
|
function base642(bytes) {
|
|
3241
4493
|
let binary = "";
|
|
@@ -3244,8 +4496,8 @@ function base642(bytes) {
|
|
|
3244
4496
|
return btoa(binary);
|
|
3245
4497
|
}
|
|
3246
4498
|
function captionFragmentHtml(label, number, text, revision) {
|
|
3247
|
-
const untracked =
|
|
3248
|
-
document:
|
|
4499
|
+
const untracked = chunk2A4MDHJR_cjs.docxPackage({
|
|
4500
|
+
document: chunk2A4MDHJR_cjs.documentXml(captionParagraphXml(label, number, text)),
|
|
3249
4501
|
styles: CAPTION_STYLES,
|
|
3250
4502
|
title: "Caption"
|
|
3251
4503
|
});
|
|
@@ -3264,7 +4516,7 @@ function TransformAction({
|
|
|
3264
4516
|
icon
|
|
3265
4517
|
}) {
|
|
3266
4518
|
const state = react.useEditorCommand(TRANSFORMS[action]);
|
|
3267
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4519
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: `picture-${action}`, label, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3268
4520
|
react.DocxEditor.Toolbar.Action,
|
|
3269
4521
|
{
|
|
3270
4522
|
label,
|
|
@@ -3274,7 +4526,7 @@ function TransformAction({
|
|
|
3274
4526
|
onSelect: () => void state.execute(),
|
|
3275
4527
|
className: `native-docx-picture-${action}`
|
|
3276
4528
|
}
|
|
3277
|
-
);
|
|
4529
|
+
) });
|
|
3278
4530
|
}
|
|
3279
4531
|
function insertCaption(editor, label, text, track) {
|
|
3280
4532
|
const surface = editor.surface;
|
|
@@ -3318,9 +4570,9 @@ function insertCaption(editor, label, text, track) {
|
|
|
3318
4570
|
function CaptionButton({ defaultLabel = "Figure" }) {
|
|
3319
4571
|
const editor = react.useDocxEditor();
|
|
3320
4572
|
const track = useTrackedOrNoted();
|
|
3321
|
-
const [label, setLabel] =
|
|
3322
|
-
const [text, setText] =
|
|
3323
|
-
const [error, setError] =
|
|
4573
|
+
const [label, setLabel] = React4.useState(defaultLabel);
|
|
4574
|
+
const [text, setText] = React4.useState("");
|
|
4575
|
+
const [error, setError] = React4.useState("");
|
|
3324
4576
|
return /* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label: "Insert caption", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Captions, { size: 16 }), testId: "docx-insert-caption", children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3325
4577
|
"form",
|
|
3326
4578
|
{
|
|
@@ -3372,9 +4624,9 @@ function CaptionButton({ defaultLabel = "Figure" }) {
|
|
|
3372
4624
|
}
|
|
3373
4625
|
function PictureButtons() {
|
|
3374
4626
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3375
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageWrap, {}),
|
|
3376
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageProperties, {}),
|
|
3377
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageAltText, {}),
|
|
4627
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "picture-wrap", label: "Wrap text", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageWrap, {}) }),
|
|
4628
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "picture-properties", label: "Size and position", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageProperties, {}) }),
|
|
4629
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "picture-alt-text", label: "Alt text", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageAltText, {}) }),
|
|
3378
4630
|
/* @__PURE__ */ jsxRuntime.jsx(TransformAction, { action: "rotateCW", label: "Rotate right 90\xB0", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCw, { size: 16 }) }),
|
|
3379
4631
|
/* @__PURE__ */ jsxRuntime.jsx(TransformAction, { action: "rotateCCW", label: "Rotate left 90\xB0", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { size: 16 }) }),
|
|
3380
4632
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3386,7 +4638,7 @@ function PictureButtons() {
|
|
|
3386
4638
|
}
|
|
3387
4639
|
),
|
|
3388
4640
|
/* @__PURE__ */ jsxRuntime.jsx(TransformAction, { action: "flipV", label: "Flip vertical", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FlipVertical2, { size: 16 }) }),
|
|
3389
|
-
/* @__PURE__ */ jsxRuntime.jsx(CaptionButton, {})
|
|
4641
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "picture-caption", label: "Insert caption", children: /* @__PURE__ */ jsxRuntime.jsx(CaptionButton, {}) })
|
|
3390
4642
|
] });
|
|
3391
4643
|
}
|
|
3392
4644
|
var LAYOUT_TAB = "Layout";
|
|
@@ -3439,9 +4691,9 @@ function tableCells(root, paragraphId) {
|
|
|
3439
4691
|
}
|
|
3440
4692
|
function TableTabKeys({ scope }) {
|
|
3441
4693
|
const editor = react.useDocxEditor();
|
|
3442
|
-
const latest =
|
|
4694
|
+
const latest = React4.useRef(editor);
|
|
3443
4695
|
latest.current = editor;
|
|
3444
|
-
|
|
4696
|
+
React4.useEffect(() => {
|
|
3445
4697
|
const element = scope.current;
|
|
3446
4698
|
if (!element) return;
|
|
3447
4699
|
const onKeyDown = (event) => {
|
|
@@ -3587,7 +4839,7 @@ function covered(room, vector, receipt) {
|
|
|
3587
4839
|
}
|
|
3588
4840
|
return true;
|
|
3589
4841
|
}
|
|
3590
|
-
var EditorBoundary = class extends
|
|
4842
|
+
var EditorBoundary = class extends React4__default.default.Component {
|
|
3591
4843
|
state = {};
|
|
3592
4844
|
static getDerivedStateFromError(error) {
|
|
3593
4845
|
return { error };
|
|
@@ -3600,8 +4852,8 @@ var EditorBoundary = class extends React3__default.default.Component {
|
|
|
3600
4852
|
}
|
|
3601
4853
|
};
|
|
3602
4854
|
function DocxParticipants({ session }) {
|
|
3603
|
-
const [people, setPeople] =
|
|
3604
|
-
|
|
4855
|
+
const [people, setPeople] = React4.useState([]);
|
|
4856
|
+
React4.useEffect(() => {
|
|
3605
4857
|
if (!session) return;
|
|
3606
4858
|
setPeople(session.participants());
|
|
3607
4859
|
return session.subscribeParticipants(setPeople);
|
|
@@ -3630,7 +4882,7 @@ function DocxRibbon({
|
|
|
3630
4882
|
badge,
|
|
3631
4883
|
imageGeneration
|
|
3632
4884
|
}) {
|
|
3633
|
-
const [selected, setTab] =
|
|
4885
|
+
const [selected, setTab] = React4.useState("Home");
|
|
3634
4886
|
const contextual = useContextualTabs(selected);
|
|
3635
4887
|
useGenerateImageTarget();
|
|
3636
4888
|
const tab = contextual.shown;
|
|
@@ -3649,46 +4901,53 @@ function DocxRibbon({
|
|
|
3649
4901
|
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Undo, {}),
|
|
3650
4902
|
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Redo, {}),
|
|
3651
4903
|
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Save, {}),
|
|
3652
|
-
|
|
3653
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
4904
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RibbonOverflow, { tab, children: [
|
|
4905
|
+
tab === "Home" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4906
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-style", label: "Styles", priority: 80, children: /* @__PURE__ */ jsxRuntime.jsx(StyleGallery, {}) }),
|
|
4907
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-bold", label: "Bold", priority: 100, children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Bold, {}) }),
|
|
4908
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-italic", label: "Italic", priority: 95, children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Italic, {}) }),
|
|
4909
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-underline", label: "Underline", priority: 90, children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Underline, {}) }),
|
|
4910
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-font", label: "Font", priority: 60, children: /* @__PURE__ */ jsxRuntime.jsxs(RibbonMenu, { label: "Font", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { size: 16 }), children: [
|
|
4911
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.FontFamily, {}),
|
|
4912
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.FontSize, {}),
|
|
4913
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.FontColor, {}),
|
|
4914
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Highlight, {})
|
|
4915
|
+
] }) }),
|
|
4916
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "home-more-formatting", label: "More formatting", priority: 50, children: /* @__PURE__ */ jsxRuntime.jsxs(RibbonMenu, { label: "More formatting", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pilcrow, { size: 16 }), children: [
|
|
4917
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Alignment, {}),
|
|
4918
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.BulletList, {}),
|
|
4919
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.NumberedList, {}),
|
|
4920
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.LineSpacing, {}),
|
|
4921
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Indent, {}),
|
|
4922
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Outdent, {}),
|
|
4923
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Strike, {}),
|
|
4924
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ClearFormatting, {})
|
|
4925
|
+
] }) })
|
|
4926
|
+
] }),
|
|
4927
|
+
tab === "Insert" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4928
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-table", label: "Table", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableInsert, {}) }),
|
|
4929
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-picture", label: "Picture", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageInsert, {}) }),
|
|
4930
|
+
imageGeneration && /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-generate-image", label: "Generate image", children: /* @__PURE__ */ jsxRuntime.jsx(GenerateImageButton, { generation: imageGeneration }) }),
|
|
4931
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-page-break", label: "Page break", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Button, { slotId: "insert.pageBreak" }) }),
|
|
4932
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-link", label: "Link", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Link, {}) }),
|
|
4933
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-defined-term", label: "Defined term", children: /* @__PURE__ */ jsxRuntime.jsx(DefinedTermButtons, {}) }),
|
|
4934
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsxRuntime.jsx(QuickParts, {}) }),
|
|
4935
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "insert-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsxRuntime.jsx(CrossReferenceButton, {}) })
|
|
3662
4936
|
] }),
|
|
3663
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3667
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3668
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.
|
|
4937
|
+
/* @__PURE__ */ jsxRuntime.jsx(LayoutTabContent, { tab }),
|
|
4938
|
+
tab === "Design" && /* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "design-house-template", label: "House template", children: /* @__PURE__ */ jsxRuntime.jsx(HouseTemplatePanel, {}) }),
|
|
4939
|
+
tab === "References" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4940
|
+
/* @__PURE__ */ jsxRuntime.jsx(NoteButtons, {}),
|
|
4941
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "references-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsxRuntime.jsx(CrossReferenceButton, {}) }),
|
|
4942
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "references-update-cross-references", label: "Update cross-references", children: /* @__PURE__ */ jsxRuntime.jsx(UpdateCrossReferencesButton, {}) })
|
|
4943
|
+
] }),
|
|
4944
|
+
tab === "Review" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4945
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "review-editing-mode", label: "Editing mode", priority: 10, children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.EditingMode, {}) }),
|
|
4946
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "review-comments", label: "Comments", children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Comments, {}) }),
|
|
4947
|
+
/* @__PURE__ */ jsxRuntime.jsx(RibbonItem, { id: "review-options", label: "Review options", children: /* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label: "Review options", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersRound, { size: 16 }), children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Reviewers, {}) }) })
|
|
3672
4948
|
] })
|
|
3673
4949
|
] }),
|
|
3674
|
-
|
|
3675
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableInsert, {}),
|
|
3676
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.ImageInsert, {}),
|
|
3677
|
-
imageGeneration && /* @__PURE__ */ jsxRuntime.jsx(GenerateImageButton, { generation: imageGeneration }),
|
|
3678
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Button, { slotId: "insert.pageBreak" }),
|
|
3679
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Link, {}),
|
|
3680
|
-
/* @__PURE__ */ jsxRuntime.jsx(DefinedTermButtons, {}),
|
|
3681
|
-
/* @__PURE__ */ jsxRuntime.jsx(QuickParts, {})
|
|
3682
|
-
] }),
|
|
3683
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableCellFill, { hidden: true }),
|
|
3684
|
-
/* @__PURE__ */ jsxRuntime.jsx(LayoutTabContent, { tab }),
|
|
3685
|
-
tab === "Design" && /* @__PURE__ */ jsxRuntime.jsx(HouseTemplatePanel, {}),
|
|
3686
|
-
tab === "References" && /* @__PURE__ */ jsxRuntime.jsx(NoteButtons, {}),
|
|
3687
|
-
tab === "Review" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3688
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.EditingMode, {}),
|
|
3689
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Comments, {}),
|
|
3690
|
-
/* @__PURE__ */ jsxRuntime.jsx(RibbonMenu, { label: "Review options", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { size: 16 }), children: /* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.Reviewers, {}) })
|
|
3691
|
-
] })
|
|
4950
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Toolbar.TableCellFill, { hidden: true })
|
|
3692
4951
|
] }),
|
|
3693
4952
|
badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "native-docx-ribbon-badge", "data-testid": "docx-ribbon-badge", children: badge })
|
|
3694
4953
|
] });
|
|
@@ -3704,18 +4963,18 @@ function NativeDocxEditor({
|
|
|
3704
4963
|
stream,
|
|
3705
4964
|
adapter
|
|
3706
4965
|
}) {
|
|
3707
|
-
const [ready, setReady] =
|
|
3708
|
-
const [status, setStatus] =
|
|
3709
|
-
const revision =
|
|
3710
|
-
const stageRef =
|
|
3711
|
-
const ref =
|
|
4966
|
+
const [ready, setReady] = React4.useState(), [error, setError] = React4.useState(""), [retry, setRetry] = React4.useState(0);
|
|
4967
|
+
const [status, setStatus] = React4.useState("Connecting\u2026"), [dirty, setDirty] = React4.useState(false), [saving, setSaving] = React4.useState(false), [offline, setOffline] = React4.useState(false);
|
|
4968
|
+
const revision = React4.useRef(0);
|
|
4969
|
+
const stageRef = React4.useRef(null), fitCleanup = React4.useRef(void 0);
|
|
4970
|
+
const ref = React4.useRef(null), dirtyRef = React4.useRef(false), draftTimer = React4.useRef(void 0);
|
|
3712
4971
|
const isDraft = draftContent !== void 0;
|
|
3713
|
-
const streamRef =
|
|
4972
|
+
const streamRef = React4.useRef(stream);
|
|
3714
4973
|
streamRef.current = stream;
|
|
3715
|
-
const streamWriter =
|
|
3716
|
-
const streamFinished =
|
|
3717
|
-
const streamTimer =
|
|
3718
|
-
const [streamAttempt, setStreamAttempt] =
|
|
4974
|
+
const streamWriter = React4.useRef(null);
|
|
4975
|
+
const streamFinished = React4.useRef(false);
|
|
4976
|
+
const streamTimer = React4.useRef(void 0);
|
|
4977
|
+
const [streamAttempt, setStreamAttempt] = React4.useState(0);
|
|
3719
4978
|
function updateStream() {
|
|
3720
4979
|
const current = streamRef.current;
|
|
3721
4980
|
if (!current || !streamWriter.current || streamFinished.current) return;
|
|
@@ -3731,7 +4990,7 @@ function NativeDocxEditor({
|
|
|
3731
4990
|
);
|
|
3732
4991
|
}
|
|
3733
4992
|
}
|
|
3734
|
-
|
|
4993
|
+
React4.useEffect(() => {
|
|
3735
4994
|
if (!streamRef.current) return;
|
|
3736
4995
|
if (!streamRef.current.busy) {
|
|
3737
4996
|
clearTimeout(streamTimer.current);
|
|
@@ -3744,8 +5003,8 @@ function NativeDocxEditor({
|
|
|
3744
5003
|
}, 120);
|
|
3745
5004
|
}
|
|
3746
5005
|
}, [stream?.content, stream?.busy, stream?.error, streamAttempt]);
|
|
3747
|
-
|
|
3748
|
-
|
|
5006
|
+
React4.useEffect(() => () => clearTimeout(streamTimer.current), []);
|
|
5007
|
+
React4.useEffect(() => {
|
|
3749
5008
|
let cancelled = false;
|
|
3750
5009
|
let room;
|
|
3751
5010
|
const cleanups = [];
|
|
@@ -3873,7 +5132,7 @@ function NativeDocxEditor({
|
|
|
3873
5132
|
room?.destroy();
|
|
3874
5133
|
};
|
|
3875
5134
|
}, [documentId, isDraft, snapshot, retry]);
|
|
3876
|
-
|
|
5135
|
+
React4.useEffect(() => {
|
|
3877
5136
|
adapter.onDirtyChange?.(dirty);
|
|
3878
5137
|
const beforeUnload = (e) => {
|
|
3879
5138
|
if (dirtyRef.current) e.preventDefault();
|
|
@@ -3885,6 +5144,7 @@ function NativeDocxEditor({
|
|
|
3885
5144
|
};
|
|
3886
5145
|
}, [dirty]);
|
|
3887
5146
|
async function exportDocument() {
|
|
5147
|
+
runBeforeSave(ref.current);
|
|
3888
5148
|
const data = await ref.current?.save();
|
|
3889
5149
|
if (!data) return;
|
|
3890
5150
|
const url = URL.createObjectURL(
|
|
@@ -3898,7 +5158,7 @@ function NativeDocxEditor({
|
|
|
3898
5158
|
a.click();
|
|
3899
5159
|
setTimeout(() => URL.revokeObjectURL(url), 5e3);
|
|
3900
5160
|
}
|
|
3901
|
-
|
|
5161
|
+
React4.useLayoutEffect(() => {
|
|
3902
5162
|
const editor = ref.current;
|
|
3903
5163
|
return () => {
|
|
3904
5164
|
if (isDraft && editor && dirtyRef.current)
|
|
@@ -3911,6 +5171,7 @@ function NativeDocxEditor({
|
|
|
3911
5171
|
async function saveVersion() {
|
|
3912
5172
|
if (!ready || saving || stream) return;
|
|
3913
5173
|
setSaving(true);
|
|
5174
|
+
runBeforeSave(ref.current);
|
|
3914
5175
|
const atRevision = revision.current;
|
|
3915
5176
|
try {
|
|
3916
5177
|
const result = isDraft ? await (async () => {
|
|
@@ -4034,7 +5295,7 @@ function NativeDocxEditor({
|
|
|
4034
5295
|
load: adapter.definitions,
|
|
4035
5296
|
editable: !stream && !snapshot && ready.canEdit,
|
|
4036
5297
|
notify: adapter.notify,
|
|
4037
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
5298
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4038
5299
|
HouseTemplateProvider,
|
|
4039
5300
|
{
|
|
4040
5301
|
enabled: !stream,
|
|
@@ -4042,67 +5303,76 @@ function NativeDocxEditor({
|
|
|
4042
5303
|
documentId: isDraft || snapshot ? void 0 : documentId,
|
|
4043
5304
|
editable: !stream && !snapshot && ready.canEdit,
|
|
4044
5305
|
notify: adapter.notify,
|
|
4045
|
-
children:
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
5306
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5307
|
+
CrossReferencesProvider,
|
|
5308
|
+
{
|
|
5309
|
+
editable: !stream && !snapshot && ready.canEdit,
|
|
5310
|
+
references: adapter.references,
|
|
5311
|
+
documentId,
|
|
5312
|
+
notify: adapter.notify,
|
|
5313
|
+
children: [
|
|
5314
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5315
|
+
react.DocxEditor.RevisionMarkup,
|
|
5316
|
+
{
|
|
5317
|
+
insertions: { mark: "underline", color: "blue" },
|
|
5318
|
+
deletions: { mark: "strikethrough", color: "red" },
|
|
5319
|
+
movedFrom: { mark: "doubleStrikethrough", color: "green" },
|
|
5320
|
+
movedTo: { mark: "doubleUnderline", color: "green" },
|
|
5321
|
+
trackMoves: true
|
|
5322
|
+
}
|
|
5323
|
+
),
|
|
5324
|
+
!stream && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5325
|
+
DocxRibbon,
|
|
5326
|
+
{
|
|
5327
|
+
onSave: () => void saveVersion(),
|
|
5328
|
+
imageGeneration: adapter.imageGeneration && {
|
|
5329
|
+
notify: adapter.notify,
|
|
5330
|
+
...adapter.imageGeneration
|
|
5331
|
+
},
|
|
5332
|
+
badge: (
|
|
5333
|
+
// Says the document is shared live, in place of a title row above the ribbon.
|
|
5334
|
+
ready.room && ready.canEdit && !snapshot ? /* @__PURE__ */ jsxRuntime.jsx("span", { title: "Edits sync live with everyone who has this document open", children: "Co-edit mode" }) : void 0
|
|
5335
|
+
)
|
|
5336
|
+
}
|
|
5337
|
+
),
|
|
5338
|
+
!stream && /* @__PURE__ */ jsxRuntime.jsx(WordShortcuts, { scope: stageRef }),
|
|
5339
|
+
!stream && /* @__PURE__ */ jsxRuntime.jsx(TableTabKeys, { scope: stageRef }),
|
|
5340
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5341
|
+
"div",
|
|
5342
|
+
{
|
|
5343
|
+
className: "native-docx-stage",
|
|
5344
|
+
ref: stageRef,
|
|
5345
|
+
onMouseDownCapture: (event) => {
|
|
5346
|
+
if (event.button === 2 && ref.current?.getSelectionPlacement())
|
|
5347
|
+
event.preventDefault();
|
|
5348
|
+
},
|
|
5349
|
+
children: [
|
|
5350
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.DocxEditor.Viewport, { className: "native-docx-viewport", children: [
|
|
5351
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Content, {}),
|
|
5352
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5353
|
+
DocxMentions,
|
|
5354
|
+
{
|
|
5355
|
+
initialCommentId,
|
|
5356
|
+
mentions: adapter.mentions,
|
|
5357
|
+
notify: adapter.notify,
|
|
5358
|
+
getAgentStatus: adapter.getAgentStatus,
|
|
5359
|
+
requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
|
|
5360
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxCommentActivity, {}) }) })
|
|
5361
|
+
}
|
|
5362
|
+
),
|
|
5363
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HeaderFooterChrome, {}),
|
|
5364
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.NotesChrome, {}),
|
|
5365
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Equation, {}),
|
|
5366
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HyperLink, {}),
|
|
5367
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxContextMenuExtras, {}) })
|
|
5368
|
+
] }),
|
|
5369
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.PageNumber, {})
|
|
5370
|
+
]
|
|
5371
|
+
}
|
|
4067
5372
|
)
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
!stream && /* @__PURE__ */ jsxRuntime.jsx(TableTabKeys, { scope: stageRef }),
|
|
4072
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4073
|
-
"div",
|
|
4074
|
-
{
|
|
4075
|
-
className: "native-docx-stage",
|
|
4076
|
-
ref: stageRef,
|
|
4077
|
-
onMouseDownCapture: (event) => {
|
|
4078
|
-
if (event.button === 2 && ref.current?.getSelectionPlacement())
|
|
4079
|
-
event.preventDefault();
|
|
4080
|
-
},
|
|
4081
|
-
children: [
|
|
4082
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.DocxEditor.Viewport, { className: "native-docx-viewport", children: [
|
|
4083
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Content, {}),
|
|
4084
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4085
|
-
DocxMentions,
|
|
4086
|
-
{
|
|
4087
|
-
initialCommentId,
|
|
4088
|
-
mentions: adapter.mentions,
|
|
4089
|
-
notify: adapter.notify,
|
|
4090
|
-
getAgentStatus: adapter.getAgentStatus,
|
|
4091
|
-
requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
|
|
4092
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsxRuntime.jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(DocxCommentActivity, {}) }) })
|
|
4093
|
-
}
|
|
4094
|
-
),
|
|
4095
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HeaderFooterChrome, {}),
|
|
4096
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.NotesChrome, {}),
|
|
4097
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.Equation, {}),
|
|
4098
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.HyperLink, {}),
|
|
4099
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.ContextMenu, {})
|
|
4100
|
-
] }),
|
|
4101
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.DocxEditor.PageNumber, {})
|
|
4102
|
-
]
|
|
4103
|
-
}
|
|
4104
|
-
)
|
|
4105
|
-
]
|
|
5373
|
+
]
|
|
5374
|
+
}
|
|
5375
|
+
)
|
|
4106
5376
|
}
|
|
4107
5377
|
)
|
|
4108
5378
|
}
|
|
@@ -4202,6 +5472,9 @@ async function loadFonts(baseUrl) {
|
|
|
4202
5472
|
}
|
|
4203
5473
|
|
|
4204
5474
|
exports.BUILTIN_TEMPLATE_NAME = BUILTIN_TEMPLATE_NAME;
|
|
5475
|
+
exports.CrossReferenceDialog = CrossReferenceDialog;
|
|
5476
|
+
exports.CrossReferencesProvider = CrossReferencesProvider;
|
|
5477
|
+
exports.DEFAULT_CROSS_REFERENCES_LABELS = DEFAULT_CROSS_REFERENCES_LABELS;
|
|
4205
5478
|
exports.DEFAULT_DEFINED_TERMS_LABELS = DEFAULT_DEFINED_TERMS_LABELS;
|
|
4206
5479
|
exports.DEFINED_TERM_TRIGGER = DEFINED_TERM_TRIGGER;
|
|
4207
5480
|
exports.DefinedTermsProvider = DefinedTermsProvider;
|
|
@@ -4213,24 +5486,33 @@ exports.DocxParticipants = DocxParticipants;
|
|
|
4213
5486
|
exports.DocxRibbon = DocxRibbon;
|
|
4214
5487
|
exports.GenerateImageButton = GenerateImageButton;
|
|
4215
5488
|
exports.HouseTemplateProvider = HouseTemplateProvider;
|
|
5489
|
+
exports.LinkHoverCard = LinkHoverCard;
|
|
4216
5490
|
exports.NativeDocxEditor = NativeDocxEditor;
|
|
4217
5491
|
exports.builtinHouseTemplate = builtinHouseTemplate;
|
|
4218
5492
|
exports.contentPath = contentPath;
|
|
4219
5493
|
exports.editorPort = editorPort;
|
|
4220
5494
|
exports.findDefinitionsSection = findDefinitionsSection;
|
|
5495
|
+
exports.insertCrossReference = insertCrossReference;
|
|
4221
5496
|
exports.insertDefinedTerm = insertDefinedTerm;
|
|
5497
|
+
exports.insertDocumentReference = insertDocumentReference;
|
|
5498
|
+
exports.listTargets = listTargets;
|
|
4222
5499
|
exports.loadDocxFonts = loadDocxFonts;
|
|
4223
5500
|
exports.normalizeDocxExport = normalizeDocxExport;
|
|
5501
|
+
exports.paragraphNumber = paragraphNumber;
|
|
5502
|
+
exports.referenceText = referenceText;
|
|
5503
|
+
exports.referencesPort = referencesPort;
|
|
4224
5504
|
exports.resolveHouseTemplate = resolveHouseTemplate;
|
|
4225
5505
|
exports.reviewModule = reviewModule;
|
|
5506
|
+
exports.shortTitle = shortTitle;
|
|
4226
5507
|
exports.structuralPort = structuralPort;
|
|
4227
5508
|
exports.templateFileName = templateFileName;
|
|
4228
5509
|
exports.trackedOrNoted = trackedOrNoted;
|
|
5510
|
+
exports.useCrossReferences = useCrossReferences;
|
|
4229
5511
|
exports.useDefinedTerms = useDefinedTerms;
|
|
4230
5512
|
exports.useHouseTemplate = useHouseTemplate;
|
|
4231
5513
|
exports.useReview = useReview;
|
|
4232
5514
|
exports.useReviewItem = useReviewItem;
|
|
4233
5515
|
exports.useTrackedOrNoted = useTrackedOrNoted;
|
|
4234
5516
|
exports.withDirectEditing = withDirectEditing;
|
|
4235
|
-
//# sourceMappingURL=chunk-
|
|
4236
|
-
//# sourceMappingURL=chunk-
|
|
5517
|
+
//# sourceMappingURL=chunk-ZWWN4CUL.cjs.map
|
|
5518
|
+
//# sourceMappingURL=chunk-ZWWN4CUL.cjs.map
|