@arbidocs/blocks 0.4.93 → 0.4.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/index.cjs +283 -283
- package/dist/agents/index.js +7 -7
- package/dist/{chunk-6XS5IJ5R.cjs → chunk-3OXWJ3CZ.cjs} +5 -5
- package/dist/{chunk-6XS5IJ5R.cjs.map → chunk-3OXWJ3CZ.cjs.map} +1 -1
- package/dist/{chunk-3WW32OUU.cjs → chunk-3US5OIDQ.cjs} +3 -3
- package/dist/{chunk-3WW32OUU.cjs.map → chunk-3US5OIDQ.cjs.map} +1 -1
- package/dist/chunk-AF6RDAJF.js +14 -0
- package/dist/chunk-AF6RDAJF.js.map +1 -0
- package/dist/chunk-AOFATOT3.cjs +196 -0
- package/dist/chunk-AOFATOT3.cjs.map +1 -0
- package/dist/chunk-D3QPYKZG.js +173 -0
- package/dist/chunk-D3QPYKZG.js.map +1 -0
- package/dist/{chunk-2ZDFVRGV.cjs → chunk-E2AAIMXO.cjs} +975 -61
- package/dist/chunk-E2AAIMXO.cjs.map +1 -0
- package/dist/{chunk-MROSCSPW.cjs → chunk-KKU7MUWE.cjs} +46 -46
- package/dist/{chunk-MROSCSPW.cjs.map → chunk-KKU7MUWE.cjs.map} +1 -1
- package/dist/{chunk-AMC5PMJ3.cjs → chunk-LENXDIMY.cjs} +36 -68
- package/dist/chunk-LENXDIMY.cjs.map +1 -0
- package/dist/{chunk-SF4BDUZS.js → chunk-PGDL26TQ.js} +3 -3
- package/dist/{chunk-SF4BDUZS.js.map → chunk-PGDL26TQ.js.map} +1 -1
- package/dist/chunk-RC25WMVB.cjs +16 -0
- package/dist/chunk-RC25WMVB.cjs.map +1 -0
- package/dist/{chunk-5YXG342J.cjs → chunk-RPCQBET5.cjs} +3 -3
- package/dist/{chunk-5YXG342J.cjs.map → chunk-RPCQBET5.cjs.map} +1 -1
- package/dist/{chunk-YFPIJUV3.cjs → chunk-RZGVMV6B.cjs} +5 -5
- package/dist/{chunk-YFPIJUV3.cjs.map → chunk-RZGVMV6B.cjs.map} +1 -1
- package/dist/{chunk-W2R7YVFM.js → chunk-WXLKMEMB.js} +970 -65
- package/dist/chunk-WXLKMEMB.js.map +1 -0
- package/dist/{chunk-BX62HJZU.js → chunk-YPKSLTL5.js} +3 -3
- package/dist/{chunk-BX62HJZU.js.map → chunk-YPKSLTL5.js.map} +1 -1
- package/dist/{chunk-UO74FLRK.js → chunk-Z3G65XHZ.js} +22 -53
- package/dist/chunk-Z3G65XHZ.js.map +1 -0
- package/dist/{chunk-W7NZRZ54.js → chunk-Z7OMEYDG.js} +3 -3
- package/dist/{chunk-W7NZRZ54.js.map → chunk-Z7OMEYDG.js.map} +1 -1
- package/dist/{chunk-UDLMLU6T.js → chunk-ZNDAXSDP.js} +3 -3
- package/dist/{chunk-UDLMLU6T.js.map → chunk-ZNDAXSDP.js.map} +1 -1
- package/dist/{chunk-SJVUKXS6.js → chunk-ZNGDEQBN.js} +8 -8
- package/dist/{chunk-SJVUKXS6.js.map → chunk-ZNGDEQBN.js.map} +1 -1
- package/dist/connect/docx.cjs +8 -6
- package/dist/connect/docx.cjs.map +1 -1
- package/dist/connect/docx.js +6 -4
- package/dist/connect/docx.js.map +1 -1
- package/dist/connect/index.cjs +55 -53
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +11 -9
- package/dist/connect/index.js.map +1 -1
- package/dist/docx/NativeDocxEditor.d.ts +6 -0
- package/dist/docx/definitions/DefinedTerms.d.ts +50 -0
- package/dist/docx/definitions/commands.d.ts +78 -0
- package/dist/docx/definitions/fragment.d.ts +29 -0
- package/dist/docx/definitions/port.d.ts +76 -0
- package/dist/docx/index.cjs +53 -15
- package/dist/docx/index.cjs.map +1 -1
- package/dist/docx/index.d.ts +3 -0
- package/dist/docx/index.js +5 -3
- package/dist/docx/index.js.map +1 -1
- package/dist/facts/index.cjs +9 -14
- package/dist/facts/index.cjs.map +1 -1
- package/dist/facts/index.js +5 -12
- package/dist/facts/index.js.map +1 -1
- package/dist/files/index.cjs +2 -2
- package/dist/files/index.js +2 -2
- package/dist/home/index.cjs +1 -1
- package/dist/home/index.js +1 -1
- package/dist/index.cjs +914 -774
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +102 -15
- package/dist/index.js.map +1 -1
- package/dist/settings/index.cjs +35 -35
- package/dist/settings/index.js +3 -3
- 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/definitions.d.ts +92 -0
- package/dist/tags/glossary.d.ts +44 -0
- package/dist/tags/index.d.ts +2 -0
- package/dist/tags/ooxml.d.ts +46 -0
- package/dist/tags/tagTableDocx.d.ts +1 -1
- package/dist/workflow-canvas/index.cjs +50 -50
- package/dist/workflow-canvas/index.js +7 -7
- package/dist/workspaces/index.cjs +1 -1
- package/dist/workspaces/index.js +1 -1
- package/package.json +4 -4
- package/src/docx/README.md +11 -0
- package/dist/chunk-2ZDFVRGV.cjs.map +0 -1
- package/dist/chunk-AMC5PMJ3.cjs.map +0 -1
- package/dist/chunk-UO74FLRK.js.map +0 -1
- package/dist/chunk-W2R7YVFM.js.map +0 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { stylesXml, definitionBookmark, DEFINITION_BOOKMARK_PREFIX, compareTerms, groupDefinitions, definitionLabels, filterTermGroups, toDefinition, definitionIdOfBookmark, esc, parseDefinition, docxPackage, documentXml } from './chunk-D3QPYKZG.js';
|
|
3
|
+
import { filterMentionCandidates, MentionMenu, findMentionQuery, listOptionId, extractMentions } from './chunk-AA3PT6KR.js';
|
|
3
4
|
import { unzipSync, strFromU8, strToU8, zipSync } from 'fflate';
|
|
4
5
|
import { collectReviewItems, revisionItemsOf } from '@docx-editor.dev/core/store';
|
|
5
6
|
import React3, { createContext, useContext, useState, useRef, useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
|
|
6
7
|
import { useDocxEditor, ReviewRailContext, useEditorSnapshot, useChromeTranslate, DocxEditor, createFontSource } from '@docx-editor.dev/react';
|
|
7
8
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
9
|
import { createPortal } from 'react-dom';
|
|
9
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, splitMarkdownBlocks, AiMarkdown } from '@arbidocs/react/ui';
|
|
10
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Button, DialogFooter, cn, splitMarkdownBlocks, AiMarkdown } from '@arbidocs/react/ui';
|
|
10
11
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
11
12
|
import * as Y from 'yjs';
|
|
12
13
|
import { DOCUMENT_COLLABORATION_VERSIONS, collaborationModule } from '@arbidocs/coedit';
|
|
13
14
|
import { createHocuspocusCollaboration } from '@arbidocs/coedit/hocuspocus';
|
|
14
|
-
import { Type, Ellipsis, RefreshCw, WifiOff, Check, Download, Save } from 'lucide-react';
|
|
15
|
+
import { Type, Ellipsis, RefreshCw, WifiOff, Check, Download, Save, BookA, ListRestart } from 'lucide-react';
|
|
15
16
|
|
|
16
17
|
function normalizeDocxExport(data) {
|
|
17
18
|
const files = unzipSync(new Uint8Array(data));
|
|
@@ -508,18 +509,18 @@ function ReviewCardSlot({ children }) {
|
|
|
508
509
|
var DocxEditorReview = Object.assign(DocxEditorReviewRail, { Card: ReviewCardSlot });
|
|
509
510
|
|
|
510
511
|
// src/docx/mentions.ts
|
|
511
|
-
function mentionCandidates(
|
|
512
|
+
function mentionCandidates(mentions2) {
|
|
512
513
|
return [
|
|
513
514
|
{ id: "arbi", label: "ARBI", kind: "assistant" },
|
|
514
|
-
...
|
|
515
|
+
...mentions2.filter((person) => person.name.trim()).map((person) => ({
|
|
515
516
|
id: person.id,
|
|
516
517
|
label: person.name,
|
|
517
518
|
kind: person.kind === "agent" ? "assistant" : "user"
|
|
518
519
|
}))
|
|
519
520
|
];
|
|
520
521
|
}
|
|
521
|
-
function mentionedDocxRecipients(text,
|
|
522
|
-
return extractMentions(text, mentionCandidates(
|
|
522
|
+
function mentionedDocxRecipients(text, mentions2) {
|
|
523
|
+
return extractMentions(text, mentionCandidates(mentions2)).map((person) => person.id);
|
|
523
524
|
}
|
|
524
525
|
var ActivityContext = createContext({});
|
|
525
526
|
function DocxCommentActivity() {
|
|
@@ -602,7 +603,7 @@ function DocxCommentActivity() {
|
|
|
602
603
|
}
|
|
603
604
|
function DocxMentions({
|
|
604
605
|
children,
|
|
605
|
-
mentions = [],
|
|
606
|
+
mentions: mentions2 = [],
|
|
606
607
|
initialCommentId,
|
|
607
608
|
requestAgent,
|
|
608
609
|
getAgentStatus,
|
|
@@ -661,7 +662,7 @@ function DocxMentions({
|
|
|
661
662
|
const [suggestions, setSuggestions] = useState(null);
|
|
662
663
|
const [selected, setSelected] = useState(0);
|
|
663
664
|
const candidates = filterMentionCandidates(
|
|
664
|
-
mentionCandidates(
|
|
665
|
+
mentionCandidates(mentions2),
|
|
665
666
|
suggestions?.query || ""
|
|
666
667
|
).slice(0, 8);
|
|
667
668
|
useEffect(() => {
|
|
@@ -682,7 +683,7 @@ function DocxMentions({
|
|
|
682
683
|
}));
|
|
683
684
|
};
|
|
684
685
|
const hasAgent = submission.recipientIds.some(
|
|
685
|
-
(id) => id === "arbi" ||
|
|
686
|
+
(id) => id === "arbi" || mentions2.some((person) => person.id === id && person.kind === "agent")
|
|
686
687
|
);
|
|
687
688
|
if (hasAgent) update("delivering");
|
|
688
689
|
void requestAgent({
|
|
@@ -716,7 +717,7 @@ function DocxMentions({
|
|
|
716
717
|
"error"
|
|
717
718
|
);
|
|
718
719
|
});
|
|
719
|
-
}, [review.items, requestAgent, getAgentStatus,
|
|
720
|
+
}, [review.items, requestAgent, getAgentStatus, mentions2, notify]);
|
|
720
721
|
const choose = (name) => {
|
|
721
722
|
const field = input.current;
|
|
722
723
|
if (!field || !suggestions) return;
|
|
@@ -734,7 +735,7 @@ function DocxMentions({
|
|
|
734
735
|
'[data-testid="review-draft-input"], [data-testid="review-reply-input"]'
|
|
735
736
|
);
|
|
736
737
|
if (!field || field.readOnly || !requestAgent) return false;
|
|
737
|
-
const recipientIds = mentionedDocxRecipients(field.value,
|
|
738
|
+
const recipientIds = mentionedDocxRecipients(field.value, mentions2);
|
|
738
739
|
if (!recipientIds.length) return false;
|
|
739
740
|
pending.current = {
|
|
740
741
|
ids: new Set(review.items.filter((i) => i.kind === "comment").map((i) => i.item.id)),
|
|
@@ -781,7 +782,7 @@ function DocxMentions({
|
|
|
781
782
|
(entry) => entry.kind === "comment" && entry.parentId === commentId
|
|
782
783
|
);
|
|
783
784
|
const author = replies.at(-1)?.author || target.author;
|
|
784
|
-
const agent =
|
|
785
|
+
const agent = mentions2.find((person) => person.kind === "agent" && person.name === author);
|
|
785
786
|
if (agent || author === "ARBI" || author === "Assistant")
|
|
786
787
|
prefixMention(
|
|
787
788
|
field,
|
|
@@ -859,7 +860,7 @@ function DocxMentions({
|
|
|
859
860
|
onMouseDown: (event) => event.preventDefault(),
|
|
860
861
|
onClick: (event) => {
|
|
861
862
|
event.stopPropagation();
|
|
862
|
-
if (!mentionedDocxRecipients(field.value,
|
|
863
|
+
if (!mentionedDocxRecipients(field.value, mentions2).includes("arbi"))
|
|
863
864
|
prefixMention(field);
|
|
864
865
|
else field.focus();
|
|
865
866
|
},
|
|
@@ -904,6 +905,869 @@ function DocxMentions({
|
|
|
904
905
|
}
|
|
905
906
|
) });
|
|
906
907
|
}
|
|
908
|
+
|
|
909
|
+
// src/docx/definitions/fragment.ts
|
|
910
|
+
var DEFINED_TERM_STYLE = "DefinedTerm";
|
|
911
|
+
var FRAGMENT_STYLES = stylesXml(
|
|
912
|
+
"",
|
|
913
|
+
`<w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/><w:qFormat/></w: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>`
|
|
914
|
+
);
|
|
915
|
+
var textRun = (text, props = "") => `<w:r>${props ? `<w:rPr>${props}</w:rPr>` : ""}<w:t xml:space="preserve">${esc(text)}</w:t></w:r>`;
|
|
916
|
+
function definitionTooltip(definition) {
|
|
917
|
+
const line = `\u201C${definition.term}\u201D${definition.rest}`.replace(/\s+/g, " ").trim();
|
|
918
|
+
return line.length > 255 ? `${line.slice(0, 254)}\u2026` : line;
|
|
919
|
+
}
|
|
920
|
+
var definitionParagraphText = (definition) => `\u201C${definition.term}\u201D${definition.rest}`;
|
|
921
|
+
function definitionParagraphXml(definition, bookmark, id = 0) {
|
|
922
|
+
return `<w:p><w:bookmarkStart w:id="${id}" w:name="${esc(bookmark)}"/>${textRun("\u201C")}${textRun(
|
|
923
|
+
definition.term,
|
|
924
|
+
"<w:b/>"
|
|
925
|
+
)}${textRun("\u201D")}<w:bookmarkEnd w:id="${id}"/>${textRun(definition.rest)}</w:p>`;
|
|
926
|
+
}
|
|
927
|
+
function headingParagraphXml(text, styleId) {
|
|
928
|
+
return styleId ? `<w:p><w:pPr><w:pStyle w:val="${esc(styleId)}"/></w:pPr>${textRun(text)}</w:p>` : `<w:p><w:pPr><w:keepNext/></w:pPr>${textRun(text, "<w:b/>")}</w:p>`;
|
|
929
|
+
}
|
|
930
|
+
function termLinkXml(term, bookmark, tooltip) {
|
|
931
|
+
return `<w:p><w:hyperlink w:anchor="${esc(bookmark)}" w:tooltip="${esc(tooltip)}" w:history="1">${textRun(
|
|
932
|
+
term,
|
|
933
|
+
`<w:rStyle w:val="${DEFINED_TERM_STYLE}"/>`
|
|
934
|
+
)}</w:hyperlink></w:p>`;
|
|
935
|
+
}
|
|
936
|
+
function base64(bytes) {
|
|
937
|
+
let binary = "";
|
|
938
|
+
for (let i = 0; i < bytes.length; i += 32768)
|
|
939
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
940
|
+
return btoa(binary);
|
|
941
|
+
}
|
|
942
|
+
function fragmentHtml(body, covered2) {
|
|
943
|
+
const bytes = docxPackage({
|
|
944
|
+
document: documentXml(body),
|
|
945
|
+
styles: FRAGMENT_STYLES,
|
|
946
|
+
title: "Defined terms"
|
|
947
|
+
});
|
|
948
|
+
return `<div data-docx-fragment="${base64(bytes)}" data-docx-fragment-end="${covered2 ? "covered" : "open"}"></div>`;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// src/docx/definitions/commands.ts
|
|
952
|
+
var DEFINITIONS_HEADING = "Definitions";
|
|
953
|
+
var SECTION_TITLE = /^(definitions?(\s*(and|&)\s*interpretations?)?|interpretations?(\s*(and|&)\s*definitions?)?|defined\s+terms|glossary)$/i;
|
|
954
|
+
var NUMBERING = /^(?:(?:clause|section|article|schedule|part)\s+)?(?:[0-9]+(?:\.[0-9]+)*|[A-Z]|[ivxlc]+)[.):]?\s+(?:[-–—]\s*)?/i;
|
|
955
|
+
function isDefinitionsTitle(paragraph) {
|
|
956
|
+
if (!paragraph.topLevel) return false;
|
|
957
|
+
const title = paragraph.text.trim().replace(NUMBERING, "").replace(/[.:]+$/, "").trim();
|
|
958
|
+
return SECTION_TITLE.test(title) && (paragraph.heading || title.length <= 40);
|
|
959
|
+
}
|
|
960
|
+
function findDefinitionsSection(paragraphs) {
|
|
961
|
+
const title = paragraphs.findIndex(isDefinitionsTitle);
|
|
962
|
+
if (title < 0) return null;
|
|
963
|
+
let end = title + 1;
|
|
964
|
+
while (end < paragraphs.length && paragraphs[end].topLevel && !paragraphs[end].heading) end++;
|
|
965
|
+
return { title, start: title + 1, end };
|
|
966
|
+
}
|
|
967
|
+
var termOf = (paragraph) => parseDefinition(paragraph.text)?.term ?? null;
|
|
968
|
+
function insertionIndex(paragraphs, section, term, skip = /* @__PURE__ */ new Set()) {
|
|
969
|
+
let afterLast = section.start;
|
|
970
|
+
for (let i = section.start; i < section.end; i++) {
|
|
971
|
+
if (skip.has(paragraphs[i].id)) continue;
|
|
972
|
+
const other = termOf(paragraphs[i]);
|
|
973
|
+
if (other === null) continue;
|
|
974
|
+
if (compareTerms(other, term) > 0) return i;
|
|
975
|
+
afterLast = i + 1;
|
|
976
|
+
}
|
|
977
|
+
return afterLast;
|
|
978
|
+
}
|
|
979
|
+
var headingStyle = (paragraphs) => paragraphs.find((p) => p.topLevel && p.heading && p.styleId)?.styleId;
|
|
980
|
+
function insertParagraphs(port, index, body, count, keep) {
|
|
981
|
+
const before = port.paragraphs();
|
|
982
|
+
const kept = keep ? before.findIndex((p) => p.id === keep.paragraphId) : -1;
|
|
983
|
+
if (index < before.length) {
|
|
984
|
+
port.setCaret({ paragraphId: before[index].id, offset: 0 });
|
|
985
|
+
} else {
|
|
986
|
+
const last = before[before.length - 1];
|
|
987
|
+
port.setCaret({ paragraphId: last.id, offset: last.text.length });
|
|
988
|
+
port.splitParagraph();
|
|
989
|
+
const opened = port.paragraphs();
|
|
990
|
+
port.setCaret({ paragraphId: opened[opened.length - 1].id, offset: 0 });
|
|
991
|
+
}
|
|
992
|
+
if (!port.paste(body, "", true)) throw new Error("The definition could not be added.");
|
|
993
|
+
if (!keep || kept < 0) return keep;
|
|
994
|
+
const after = port.paragraphs();
|
|
995
|
+
const moved = index <= kept ? kept + count : kept;
|
|
996
|
+
return { paragraphId: after[moved]?.id ?? keep.paragraphId, offset: keep.offset };
|
|
997
|
+
}
|
|
998
|
+
function addDefinition(port, definition, keep) {
|
|
999
|
+
const paragraphs = port.paragraphs();
|
|
1000
|
+
const section = findDefinitionsSection(paragraphs);
|
|
1001
|
+
const paragraph = definitionParagraphXml(definition, definitionBookmark(definition.id));
|
|
1002
|
+
if (section)
|
|
1003
|
+
return insertParagraphs(
|
|
1004
|
+
port,
|
|
1005
|
+
insertionIndex(paragraphs, section, definition.term),
|
|
1006
|
+
paragraph,
|
|
1007
|
+
1,
|
|
1008
|
+
keep
|
|
1009
|
+
);
|
|
1010
|
+
return insertParagraphs(
|
|
1011
|
+
port,
|
|
1012
|
+
paragraphs.length,
|
|
1013
|
+
headingParagraphXml(DEFINITIONS_HEADING, headingStyle(paragraphs)) + paragraph,
|
|
1014
|
+
2,
|
|
1015
|
+
keep
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
var hasBookmark = (paragraphs, name) => paragraphs.some((p) => p.bookmarks.includes(name));
|
|
1019
|
+
function insertDefinedTerm(port, definition, options = {}) {
|
|
1020
|
+
const start = port.caret();
|
|
1021
|
+
if (!start) throw new Error("Place the cursor where the term should go.");
|
|
1022
|
+
let caret = start;
|
|
1023
|
+
if (options.replace) {
|
|
1024
|
+
caret = { paragraphId: start.paragraphId, offset: Math.max(0, start.offset - options.replace) };
|
|
1025
|
+
port.deleteRange(caret, start);
|
|
1026
|
+
}
|
|
1027
|
+
const bookmark = definitionBookmark(definition.id);
|
|
1028
|
+
const addedDefinition = !hasBookmark(port.paragraphs(), bookmark);
|
|
1029
|
+
if (addedDefinition) caret = addDefinition(port, definition, caret) ?? caret;
|
|
1030
|
+
port.setCaret(caret);
|
|
1031
|
+
if (!port.paste(
|
|
1032
|
+
termLinkXml(definition.term, bookmark, definitionTooltip(definition)),
|
|
1033
|
+
definition.term,
|
|
1034
|
+
false
|
|
1035
|
+
))
|
|
1036
|
+
throw new Error("The term could not be inserted.");
|
|
1037
|
+
port.setCaret({ paragraphId: caret.paragraphId, offset: caret.offset + definition.term.length });
|
|
1038
|
+
return { addedDefinition };
|
|
1039
|
+
}
|
|
1040
|
+
var escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1041
|
+
var mentions = (text, term) => new RegExp(`(^|[^\\p{L}\\p{N}])${escapeRegExp(term)}($|[^\\p{L}\\p{N}])`, "iu").test(text);
|
|
1042
|
+
function updateDefinitions(port, definitions) {
|
|
1043
|
+
const result = {
|
|
1044
|
+
added: [],
|
|
1045
|
+
refreshed: [],
|
|
1046
|
+
reordered: [],
|
|
1047
|
+
unused: [],
|
|
1048
|
+
unknown: []
|
|
1049
|
+
};
|
|
1050
|
+
let paragraphs = port.paragraphs();
|
|
1051
|
+
const linked = new Set(
|
|
1052
|
+
paragraphs.flatMap(
|
|
1053
|
+
(p) => p.links.map((l) => l.anchor).filter((a) => a.startsWith(DEFINITION_BOOKMARK_PREFIX))
|
|
1054
|
+
)
|
|
1055
|
+
);
|
|
1056
|
+
const declared = /* @__PURE__ */ new Map();
|
|
1057
|
+
for (const p of paragraphs)
|
|
1058
|
+
for (const b of p.bookmarks)
|
|
1059
|
+
if (b.startsWith(DEFINITION_BOOKMARK_PREFIX) && !declared.has(b)) declared.set(b, p);
|
|
1060
|
+
const factOf = (bookmark) => {
|
|
1061
|
+
const id = definitionIdOfBookmark(bookmark);
|
|
1062
|
+
return id ? definitions.get(id) : void 0;
|
|
1063
|
+
};
|
|
1064
|
+
for (const bookmark of [...linked, ...declared.keys()])
|
|
1065
|
+
if (!factOf(bookmark) && !result.unknown.includes(bookmark)) result.unknown.push(bookmark);
|
|
1066
|
+
const section = findDefinitionsSection(paragraphs);
|
|
1067
|
+
const rewrite = /* @__PURE__ */ new Map();
|
|
1068
|
+
for (const [bookmark, paragraph] of declared) {
|
|
1069
|
+
const fact = factOf(bookmark);
|
|
1070
|
+
if (fact && paragraph.text !== definitionParagraphText(fact)) {
|
|
1071
|
+
rewrite.set(paragraph.id, fact);
|
|
1072
|
+
result.refreshed.push(fact.term);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (section) {
|
|
1076
|
+
let previous = null;
|
|
1077
|
+
for (let i = section.start; i < section.end; i++) {
|
|
1078
|
+
const p = paragraphs[i];
|
|
1079
|
+
const term = termOf(p);
|
|
1080
|
+
if (term === null) continue;
|
|
1081
|
+
const bookmark = p.bookmarks.find((b) => b.startsWith(DEFINITION_BOOKMARK_PREFIX));
|
|
1082
|
+
const fact = bookmark ? factOf(bookmark) : void 0;
|
|
1083
|
+
if (previous !== null && compareTerms(term, previous) < 0 && fact) {
|
|
1084
|
+
if (!rewrite.has(p.id)) result.reordered.push(fact.term);
|
|
1085
|
+
rewrite.set(p.id, fact);
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
previous = term;
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
for (const id of [...rewrite.keys()].reverse()) {
|
|
1092
|
+
const index = paragraphs.findIndex((p) => p.id === id);
|
|
1093
|
+
const previous = paragraphs[index - 1];
|
|
1094
|
+
const target = paragraphs[index];
|
|
1095
|
+
if (!previous) continue;
|
|
1096
|
+
port.deleteRange(
|
|
1097
|
+
{ paragraphId: previous.id, offset: previous.text.length },
|
|
1098
|
+
{ paragraphId: target.id, offset: target.text.length }
|
|
1099
|
+
);
|
|
1100
|
+
paragraphs = port.paragraphs();
|
|
1101
|
+
}
|
|
1102
|
+
const toAdd = [...rewrite.values()];
|
|
1103
|
+
for (const bookmark of linked) {
|
|
1104
|
+
const fact = factOf(bookmark);
|
|
1105
|
+
if (fact && !declared.has(bookmark) && !toAdd.some((d) => d.id === fact.id)) {
|
|
1106
|
+
toAdd.push(fact);
|
|
1107
|
+
result.added.push(fact.term);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
toAdd.sort((a, b) => compareTerms(a.term, b.term));
|
|
1111
|
+
for (const definition of toAdd) addDefinition(port, definition);
|
|
1112
|
+
paragraphs = port.paragraphs();
|
|
1113
|
+
const after = findDefinitionsSection(paragraphs);
|
|
1114
|
+
if (after) {
|
|
1115
|
+
const inSection = (i) => i >= after.title && i < after.end;
|
|
1116
|
+
const outside = paragraphs.filter((_, i) => !inSection(i));
|
|
1117
|
+
const linkedNow = new Set(outside.flatMap((p) => p.links.map((l) => l.anchor)));
|
|
1118
|
+
const outsideText = outside.map((p) => p.text).join("\n");
|
|
1119
|
+
for (let i = after.start; i < after.end; i++) {
|
|
1120
|
+
const p = paragraphs[i];
|
|
1121
|
+
const term = termOf(p);
|
|
1122
|
+
if (term === null) continue;
|
|
1123
|
+
const used = p.bookmarks.some((b) => linkedNow.has(b)) || mentions(outsideText, term);
|
|
1124
|
+
if (!used) result.unused.push({ term, paragraphId: p.id });
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return result;
|
|
1128
|
+
}
|
|
1129
|
+
function definitionOfAnchor(anchor, definitions) {
|
|
1130
|
+
const id = definitionIdOfBookmark(anchor.replace(/^#/, ""));
|
|
1131
|
+
return id ? definitions.get(id) : void 0;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
// src/docx/definitions/port.ts
|
|
1135
|
+
var attr = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
|
|
1136
|
+
var HEADING_STYLE = /^(heading|berschrift|titre|t[ií]tulo|titolo|kop)\s*\d/i;
|
|
1137
|
+
function readParagraphs(root) {
|
|
1138
|
+
const out = [];
|
|
1139
|
+
const body = root.children?.find((n) => n.kind === "body") ?? root;
|
|
1140
|
+
const visit = (node, topLevel, pending) => {
|
|
1141
|
+
for (const child of node.children ?? []) {
|
|
1142
|
+
if (child.kind === "paragraph") {
|
|
1143
|
+
out.push(readParagraph(child, topLevel, pending.splice(0)));
|
|
1144
|
+
} else if (child.localName === "bookmarkStart") {
|
|
1145
|
+
const name = attr(child, "name");
|
|
1146
|
+
if (name) pending.push(name);
|
|
1147
|
+
} else if (child.localName === "tbl" || child.localName === "tr" || child.localName === "tc") {
|
|
1148
|
+
visit(child, false, pending);
|
|
1149
|
+
} else if (child.localName === "sdt" || child.localName === "sdtContent") {
|
|
1150
|
+
visit(child, topLevel, pending);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
visit(body, true, []);
|
|
1155
|
+
return out;
|
|
1156
|
+
}
|
|
1157
|
+
function readParagraph(node, topLevel, bookmarks) {
|
|
1158
|
+
let text = "";
|
|
1159
|
+
const links = [];
|
|
1160
|
+
let styleId;
|
|
1161
|
+
let outline = false;
|
|
1162
|
+
const walk = (n, link) => {
|
|
1163
|
+
for (const c of n.children ?? []) {
|
|
1164
|
+
if (c.kind === "paragraphProperties" || c.localName === "pPr") {
|
|
1165
|
+
for (const p of c.children ?? []) {
|
|
1166
|
+
if (p.localName === "pStyle") styleId = attr(p, "val");
|
|
1167
|
+
if (p.localName === "outlineLvl" && Number(attr(p, "val")) < 9) outline = true;
|
|
1168
|
+
}
|
|
1169
|
+
continue;
|
|
1170
|
+
}
|
|
1171
|
+
if (c.localName === "delText" || c.localName === "del" || c.localName === "rPr") continue;
|
|
1172
|
+
if (c.localName === "bookmarkStart") {
|
|
1173
|
+
const name = attr(c, "name");
|
|
1174
|
+
if (name) bookmarks.push(name);
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
if (c.localName === "hyperlink") {
|
|
1178
|
+
const anchor = attr(c, "anchor");
|
|
1179
|
+
const next = anchor ? { anchor, text: "" } : void 0;
|
|
1180
|
+
walk(c, next ?? link);
|
|
1181
|
+
if (next) links.push(next);
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
if (c.kind === "textValue") {
|
|
1185
|
+
text += c.value ?? "";
|
|
1186
|
+
if (link) link.text += c.value ?? "";
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
if (c.localName === "tab") text += " ";
|
|
1190
|
+
walk(c, link);
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
walk(node);
|
|
1194
|
+
return {
|
|
1195
|
+
id: node.id,
|
|
1196
|
+
text,
|
|
1197
|
+
heading: outline || !!styleId && HEADING_STYLE.test(styleId),
|
|
1198
|
+
styleId,
|
|
1199
|
+
topLevel,
|
|
1200
|
+
bookmarks,
|
|
1201
|
+
links
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
function editorPort(editor) {
|
|
1205
|
+
const surface = () => {
|
|
1206
|
+
const s = editor.surface;
|
|
1207
|
+
if (!s) throw new Error("The document is not open.");
|
|
1208
|
+
return s;
|
|
1209
|
+
};
|
|
1210
|
+
return {
|
|
1211
|
+
paragraphs: () => readParagraphs(surface().session.part().root),
|
|
1212
|
+
caret: () => {
|
|
1213
|
+
const selection = surface().state().selection;
|
|
1214
|
+
if (!selection) return null;
|
|
1215
|
+
const { anchor, head } = selection;
|
|
1216
|
+
return anchor.paragraphId === head.paragraphId && anchor.offset === head.offset ? { paragraphId: anchor.paragraphId, offset: anchor.offset } : null;
|
|
1217
|
+
},
|
|
1218
|
+
setCaret: (point) => surface().setSelection({ anchor: point, head: point }),
|
|
1219
|
+
deleteRange: (from, to) => {
|
|
1220
|
+
surface().setSelection({ anchor: from, head: to });
|
|
1221
|
+
surface().deleteSelection();
|
|
1222
|
+
},
|
|
1223
|
+
paste: (body, text, covered2) => editor.exec({ type: "paste", text, html: fragmentHtml(body, covered2) }).ok,
|
|
1224
|
+
splitParagraph: () => surface().splitParagraph()
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
function withDirectEditing(editor, fn) {
|
|
1228
|
+
const mode = editor.getEditingMode();
|
|
1229
|
+
if (mode === "viewing") throw new Error("This document is read only.");
|
|
1230
|
+
if (mode === "suggesting") editor.setEditingMode("editing");
|
|
1231
|
+
try {
|
|
1232
|
+
return fn();
|
|
1233
|
+
} finally {
|
|
1234
|
+
if (mode === "suggesting") editor.setEditingMode("suggesting");
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
function holdCaret(editor, timeoutMs = 5e3) {
|
|
1238
|
+
const surface = editor.surface;
|
|
1239
|
+
const selection = surface?.state().selection;
|
|
1240
|
+
if (!surface || !selection) return;
|
|
1241
|
+
const { paragraphId, offset } = selection.head;
|
|
1242
|
+
const paraId = surface.session.paraIdOf(paragraphId);
|
|
1243
|
+
if (!paraId) return;
|
|
1244
|
+
let done = false;
|
|
1245
|
+
const stop = () => {
|
|
1246
|
+
done = true;
|
|
1247
|
+
offChange();
|
|
1248
|
+
offSelection();
|
|
1249
|
+
clearTimeout(timer);
|
|
1250
|
+
};
|
|
1251
|
+
const restore = () => {
|
|
1252
|
+
if (done) return;
|
|
1253
|
+
const now = surface.state().selection;
|
|
1254
|
+
const node = surface.session.nodeIdOf(paraId);
|
|
1255
|
+
if (!now || !node) return;
|
|
1256
|
+
if (now.head.offset !== offset || now.head.paragraphId !== paragraphId) return stop();
|
|
1257
|
+
if (node === paragraphId) return;
|
|
1258
|
+
stop();
|
|
1259
|
+
const point = { paragraphId: node, offset };
|
|
1260
|
+
surface.setSelection({ anchor: point, head: point });
|
|
1261
|
+
};
|
|
1262
|
+
const offChange = editor.on("change", restore);
|
|
1263
|
+
const offSelection = editor.on("selectionChange", restore);
|
|
1264
|
+
const timer = setTimeout(stop, timeoutMs);
|
|
1265
|
+
}
|
|
1266
|
+
var DEFINED_TERM_TRIGGER = "@@";
|
|
1267
|
+
var TRIGGER_QUERY = /(?:^|[\s([{"“‘'])@@([^@\n\t]{0,40})$/;
|
|
1268
|
+
var MAX_GROUPS = 8;
|
|
1269
|
+
var STALE_AFTER_MS = 3e4;
|
|
1270
|
+
var DEFAULT_DEFINED_TERMS_LABELS = {
|
|
1271
|
+
insert: "Defined term",
|
|
1272
|
+
update: "Update definitions",
|
|
1273
|
+
search: "Search defined terms",
|
|
1274
|
+
allAgreements: "All definitions",
|
|
1275
|
+
loading: "Loading definitions\u2026",
|
|
1276
|
+
empty: "No definitions yet. Label a fact \u201CDefinitions\u201D to use it here.",
|
|
1277
|
+
noMatch: "No defined term matches.",
|
|
1278
|
+
hint: "Enter to insert \xB7 Esc to close",
|
|
1279
|
+
preferred: "Preferred",
|
|
1280
|
+
alsoIn: (source) => `Also defined${source ? ` in ${source}` : ""}`,
|
|
1281
|
+
updated: "Definitions updated",
|
|
1282
|
+
updateSummary: (r) => [
|
|
1283
|
+
r.added.length ? `${r.added.length} added` : "",
|
|
1284
|
+
r.refreshed.length ? `${r.refreshed.length} reworded` : "",
|
|
1285
|
+
r.reordered.length ? `${r.reordered.length} reordered` : ""
|
|
1286
|
+
].filter(Boolean).join(" \xB7 ") || "The Definitions section is up to date.",
|
|
1287
|
+
unusedTitle: "Defined but never used",
|
|
1288
|
+
unusedNone: "Every definition in the section is used.",
|
|
1289
|
+
unknownTitle: "Links to definitions that no longer exist",
|
|
1290
|
+
show: "Show",
|
|
1291
|
+
close: "Close"
|
|
1292
|
+
};
|
|
1293
|
+
var DefinedTermsContext = createContext(null);
|
|
1294
|
+
var useDefinedTerms = () => useContext(DefinedTermsContext);
|
|
1295
|
+
function rowsOf(groups) {
|
|
1296
|
+
return groups.flatMap(
|
|
1297
|
+
(group) => group.definitions.map((definition, i) => ({ group, definition, variant: i > 0 }))
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
var sourceOf = (d) => [d.source, ...(d.labels ?? []).map((l) => l.name)].filter(Boolean).join(" \xB7 ");
|
|
1301
|
+
function DefinedTermsProvider({
|
|
1302
|
+
children,
|
|
1303
|
+
load,
|
|
1304
|
+
editable,
|
|
1305
|
+
notify,
|
|
1306
|
+
labels
|
|
1307
|
+
}) {
|
|
1308
|
+
const editor = useDocxEditor();
|
|
1309
|
+
const l = useMemo(() => ({ ...DEFAULT_DEFINED_TERMS_LABELS, ...labels }), [labels]);
|
|
1310
|
+
const [sources, setSources] = useState(null);
|
|
1311
|
+
const loadedAt = useRef(0);
|
|
1312
|
+
const loading = useRef(null);
|
|
1313
|
+
const [labelId, setLabelId] = useState(null);
|
|
1314
|
+
const [picker, setPicker] = useState(null);
|
|
1315
|
+
const [selected, setSelected] = useState(0);
|
|
1316
|
+
const [report, setReport] = useState(null);
|
|
1317
|
+
const marker = useRef(null);
|
|
1318
|
+
const dismissedAt = useRef(null);
|
|
1319
|
+
const refresh = useCallback(
|
|
1320
|
+
(force = false) => {
|
|
1321
|
+
if (!load) return Promise.resolve([]);
|
|
1322
|
+
if (!force && sources && Date.now() - loadedAt.current < STALE_AFTER_MS)
|
|
1323
|
+
return Promise.resolve(sources);
|
|
1324
|
+
if (!loading.current)
|
|
1325
|
+
loading.current = load().then((list) => {
|
|
1326
|
+
loadedAt.current = Date.now();
|
|
1327
|
+
setSources(list);
|
|
1328
|
+
return list;
|
|
1329
|
+
}).catch((error) => {
|
|
1330
|
+
notify?.(
|
|
1331
|
+
error instanceof Error ? error.message : "Could not load definitions.",
|
|
1332
|
+
"error"
|
|
1333
|
+
);
|
|
1334
|
+
setSources((previous) => previous ?? []);
|
|
1335
|
+
return sources ?? [];
|
|
1336
|
+
}).finally(() => {
|
|
1337
|
+
loading.current = null;
|
|
1338
|
+
});
|
|
1339
|
+
return loading.current;
|
|
1340
|
+
},
|
|
1341
|
+
[load, sources, notify]
|
|
1342
|
+
);
|
|
1343
|
+
const all = useMemo(() => groupDefinitions(sources ?? []).groups, [sources]);
|
|
1344
|
+
const byId = useMemo(
|
|
1345
|
+
() => new Map(all.flatMap((g) => g.definitions).map((d) => [d.id, d])),
|
|
1346
|
+
[all]
|
|
1347
|
+
);
|
|
1348
|
+
const agreements = useMemo(() => definitionLabels(sources ?? []), [sources]);
|
|
1349
|
+
const groups = useMemo(
|
|
1350
|
+
() => picker ? filterTermGroups(groupDefinitions(sources ?? [], { labelId }).groups, picker.query).slice(
|
|
1351
|
+
0,
|
|
1352
|
+
MAX_GROUPS
|
|
1353
|
+
) : [],
|
|
1354
|
+
[sources, labelId, picker]
|
|
1355
|
+
);
|
|
1356
|
+
const rows = useMemo(() => rowsOf(groups), [groups]);
|
|
1357
|
+
useEffect(() => setSelected(0), [picker?.query, labelId]);
|
|
1358
|
+
const container = () => marker.current?.closest(".native-docx-viewer") ?? document.body;
|
|
1359
|
+
const [viewer, setViewer] = useState(null);
|
|
1360
|
+
useEffect(() => setViewer(container()), []);
|
|
1361
|
+
const refreshRef = useRef(refresh);
|
|
1362
|
+
refreshRef.current = refresh;
|
|
1363
|
+
const firstHover = useCallback(() => void refreshRef.current(), []);
|
|
1364
|
+
const caretRect = () => container().querySelector(".docx-editor-one-surface__caret")?.getBoundingClientRect();
|
|
1365
|
+
const run = useCallback(
|
|
1366
|
+
(fn) => {
|
|
1367
|
+
if (!editor) return void 0;
|
|
1368
|
+
try {
|
|
1369
|
+
return withDirectEditing(editor, fn);
|
|
1370
|
+
} catch (error) {
|
|
1371
|
+
notify?.(error instanceof Error ? error.message : "Could not change the document.", "error");
|
|
1372
|
+
return void 0;
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
[editor, notify]
|
|
1376
|
+
);
|
|
1377
|
+
const pick = useCallback(
|
|
1378
|
+
(row) => {
|
|
1379
|
+
if (!editor || !picker || !row) return;
|
|
1380
|
+
const port = editorPort(editor);
|
|
1381
|
+
const result = run(() => {
|
|
1382
|
+
if (picker.mode === "search" && picker.caret) port.setCaret(picker.caret);
|
|
1383
|
+
return insertDefinedTerm(port, row.definition, {
|
|
1384
|
+
replace: picker.mode === "typing" ? DEFINED_TERM_TRIGGER.length + picker.query.length : 0
|
|
1385
|
+
});
|
|
1386
|
+
});
|
|
1387
|
+
setPicker(null);
|
|
1388
|
+
editor.surface?.focus();
|
|
1389
|
+
if (result) holdCaret(editor);
|
|
1390
|
+
if (result?.addedDefinition)
|
|
1391
|
+
notify?.(`\u201C${row.definition.term}\u201D added to the Definitions section.`, "success");
|
|
1392
|
+
},
|
|
1393
|
+
[editor, picker, run, notify]
|
|
1394
|
+
);
|
|
1395
|
+
const openPicker = useCallback(
|
|
1396
|
+
(anchor) => {
|
|
1397
|
+
if (!editor || !editable) return;
|
|
1398
|
+
const caret = editorPort(editor).caret();
|
|
1399
|
+
const rect = caretRect() ?? anchor?.getBoundingClientRect();
|
|
1400
|
+
void refresh();
|
|
1401
|
+
setPicker({
|
|
1402
|
+
mode: "search",
|
|
1403
|
+
query: "",
|
|
1404
|
+
left: rect?.left ?? 120,
|
|
1405
|
+
top: (rect?.bottom ?? 120) + 4,
|
|
1406
|
+
caret
|
|
1407
|
+
});
|
|
1408
|
+
},
|
|
1409
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1410
|
+
[editor, editable, refresh]
|
|
1411
|
+
);
|
|
1412
|
+
useEffect(() => {
|
|
1413
|
+
if (!editor || !editable || !load) return;
|
|
1414
|
+
let frame = 0;
|
|
1415
|
+
const check = () => {
|
|
1416
|
+
cancelAnimationFrame(frame);
|
|
1417
|
+
frame = requestAnimationFrame(() => {
|
|
1418
|
+
const port = editorPort(editor);
|
|
1419
|
+
const caret = port.caret();
|
|
1420
|
+
const paragraph = caret && port.paragraphs().find((p) => p.id === caret.paragraphId);
|
|
1421
|
+
const match = paragraph && TRIGGER_QUERY.exec(paragraph.text.slice(0, caret.offset));
|
|
1422
|
+
setPicker((current) => {
|
|
1423
|
+
if (current?.mode === "search") return current;
|
|
1424
|
+
if (!match || !caret) return null;
|
|
1425
|
+
const key = `${caret.paragraphId}:${caret.offset - match[1].length}`;
|
|
1426
|
+
if (dismissedAt.current === key) return null;
|
|
1427
|
+
const rect = caretRect();
|
|
1428
|
+
return {
|
|
1429
|
+
mode: "typing",
|
|
1430
|
+
query: match[1],
|
|
1431
|
+
left: current?.left ?? rect?.left ?? 120,
|
|
1432
|
+
top: current?.top ?? (rect?.bottom ?? 120) + 4,
|
|
1433
|
+
caret
|
|
1434
|
+
};
|
|
1435
|
+
});
|
|
1436
|
+
if (match) void refresh();
|
|
1437
|
+
});
|
|
1438
|
+
};
|
|
1439
|
+
const offChange = editor.on("change", check);
|
|
1440
|
+
const offSelection = editor.on("selectionChange", check);
|
|
1441
|
+
return () => {
|
|
1442
|
+
cancelAnimationFrame(frame);
|
|
1443
|
+
offChange();
|
|
1444
|
+
offSelection();
|
|
1445
|
+
};
|
|
1446
|
+
}, [editor, editable, load, refresh]);
|
|
1447
|
+
useEffect(() => {
|
|
1448
|
+
if (picker?.mode !== "typing") return;
|
|
1449
|
+
const keys = (event) => {
|
|
1450
|
+
if (event.key === "Escape") {
|
|
1451
|
+
dismissedAt.current = picker.caret ? `${picker.caret.paragraphId}:${picker.caret.offset - picker.query.length}` : null;
|
|
1452
|
+
setPicker(null);
|
|
1453
|
+
} else if (!rows.length) return;
|
|
1454
|
+
else if (event.key === "ArrowDown") setSelected((i) => (i + 1) % rows.length);
|
|
1455
|
+
else if (event.key === "ArrowUp") setSelected((i) => (i - 1 + rows.length) % rows.length);
|
|
1456
|
+
else if (event.key === "Enter" || event.key === "Tab") pick(rows[selected] ?? rows[0]);
|
|
1457
|
+
else return;
|
|
1458
|
+
event.preventDefault();
|
|
1459
|
+
event.stopPropagation();
|
|
1460
|
+
};
|
|
1461
|
+
window.addEventListener("keydown", keys, true);
|
|
1462
|
+
return () => window.removeEventListener("keydown", keys, true);
|
|
1463
|
+
}, [picker, rows, selected, pick]);
|
|
1464
|
+
const update = useCallback(() => {
|
|
1465
|
+
if (!editor || !editable) return;
|
|
1466
|
+
void refresh(true).then((list) => {
|
|
1467
|
+
const definitions = new Map(
|
|
1468
|
+
list.flatMap((s) => {
|
|
1469
|
+
const d = toDefinition(s);
|
|
1470
|
+
return d ? [[d.id, d]] : [];
|
|
1471
|
+
})
|
|
1472
|
+
);
|
|
1473
|
+
const surface = editor.surface;
|
|
1474
|
+
const before = surface?.state().selection?.head;
|
|
1475
|
+
const paraId = before && surface?.session.paraIdOf(before.paragraphId);
|
|
1476
|
+
const result = run(() => updateDefinitions(editorPort(editor), definitions));
|
|
1477
|
+
const node = paraId && surface?.session.nodeIdOf(paraId);
|
|
1478
|
+
if (result && before && node) {
|
|
1479
|
+
const point = { paragraphId: node, offset: before.offset };
|
|
1480
|
+
surface.setSelection({ anchor: point, head: point });
|
|
1481
|
+
holdCaret(editor);
|
|
1482
|
+
}
|
|
1483
|
+
if (result) setReport(result);
|
|
1484
|
+
});
|
|
1485
|
+
}, [editor, editable, refresh, run]);
|
|
1486
|
+
const value = useMemo(
|
|
1487
|
+
() => load && editable ? { openPicker, update, labels: l } : null,
|
|
1488
|
+
[load, editable, openPicker, update, l]
|
|
1489
|
+
);
|
|
1490
|
+
return /* @__PURE__ */ jsxs(DefinedTermsContext.Provider, { value, children: [
|
|
1491
|
+
/* @__PURE__ */ jsx("span", { ref: marker, hidden: true }),
|
|
1492
|
+
children,
|
|
1493
|
+
load && /* @__PURE__ */ jsx(
|
|
1494
|
+
DefinedTermHover,
|
|
1495
|
+
{
|
|
1496
|
+
root: viewer,
|
|
1497
|
+
resolve: (anchor) => definitionOfAnchor(anchor, byId),
|
|
1498
|
+
onFirstHover: firstHover
|
|
1499
|
+
}
|
|
1500
|
+
),
|
|
1501
|
+
picker && createPortal(
|
|
1502
|
+
/* @__PURE__ */ jsx(
|
|
1503
|
+
DefinedTermMenu,
|
|
1504
|
+
{
|
|
1505
|
+
picker,
|
|
1506
|
+
rows,
|
|
1507
|
+
loading: sources === null,
|
|
1508
|
+
selected,
|
|
1509
|
+
setSelected,
|
|
1510
|
+
agreements,
|
|
1511
|
+
labelId,
|
|
1512
|
+
setLabelId,
|
|
1513
|
+
onQuery: (query) => setPicker((p) => p ? { ...p, query } : p),
|
|
1514
|
+
onPick: pick,
|
|
1515
|
+
onClose: () => {
|
|
1516
|
+
setPicker(null);
|
|
1517
|
+
editor?.surface?.focus();
|
|
1518
|
+
},
|
|
1519
|
+
labels: l
|
|
1520
|
+
}
|
|
1521
|
+
),
|
|
1522
|
+
document.body
|
|
1523
|
+
),
|
|
1524
|
+
/* @__PURE__ */ jsx(Dialog, { open: !!report, onOpenChange: (open) => !open && setReport(null), children: /* @__PURE__ */ jsxs(
|
|
1525
|
+
DialogContent,
|
|
1526
|
+
{
|
|
1527
|
+
className: "max-h-[85dvh] overflow-y-auto",
|
|
1528
|
+
"data-testid": "docx-definitions-report",
|
|
1529
|
+
children: [
|
|
1530
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
1531
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: l.updated }),
|
|
1532
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: report && l.updateSummary(report) })
|
|
1533
|
+
] }),
|
|
1534
|
+
report && /* @__PURE__ */ jsxs("div", { className: "space-y-4 text-sm", children: [
|
|
1535
|
+
/* @__PURE__ */ jsxs("section", { children: [
|
|
1536
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-1 font-medium", children: l.unusedTitle }),
|
|
1537
|
+
report.unused.length ? /* @__PURE__ */ jsx("ul", { className: "space-y-1", "data-testid": "docx-definitions-unused", children: report.unused.map((u) => /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2", children: [
|
|
1538
|
+
/* @__PURE__ */ jsx("span", { children: u.term }),
|
|
1539
|
+
/* @__PURE__ */ jsx(
|
|
1540
|
+
Button,
|
|
1541
|
+
{
|
|
1542
|
+
size: "sm",
|
|
1543
|
+
variant: "ghost",
|
|
1544
|
+
onClick: () => {
|
|
1545
|
+
const surface = editor?.surface;
|
|
1546
|
+
surface?.setSelection({
|
|
1547
|
+
anchor: { paragraphId: u.paragraphId, offset: 0 },
|
|
1548
|
+
head: { paragraphId: u.paragraphId, offset: 0 }
|
|
1549
|
+
});
|
|
1550
|
+
surface?.revealParagraph(u.paragraphId);
|
|
1551
|
+
setReport(null);
|
|
1552
|
+
},
|
|
1553
|
+
children: l.show
|
|
1554
|
+
}
|
|
1555
|
+
)
|
|
1556
|
+
] }, u.paragraphId)) }) : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: l.unusedNone })
|
|
1557
|
+
] }),
|
|
1558
|
+
report.unknown.length > 0 && /* @__PURE__ */ jsxs("section", { children: [
|
|
1559
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-1 font-medium", children: l.unknownTitle }),
|
|
1560
|
+
/* @__PURE__ */ jsx("ul", { className: "list-disc pl-5 text-muted-foreground", children: report.unknown.map((name) => /* @__PURE__ */ jsx("li", { children: name }, name)) })
|
|
1561
|
+
] })
|
|
1562
|
+
] }),
|
|
1563
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setReport(null), children: l.close }) })
|
|
1564
|
+
]
|
|
1565
|
+
}
|
|
1566
|
+
) })
|
|
1567
|
+
] });
|
|
1568
|
+
}
|
|
1569
|
+
function DefinedTermMenu({
|
|
1570
|
+
picker,
|
|
1571
|
+
rows,
|
|
1572
|
+
loading,
|
|
1573
|
+
selected,
|
|
1574
|
+
setSelected,
|
|
1575
|
+
agreements,
|
|
1576
|
+
labelId,
|
|
1577
|
+
setLabelId,
|
|
1578
|
+
onQuery,
|
|
1579
|
+
onPick,
|
|
1580
|
+
onClose,
|
|
1581
|
+
labels: l
|
|
1582
|
+
}) {
|
|
1583
|
+
const listboxId = React3.useId();
|
|
1584
|
+
const element = useRef(null);
|
|
1585
|
+
const search = picker.mode === "search";
|
|
1586
|
+
useEffect(() => {
|
|
1587
|
+
const dismiss = (event) => {
|
|
1588
|
+
if (!element.current?.contains(event.target)) onClose();
|
|
1589
|
+
};
|
|
1590
|
+
document.addEventListener("pointerdown", dismiss);
|
|
1591
|
+
return () => document.removeEventListener("pointerdown", dismiss);
|
|
1592
|
+
}, [onClose]);
|
|
1593
|
+
useEffect(() => {
|
|
1594
|
+
element.current?.querySelector(`[data-index="${selected}"]`)?.scrollIntoView?.({ block: "nearest" });
|
|
1595
|
+
}, [selected]);
|
|
1596
|
+
const left = Math.max(8, Math.min(picker.left, window.innerWidth - 368));
|
|
1597
|
+
return /* @__PURE__ */ jsxs(
|
|
1598
|
+
"div",
|
|
1599
|
+
{
|
|
1600
|
+
ref: element,
|
|
1601
|
+
className: "native-docx-term-menu rounded-md border border-border bg-popover text-popover-foreground shadow-lg",
|
|
1602
|
+
style: { position: "fixed", left, top: picker.top, width: 360, zIndex: 1e3 },
|
|
1603
|
+
"data-testid": "docx-defined-term-menu",
|
|
1604
|
+
onMouseDown: (event) => {
|
|
1605
|
+
if (!(event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement))
|
|
1606
|
+
event.preventDefault();
|
|
1607
|
+
},
|
|
1608
|
+
children: [
|
|
1609
|
+
(search || agreements.length > 0) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border/50 p-2", children: [
|
|
1610
|
+
search && /* @__PURE__ */ jsx(
|
|
1611
|
+
"input",
|
|
1612
|
+
{
|
|
1613
|
+
autoFocus: true,
|
|
1614
|
+
className: "min-w-0 flex-1 rounded border border-border bg-background px-2 py-1 text-sm",
|
|
1615
|
+
placeholder: l.search,
|
|
1616
|
+
"aria-label": l.search,
|
|
1617
|
+
role: "combobox",
|
|
1618
|
+
"aria-expanded": true,
|
|
1619
|
+
"aria-controls": listboxId,
|
|
1620
|
+
"aria-activedescendant": rows.length ? listOptionId(listboxId, selected) : void 0,
|
|
1621
|
+
value: picker.query,
|
|
1622
|
+
"data-testid": "docx-defined-term-search",
|
|
1623
|
+
onChange: (event) => onQuery(event.target.value),
|
|
1624
|
+
onKeyDown: (event) => {
|
|
1625
|
+
if (event.key === "Escape") onClose();
|
|
1626
|
+
else if (!rows.length) return;
|
|
1627
|
+
else if (event.key === "ArrowDown") setSelected((selected + 1) % rows.length);
|
|
1628
|
+
else if (event.key === "ArrowUp")
|
|
1629
|
+
setSelected((selected - 1 + rows.length) % rows.length);
|
|
1630
|
+
else if (event.key === "Enter") onPick(rows[selected] ?? rows[0]);
|
|
1631
|
+
else return;
|
|
1632
|
+
event.preventDefault();
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
),
|
|
1636
|
+
agreements.length > 0 && /* @__PURE__ */ jsxs(
|
|
1637
|
+
"select",
|
|
1638
|
+
{
|
|
1639
|
+
className: "max-w-[45%] rounded border border-border bg-background px-1 py-1 text-xs",
|
|
1640
|
+
"aria-label": "Narrow to",
|
|
1641
|
+
value: labelId ?? "",
|
|
1642
|
+
"data-testid": "docx-defined-term-label",
|
|
1643
|
+
onChange: (event) => setLabelId(event.target.value || null),
|
|
1644
|
+
children: [
|
|
1645
|
+
/* @__PURE__ */ jsx("option", { value: "", children: l.allAgreements }),
|
|
1646
|
+
agreements.map((a) => /* @__PURE__ */ jsx("option", { value: a.id, children: a.name }, a.id))
|
|
1647
|
+
]
|
|
1648
|
+
}
|
|
1649
|
+
)
|
|
1650
|
+
] }),
|
|
1651
|
+
/* @__PURE__ */ jsx("div", { className: "border-b border-border/50 px-3 py-1.5 text-xs text-muted-foreground", children: l.hint }),
|
|
1652
|
+
/* @__PURE__ */ jsxs(
|
|
1653
|
+
"div",
|
|
1654
|
+
{
|
|
1655
|
+
id: listboxId,
|
|
1656
|
+
role: "listbox",
|
|
1657
|
+
"aria-label": l.search,
|
|
1658
|
+
className: "scrollbar-subtle max-h-72 overflow-y-auto py-1",
|
|
1659
|
+
children: [
|
|
1660
|
+
rows.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm text-muted-foreground", children: loading ? l.loading : picker.query ? l.noMatch : l.empty }),
|
|
1661
|
+
rows.map((row, index) => /* @__PURE__ */ jsxs(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
id: listOptionId(listboxId, index),
|
|
1665
|
+
role: "option",
|
|
1666
|
+
"aria-selected": index === selected,
|
|
1667
|
+
"data-index": index,
|
|
1668
|
+
"data-testid": `docx-defined-term-${row.definition.id}`,
|
|
1669
|
+
className: cn(
|
|
1670
|
+
"cursor-pointer px-3 py-1.5 text-sm",
|
|
1671
|
+
row.variant && "pl-6",
|
|
1672
|
+
index === selected ? "bg-accent text-accent-foreground" : "hover:bg-accent/50"
|
|
1673
|
+
),
|
|
1674
|
+
onMouseEnter: () => setSelected(index),
|
|
1675
|
+
onClick: () => onPick(row),
|
|
1676
|
+
children: [
|
|
1677
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
1678
|
+
/* @__PURE__ */ jsx("span", { className: cn("shrink-0", row.variant ? "text-xs" : "font-medium"), children: row.variant ? l.alsoIn(sourceOf(row.definition)) : row.group.term }),
|
|
1679
|
+
!row.variant && sourceOf(row.definition) && /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: sourceOf(row.definition) }),
|
|
1680
|
+
!row.variant && row.group.definitions.length > 1 && row.definition.confirmed && /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 rounded bg-muted px-1 text-[10px] uppercase text-muted-foreground", children: l.preferred })
|
|
1681
|
+
] }),
|
|
1682
|
+
/* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-xs text-muted-foreground", children: row.definition.meaning })
|
|
1683
|
+
]
|
|
1684
|
+
},
|
|
1685
|
+
row.definition.id
|
|
1686
|
+
))
|
|
1687
|
+
]
|
|
1688
|
+
}
|
|
1689
|
+
)
|
|
1690
|
+
]
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
}
|
|
1694
|
+
function DefinedTermHover({
|
|
1695
|
+
root,
|
|
1696
|
+
resolve,
|
|
1697
|
+
onFirstHover
|
|
1698
|
+
}) {
|
|
1699
|
+
const [card, setCard] = useState(null);
|
|
1700
|
+
const hovered = useRef(false);
|
|
1701
|
+
useEffect(() => {
|
|
1702
|
+
if (!root) return;
|
|
1703
|
+
const over = (event) => {
|
|
1704
|
+
const link = event.target?.closest?.(
|
|
1705
|
+
'a.docx-hyperlink[data-docx-link-kind="internal"]'
|
|
1706
|
+
);
|
|
1707
|
+
const href = link?.getAttribute("href") ?? "";
|
|
1708
|
+
if (!link || !href.startsWith("#_dt_")) return;
|
|
1709
|
+
if (!hovered.current) {
|
|
1710
|
+
hovered.current = true;
|
|
1711
|
+
onFirstHover();
|
|
1712
|
+
}
|
|
1713
|
+
const title = link.getAttribute("title");
|
|
1714
|
+
if (title) {
|
|
1715
|
+
link.dataset.definition = title;
|
|
1716
|
+
link.removeAttribute("title");
|
|
1717
|
+
}
|
|
1718
|
+
const rect = link.getBoundingClientRect();
|
|
1719
|
+
setCard({
|
|
1720
|
+
left: rect.left,
|
|
1721
|
+
top: rect.bottom + 6,
|
|
1722
|
+
anchor: href.slice(1),
|
|
1723
|
+
fallback: link.dataset.definition ?? ""
|
|
1724
|
+
});
|
|
1725
|
+
};
|
|
1726
|
+
const out = (event) => {
|
|
1727
|
+
const link = event.target?.closest?.("a.docx-hyperlink");
|
|
1728
|
+
if (link && !link.contains(event.relatedTarget)) setCard(null);
|
|
1729
|
+
};
|
|
1730
|
+
root.addEventListener("mouseover", over);
|
|
1731
|
+
root.addEventListener("mouseout", out);
|
|
1732
|
+
const hide = () => setCard(null);
|
|
1733
|
+
window.addEventListener("keydown", hide, true);
|
|
1734
|
+
window.addEventListener("pointerdown", hide, true);
|
|
1735
|
+
window.addEventListener("scroll", hide, true);
|
|
1736
|
+
return () => {
|
|
1737
|
+
root.removeEventListener("mouseover", over);
|
|
1738
|
+
root.removeEventListener("mouseout", out);
|
|
1739
|
+
window.removeEventListener("keydown", hide, true);
|
|
1740
|
+
window.removeEventListener("pointerdown", hide, true);
|
|
1741
|
+
window.removeEventListener("scroll", hide, true);
|
|
1742
|
+
};
|
|
1743
|
+
}, [root, onFirstHover]);
|
|
1744
|
+
if (!card) return null;
|
|
1745
|
+
const definition = resolve(card.anchor);
|
|
1746
|
+
return createPortal(
|
|
1747
|
+
/* @__PURE__ */ jsx(
|
|
1748
|
+
"div",
|
|
1749
|
+
{
|
|
1750
|
+
role: "tooltip",
|
|
1751
|
+
className: "native-docx-term-card rounded-md border border-border bg-popover p-3 text-sm text-popover-foreground shadow-lg",
|
|
1752
|
+
style: {
|
|
1753
|
+
position: "fixed",
|
|
1754
|
+
left: Math.max(8, Math.min(card.left, window.innerWidth - 348)),
|
|
1755
|
+
top: card.top,
|
|
1756
|
+
width: 340,
|
|
1757
|
+
zIndex: 1e3,
|
|
1758
|
+
pointerEvents: "none"
|
|
1759
|
+
},
|
|
1760
|
+
"data-testid": "docx-defined-term-card",
|
|
1761
|
+
children: definition ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1762
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: definition.term }),
|
|
1763
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-muted-foreground", children: definition.meaning }),
|
|
1764
|
+
sourceOf(definition) && /* @__PURE__ */ jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: sourceOf(definition) })
|
|
1765
|
+
] }) : /* @__PURE__ */ jsx("p", { children: card.fallback })
|
|
1766
|
+
}
|
|
1767
|
+
),
|
|
1768
|
+
document.body
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
907
1771
|
function wordDraftHtml(markdown) {
|
|
908
1772
|
const template = document.createElement("template");
|
|
909
1773
|
template.innerHTML = renderToStaticMarkup(/* @__PURE__ */ jsx(AiMarkdown, { children: markdown }));
|
|
@@ -1089,6 +1953,38 @@ function RibbonMenu({
|
|
|
1089
1953
|
)
|
|
1090
1954
|
] });
|
|
1091
1955
|
}
|
|
1956
|
+
function DefinedTermButtons() {
|
|
1957
|
+
const terms = useDefinedTerms();
|
|
1958
|
+
if (!terms) return null;
|
|
1959
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1960
|
+
/* @__PURE__ */ jsx(
|
|
1961
|
+
"button",
|
|
1962
|
+
{
|
|
1963
|
+
type: "button",
|
|
1964
|
+
className: "native-docx-ribbon-trigger",
|
|
1965
|
+
"aria-label": terms.labels.insert,
|
|
1966
|
+
title: `${terms.labels.insert} (type @@)`,
|
|
1967
|
+
"data-testid": "docx-insert-defined-term",
|
|
1968
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1969
|
+
onClick: (event) => terms.openPicker(event.currentTarget),
|
|
1970
|
+
children: /* @__PURE__ */ jsx(BookA, { size: 16 })
|
|
1971
|
+
}
|
|
1972
|
+
),
|
|
1973
|
+
/* @__PURE__ */ jsx(
|
|
1974
|
+
"button",
|
|
1975
|
+
{
|
|
1976
|
+
type: "button",
|
|
1977
|
+
className: "native-docx-ribbon-trigger",
|
|
1978
|
+
"aria-label": terms.labels.update,
|
|
1979
|
+
title: terms.labels.update,
|
|
1980
|
+
"data-testid": "docx-update-definitions",
|
|
1981
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1982
|
+
onClick: () => terms.update(),
|
|
1983
|
+
children: /* @__PURE__ */ jsx(ListRestart, { size: 16 })
|
|
1984
|
+
}
|
|
1985
|
+
)
|
|
1986
|
+
] });
|
|
1987
|
+
}
|
|
1092
1988
|
function DocxRibbon({ onSave }) {
|
|
1093
1989
|
const [tab, setTab] = useState("Home");
|
|
1094
1990
|
const t = useChromeTranslate();
|
|
@@ -1127,7 +2023,8 @@ function DocxRibbon({ onSave }) {
|
|
|
1127
2023
|
tab === "Insert" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1128
2024
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.TableInsert, {}),
|
|
1129
2025
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.ImageInsert, {}),
|
|
1130
|
-
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Link, {})
|
|
2026
|
+
/* @__PURE__ */ jsx(DocxEditor.Toolbar.Link, {}),
|
|
2027
|
+
/* @__PURE__ */ jsx(DefinedTermButtons, {})
|
|
1131
2028
|
] }),
|
|
1132
2029
|
tab === "Review" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1133
2030
|
/* @__PURE__ */ jsx(DocxEditor.Toolbar.EditingMode, {}),
|
|
@@ -1449,7 +2346,7 @@ function NativeDocxEditor({
|
|
|
1449
2346
|
)
|
|
1450
2347
|
] }),
|
|
1451
2348
|
!ready && !error && /* @__PURE__ */ jsx("div", { className: "native-docx-error", role: "status", children: "Opening Word document\u2026" }),
|
|
1452
|
-
ready && /* @__PURE__ */ jsx("div", { className: "native-docx-body docx-editor", children: /* @__PURE__ */ jsx(EditorBoundary, { children: /* @__PURE__ */
|
|
2349
|
+
ready && /* @__PURE__ */ jsx("div", { className: "native-docx-body docx-editor", children: /* @__PURE__ */ jsx(EditorBoundary, { children: /* @__PURE__ */ jsx(
|
|
1453
2350
|
DocxEditor.Root,
|
|
1454
2351
|
{
|
|
1455
2352
|
document: ready.document,
|
|
@@ -1464,52 +2361,60 @@ function NativeDocxEditor({
|
|
|
1464
2361
|
if (change.source !== "load") changed();
|
|
1465
2362
|
},
|
|
1466
2363
|
onFontError: (e) => setError(e.message),
|
|
1467
|
-
children:
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
2364
|
+
children: /* @__PURE__ */ jsxs(
|
|
2365
|
+
DefinedTermsProvider,
|
|
2366
|
+
{
|
|
2367
|
+
load: adapter.definitions,
|
|
2368
|
+
editable: !stream && !snapshot && ready.canEdit,
|
|
2369
|
+
notify: adapter.notify,
|
|
2370
|
+
children: [
|
|
2371
|
+
/* @__PURE__ */ jsx(
|
|
2372
|
+
DocxEditor.RevisionMarkup,
|
|
2373
|
+
{
|
|
2374
|
+
insertions: { mark: "underline", color: "blue" },
|
|
2375
|
+
deletions: { mark: "strikethrough", color: "red" },
|
|
2376
|
+
movedFrom: { mark: "doubleStrikethrough", color: "green" },
|
|
2377
|
+
movedTo: { mark: "doubleUnderline", color: "green" },
|
|
2378
|
+
trackMoves: true
|
|
2379
|
+
}
|
|
2380
|
+
),
|
|
2381
|
+
!stream && /* @__PURE__ */ jsx(DocxRibbon, { onSave: () => void saveVersion() }),
|
|
2382
|
+
/* @__PURE__ */ jsxs(
|
|
2383
|
+
"div",
|
|
2384
|
+
{
|
|
2385
|
+
className: "native-docx-stage",
|
|
2386
|
+
ref: stageRef,
|
|
2387
|
+
onMouseDownCapture: (event) => {
|
|
2388
|
+
if (event.button === 2 && ref.current?.getSelectionPlacement())
|
|
2389
|
+
event.preventDefault();
|
|
2390
|
+
},
|
|
2391
|
+
children: [
|
|
2392
|
+
/* @__PURE__ */ jsxs(DocxEditor.Viewport, { className: "native-docx-viewport", children: [
|
|
2393
|
+
/* @__PURE__ */ jsx(DocxEditor.Content, {}),
|
|
2394
|
+
/* @__PURE__ */ jsx(
|
|
2395
|
+
DocxMentions,
|
|
2396
|
+
{
|
|
2397
|
+
initialCommentId,
|
|
2398
|
+
mentions: adapter.mentions,
|
|
2399
|
+
notify: adapter.notify,
|
|
2400
|
+
getAgentStatus: adapter.getAgentStatus,
|
|
2401
|
+
requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
|
|
2402
|
+
children: /* @__PURE__ */ jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsx(DocxEditorReview.Card, { children: /* @__PURE__ */ jsx(DocxCommentActivity, {}) }) })
|
|
2403
|
+
}
|
|
2404
|
+
),
|
|
2405
|
+
/* @__PURE__ */ jsx(DocxEditor.HeaderFooterChrome, {}),
|
|
2406
|
+
/* @__PURE__ */ jsx(DocxEditor.NotesChrome, {}),
|
|
2407
|
+
/* @__PURE__ */ jsx(DocxEditor.Equation, {}),
|
|
2408
|
+
/* @__PURE__ */ jsx(DocxEditor.HyperLink, {}),
|
|
2409
|
+
/* @__PURE__ */ jsx(DocxEditor.ContextMenu, {})
|
|
2410
|
+
] }),
|
|
2411
|
+
/* @__PURE__ */ jsx(DocxEditor.PageNumber, {})
|
|
2412
|
+
]
|
|
2413
|
+
}
|
|
2414
|
+
)
|
|
2415
|
+
]
|
|
2416
|
+
}
|
|
2417
|
+
)
|
|
1513
2418
|
}
|
|
1514
2419
|
) }, retry) }),
|
|
1515
2420
|
/* @__PURE__ */ jsxs("div", { className: "native-docx-actions", children: [
|
|
@@ -1604,6 +2509,6 @@ async function loadFonts(baseUrl) {
|
|
|
1604
2509
|
};
|
|
1605
2510
|
}
|
|
1606
2511
|
|
|
1607
|
-
export { DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, NativeDocxEditor, loadDocxFonts, normalizeDocxExport, reviewModule, useReview, useReviewItem };
|
|
1608
|
-
//# sourceMappingURL=chunk-
|
|
1609
|
-
//# sourceMappingURL=chunk-
|
|
2512
|
+
export { DEFAULT_DEFINED_TERMS_LABELS, DEFINED_TERM_TRIGGER, DefinedTermsProvider, DocxCommentActivity, DocxEditorReview, DocxMentions, DocxParticipants, DocxRibbon, NativeDocxEditor, editorPort, findDefinitionsSection, insertDefinedTerm, loadDocxFonts, normalizeDocxExport, reviewModule, updateDefinitions, useDefinedTerms, useReview, useReviewItem, withDirectEditing };
|
|
2513
|
+
//# sourceMappingURL=chunk-WXLKMEMB.js.map
|
|
2514
|
+
//# sourceMappingURL=chunk-WXLKMEMB.js.map
|