@a3s-lab/office 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -3
- package/dist/{0~7043.js → 0~7231.js} +160 -2
- package/dist/{0~5093.js → 0~7360.js} +233 -52
- package/dist/0~document-editor.js +1159 -149
- package/dist/0~spreadsheet-editor.js +183 -34
- package/dist/0~work-docx-export.js +299 -11
- package/dist/0~work-docx-import.js +30 -7
- package/dist/0~work-office-diagnostics.js +125 -5
- package/dist/1544.js +13 -1
- package/dist/4104.js +29 -6
- package/dist/4121.js +1939 -1
- package/dist/6282.js +501 -1006
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +18 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +5 -2
- package/dist/internal/features/work/editors/document-font-dialog-run-shading-model.d.ts +23 -0
- package/dist/internal/features/work/editors/document-font-dialog-run-shading-section.d.ts +8 -0
- package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-proofing-dialog-model.d.ts +22 -0
- package/dist/internal/features/work/editors/document-proofing-dialog.d.ts +7 -0
- package/dist/internal/features/work/editors/document-table-of-contents-dialog.d.ts +10 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +3 -1
- package/dist/internal/features/work/editors/spreadsheet-data-validation.d.ts +7 -1
- package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +2 -0
- package/dist/internal/features/work/work-document-character-formatting.d.ts +8 -0
- package/dist/internal/features/work/work-document-format-changes.d.ts +6 -0
- package/dist/internal/features/work/work-document-highlight.d.ts +9 -0
- package/dist/internal/features/work/work-document-outline.d.ts +1 -0
- package/dist/internal/features/work/work-document-paragraph-shading.d.ts +6 -0
- package/dist/internal/features/work/work-document-proofing.d.ts +19 -0
- package/dist/internal/features/work/work-document-run-shading.d.ts +12 -0
- package/dist/internal/features/work/work-document-table-of-contents-node.d.ts +18 -0
- package/dist/internal/features/work/work-document-table-of-contents.d.ts +51 -0
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-field-instructions.d.ts +1 -1
- package/dist/internal/features/work/work-docx-import.d.ts +3 -1
- package/dist/internal/features/work/work-docx-proofing-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-proofing.d.ts +38 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +7 -0
- package/dist/internal/features/work/work-docx-run-shading-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-shading-export.d.ts +17 -0
- package/dist/internal/features/work/work-docx-run-shading.d.ts +20 -0
- package/dist/internal/features/work/work-docx-table-of-contents-export.d.ts +11 -0
- package/dist/internal/features/work/work-docx-table-of-contents-import.d.ts +15 -0
- package/dist/internal/features/work/work-spreadsheet-data-validation.d.ts +7 -0
- package/dist/internal/features/work/work-types.d.ts +9 -0
- package/dist/internal/kernel/office-kernel-protocol.d.ts +1 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +311 -4
- package/docs/latest/en/browser-editor-architecture.md +50 -1
- package/package.json +12 -2
|
@@ -6,7 +6,7 @@ import { Fragment as external_react_Fragment, forwardRef, useCallback, useEffect
|
|
|
6
6
|
import { Extension, createNodeFromContent } from "@tiptap/core";
|
|
7
7
|
import { NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
8
8
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
9
|
-
import { AArrowDown, AArrowUp, ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowUp, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, BookMarked, BookOpen, Bookmark, CaseUpper, Check, CheckCheck, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, ClipboardCopy, ClipboardPaste, Cloud, Columns3, Eraser, Eye, FileDiff, FilePlus2, FileText, Globe2, Grid2X2, Hash, Highlighter, Image, IndentDecrease, IndentIncrease, Italic, Link2, List, ListChecks, ListOrdered, MessageSquarePlus, MessageSquareReply, MessagesSquare, MoveVertical, Paintbrush, Palette, PanelBottom, PanelBottomOpen, PanelLeftOpen, PanelTop, PanelTopOpen, Pilcrow, PilcrowLeft, PilcrowRight, Plus, Quote, Redo2, RefreshCw, Replace, ReplaceAll, RotateCcw, Rows3, Ruler, Scan, Search, Settings2, Square, StretchHorizontal, Strikethrough, Subscript, Superscript, Table2, TableCellsMerge, TableCellsSplit, TableProperties, TextWrap, Trash2, TriangleAlert, Type, Underline, Undo2, Unlink, Unlink2, X, XCircle, ZoomIn, ZoomOut } from "lucide-react";
|
|
9
|
+
import { AArrowDown, AArrowUp, ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowUp, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, BookMarked, BookOpen, Bookmark, CaseUpper, Check, CheckCheck, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, ClipboardCopy, ClipboardPaste, Cloud, Columns3, Eraser, Eye, FileDiff, FilePlus2, FileText, Globe2, Grid2X2, Hash, Highlighter, Image, IndentDecrease, IndentIncrease, Italic, Languages, Link2, List, ListChecks, ListOrdered, ListTree, MessageSquarePlus, MessageSquareReply, MessagesSquare, MoveVertical, Paintbrush, Palette, PanelBottom, PanelBottomOpen, PanelLeftOpen, PanelTop, PanelTopOpen, Pilcrow, PilcrowLeft, PilcrowRight, Plus, Quote, Redo2, RefreshCw, Replace, ReplaceAll, RotateCcw, Rows3, Ruler, Scan, Search, Settings2, Square, StretchHorizontal, Strikethrough, Subscript, Superscript, Table2, TableCellsMerge, TableCellsSplit, TableProperties, TextWrap, Trash2, TriangleAlert, Type, Underline, Undo2, Unlink, Unlink2, X, XCircle, ZoomIn, ZoomOut } from "lucide-react";
|
|
10
10
|
import { Node as model_Node } from "@tiptap/pm/model";
|
|
11
11
|
import extension_color from "@tiptap/extension-color";
|
|
12
12
|
import { TableKit } from "@tiptap/extension-table";
|
|
@@ -15,11 +15,11 @@ import font_size from "@tiptap/extension-text-style/font-size";
|
|
|
15
15
|
import starter_kit from "@tiptap/starter-kit";
|
|
16
16
|
import { BubbleMenu } from "@tiptap/react/menus";
|
|
17
17
|
import { TableMap, isInTable, selectedRect } from "@tiptap/pm/tables";
|
|
18
|
-
import { documentTableSizing, transferChangedDocumentTextStatistics, documentPageBordersVisible, documentUnderlineStyle, DOCUMENT_PAGE_BORDER_EDGES,
|
|
18
|
+
import { documentTableSizing, transferChangedDocumentTextStatistics, documentPageBordersVisible, documentUnderlineStyle, DOCUMENT_PAGE_BORDER_EDGES, documentTableRowOptions, normalizeDocumentColumns, clampDocumentMargin, materializeLazyDocumentEditorRoot, documentKerningThresholdPoints, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, nextDocumentTabAlignment, documentCitationCount, normalizedTabPosition, resolveDocumentPageBorders, documentLazyHtmlChunkFragment, DocumentFontFamily, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, DOCUMENT_CHUNK_VISIBLE_IDS_META, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, retainAnchoredDocumentComments, DocumentTableRowIdentity, work_document_page_margins_twipsToMillimeters, DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, resolveWorkDocumentEditorInput, documentCharacterPositionPoints, documentBulletListStyle, collectDocumentTextLayoutParagraphs, readOfficeDocumentCollaboration as readWorkOfficeDocumentCollaboration, normalizeDocumentCharacterScalePercent, documentOrderedListState, normalizeDocumentPageChrome, documentTextStatistics, documentPageMarginsForLayout, invalidateDocumentLazyHtmlProjection, documentTableCellFormat, normalizeDocumentPageGeometry, normalizeDocumentImageLayer, documentImageProperties, isValidDocumentCitationTag, sanitizeDocumentPageChromeHtml, pageTwipsToMillimeters, normalizeDocumentPageBorders, activeDocumentSection, DocumentParagraphFormatting, normalizeDocumentHtml, documentInitialSectionLayout, documentModelHasTrustedInitialIntegrityFeatures, documentModelUsesWindowing, documentParagraphDirection, documentParagraphPagination, documentPageChromeLegacyFields, documentChunkMountedIds, collectDocumentCommentAnchors, documentTextCaseKeyboardShortcuts, DocumentTextStyle, canChangeDocumentIndent, documentCharacterSpacingPoints, documentKerningIsEffective, DocumentSuperscript, documentSectionById, activeDocumentBookmark, DocumentEquation, documentLazyHtmlProjectionFingerprint, documentLazyHtmlProjection, normalizeDocumentParagraphIndent, updateDocumentGutterPosition, DocumentStrike, mountWorkLiveDocumentCapture, registerDocumentPageSurfaceGeometry, documentHiddenTextKeyboardShortcut, syncDocumentContentFromHtml, documentLegacyTextEffectsCss, editorDocumentCaptionTargets, resolveDocumentPageChrome, documentImageLayoutOptions, MAX_DOCUMENT_NUMBERING_START, resolveDocumentPageSize, editorDocumentBookmarkReferenceTargets, serializeWorkDocumentNode, DOCUMENT_CHUNK_PAGINATION_META, createOfficeDocumentCollaborationBinding as createWorkOfficeDocumentCollaborationBinding, documentModelForContent, documentLegacyTextEffectsFromTextStyleAttributes, normalizeDocumentEmphasisMark, selectedDocumentChunkId, documentCommentViews, documentParagraphSpacing, normalizeDocumentTabStops, patchDocumentLazyHtmlProjection, normalizeDocumentTextCase, documentUnderlineColor, documentBookmarkNameExists, collectDocumentChanges, DocumentImage, selectedDocumentTableOfContentsOptions, resolveDocumentPageMargins, updateDocumentPageMarginMode, canSetDocumentTableRowRepeatHeader, normalizeDocumentCharacterSpacingTwips, DocumentCharacterFormatting, millimetersToPixels as work_document_layout_millimetersToPixels, DOCUMENT_CHUNK_HYDRATION_META, documentTabLeaderLabel, createSchemaDerivedWorkDocumentModel, updateDocumentCustomPageMillimeters, DocumentUnderline, documentCommentDraftRange, documentParagraphTabStops, documentTableHorizontalAlignment, documentUnderlineKeyboardShortcuts, documentParagraphIndent, DocumentScriptFontFormatting, canInsertDocumentComment, documentHasTableOfContents, documentTextLayoutBatches, normalizeDocumentImageWrapSide, updateDocumentPageOrientation, documentCitationStyleDetails, validateDocumentBookmarkName, setCustomDocumentColumns, updateDocumentPageMarginMillimeters, documentCitationStyle, normalizeDocumentCharacterPositionHalfPoints, documentTransactionsOnlyHydrateChunks, normalizeDocumentKerningThresholdHalfPoints, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DOCUMENT_TABLE_STYLE_OPTIONS, updateDocumentColumnWidth, updateDocumentPaperSizePreset, documentPageMetrics, documentStrikeStyle, DocumentHighlight, createDocumentBibliography, DocumentSubscript, updateDocumentPageChromeVariant, updateDocumentMirrorMargins, activeDocumentTableStyle, measureDocumentLayoutBlocksIncrementally, documentWordLineHeightFactor, normalizeDocumentLegacyTextEffect, createWorkDocumentExtensions } from "./6282.js";
|
|
19
19
|
import { useOfficeTaskPaneEscape, normalizeOfficeFontFamily, OfficeCheckbox, useOfficeDialog, useOfficeTaskPaneModal, CommittedOfficeNumberField, officeFontFamilyLabel, officeFontFamilies, CollectionState, createOfficeKernelClient, OfficeNumberField } from "./0~7048.js";
|
|
20
20
|
import { moveOfficeMenuFocus, office_text_field_OfficeTextArea, Popover, officeOverlayPortalRoot, button_Button, useOfficePublishPresenceLocation, OfficeTiptapPresenceLayer, icon_button_IconButton, office_text_field_OfficeTextField, useDialogFocusScope, useOfficeEditorWheelZoom, office_text_field_OfficeFileInput } from "./0~6090.js";
|
|
21
21
|
import { WorkOfficePreviewBar, isWorkspaceContextMenuKeyboardEvent, Tabs, WorkOfficeZoomControls, WorkOfficeStatusBar, Dialog, WorkOfficeRibbon, workspaceContextMenuPosition, OfficeSelect, WorkspaceContextMenu, WorkOfficeRibbonGroup, WorkOfficeRibbonButton } from "./0~4595.js";
|
|
22
|
-
import {
|
|
22
|
+
import { documentFontNameFromCssFamily, normalizeDocumentRunBorder, parseDocumentScriptFonts, parseDocumentRunShading, DOCUMENT_RUN_BORDER_STYLES, serializeDocumentRunBorder, documentScriptFontDirectFamily, serializeDocumentRunShading, patchDocumentScriptFonts, serializeDocumentScriptFonts, documentRunBorderIsVisible, cssDocumentFontFamily, isDocumentParagraphArtBorderStyle, visibleWorkDocumentOutlineItems, DEFAULT_DOCUMENT_TABLE_OF_CONTENTS_OPTIONS, createOfficeId as createWorkId, normalizeDocumentLanguageTag, currentWorkDocumentOutlineItem, normalizeDocumentNoProof, parseDocumentRunBorder, DocumentParagraphIdentity, parseDocumentProofingLanguages, collectWorkDocumentOutline, documentScriptFontSlotFromHint, documentBorderPresentation, documentScriptFontFamilyForRendering, normalizeDocumentRunShading, normalizeDocumentScriptFontSlot, documentScriptFontSegments, patchDocumentProofingLanguages, serializeDocumentProofingLanguages, documentRunShadingDomAttributes } from "./4121.js";
|
|
23
23
|
import { normalizeDocumentHref, DOCUMENT_LINK_VALIDATION_MESSAGE } from "./0~work-document-links.js";
|
|
24
24
|
import { OfficeColorPicker, isOfficeShortcutBlocked } from "./0~3635.js";
|
|
25
25
|
import { OfficeTableInsertPopover, readOfficeFileAsDataUrl } from "./0~9445.js";
|
|
@@ -4087,6 +4087,9 @@ function createDocumentPageChromeEditorExtensions(placeholder = '输入页眉或
|
|
|
4087
4087
|
DocumentFontFamily,
|
|
4088
4088
|
font_size,
|
|
4089
4089
|
extension_color,
|
|
4090
|
+
DocumentHighlight.configure({
|
|
4091
|
+
multicolor: true
|
|
4092
|
+
}),
|
|
4090
4093
|
DocumentUnderline,
|
|
4091
4094
|
DocumentStrike,
|
|
4092
4095
|
DocumentCharacterFormatting,
|
|
@@ -4804,65 +4807,6 @@ function normalizeDocumentPageNumberInput(value) {
|
|
|
4804
4807
|
const number = Number(value);
|
|
4805
4808
|
return Number.isFinite(number) ? Math.min(9999, Math.max(1, Math.round(number))) : null;
|
|
4806
4809
|
}
|
|
4807
|
-
function collectWorkDocumentOutline(document1) {
|
|
4808
|
-
const items = [];
|
|
4809
|
-
const hierarchy = [];
|
|
4810
|
-
document1.descendants((node, position)=>{
|
|
4811
|
-
if ('heading' !== node.type.name) return;
|
|
4812
|
-
const level = documentHeadingLevel(node.attrs.level);
|
|
4813
|
-
while((hierarchy.at(-1)?.level ?? 0) >= level)hierarchy.pop();
|
|
4814
|
-
const parent = hierarchy.at(-1);
|
|
4815
|
-
const from = position + 1;
|
|
4816
|
-
const item = {
|
|
4817
|
-
id: `heading-${position}`,
|
|
4818
|
-
text: normalizedDocumentHeadingText(node.textContent),
|
|
4819
|
-
level,
|
|
4820
|
-
depth: hierarchy.length,
|
|
4821
|
-
from,
|
|
4822
|
-
to: from + node.content.size,
|
|
4823
|
-
...parent ? {
|
|
4824
|
-
parentId: parent.id
|
|
4825
|
-
} : {}
|
|
4826
|
-
};
|
|
4827
|
-
items.push(item);
|
|
4828
|
-
hierarchy.push(item);
|
|
4829
|
-
});
|
|
4830
|
-
return items.map((item, index)=>({
|
|
4831
|
-
...item,
|
|
4832
|
-
hasChildren: (items[index + 1]?.depth ?? -1) > item.depth
|
|
4833
|
-
}));
|
|
4834
|
-
}
|
|
4835
|
-
function currentWorkDocumentOutlineItem(items, position) {
|
|
4836
|
-
let current = null;
|
|
4837
|
-
for (const item of items){
|
|
4838
|
-
if (item.from > position) break;
|
|
4839
|
-
current = item;
|
|
4840
|
-
}
|
|
4841
|
-
return current;
|
|
4842
|
-
}
|
|
4843
|
-
function visibleWorkDocumentOutlineItems(items, collapsedIds, rawQuery) {
|
|
4844
|
-
const query = normalizedDocumentOutlineQuery(rawQuery);
|
|
4845
|
-
if (query) return items.filter((item)=>normalizedDocumentOutlineQuery(item.text).includes(query));
|
|
4846
|
-
const visible = [];
|
|
4847
|
-
let hiddenBelowDepth = null;
|
|
4848
|
-
for (const item of items){
|
|
4849
|
-
if (null !== hiddenBelowDepth && item.depth <= hiddenBelowDepth) hiddenBelowDepth = null;
|
|
4850
|
-
if (null === hiddenBelowDepth) {
|
|
4851
|
-
visible.push(item);
|
|
4852
|
-
if (item.hasChildren && collapsedIds.has(item.id)) hiddenBelowDepth = item.depth;
|
|
4853
|
-
}
|
|
4854
|
-
}
|
|
4855
|
-
return visible;
|
|
4856
|
-
}
|
|
4857
|
-
function documentHeadingLevel(value) {
|
|
4858
|
-
return 'number' == typeof value && Number.isInteger(value) && value >= 1 && value <= 6 ? value : 1;
|
|
4859
|
-
}
|
|
4860
|
-
function normalizedDocumentHeadingText(value) {
|
|
4861
|
-
return value.replace(/\s+/g, ' ').trim() || '未命名标题';
|
|
4862
|
-
}
|
|
4863
|
-
function normalizedDocumentOutlineQuery(value) {
|
|
4864
|
-
return value.normalize('NFKC').trim().toLocaleLowerCase();
|
|
4865
|
-
}
|
|
4866
4810
|
const DOCUMENT_OUTLINE_ITEM_HEIGHT = 31;
|
|
4867
4811
|
const DOCUMENT_OUTLINE_LIST_PADDING_TOP = 6;
|
|
4868
4812
|
const document_outline_navigation_DocumentOutlineNavigation = /*#__PURE__*/ forwardRef(function({ activeItemId, collapsedIds, items, rovingId, onNavigate, onRovingIdChange, onToggleCollapsed }, ref) {
|
|
@@ -7521,6 +7465,24 @@ const documentCommandCatalog = {
|
|
|
7521
7465
|
]
|
|
7522
7466
|
}
|
|
7523
7467
|
},
|
|
7468
|
+
tableOfContents: {
|
|
7469
|
+
id: 'references.tableOfContents',
|
|
7470
|
+
label: '插入或自定义目录',
|
|
7471
|
+
location: {
|
|
7472
|
+
area: 'ribbon',
|
|
7473
|
+
tab: 'references',
|
|
7474
|
+
group: 'tableOfContents'
|
|
7475
|
+
}
|
|
7476
|
+
},
|
|
7477
|
+
refreshTableOfContents: {
|
|
7478
|
+
id: 'references.refreshTableOfContents',
|
|
7479
|
+
label: '更新目录',
|
|
7480
|
+
location: {
|
|
7481
|
+
area: 'ribbon',
|
|
7482
|
+
tab: 'references',
|
|
7483
|
+
group: 'tableOfContents'
|
|
7484
|
+
}
|
|
7485
|
+
},
|
|
7524
7486
|
refreshFields: {
|
|
7525
7487
|
id: 'references.refreshFields',
|
|
7526
7488
|
label: '更新域',
|
|
@@ -8107,6 +8069,428 @@ function DocumentStatusBar({ bibliographyCount, citationCount, currentPage, page
|
|
|
8107
8069
|
]
|
|
8108
8070
|
});
|
|
8109
8071
|
}
|
|
8072
|
+
const proofingStateOptions = [
|
|
8073
|
+
{
|
|
8074
|
+
value: 'mixed',
|
|
8075
|
+
label: '混合(保持不变)',
|
|
8076
|
+
disabled: true
|
|
8077
|
+
},
|
|
8078
|
+
{
|
|
8079
|
+
value: 'inherit',
|
|
8080
|
+
label: '跟随样式'
|
|
8081
|
+
},
|
|
8082
|
+
{
|
|
8083
|
+
value: 'check',
|
|
8084
|
+
label: '检查拼写和语法'
|
|
8085
|
+
},
|
|
8086
|
+
{
|
|
8087
|
+
value: 'skip',
|
|
8088
|
+
label: '不检查拼写或语法'
|
|
8089
|
+
}
|
|
8090
|
+
];
|
|
8091
|
+
const proofingLanguageSuggestions = [
|
|
8092
|
+
'en-US',
|
|
8093
|
+
'en-GB',
|
|
8094
|
+
'zh-CN',
|
|
8095
|
+
'zh-TW',
|
|
8096
|
+
'ja-JP',
|
|
8097
|
+
'ko-KR',
|
|
8098
|
+
'ar-SA',
|
|
8099
|
+
'he-IL',
|
|
8100
|
+
'fr-FR',
|
|
8101
|
+
'de-DE',
|
|
8102
|
+
'es-ES',
|
|
8103
|
+
'x-none'
|
|
8104
|
+
];
|
|
8105
|
+
function DocumentProofingDialog({ source, restoreFocusTarget, onApply, onClose }) {
|
|
8106
|
+
const [draft, setDraft] = useState(()=>({
|
|
8107
|
+
latin: source.latin.value ?? '',
|
|
8108
|
+
eastAsia: source.eastAsia.value ?? '',
|
|
8109
|
+
bidi: source.bidi.value ?? '',
|
|
8110
|
+
noProof: proofingStateDraft(source)
|
|
8111
|
+
}));
|
|
8112
|
+
const [touched, setTouched] = useState({
|
|
8113
|
+
latin: false,
|
|
8114
|
+
eastAsia: false,
|
|
8115
|
+
bidi: false,
|
|
8116
|
+
noProof: false
|
|
8117
|
+
});
|
|
8118
|
+
const formId = useId();
|
|
8119
|
+
const datalistId = useId();
|
|
8120
|
+
const error = proofingDialogError(draft, touched);
|
|
8121
|
+
const patch = proofingDialogPatch(source, draft, touched);
|
|
8122
|
+
const hasChanges = Object.keys(patch).length > 0;
|
|
8123
|
+
const submit = (event)=>{
|
|
8124
|
+
event?.preventDefault();
|
|
8125
|
+
if (!hasChanges || error) return;
|
|
8126
|
+
if (onApply(patch)) onClose();
|
|
8127
|
+
};
|
|
8128
|
+
return /*#__PURE__*/ jsx(Dialog, {
|
|
8129
|
+
title: "设置校对语言",
|
|
8130
|
+
description: source.selectedCharacters ? `为选中的 ${source.selectedCharacters} 个字符分别设置拉丁、东亚和双向文字校对语言。` : '设置当前位置后续输入文字的校对语言。',
|
|
8131
|
+
className: "work-document-proofing-dialog",
|
|
8132
|
+
restoreFocusTarget: restoreFocusTarget,
|
|
8133
|
+
onClose: onClose,
|
|
8134
|
+
footer: /*#__PURE__*/ jsxs(Fragment, {
|
|
8135
|
+
children: [
|
|
8136
|
+
/*#__PURE__*/ jsx(button_Button, {
|
|
8137
|
+
tone: "quiet",
|
|
8138
|
+
onClick: onClose,
|
|
8139
|
+
children: "取消"
|
|
8140
|
+
}),
|
|
8141
|
+
/*#__PURE__*/ jsx(button_Button, {
|
|
8142
|
+
tone: "primary",
|
|
8143
|
+
type: "submit",
|
|
8144
|
+
form: formId,
|
|
8145
|
+
disabled: !hasChanges || Boolean(error),
|
|
8146
|
+
children: "应用"
|
|
8147
|
+
})
|
|
8148
|
+
]
|
|
8149
|
+
}),
|
|
8150
|
+
children: /*#__PURE__*/ jsxs("form", {
|
|
8151
|
+
id: formId,
|
|
8152
|
+
onSubmit: submit,
|
|
8153
|
+
children: [
|
|
8154
|
+
/*#__PURE__*/ jsxs("fieldset", {
|
|
8155
|
+
children: [
|
|
8156
|
+
/*#__PURE__*/ jsx("legend", {
|
|
8157
|
+
children: "按文字系统设置语言"
|
|
8158
|
+
}),
|
|
8159
|
+
/*#__PURE__*/ jsx(ProofingLanguageField, {
|
|
8160
|
+
label: "拉丁文字",
|
|
8161
|
+
languageKey: "latin",
|
|
8162
|
+
value: draft.latin,
|
|
8163
|
+
mixed: source.latin.mixed && !touched.latin,
|
|
8164
|
+
list: datalistId,
|
|
8165
|
+
initialFocus: true,
|
|
8166
|
+
error: touched.latin && !validLanguageDraft(draft.latin),
|
|
8167
|
+
onChange: (value)=>{
|
|
8168
|
+
setDraft((current)=>({
|
|
8169
|
+
...current,
|
|
8170
|
+
latin: value
|
|
8171
|
+
}));
|
|
8172
|
+
setTouched((current)=>({
|
|
8173
|
+
...current,
|
|
8174
|
+
latin: true
|
|
8175
|
+
}));
|
|
8176
|
+
}
|
|
8177
|
+
}),
|
|
8178
|
+
/*#__PURE__*/ jsx(ProofingLanguageField, {
|
|
8179
|
+
label: "东亚文字",
|
|
8180
|
+
languageKey: "eastAsia",
|
|
8181
|
+
value: draft.eastAsia,
|
|
8182
|
+
mixed: source.eastAsia.mixed && !touched.eastAsia,
|
|
8183
|
+
list: datalistId,
|
|
8184
|
+
error: touched.eastAsia && !validLanguageDraft(draft.eastAsia),
|
|
8185
|
+
onChange: (value)=>{
|
|
8186
|
+
setDraft((current)=>({
|
|
8187
|
+
...current,
|
|
8188
|
+
eastAsia: value
|
|
8189
|
+
}));
|
|
8190
|
+
setTouched((current)=>({
|
|
8191
|
+
...current,
|
|
8192
|
+
eastAsia: true
|
|
8193
|
+
}));
|
|
8194
|
+
}
|
|
8195
|
+
}),
|
|
8196
|
+
/*#__PURE__*/ jsx(ProofingLanguageField, {
|
|
8197
|
+
label: "双向文字",
|
|
8198
|
+
languageKey: "bidi",
|
|
8199
|
+
value: draft.bidi,
|
|
8200
|
+
mixed: source.bidi.mixed && !touched.bidi,
|
|
8201
|
+
list: datalistId,
|
|
8202
|
+
error: touched.bidi && !validLanguageDraft(draft.bidi),
|
|
8203
|
+
onChange: (value)=>{
|
|
8204
|
+
setDraft((current)=>({
|
|
8205
|
+
...current,
|
|
8206
|
+
bidi: value
|
|
8207
|
+
}));
|
|
8208
|
+
setTouched((current)=>({
|
|
8209
|
+
...current,
|
|
8210
|
+
bidi: true
|
|
8211
|
+
}));
|
|
8212
|
+
}
|
|
8213
|
+
}),
|
|
8214
|
+
/*#__PURE__*/ jsx("datalist", {
|
|
8215
|
+
id: datalistId,
|
|
8216
|
+
children: proofingLanguageSuggestions.map((language)=>/*#__PURE__*/ jsx("option", {
|
|
8217
|
+
value: language
|
|
8218
|
+
}, language))
|
|
8219
|
+
})
|
|
8220
|
+
]
|
|
8221
|
+
}),
|
|
8222
|
+
/*#__PURE__*/ jsxs("div", {
|
|
8223
|
+
className: "work-document-proofing-dialog-state",
|
|
8224
|
+
children: [
|
|
8225
|
+
/*#__PURE__*/ jsx("span", {
|
|
8226
|
+
className: "work-document-proofing-dialog-state-label",
|
|
8227
|
+
"aria-hidden": "true",
|
|
8228
|
+
children: "校对行为"
|
|
8229
|
+
}),
|
|
8230
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
8231
|
+
ariaLabel: "校对行为",
|
|
8232
|
+
value: draft.noProof,
|
|
8233
|
+
options: proofingStateOptions,
|
|
8234
|
+
onValueChange: (noProof)=>{
|
|
8235
|
+
setDraft((current)=>({
|
|
8236
|
+
...current,
|
|
8237
|
+
noProof
|
|
8238
|
+
}));
|
|
8239
|
+
setTouched((current)=>({
|
|
8240
|
+
...current,
|
|
8241
|
+
noProof: true
|
|
8242
|
+
}));
|
|
8243
|
+
}
|
|
8244
|
+
}),
|
|
8245
|
+
source.noProof.mixed && !touched.noProof && /*#__PURE__*/ jsx("p", {
|
|
8246
|
+
role: "status",
|
|
8247
|
+
children: "当前选区包含不同的校对行为,保持不变。"
|
|
8248
|
+
})
|
|
8249
|
+
]
|
|
8250
|
+
}),
|
|
8251
|
+
/*#__PURE__*/ jsxs("p", {
|
|
8252
|
+
className: "work-document-proofing-dialog-help",
|
|
8253
|
+
children: [
|
|
8254
|
+
"使用 BCP 47 语言标记,例如 ",
|
|
8255
|
+
/*#__PURE__*/ jsx("code", {
|
|
8256
|
+
children: "en-US"
|
|
8257
|
+
}),
|
|
8258
|
+
"、",
|
|
8259
|
+
/*#__PURE__*/ jsx("code", {
|
|
8260
|
+
children: "zh-CN"
|
|
8261
|
+
}),
|
|
8262
|
+
" 或",
|
|
8263
|
+
' ',
|
|
8264
|
+
/*#__PURE__*/ jsx("code", {
|
|
8265
|
+
children: "ar-SA"
|
|
8266
|
+
}),
|
|
8267
|
+
"。留空或选择“跟随样式”会移除直接格式。"
|
|
8268
|
+
]
|
|
8269
|
+
}),
|
|
8270
|
+
error && /*#__PURE__*/ jsx("p", {
|
|
8271
|
+
className: "work-document-proofing-dialog-error",
|
|
8272
|
+
role: "alert",
|
|
8273
|
+
children: error
|
|
8274
|
+
})
|
|
8275
|
+
]
|
|
8276
|
+
})
|
|
8277
|
+
});
|
|
8278
|
+
}
|
|
8279
|
+
function ProofingLanguageField({ label, languageKey, value, mixed, list, initialFocus = false, error, onChange }) {
|
|
8280
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
8281
|
+
className: "work-document-proofing-dialog-language",
|
|
8282
|
+
children: [
|
|
8283
|
+
/*#__PURE__*/ jsx("label", {
|
|
8284
|
+
htmlFor: `work-document-proofing-${languageKey}`,
|
|
8285
|
+
children: label
|
|
8286
|
+
}),
|
|
8287
|
+
/*#__PURE__*/ jsxs("div", {
|
|
8288
|
+
children: [
|
|
8289
|
+
/*#__PURE__*/ jsx(office_text_field_OfficeTextField, {
|
|
8290
|
+
id: `work-document-proofing-${languageKey}`,
|
|
8291
|
+
"aria-label": `${label}校对语言`,
|
|
8292
|
+
"aria-invalid": error || void 0,
|
|
8293
|
+
"data-autofocus": initialFocus ? 'true' : void 0,
|
|
8294
|
+
list: list,
|
|
8295
|
+
value: value,
|
|
8296
|
+
placeholder: mixed ? '混合(保持不变)' : '跟随样式',
|
|
8297
|
+
spellCheck: false,
|
|
8298
|
+
onChange: (event)=>onChange(event.currentTarget.value)
|
|
8299
|
+
}),
|
|
8300
|
+
/*#__PURE__*/ jsx(button_Button, {
|
|
8301
|
+
tone: "quiet",
|
|
8302
|
+
type: "button",
|
|
8303
|
+
"aria-label": `${label}跟随样式`,
|
|
8304
|
+
onClick: ()=>onChange(''),
|
|
8305
|
+
children: "跟随样式"
|
|
8306
|
+
})
|
|
8307
|
+
]
|
|
8308
|
+
}),
|
|
8309
|
+
mixed && /*#__PURE__*/ jsxs("p", {
|
|
8310
|
+
role: "status",
|
|
8311
|
+
children: [
|
|
8312
|
+
"当前选区包含不同的",
|
|
8313
|
+
label,
|
|
8314
|
+
"校对语言,输入后才会统一修改。"
|
|
8315
|
+
]
|
|
8316
|
+
})
|
|
8317
|
+
]
|
|
8318
|
+
});
|
|
8319
|
+
}
|
|
8320
|
+
function proofingStateDraft(source) {
|
|
8321
|
+
if (source.noProof.mixed) return 'mixed';
|
|
8322
|
+
if (null === source.noProof.value) return 'inherit';
|
|
8323
|
+
return source.noProof.value ? 'skip' : 'check';
|
|
8324
|
+
}
|
|
8325
|
+
function proofingDialogPatch(source, draft, touched) {
|
|
8326
|
+
const languages = {};
|
|
8327
|
+
for (const key of [
|
|
8328
|
+
'latin',
|
|
8329
|
+
'eastAsia',
|
|
8330
|
+
'bidi'
|
|
8331
|
+
]){
|
|
8332
|
+
if (!touched[key] || !validLanguageDraft(draft[key])) continue;
|
|
8333
|
+
const value = draft[key] || null;
|
|
8334
|
+
if (source[key].mixed || source[key].value !== value) languages[key] = value;
|
|
8335
|
+
}
|
|
8336
|
+
const patch = {};
|
|
8337
|
+
if (Object.keys(languages).length) patch.languages = languages;
|
|
8338
|
+
if (touched.noProof && 'mixed' !== draft.noProof) {
|
|
8339
|
+
const noProof = 'inherit' === draft.noProof ? null : 'skip' === draft.noProof;
|
|
8340
|
+
if (source.noProof.mixed || source.noProof.value !== noProof) patch.noProof = noProof;
|
|
8341
|
+
}
|
|
8342
|
+
return patch;
|
|
8343
|
+
}
|
|
8344
|
+
function proofingDialogError(draft, touched) {
|
|
8345
|
+
for (const key of [
|
|
8346
|
+
'latin',
|
|
8347
|
+
'eastAsia',
|
|
8348
|
+
'bidi'
|
|
8349
|
+
])if (touched[key] && !validLanguageDraft(draft[key])) return '请输入有效的 BCP 47 语言标记;不能包含空格、下划线或控制字符。';
|
|
8350
|
+
return null;
|
|
8351
|
+
}
|
|
8352
|
+
function validLanguageDraft(value) {
|
|
8353
|
+
return '' === value || null !== normalizeDocumentLanguageTag(value);
|
|
8354
|
+
}
|
|
8355
|
+
const PROOFING_LANGUAGE_SLOTS = [
|
|
8356
|
+
'latin',
|
|
8357
|
+
'eastAsia',
|
|
8358
|
+
'bidi'
|
|
8359
|
+
];
|
|
8360
|
+
const PROOFING_LANGUAGE_SLOT_SET = new Set(PROOFING_LANGUAGE_SLOTS);
|
|
8361
|
+
function documentProofingDialogSource(editor) {
|
|
8362
|
+
const latin = new Map();
|
|
8363
|
+
const eastAsia = new Map();
|
|
8364
|
+
const bidi = new Map();
|
|
8365
|
+
const noProof = new Map();
|
|
8366
|
+
const { doc, selection } = editor.state;
|
|
8367
|
+
const addValues = (attributes)=>{
|
|
8368
|
+
const languages = parseDocumentProofingLanguages(attributes.proofingLanguages);
|
|
8369
|
+
addSelectedValue(latin, languages?.latin ?? null);
|
|
8370
|
+
addSelectedValue(eastAsia, languages?.eastAsia ?? null);
|
|
8371
|
+
addSelectedValue(bidi, languages?.bidi ?? null);
|
|
8372
|
+
addSelectedValue(noProof, normalizeDocumentNoProof(attributes.noProof));
|
|
8373
|
+
};
|
|
8374
|
+
if (selection.empty) addValues(editor.getAttributes('textStyle'));
|
|
8375
|
+
else doc.nodesBetween(selection.from, selection.to, (node, position)=>{
|
|
8376
|
+
if (!node.isText || position >= selection.to || position + node.nodeSize <= selection.from) return;
|
|
8377
|
+
const textStyle = node.marks.find((mark)=>'textStyle' === mark.type.name);
|
|
8378
|
+
addValues(textStyle?.attrs ?? {});
|
|
8379
|
+
});
|
|
8380
|
+
if (!latin.size) addValues(editor.getAttributes('textStyle'));
|
|
8381
|
+
const selectedText = selection.empty ? '' : doc.textBetween(selection.from, selection.to, '', '');
|
|
8382
|
+
return {
|
|
8383
|
+
latin: selectedValue(latin),
|
|
8384
|
+
eastAsia: selectedValue(eastAsia),
|
|
8385
|
+
bidi: selectedValue(bidi),
|
|
8386
|
+
noProof: selectedValue(noProof),
|
|
8387
|
+
selectedCharacters: Array.from(selectedText).length
|
|
8388
|
+
};
|
|
8389
|
+
}
|
|
8390
|
+
function applyDocumentProofingDialogPatch(editor, selection, patch) {
|
|
8391
|
+
if (!validDocumentProofingDialogPatch(patch) || editor.isDestroyed) return false;
|
|
8392
|
+
const maximum = editor.state.doc.content.size;
|
|
8393
|
+
if (!Number.isSafeInteger(selection.from) || !Number.isSafeInteger(selection.to) || selection.from < 0 || selection.to < selection.from || selection.to > maximum) return false;
|
|
8394
|
+
const textStyle = editor.state.schema.marks.textStyle;
|
|
8395
|
+
if (!textStyle) return false;
|
|
8396
|
+
const transaction = editor.state.tr;
|
|
8397
|
+
try {
|
|
8398
|
+
transaction.setSelection(TextSelection.create(transaction.doc, selection.from, selection.to));
|
|
8399
|
+
} catch {
|
|
8400
|
+
return false;
|
|
8401
|
+
}
|
|
8402
|
+
if (selection.from === selection.to) {
|
|
8403
|
+
const marks = transaction.selection.$from.marks();
|
|
8404
|
+
const current = marks.find((mark)=>mark.type === textStyle);
|
|
8405
|
+
const attributes = patchedProofingAttributes(current, patch);
|
|
8406
|
+
if (!attributes) return false;
|
|
8407
|
+
const retained = marks.filter((mark)=>mark.type !== textStyle);
|
|
8408
|
+
if (textStyleAttributesHaveValue(attributes)) retained.push(textStyle.create(attributes));
|
|
8409
|
+
transaction.setStoredMarks(retained);
|
|
8410
|
+
transaction.scrollIntoView();
|
|
8411
|
+
editor.view.dispatch(transaction);
|
|
8412
|
+
editor.view.focus();
|
|
8413
|
+
return true;
|
|
8414
|
+
}
|
|
8415
|
+
const updates = [];
|
|
8416
|
+
transaction.doc.nodesBetween(selection.from, selection.to, (node, position)=>{
|
|
8417
|
+
if (!node.isText || !node.text) return;
|
|
8418
|
+
const from = Math.max(selection.from, position);
|
|
8419
|
+
const to = Math.min(selection.to, position + node.nodeSize);
|
|
8420
|
+
if (to <= from) return;
|
|
8421
|
+
const current = node.marks.find((mark)=>mark.type === textStyle);
|
|
8422
|
+
const attributes = patchedProofingAttributes(current, patch);
|
|
8423
|
+
if (attributes) updates.push({
|
|
8424
|
+
from,
|
|
8425
|
+
to,
|
|
8426
|
+
current,
|
|
8427
|
+
attributes
|
|
8428
|
+
});
|
|
8429
|
+
});
|
|
8430
|
+
for (const update of updates){
|
|
8431
|
+
if (update.current) transaction.removeMark(update.from, update.to, update.current);
|
|
8432
|
+
if (textStyleAttributesHaveValue(update.attributes)) transaction.addMark(update.from, update.to, textStyle.create(update.attributes));
|
|
8433
|
+
}
|
|
8434
|
+
if (!transaction.docChanged) return false;
|
|
8435
|
+
editor.view.dispatch(transaction.scrollIntoView());
|
|
8436
|
+
editor.view.focus();
|
|
8437
|
+
return true;
|
|
8438
|
+
}
|
|
8439
|
+
function patchedProofingAttributes(current, patch) {
|
|
8440
|
+
const attributes = {
|
|
8441
|
+
...current?.attrs ?? {}
|
|
8442
|
+
};
|
|
8443
|
+
let changed = false;
|
|
8444
|
+
if (patch.languages) {
|
|
8445
|
+
const currentLanguages = parseDocumentProofingLanguages(current?.attrs.proofingLanguages);
|
|
8446
|
+
const nextLanguages = patchDocumentProofingLanguages(currentLanguages, patch.languages);
|
|
8447
|
+
const currentSerialized = serializeDocumentProofingLanguages(currentLanguages) ?? null;
|
|
8448
|
+
const nextSerialized = serializeDocumentProofingLanguages(nextLanguages) ?? null;
|
|
8449
|
+
if (currentSerialized !== nextSerialized) {
|
|
8450
|
+
attributes.proofingLanguages = nextSerialized;
|
|
8451
|
+
changed = true;
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
if (void 0 !== patch.noProof) {
|
|
8455
|
+
const currentNoProof = normalizeDocumentNoProof(current?.attrs.noProof);
|
|
8456
|
+
if (currentNoProof !== patch.noProof) {
|
|
8457
|
+
attributes.noProof = patch.noProof;
|
|
8458
|
+
changed = true;
|
|
8459
|
+
}
|
|
8460
|
+
}
|
|
8461
|
+
return changed ? attributes : null;
|
|
8462
|
+
}
|
|
8463
|
+
function validDocumentProofingDialogPatch(patch) {
|
|
8464
|
+
if (!isRecord(patch)) return false;
|
|
8465
|
+
const keys = Object.keys(patch);
|
|
8466
|
+
if (!keys.length || keys.some((key)=>'languages' !== key && 'noProof' !== key)) return false;
|
|
8467
|
+
if (void 0 !== patch.noProof && null !== patch.noProof && null === normalizeDocumentNoProof(patch.noProof)) return false;
|
|
8468
|
+
if (void 0 !== patch.languages) {
|
|
8469
|
+
if (!isRecord(patch.languages)) return false;
|
|
8470
|
+
const languageEntries = Object.entries(patch.languages);
|
|
8471
|
+
if (!languageEntries.length || languageEntries.some(([slot, language])=>!PROOFING_LANGUAGE_SLOT_SET.has(slot) || null !== language && null === normalizeDocumentLanguageTag(language))) return false;
|
|
8472
|
+
}
|
|
8473
|
+
return void 0 !== patch.languages || void 0 !== patch.noProof;
|
|
8474
|
+
}
|
|
8475
|
+
function addSelectedValue(values, value) {
|
|
8476
|
+
values.set(null === value ? 'inherited' : String(value), value);
|
|
8477
|
+
}
|
|
8478
|
+
function selectedValue(values) {
|
|
8479
|
+
if (1 !== values.size) return {
|
|
8480
|
+
mixed: true,
|
|
8481
|
+
value: null
|
|
8482
|
+
};
|
|
8483
|
+
return {
|
|
8484
|
+
mixed: false,
|
|
8485
|
+
value: values.values().next().value ?? null
|
|
8486
|
+
};
|
|
8487
|
+
}
|
|
8488
|
+
function textStyleAttributesHaveValue(attributes) {
|
|
8489
|
+
return Object.values(attributes).some((value)=>null != value && '' !== value);
|
|
8490
|
+
}
|
|
8491
|
+
function isRecord(source) {
|
|
8492
|
+
return 'object' == typeof source && null !== source && !Array.isArray(source);
|
|
8493
|
+
}
|
|
8110
8494
|
function DocumentFormatTools({ editor }) {
|
|
8111
8495
|
const hasFormat = useSyncExternalStore(subscribeDocumentFormatClipboard, hasDocumentFormatClipboard, hasDocumentFormatClipboard);
|
|
8112
8496
|
const [formatPainterActive, setFormatPainterActive] = useState(false);
|
|
@@ -9194,7 +9578,7 @@ function applyDocumentScriptFontPatch(editor, selection, scalarPatch, scriptFont
|
|
|
9194
9578
|
const current = marks.find((mark)=>mark.type === textStyle);
|
|
9195
9579
|
const attributes = patchedTextStyleAttributes(current, scalarPatch, scriptFontPatch, normalizeDocumentScriptFontSlot(current?.attrs.scriptFontSlot) ?? documentScriptFontSlotFromHint(parseDocumentScriptFonts(current?.attrs.scriptFonts)?.hint));
|
|
9196
9580
|
const retained = marks.filter((mark)=>mark.type !== textStyle);
|
|
9197
|
-
if (
|
|
9581
|
+
if (document_font_dialog_script_font_model_textStyleAttributesHaveValue(attributes)) retained.push(textStyle.create(attributes));
|
|
9198
9582
|
transaction.setStoredMarks(retained);
|
|
9199
9583
|
transaction.scrollIntoView();
|
|
9200
9584
|
editor.view.dispatch(transaction);
|
|
@@ -9221,7 +9605,7 @@ function applyDocumentScriptFontPatch(editor, selection, scalarPatch, scriptFont
|
|
|
9221
9605
|
});
|
|
9222
9606
|
for (const update of updates){
|
|
9223
9607
|
if (update.current) transaction.removeMark(update.from, update.to, update.current);
|
|
9224
|
-
if (
|
|
9608
|
+
if (document_font_dialog_script_font_model_textStyleAttributesHaveValue(update.attributes)) transaction.addMark(update.from, update.to, textStyle.create(update.attributes));
|
|
9225
9609
|
}
|
|
9226
9610
|
if (!transaction.docChanged) return false;
|
|
9227
9611
|
editor.view.dispatch(transaction.scrollIntoView());
|
|
@@ -9250,7 +9634,7 @@ function patchedTextStyleAttributes(current, scalarPatch, scriptFontPatch, slot,
|
|
|
9250
9634
|
attributes.wordLineHeightFactor = family ? documentWordLineHeightFactor(family) : null;
|
|
9251
9635
|
return attributes;
|
|
9252
9636
|
}
|
|
9253
|
-
function
|
|
9637
|
+
function document_font_dialog_script_font_model_textStyleAttributesHaveValue(attributes) {
|
|
9254
9638
|
return Object.values(attributes).some((value)=>null != value && '' !== value);
|
|
9255
9639
|
}
|
|
9256
9640
|
function validScriptFontPatch(patch) {
|
|
@@ -9343,6 +9727,87 @@ function runBorderSpaceFromDraft(draft) {
|
|
|
9343
9727
|
function formatPoints(value) {
|
|
9344
9728
|
return Number(value.toFixed(3)).toString();
|
|
9345
9729
|
}
|
|
9730
|
+
function addDocumentFontDialogRunShadingValue(values, source) {
|
|
9731
|
+
const shading = parseDocumentRunShading(source);
|
|
9732
|
+
const serialized = serializeDocumentRunShading(shading);
|
|
9733
|
+
values.set(serialized ?? 'inherited', shading);
|
|
9734
|
+
}
|
|
9735
|
+
function selectedDocumentFontDialogRunShadingValue(values) {
|
|
9736
|
+
return 1 === values.size ? {
|
|
9737
|
+
mixed: false,
|
|
9738
|
+
value: values.values().next().value ?? null
|
|
9739
|
+
} : {
|
|
9740
|
+
mixed: true,
|
|
9741
|
+
value: null
|
|
9742
|
+
};
|
|
9743
|
+
}
|
|
9744
|
+
function createDocumentFontDialogRunShadingDraft(source) {
|
|
9745
|
+
const shading = source.value;
|
|
9746
|
+
return {
|
|
9747
|
+
runShadingMode: source.mixed ? 'mixed' : shading ? 'nil' === shading.pattern ? 'none' : 'value' : 'inherit',
|
|
9748
|
+
runShadingPattern: shading && 'nil' !== shading.pattern ? shading.pattern : 'clear',
|
|
9749
|
+
runShadingColor: shading?.color?.value ?? 'auto',
|
|
9750
|
+
runShadingFill: shading?.fill?.value ?? 'auto'
|
|
9751
|
+
};
|
|
9752
|
+
}
|
|
9753
|
+
function documentFontDialogRunShadingDraftError(draft) {
|
|
9754
|
+
if ('value' !== draft.runShadingMode) return null;
|
|
9755
|
+
if (!validColor(draft.runShadingColor)) return '请选择有效的字符底纹前景色。';
|
|
9756
|
+
if (!validColor(draft.runShadingFill)) return '请选择有效的字符底纹背景色。';
|
|
9757
|
+
return null;
|
|
9758
|
+
}
|
|
9759
|
+
function documentFontDialogRunShadingPatch(source, draft, touched) {
|
|
9760
|
+
if (!touched || 'mixed' === draft.runShadingMode) return {};
|
|
9761
|
+
if ('inherit' === draft.runShadingMode) return source.mixed || source.value ? {
|
|
9762
|
+
runShading: null
|
|
9763
|
+
} : {};
|
|
9764
|
+
const shading = 'none' === draft.runShadingMode ? {
|
|
9765
|
+
pattern: 'nil'
|
|
9766
|
+
} : documentFontDialogRunShadingFromDraft(source, draft);
|
|
9767
|
+
if (!shading) return {};
|
|
9768
|
+
return serializeDocumentRunShading(source.value) === serializeDocumentRunShading(shading) ? {} : {
|
|
9769
|
+
runShading: shading
|
|
9770
|
+
};
|
|
9771
|
+
}
|
|
9772
|
+
function documentFontDialogRunShadingFromDraft(source, draft) {
|
|
9773
|
+
if ('none' === draft.runShadingMode) return {
|
|
9774
|
+
pattern: 'nil'
|
|
9775
|
+
};
|
|
9776
|
+
if ('value' !== draft.runShadingMode) return source.value;
|
|
9777
|
+
return normalizeDocumentRunShading({
|
|
9778
|
+
pattern: draft.runShadingPattern,
|
|
9779
|
+
...shadingColorPatch('color', draft.runShadingColor, source.value?.color),
|
|
9780
|
+
...shadingColorPatch('fill', draft.runShadingFill, source.value?.fill)
|
|
9781
|
+
});
|
|
9782
|
+
}
|
|
9783
|
+
function documentFontDialogRunShadingPreviewStyle(source, draft) {
|
|
9784
|
+
const shading = documentFontDialogRunShadingFromDraft(source, draft);
|
|
9785
|
+
const cssText = documentRunShadingDomAttributes(shading).style;
|
|
9786
|
+
if (!cssText) return {};
|
|
9787
|
+
const probe = document.createElement('span');
|
|
9788
|
+
probe.style.cssText = cssText;
|
|
9789
|
+
return {
|
|
9790
|
+
backgroundColor: probe.style.backgroundColor || void 0,
|
|
9791
|
+
backgroundImage: probe.style.backgroundImage || void 0,
|
|
9792
|
+
backgroundSize: probe.style.backgroundSize || void 0,
|
|
9793
|
+
boxDecorationBreak: 'clone',
|
|
9794
|
+
WebkitBoxDecorationBreak: 'clone'
|
|
9795
|
+
};
|
|
9796
|
+
}
|
|
9797
|
+
function shadingColorPatch(name, value, source) {
|
|
9798
|
+
if (!source && 'auto' === value) return {};
|
|
9799
|
+
return {
|
|
9800
|
+
[name]: {
|
|
9801
|
+
value,
|
|
9802
|
+
...source?.theme && source.value === value ? {
|
|
9803
|
+
theme: source.theme
|
|
9804
|
+
} : {}
|
|
9805
|
+
}
|
|
9806
|
+
};
|
|
9807
|
+
}
|
|
9808
|
+
function validColor(value) {
|
|
9809
|
+
return 'auto' === value || /^#[0-9a-f]{6}$/i.test(value);
|
|
9810
|
+
}
|
|
9346
9811
|
function documentFontDialogSource(editor) {
|
|
9347
9812
|
const { doc, selection } = editor.state;
|
|
9348
9813
|
const scaleValues = new Map();
|
|
@@ -9356,6 +9821,7 @@ function documentFontDialogSource(editor) {
|
|
|
9356
9821
|
const legacyTextEmbossValues = new Map();
|
|
9357
9822
|
const legacyTextImprintValues = new Map();
|
|
9358
9823
|
const runBorderValues = new Map();
|
|
9824
|
+
const runShadingValues = new Map();
|
|
9359
9825
|
const latinFontValues = new Map();
|
|
9360
9826
|
const eastAsiaFontValues = new Map();
|
|
9361
9827
|
const complexScriptFontValues = new Map();
|
|
@@ -9371,6 +9837,7 @@ function documentFontDialogSource(editor) {
|
|
|
9371
9837
|
addLegacyTextEffectValue(legacyTextEmbossValues, attributes.legacyTextEmboss);
|
|
9372
9838
|
addLegacyTextEffectValue(legacyTextImprintValues, attributes.legacyTextImprint);
|
|
9373
9839
|
addDocumentFontDialogRunBorderValue(runBorderValues, attributes.runBorder);
|
|
9840
|
+
addDocumentFontDialogRunShadingValue(runShadingValues, attributes.runShading);
|
|
9374
9841
|
addDocumentScriptFontValues(latinFontValues, eastAsiaFontValues, complexScriptFontValues, attributes);
|
|
9375
9842
|
};
|
|
9376
9843
|
if (selection.empty) addValues(editor.getAttributes('textStyle'));
|
|
@@ -9379,21 +9846,22 @@ function documentFontDialogSource(editor) {
|
|
|
9379
9846
|
const textStyle = node.marks.find((mark)=>'textStyle' === mark.type.name);
|
|
9380
9847
|
addValues(textStyle?.attrs ?? {});
|
|
9381
9848
|
});
|
|
9382
|
-
if (!scaleValues.size || !spacingValues.size || !positionValues.size || !kerningValues.size || !emphasisValues.size || !hiddenTextValues.size || !legacyTextOutlineValues.size || !legacyTextShadowValues.size || !legacyTextEmbossValues.size || !legacyTextImprintValues.size || !runBorderValues.size || !latinFontValues.size || !eastAsiaFontValues.size || !complexScriptFontValues.size) addValues(editor.getAttributes('textStyle'));
|
|
9383
|
-
const characterScale =
|
|
9384
|
-
const characterPosition =
|
|
9385
|
-
const characterSpacing =
|
|
9386
|
-
const kerningThreshold =
|
|
9387
|
-
const emphasisMark =
|
|
9388
|
-
const hiddenText =
|
|
9389
|
-
const legacyTextOutline =
|
|
9390
|
-
const legacyTextShadow =
|
|
9391
|
-
const legacyTextEmboss =
|
|
9392
|
-
const legacyTextImprint =
|
|
9849
|
+
if (!scaleValues.size || !spacingValues.size || !positionValues.size || !kerningValues.size || !emphasisValues.size || !hiddenTextValues.size || !legacyTextOutlineValues.size || !legacyTextShadowValues.size || !legacyTextEmbossValues.size || !legacyTextImprintValues.size || !runBorderValues.size || !runShadingValues.size || !latinFontValues.size || !eastAsiaFontValues.size || !complexScriptFontValues.size) addValues(editor.getAttributes('textStyle'));
|
|
9850
|
+
const characterScale = document_font_dialog_model_selectedValue(scaleValues);
|
|
9851
|
+
const characterPosition = document_font_dialog_model_selectedValue(positionValues);
|
|
9852
|
+
const characterSpacing = document_font_dialog_model_selectedValue(spacingValues);
|
|
9853
|
+
const kerningThreshold = document_font_dialog_model_selectedValue(kerningValues);
|
|
9854
|
+
const emphasisMark = document_font_dialog_model_selectedValue(emphasisValues);
|
|
9855
|
+
const hiddenText = document_font_dialog_model_selectedValue(hiddenTextValues);
|
|
9856
|
+
const legacyTextOutline = document_font_dialog_model_selectedValue(legacyTextOutlineValues);
|
|
9857
|
+
const legacyTextShadow = document_font_dialog_model_selectedValue(legacyTextShadowValues);
|
|
9858
|
+
const legacyTextEmboss = document_font_dialog_model_selectedValue(legacyTextEmbossValues);
|
|
9859
|
+
const legacyTextImprint = document_font_dialog_model_selectedValue(legacyTextImprintValues);
|
|
9393
9860
|
const runBorder = selectedDocumentFontDialogRunBorderValue(runBorderValues);
|
|
9394
|
-
const
|
|
9395
|
-
const
|
|
9396
|
-
const
|
|
9861
|
+
const runShading = selectedDocumentFontDialogRunShadingValue(runShadingValues);
|
|
9862
|
+
const latinFont = document_font_dialog_model_selectedValue(latinFontValues);
|
|
9863
|
+
const eastAsiaFont = document_font_dialog_model_selectedValue(eastAsiaFontValues);
|
|
9864
|
+
const complexScriptFont = document_font_dialog_model_selectedValue(complexScriptFontValues);
|
|
9397
9865
|
const textStyle = editor.getAttributes('textStyle');
|
|
9398
9866
|
const selectedText = selection.empty ? '' : doc.textBetween(selection.from, selection.to, ' ', ' ').replace(/\s+/g, ' ').trim();
|
|
9399
9867
|
return {
|
|
@@ -9408,6 +9876,7 @@ function documentFontDialogSource(editor) {
|
|
|
9408
9876
|
legacyTextEmboss,
|
|
9409
9877
|
legacyTextImprint,
|
|
9410
9878
|
runBorder,
|
|
9879
|
+
runShading,
|
|
9411
9880
|
latinFont,
|
|
9412
9881
|
eastAsiaFont,
|
|
9413
9882
|
complexScriptFont,
|
|
@@ -9440,6 +9909,7 @@ function createDocumentFontDialogDraft(source) {
|
|
|
9440
9909
|
legacyTextEmboss: source.legacyTextEmboss.value ?? false,
|
|
9441
9910
|
legacyTextImprint: source.legacyTextImprint.value ?? false,
|
|
9442
9911
|
...createDocumentFontDialogRunBorderDraft(source.runBorder),
|
|
9912
|
+
...createDocumentFontDialogRunShadingDraft(source.runShading),
|
|
9443
9913
|
latinFont: documentFontFamilyDraftValue(source.latinFont),
|
|
9444
9914
|
eastAsiaFont: documentFontFamilyDraftValue(source.eastAsiaFont),
|
|
9445
9915
|
complexScriptFont: documentFontFamilyDraftValue(source.complexScriptFont)
|
|
@@ -9448,6 +9918,8 @@ function createDocumentFontDialogDraft(source) {
|
|
|
9448
9918
|
function documentFontDialogDraftError(draft) {
|
|
9449
9919
|
const runBorderError = documentFontDialogRunBorderDraftError(draft);
|
|
9450
9920
|
if (runBorderError) return runBorderError;
|
|
9921
|
+
const runShadingError = documentFontDialogRunShadingDraftError(draft);
|
|
9922
|
+
if (runShadingError) return runShadingError;
|
|
9451
9923
|
if ('mixed' !== draft.characterScaleMode && null === characterScalePercentFromDraft(draft)) return "请输入 1 至 600 的整数缩放比例。";
|
|
9452
9924
|
if ('mixed' !== draft.characterSpacingMode && 'normal' !== draft.characterSpacingMode && null === characterSpacingTwipsFromDraft(draft)) return "请输入 0.05 至 1584 磅的间距。";
|
|
9453
9925
|
if ('mixed' !== draft.characterPositionMode && 'normal' !== draft.characterPositionMode && null === characterPositionHalfPointsFromDraft(draft)) return "请输入 0.5 至 1584 磅、以 0.5 磅递增的位置值。";
|
|
@@ -9483,6 +9955,7 @@ function documentFontDialogPatch(source, draft, touched) {
|
|
|
9483
9955
|
if (touched.hiddenText && (source.hiddenText.mixed || source.hiddenText.value !== draft.hiddenText)) patch.hiddenText = draft.hiddenText;
|
|
9484
9956
|
appendLegacyTextEffectPatch(patch, 'legacyTextOutline', source.legacyTextOutline, draft.legacyTextOutline, touched.legacyTextOutline);
|
|
9485
9957
|
Object.assign(patch, documentFontDialogRunBorderPatch(source.runBorder, draft, touched.runBorder));
|
|
9958
|
+
Object.assign(patch, documentFontDialogRunShadingPatch(source.runShading, draft, touched.runShading));
|
|
9486
9959
|
appendLegacyTextEffectPatch(patch, 'legacyTextShadow', source.legacyTextShadow, draft.legacyTextShadow, touched.legacyTextShadow);
|
|
9487
9960
|
appendLegacyTextEffectPatch(patch, 'legacyTextEmboss', source.legacyTextEmboss, draft.legacyTextEmboss, touched.legacyTextEmboss);
|
|
9488
9961
|
appendLegacyTextEffectPatch(patch, 'legacyTextImprint', source.legacyTextImprint, draft.legacyTextImprint, touched.legacyTextImprint);
|
|
@@ -9503,6 +9976,7 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9503
9976
|
const hasLegacyTextEmboss = void 0 !== patch.legacyTextEmboss;
|
|
9504
9977
|
const hasLegacyTextImprint = void 0 !== patch.legacyTextImprint;
|
|
9505
9978
|
const hasRunBorder = void 0 !== patch.runBorder;
|
|
9979
|
+
const hasRunShading = void 0 !== patch.runShading;
|
|
9506
9980
|
const hasLegacyTextEffects = hasLegacyTextOutline || hasLegacyTextShadow || hasLegacyTextEmboss || hasLegacyTextImprint;
|
|
9507
9981
|
const scriptFontPatch = {
|
|
9508
9982
|
...void 0 !== patch.latinFont ? {
|
|
@@ -9522,8 +9996,9 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9522
9996
|
const kerningThreshold = hasKerning && null !== patch.kerningThresholdHalfPoints ? normalizeDocumentKerningThresholdHalfPoints(patch.kerningThresholdHalfPoints) : null;
|
|
9523
9997
|
const emphasisMark = hasEmphasis && null !== patch.emphasisMark ? normalizeDocumentEmphasisMark(patch.emphasisMark) : null;
|
|
9524
9998
|
const runBorder = hasRunBorder && null !== patch.runBorder ? normalizeDocumentRunBorder(patch.runBorder) : null;
|
|
9999
|
+
const runShading = hasRunShading && null !== patch.runShading ? normalizeDocumentRunShading(patch.runShading) : null;
|
|
9525
10000
|
const maximum = editor.state.doc.content.size;
|
|
9526
|
-
if (editor.isDestroyed || !hasScale && !hasPosition && !hasSpacing && !hasKerning && !hasEmphasis && !hasHiddenText && !hasLegacyTextEffects && !hasRunBorder && !hasScriptFonts || hasScale && null === scale || hasPosition && null === position || hasSpacing && null === spacing || hasKerning && null !== patch.kerningThresholdHalfPoints && null === kerningThreshold || hasEmphasis && null !== patch.emphasisMark && null === emphasisMark || hasRunBorder && null !== patch.runBorder && null === runBorder || hasHiddenText && 'boolean' != typeof patch.hiddenText || hasLegacyTextOutline && null === normalizeDocumentLegacyTextEffect(patch.legacyTextOutline) || hasLegacyTextShadow && null === normalizeDocumentLegacyTextEffect(patch.legacyTextShadow) || hasLegacyTextEmboss && null === normalizeDocumentLegacyTextEffect(patch.legacyTextEmboss) || hasLegacyTextImprint && null === normalizeDocumentLegacyTextEffect(patch.legacyTextImprint) || !Number.isSafeInteger(selection.from) || !Number.isSafeInteger(selection.to) || selection.from < 0 || selection.to < selection.from || selection.to > maximum || hasLegacyTextEffects && !documentFontDialogLegacyTextEffectsAreSafe(editor, selection, patch)) return false;
|
|
10001
|
+
if (editor.isDestroyed || !hasScale && !hasPosition && !hasSpacing && !hasKerning && !hasEmphasis && !hasHiddenText && !hasLegacyTextEffects && !hasRunBorder && !hasRunShading && !hasScriptFonts || hasScale && null === scale || hasPosition && null === position || hasSpacing && null === spacing || hasKerning && null !== patch.kerningThresholdHalfPoints && null === kerningThreshold || hasEmphasis && null !== patch.emphasisMark && null === emphasisMark || hasRunBorder && null !== patch.runBorder && null === runBorder || hasRunShading && null !== patch.runShading && null === runShading || hasHiddenText && 'boolean' != typeof patch.hiddenText || hasLegacyTextOutline && null === normalizeDocumentLegacyTextEffect(patch.legacyTextOutline) || hasLegacyTextShadow && null === normalizeDocumentLegacyTextEffect(patch.legacyTextShadow) || hasLegacyTextEmboss && null === normalizeDocumentLegacyTextEffect(patch.legacyTextEmboss) || hasLegacyTextImprint && null === normalizeDocumentLegacyTextEffect(patch.legacyTextImprint) || !Number.isSafeInteger(selection.from) || !Number.isSafeInteger(selection.to) || selection.from < 0 || selection.to < selection.from || selection.to > maximum || hasLegacyTextEffects && !documentFontDialogLegacyTextEffectsAreSafe(editor, selection, patch)) return false;
|
|
9527
10002
|
const attributes = {};
|
|
9528
10003
|
if (null !== scale) attributes.characterScalePercent = scale;
|
|
9529
10004
|
if (null !== position) attributes.characterPositionHalfPoints = position;
|
|
@@ -9536,6 +10011,7 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9536
10011
|
if (hasLegacyTextEmboss) attributes.legacyTextEmboss = patch.legacyTextEmboss ?? false;
|
|
9537
10012
|
if (hasLegacyTextImprint) attributes.legacyTextImprint = patch.legacyTextImprint ?? false;
|
|
9538
10013
|
if (hasRunBorder) attributes.runBorder = null === patch.runBorder ? null : serializeDocumentRunBorder(runBorder) ?? null;
|
|
10014
|
+
if (hasRunShading) attributes.runShading = null === patch.runShading ? null : serializeDocumentRunShading(runShading) ?? null;
|
|
9539
10015
|
if (hasScriptFonts) return applyDocumentScriptFontPatch(editor, selection, attributes, scriptFontPatch);
|
|
9540
10016
|
return editor.chain().setTextSelection(selection).setMark('textStyle', attributes).removeEmptyTextStyle().focus().scrollIntoView().run();
|
|
9541
10017
|
}
|
|
@@ -9633,7 +10109,7 @@ function kerningThresholdHalfPointsFromDraft(draft) {
|
|
|
9633
10109
|
if (!Number.isFinite(points) || points < 0 || points > 1638.5 || !Number.isSafeInteger(halfPoints)) return null;
|
|
9634
10110
|
return normalizeDocumentKerningThresholdHalfPoints(halfPoints);
|
|
9635
10111
|
}
|
|
9636
|
-
function
|
|
10112
|
+
function document_font_dialog_model_selectedValue(values) {
|
|
9637
10113
|
const mixed = values.size > 1;
|
|
9638
10114
|
return {
|
|
9639
10115
|
mixed,
|
|
@@ -9861,7 +10337,232 @@ function DocumentFontDialogRunBorderSection({ source, draft, touched, onDraftCha
|
|
|
9861
10337
|
"aria-hidden": "true",
|
|
9862
10338
|
children: "磅"
|
|
9863
10339
|
})
|
|
9864
|
-
]
|
|
10340
|
+
]
|
|
10341
|
+
})
|
|
10342
|
+
]
|
|
10343
|
+
}),
|
|
10344
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10345
|
+
className: "work-document-font-dialog-field",
|
|
10346
|
+
children: [
|
|
10347
|
+
/*#__PURE__*/ jsx("span", {
|
|
10348
|
+
children: "文字间距"
|
|
10349
|
+
}),
|
|
10350
|
+
/*#__PURE__*/ jsxs("span", {
|
|
10351
|
+
className: "work-document-font-dialog-measure",
|
|
10352
|
+
children: [
|
|
10353
|
+
/*#__PURE__*/ jsx(OfficeNumberField, {
|
|
10354
|
+
ariaLabel: "字符边框间距(磅)",
|
|
10355
|
+
value: draft.runBorderSpacingPoints,
|
|
10356
|
+
min: 0,
|
|
10357
|
+
max: 31,
|
|
10358
|
+
step: 1,
|
|
10359
|
+
disabled: !enabled,
|
|
10360
|
+
onValueChange: (runBorderSpacingPoints)=>update({
|
|
10361
|
+
runBorderMode: 'value',
|
|
10362
|
+
runBorderSpacingPoints
|
|
10363
|
+
})
|
|
10364
|
+
}),
|
|
10365
|
+
/*#__PURE__*/ jsx("span", {
|
|
10366
|
+
"aria-hidden": "true",
|
|
10367
|
+
children: "磅"
|
|
10368
|
+
})
|
|
10369
|
+
]
|
|
10370
|
+
})
|
|
10371
|
+
]
|
|
10372
|
+
}),
|
|
10373
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10374
|
+
className: "work-document-font-dialog-run-border-effects",
|
|
10375
|
+
children: [
|
|
10376
|
+
/*#__PURE__*/ jsx(OfficeCheckbox, {
|
|
10377
|
+
ariaLabel: "字符边框阴影",
|
|
10378
|
+
checked: draft.runBorderShadow,
|
|
10379
|
+
disabled: !enabled,
|
|
10380
|
+
onCheckedChange: (runBorderShadow)=>update({
|
|
10381
|
+
runBorderMode: 'value',
|
|
10382
|
+
runBorderShadow
|
|
10383
|
+
}),
|
|
10384
|
+
children: "阴影"
|
|
10385
|
+
}),
|
|
10386
|
+
/*#__PURE__*/ jsx(OfficeCheckbox, {
|
|
10387
|
+
ariaLabel: "字符边框框架",
|
|
10388
|
+
checked: draft.runBorderFrame,
|
|
10389
|
+
disabled: !enabled,
|
|
10390
|
+
onCheckedChange: (runBorderFrame)=>update({
|
|
10391
|
+
runBorderMode: 'value',
|
|
10392
|
+
runBorderFrame
|
|
10393
|
+
}),
|
|
10394
|
+
children: "框架"
|
|
10395
|
+
})
|
|
10396
|
+
]
|
|
10397
|
+
}),
|
|
10398
|
+
source.mixed && !touched ? /*#__PURE__*/ jsx("p", {
|
|
10399
|
+
className: "work-document-font-dialog-mixed",
|
|
10400
|
+
role: "status",
|
|
10401
|
+
children: "当前选区包含不同的字符边框。选择一种应用方式后才会统一修改。"
|
|
10402
|
+
}) : null
|
|
10403
|
+
]
|
|
10404
|
+
});
|
|
10405
|
+
}
|
|
10406
|
+
function documentFontDialogRunBorderPreviewStyle(source, draft) {
|
|
10407
|
+
const border = documentFontDialogRunBorderFromDraft(source, draft);
|
|
10408
|
+
if (!border) return {};
|
|
10409
|
+
const presentation = documentBorderPresentation(border);
|
|
10410
|
+
return {
|
|
10411
|
+
border: `${presentation.width}px ${presentation.style} ${presentation.color}`,
|
|
10412
|
+
padding: `${(border.space ?? 0) * (96 / 72)}px`,
|
|
10413
|
+
boxDecorationBreak: 'clone',
|
|
10414
|
+
WebkitBoxDecorationBreak: 'clone',
|
|
10415
|
+
...border.shadow && presentation.width > 0 ? {
|
|
10416
|
+
boxShadow: `2px 2px 0 ${presentation.color}`
|
|
10417
|
+
} : {}
|
|
10418
|
+
};
|
|
10419
|
+
}
|
|
10420
|
+
const shadingModes = [
|
|
10421
|
+
{
|
|
10422
|
+
value: 'mixed',
|
|
10423
|
+
label: '混合(保持不变)',
|
|
10424
|
+
disabled: true
|
|
10425
|
+
},
|
|
10426
|
+
{
|
|
10427
|
+
value: 'inherit',
|
|
10428
|
+
label: '跟随样式'
|
|
10429
|
+
},
|
|
10430
|
+
{
|
|
10431
|
+
value: 'none',
|
|
10432
|
+
label: '无(显式重置)'
|
|
10433
|
+
},
|
|
10434
|
+
{
|
|
10435
|
+
value: 'value',
|
|
10436
|
+
label: '底纹'
|
|
10437
|
+
}
|
|
10438
|
+
];
|
|
10439
|
+
const shadingPatterns = [
|
|
10440
|
+
{
|
|
10441
|
+
value: 'clear',
|
|
10442
|
+
label: '清除(背景色)',
|
|
10443
|
+
group: '基本'
|
|
10444
|
+
},
|
|
10445
|
+
{
|
|
10446
|
+
value: 'solid',
|
|
10447
|
+
label: '实心(前景色)',
|
|
10448
|
+
group: '基本'
|
|
10449
|
+
},
|
|
10450
|
+
{
|
|
10451
|
+
value: 'horzStripe',
|
|
10452
|
+
label: '水平条纹',
|
|
10453
|
+
group: '条纹'
|
|
10454
|
+
},
|
|
10455
|
+
{
|
|
10456
|
+
value: 'vertStripe',
|
|
10457
|
+
label: '垂直条纹',
|
|
10458
|
+
group: '条纹'
|
|
10459
|
+
},
|
|
10460
|
+
{
|
|
10461
|
+
value: 'reverseDiagStripe',
|
|
10462
|
+
label: '反向对角条纹',
|
|
10463
|
+
group: '条纹'
|
|
10464
|
+
},
|
|
10465
|
+
{
|
|
10466
|
+
value: 'diagStripe',
|
|
10467
|
+
label: '对角条纹',
|
|
10468
|
+
group: '条纹'
|
|
10469
|
+
},
|
|
10470
|
+
{
|
|
10471
|
+
value: 'horzCross',
|
|
10472
|
+
label: '水平交叉',
|
|
10473
|
+
group: '交叉'
|
|
10474
|
+
},
|
|
10475
|
+
{
|
|
10476
|
+
value: 'diagCross',
|
|
10477
|
+
label: '对角交叉',
|
|
10478
|
+
group: '交叉'
|
|
10479
|
+
},
|
|
10480
|
+
{
|
|
10481
|
+
value: 'thinHorzStripe',
|
|
10482
|
+
label: '细水平条纹',
|
|
10483
|
+
group: '细线'
|
|
10484
|
+
},
|
|
10485
|
+
{
|
|
10486
|
+
value: 'thinVertStripe',
|
|
10487
|
+
label: '细垂直条纹',
|
|
10488
|
+
group: '细线'
|
|
10489
|
+
},
|
|
10490
|
+
{
|
|
10491
|
+
value: 'thinReverseDiagStripe',
|
|
10492
|
+
label: '细反向对角条纹',
|
|
10493
|
+
group: '细线'
|
|
10494
|
+
},
|
|
10495
|
+
{
|
|
10496
|
+
value: 'thinDiagStripe',
|
|
10497
|
+
label: '细对角条纹',
|
|
10498
|
+
group: '细线'
|
|
10499
|
+
},
|
|
10500
|
+
{
|
|
10501
|
+
value: 'thinHorzCross',
|
|
10502
|
+
label: '细水平交叉',
|
|
10503
|
+
group: '细线'
|
|
10504
|
+
},
|
|
10505
|
+
{
|
|
10506
|
+
value: 'thinDiagCross',
|
|
10507
|
+
label: '细对角交叉',
|
|
10508
|
+
group: '细线'
|
|
10509
|
+
},
|
|
10510
|
+
...[
|
|
10511
|
+
5,
|
|
10512
|
+
10,
|
|
10513
|
+
12,
|
|
10514
|
+
15,
|
|
10515
|
+
20,
|
|
10516
|
+
25,
|
|
10517
|
+
30,
|
|
10518
|
+
35,
|
|
10519
|
+
37,
|
|
10520
|
+
40,
|
|
10521
|
+
45,
|
|
10522
|
+
50,
|
|
10523
|
+
55,
|
|
10524
|
+
60,
|
|
10525
|
+
62,
|
|
10526
|
+
65,
|
|
10527
|
+
70,
|
|
10528
|
+
75,
|
|
10529
|
+
80,
|
|
10530
|
+
85,
|
|
10531
|
+
87,
|
|
10532
|
+
90,
|
|
10533
|
+
95
|
|
10534
|
+
].map((percentage)=>({
|
|
10535
|
+
value: `pct${percentage}`,
|
|
10536
|
+
label: `${percentage}%`,
|
|
10537
|
+
group: '密度'
|
|
10538
|
+
}))
|
|
10539
|
+
];
|
|
10540
|
+
function DocumentFontDialogRunShadingSection({ source, draft, touched, onDraftChange, onTouched }) {
|
|
10541
|
+
const enabled = 'value' === draft.runShadingMode;
|
|
10542
|
+
const update = (patch)=>{
|
|
10543
|
+
onDraftChange(patch);
|
|
10544
|
+
onTouched();
|
|
10545
|
+
};
|
|
10546
|
+
return /*#__PURE__*/ jsxs("fieldset", {
|
|
10547
|
+
className: "work-document-font-dialog-run-shading",
|
|
10548
|
+
"aria-label": "字符底纹设置",
|
|
10549
|
+
children: [
|
|
10550
|
+
/*#__PURE__*/ jsx("legend", {
|
|
10551
|
+
children: "字符底纹"
|
|
10552
|
+
}),
|
|
10553
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10554
|
+
className: "work-document-font-dialog-field",
|
|
10555
|
+
children: [
|
|
10556
|
+
/*#__PURE__*/ jsx("span", {
|
|
10557
|
+
children: "应用方式"
|
|
10558
|
+
}),
|
|
10559
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
10560
|
+
ariaLabel: "字符底纹",
|
|
10561
|
+
value: draft.runShadingMode,
|
|
10562
|
+
options: shadingModes,
|
|
10563
|
+
onValueChange: (runShadingMode)=>update({
|
|
10564
|
+
runShadingMode
|
|
10565
|
+
})
|
|
9865
10566
|
})
|
|
9866
10567
|
]
|
|
9867
10568
|
}),
|
|
@@ -9869,78 +10570,78 @@ function DocumentFontDialogRunBorderSection({ source, draft, touched, onDraftCha
|
|
|
9869
10570
|
className: "work-document-font-dialog-field",
|
|
9870
10571
|
children: [
|
|
9871
10572
|
/*#__PURE__*/ jsx("span", {
|
|
9872
|
-
children: "
|
|
10573
|
+
children: "图案"
|
|
9873
10574
|
}),
|
|
9874
|
-
/*#__PURE__*/
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
step: 1,
|
|
9883
|
-
disabled: !enabled,
|
|
9884
|
-
onValueChange: (runBorderSpacingPoints)=>update({
|
|
9885
|
-
runBorderMode: 'value',
|
|
9886
|
-
runBorderSpacingPoints
|
|
9887
|
-
})
|
|
9888
|
-
}),
|
|
9889
|
-
/*#__PURE__*/ jsx("span", {
|
|
9890
|
-
"aria-hidden": "true",
|
|
9891
|
-
children: "磅"
|
|
10575
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
10576
|
+
ariaLabel: "字符底纹图案",
|
|
10577
|
+
value: draft.runShadingPattern,
|
|
10578
|
+
options: shadingPatterns,
|
|
10579
|
+
disabled: !enabled,
|
|
10580
|
+
onValueChange: (runShadingPattern)=>update({
|
|
10581
|
+
runShadingMode: 'value',
|
|
10582
|
+
runShadingPattern
|
|
9892
10583
|
})
|
|
9893
|
-
]
|
|
9894
10584
|
})
|
|
9895
10585
|
]
|
|
9896
10586
|
}),
|
|
9897
10587
|
/*#__PURE__*/ jsxs("div", {
|
|
9898
|
-
className: "work-document-font-dialog-
|
|
10588
|
+
className: "work-document-font-dialog-field",
|
|
9899
10589
|
children: [
|
|
9900
|
-
/*#__PURE__*/ jsx(
|
|
9901
|
-
|
|
9902
|
-
|
|
10590
|
+
/*#__PURE__*/ jsx("span", {
|
|
10591
|
+
children: "前景色"
|
|
10592
|
+
}),
|
|
10593
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
10594
|
+
ariaLabel: "字符底纹前景色",
|
|
10595
|
+
value: 'auto' === draft.runShadingColor ? '#000000' : draft.runShadingColor,
|
|
9903
10596
|
disabled: !enabled,
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
10597
|
+
resetAction: {
|
|
10598
|
+
kind: 'automatic',
|
|
10599
|
+
label: '自动前景色',
|
|
10600
|
+
onSelect: ()=>update({
|
|
10601
|
+
runShadingMode: 'value',
|
|
10602
|
+
runShadingColor: 'auto'
|
|
10603
|
+
})
|
|
10604
|
+
},
|
|
10605
|
+
onValueChange: (runShadingColor)=>update({
|
|
10606
|
+
runShadingMode: 'value',
|
|
10607
|
+
runShadingColor: runShadingColor
|
|
10608
|
+
})
|
|
10609
|
+
})
|
|
10610
|
+
]
|
|
10611
|
+
}),
|
|
10612
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10613
|
+
className: "work-document-font-dialog-field",
|
|
10614
|
+
children: [
|
|
10615
|
+
/*#__PURE__*/ jsx("span", {
|
|
10616
|
+
children: "背景色"
|
|
9909
10617
|
}),
|
|
9910
|
-
/*#__PURE__*/ jsx(
|
|
9911
|
-
ariaLabel: "
|
|
9912
|
-
|
|
10618
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
10619
|
+
ariaLabel: "字符底纹背景色",
|
|
10620
|
+
value: 'auto' === draft.runShadingFill ? '#ffffff' : draft.runShadingFill,
|
|
9913
10621
|
disabled: !enabled,
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
10622
|
+
resetAction: {
|
|
10623
|
+
kind: 'automatic',
|
|
10624
|
+
label: '自动背景色',
|
|
10625
|
+
onSelect: ()=>update({
|
|
10626
|
+
runShadingMode: 'value',
|
|
10627
|
+
runShadingFill: 'auto'
|
|
10628
|
+
})
|
|
10629
|
+
},
|
|
10630
|
+
onValueChange: (runShadingFill)=>update({
|
|
10631
|
+
runShadingMode: 'value',
|
|
10632
|
+
runShadingFill: runShadingFill
|
|
10633
|
+
})
|
|
9919
10634
|
})
|
|
9920
10635
|
]
|
|
9921
10636
|
}),
|
|
9922
10637
|
source.mixed && !touched ? /*#__PURE__*/ jsx("p", {
|
|
9923
10638
|
className: "work-document-font-dialog-mixed",
|
|
9924
10639
|
role: "status",
|
|
9925
|
-
children: "
|
|
10640
|
+
children: "当前选区包含不同的字符底纹。选择一种应用方式后才会统一修改。"
|
|
9926
10641
|
}) : null
|
|
9927
10642
|
]
|
|
9928
10643
|
});
|
|
9929
10644
|
}
|
|
9930
|
-
function documentFontDialogRunBorderPreviewStyle(source, draft) {
|
|
9931
|
-
const border = documentFontDialogRunBorderFromDraft(source, draft);
|
|
9932
|
-
if (!border) return {};
|
|
9933
|
-
const presentation = documentBorderPresentation(border);
|
|
9934
|
-
return {
|
|
9935
|
-
border: `${presentation.width}px ${presentation.style} ${presentation.color}`,
|
|
9936
|
-
padding: `${(border.space ?? 0) * (96 / 72)}px`,
|
|
9937
|
-
boxDecorationBreak: 'clone',
|
|
9938
|
-
WebkitBoxDecorationBreak: 'clone',
|
|
9939
|
-
...border.shadow && presentation.width > 0 ? {
|
|
9940
|
-
boxShadow: `2px 2px 0 ${presentation.color}`
|
|
9941
|
-
} : {}
|
|
9942
|
-
};
|
|
9943
|
-
}
|
|
9944
10645
|
const characterSpacingModes = [
|
|
9945
10646
|
{
|
|
9946
10647
|
value: 'mixed',
|
|
@@ -10023,6 +10724,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10023
10724
|
const [legacyTextEmbossTouched, setLegacyTextEmbossTouched] = useState(false);
|
|
10024
10725
|
const [legacyTextImprintTouched, setLegacyTextImprintTouched] = useState(false);
|
|
10025
10726
|
const [runBorderTouched, setRunBorderTouched] = useState(false);
|
|
10727
|
+
const [runShadingTouched, setRunShadingTouched] = useState(false);
|
|
10026
10728
|
const [latinFontTouched, setLatinFontTouched] = useState(false);
|
|
10027
10729
|
const [eastAsiaFontTouched, setEastAsiaFontTouched] = useState(false);
|
|
10028
10730
|
const [complexScriptFontTouched, setComplexScriptFontTouched] = useState(false);
|
|
@@ -10041,6 +10743,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10041
10743
|
legacyTextEmboss: legacyTextEmbossTouched,
|
|
10042
10744
|
legacyTextImprint: legacyTextImprintTouched,
|
|
10043
10745
|
runBorder: runBorderTouched,
|
|
10746
|
+
runShading: runShadingTouched,
|
|
10044
10747
|
kerning: kerningTouched,
|
|
10045
10748
|
latinFont: latinFontTouched
|
|
10046
10749
|
});
|
|
@@ -10057,6 +10760,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10057
10760
|
imprint: draft.legacyTextImprint
|
|
10058
10761
|
});
|
|
10059
10762
|
const previewRunBorder = documentFontDialogRunBorderPreviewStyle(source.runBorder, draft);
|
|
10763
|
+
const previewRunShading = documentFontDialogRunShadingPreviewStyle(source.runShading, draft);
|
|
10060
10764
|
const submit = (event)=>{
|
|
10061
10765
|
event?.preventDefault();
|
|
10062
10766
|
if (!hasChanges || error) return;
|
|
@@ -10506,6 +11210,16 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10506
11210
|
})),
|
|
10507
11211
|
onTouched: ()=>setRunBorderTouched(true)
|
|
10508
11212
|
}),
|
|
11213
|
+
/*#__PURE__*/ jsx(DocumentFontDialogRunShadingSection, {
|
|
11214
|
+
source: source.runShading,
|
|
11215
|
+
draft: draft,
|
|
11216
|
+
touched: runShadingTouched,
|
|
11217
|
+
onDraftChange: (runShadingDraft)=>setDraft((current)=>({
|
|
11218
|
+
...current,
|
|
11219
|
+
...runShadingDraft
|
|
11220
|
+
})),
|
|
11221
|
+
onTouched: ()=>setRunShadingTouched(true)
|
|
11222
|
+
}),
|
|
10509
11223
|
source.characterScale.mixed && !characterScaleTouched && /*#__PURE__*/ jsx("p", {
|
|
10510
11224
|
className: "work-document-font-dialog-mixed",
|
|
10511
11225
|
role: "status",
|
|
@@ -10541,7 +11255,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10541
11255
|
role: "status",
|
|
10542
11256
|
children: "当前选区包含不同的空心、阴影、阳文或阴文设置。勾选或取消对应选项后才会统一修改。"
|
|
10543
11257
|
}),
|
|
10544
|
-
(characterScaleTouched || characterSpacingTouched || characterPositionTouched || kerningTouched || emphasisTouched || hiddenTextTouched || legacyTextOutlineTouched || legacyTextShadowTouched || legacyTextEmbossTouched || legacyTextImprintTouched || runBorderTouched) && error && /*#__PURE__*/ jsx("p", {
|
|
11258
|
+
(characterScaleTouched || characterSpacingTouched || characterPositionTouched || kerningTouched || emphasisTouched || hiddenTextTouched || legacyTextOutlineTouched || legacyTextShadowTouched || legacyTextEmbossTouched || legacyTextImprintTouched || runBorderTouched || runShadingTouched) && error && /*#__PURE__*/ jsx("p", {
|
|
10545
11259
|
className: "work-document-font-dialog-error",
|
|
10546
11260
|
role: "alert",
|
|
10547
11261
|
children: error
|
|
@@ -10568,6 +11282,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10568
11282
|
verticalAlign: `${previewPosition}pt`,
|
|
10569
11283
|
...previewEmphasis,
|
|
10570
11284
|
...previewLegacyTextEffects,
|
|
11285
|
+
...previewRunShading,
|
|
10571
11286
|
...previewRunBorder,
|
|
10572
11287
|
...draft.hiddenText ? {
|
|
10573
11288
|
textDecorationColor: 'currentColor',
|
|
@@ -10648,7 +11363,7 @@ function previewScriptFontFamily(value, fallback) {
|
|
|
10648
11363
|
function fontDialogDescription(source) {
|
|
10649
11364
|
return source.selectedCharacters ? `分别设置当前选中内容的拉丁、东亚和复杂文字字体,以及原生字符缩放、间距、字距调整阈值、位置、着重号、隐藏文字、空心、阴影、阳文和阴文(${source.selectedCharacters} 个字符)。` : '分别设置当前位置后续输入文字的拉丁、东亚和复杂文字字体,以及原生字符缩放、间距、字距调整阈值、位置、着重号、隐藏文字、空心、阴影、阳文和阴文。';
|
|
10650
11365
|
}
|
|
10651
|
-
function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditingPartChange, onTogglePageNumber, onOpenFontDialog, onClose }) {
|
|
11366
|
+
function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditingPartChange, onTogglePageNumber, onOpenFontDialog, onOpenProofingDialog, onClose }) {
|
|
10652
11367
|
const imageInputRef = useRef(null);
|
|
10653
11368
|
const [, setRevision] = useState(0);
|
|
10654
11369
|
const officeDialog = useOfficeDialog();
|
|
@@ -10806,6 +11521,13 @@ function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditi
|
|
|
10806
11521
|
ariaLabel: "页眉页脚文字颜色",
|
|
10807
11522
|
value: pickerColor(state.color),
|
|
10808
11523
|
onValueChange: (color)=>editor.chain().focus().setColor(color).run()
|
|
11524
|
+
}),
|
|
11525
|
+
onOpenProofingDialog && /*#__PURE__*/ jsx(PageChromeRibbonButton, {
|
|
11526
|
+
label: "页眉页脚校对语言",
|
|
11527
|
+
onClick: onOpenProofingDialog,
|
|
11528
|
+
children: /*#__PURE__*/ jsx(Languages, {
|
|
11529
|
+
size: 16
|
|
11530
|
+
})
|
|
10809
11531
|
})
|
|
10810
11532
|
]
|
|
10811
11533
|
}),
|
|
@@ -14220,15 +14942,17 @@ function headingLevelForShortcut(code, key) {
|
|
|
14220
14942
|
if ('3' === value) return 3;
|
|
14221
14943
|
return null;
|
|
14222
14944
|
}
|
|
14223
|
-
function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly = false, suggestionOnly = false, history, layoutOpen, layout, layoutFonts = [], navigationOpen, pageColor, showPageNumbers, showHiddenText, showRulers, spellcheckEnabled, viewMode, zoom, pageChromeEditor, pageChromeEditingPart, pageChromeShowPageNumber, onRequestImage, onPageChromeEditingPartChange, onClosePageChrome, onTogglePageChromePageNumber, onToggleLayout, onLayoutChange, onOpenLayout, onToggleNavigation, onTogglePageNumbers, onToggleHiddenText, onToggleRulers, onPageColorChange, onToggleSpellcheck, onViewModeChange, onZoomChange, onZoomFit, onInsertSection, onInsertNote, onInsertCaption, onInsertCrossReference, citationsOpen, citationSourceCount, onToggleCitations, onInsertField, onRefreshFields, canInsertComment, onInsertComment, commentsOpen, commentCount, onToggleComments, trackChanges, changesOpen, changeCount, findReplaceMode, fileActions, onRibbonTabChange, onToggleTrackChanges, onToggleChanges, onDecideChange, onOpenWordCount, onOpenFindReplace }) {
|
|
14945
|
+
function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly = false, suggestionOnly = false, history, layoutOpen, layout, layoutFonts = [], navigationOpen, pageColor, showPageNumbers, showHiddenText, showRulers, spellcheckEnabled, viewMode, zoom, pageChromeEditor, pageChromeEditingPart, pageChromeShowPageNumber, onRequestImage, onPageChromeEditingPartChange, onClosePageChrome, onTogglePageChromePageNumber, onToggleLayout, onLayoutChange, onOpenLayout, onToggleNavigation, onTogglePageNumbers, onToggleHiddenText, onToggleRulers, onPageColorChange, onToggleSpellcheck, onViewModeChange, onZoomChange, onZoomFit, onInsertSection, onInsertNote, onInsertCaption, onInsertCrossReference, onOpenTableOfContents, citationsOpen, citationSourceCount, onToggleCitations, onInsertField, onRefreshFields, onRefreshTableOfContents, canInsertComment, onInsertComment, commentsOpen, commentCount, onToggleComments, trackChanges, changesOpen, changeCount, findReplaceMode, fileActions, onRibbonTabChange, onToggleTrackChanges, onToggleChanges, onDecideChange, onOpenWordCount, onOpenFindReplace }) {
|
|
14224
14946
|
const [activeTab, setActiveTab] = useState(reviewOnly ? 'review' : 'home');
|
|
14225
14947
|
const [fontDialogRequest, setFontDialogRequest] = useState(null);
|
|
14948
|
+
const [proofingDialogRequest, setProofingDialogRequest] = useState(null);
|
|
14226
14949
|
const officeDialog = useOfficeDialog();
|
|
14227
14950
|
const prompt = officeDialog.prompt;
|
|
14228
14951
|
const imageSelected = editor.isActive('image');
|
|
14229
14952
|
const tableSelected = editor.isActive('table');
|
|
14230
14953
|
const activeBookmark = activeDocumentBookmark(editor);
|
|
14231
14954
|
const hasRefreshableFields = documentHasRefreshableFields(editor);
|
|
14955
|
+
const hasTableOfContents = documentHasTableOfContents(editor);
|
|
14232
14956
|
const documentChanges = collectDocumentChanges(editor.state.doc);
|
|
14233
14957
|
const previousChangeIndex = adjacentDocumentChangeIndex(documentChanges, editor.state.selection, -1);
|
|
14234
14958
|
const nextChangeIndex = adjacentDocumentChangeIndex(documentChanges, editor.state.selection, 1);
|
|
@@ -14251,6 +14975,18 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14251
14975
|
source: documentFontDialogSource(target)
|
|
14252
14976
|
});
|
|
14253
14977
|
}, []);
|
|
14978
|
+
const openProofingDialog = useCallback((target)=>{
|
|
14979
|
+
if (target.isDestroyed) return;
|
|
14980
|
+
const { from, to } = target.state.selection;
|
|
14981
|
+
setProofingDialogRequest({
|
|
14982
|
+
editor: target,
|
|
14983
|
+
selection: {
|
|
14984
|
+
from,
|
|
14985
|
+
to
|
|
14986
|
+
},
|
|
14987
|
+
source: documentProofingDialogSource(target)
|
|
14988
|
+
});
|
|
14989
|
+
}, []);
|
|
14254
14990
|
const ribbonTabs = reviewOnly ? documentRibbonTabs.filter(({ id })=>'review' === id || 'view' === id) : pageChromeEditor ? [
|
|
14255
14991
|
...documentRibbonTabs,
|
|
14256
14992
|
documentPageChromeRibbonTab
|
|
@@ -14626,6 +15362,30 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14626
15362
|
}),
|
|
14627
15363
|
references: reviewOnly ? null : /*#__PURE__*/ jsxs(Fragment, {
|
|
14628
15364
|
children: [
|
|
15365
|
+
/*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
15366
|
+
label: "目录",
|
|
15367
|
+
priority: "high",
|
|
15368
|
+
children: [
|
|
15369
|
+
/*#__PURE__*/ jsx(document_toolbar_ToolbarButton, {
|
|
15370
|
+
label: "插入或自定义目录",
|
|
15371
|
+
displayLabel: true,
|
|
15372
|
+
onClick: onOpenTableOfContents,
|
|
15373
|
+
children: /*#__PURE__*/ jsx(ListTree, {
|
|
15374
|
+
size: 19
|
|
15375
|
+
})
|
|
15376
|
+
}),
|
|
15377
|
+
/*#__PURE__*/ jsx(document_toolbar_ToolbarButton, {
|
|
15378
|
+
label: "更新目录",
|
|
15379
|
+
displayLabel: true,
|
|
15380
|
+
disabled: !hasTableOfContents,
|
|
15381
|
+
title: hasTableOfContents ? '根据当前标题和页码更新目录' : '文档中没有可更新的目录',
|
|
15382
|
+
onClick: onRefreshTableOfContents,
|
|
15383
|
+
children: /*#__PURE__*/ jsx(RefreshCw, {
|
|
15384
|
+
size: 19
|
|
15385
|
+
})
|
|
15386
|
+
})
|
|
15387
|
+
]
|
|
15388
|
+
}),
|
|
14629
15389
|
/*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14630
15390
|
label: "脚注",
|
|
14631
15391
|
priority: "high",
|
|
@@ -14712,20 +15472,30 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14712
15472
|
}),
|
|
14713
15473
|
review: /*#__PURE__*/ jsxs(Fragment, {
|
|
14714
15474
|
children: [
|
|
14715
|
-
!reviewOnly && /*#__PURE__*/
|
|
15475
|
+
!reviewOnly && /*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14716
15476
|
label: "校对",
|
|
14717
15477
|
priority: "high",
|
|
14718
|
-
children:
|
|
14719
|
-
|
|
14720
|
-
|
|
14721
|
-
|
|
14722
|
-
|
|
14723
|
-
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
15478
|
+
children: [
|
|
15479
|
+
/*#__PURE__*/ jsx(document_toolbar_ToolbarButton, {
|
|
15480
|
+
label: "拼写检查",
|
|
15481
|
+
displayLabel: true,
|
|
15482
|
+
shortcut: spellingCommand.shortcut?.label,
|
|
15483
|
+
ariaKeyShortcuts: spellingCommand.shortcut?.aria,
|
|
15484
|
+
active: spellcheckEnabled,
|
|
15485
|
+
onClick: onToggleSpellcheck,
|
|
15486
|
+
children: /*#__PURE__*/ jsx(CheckCheck, {
|
|
15487
|
+
size: 19
|
|
15488
|
+
})
|
|
15489
|
+
}),
|
|
15490
|
+
/*#__PURE__*/ jsx(document_toolbar_ToolbarButton, {
|
|
15491
|
+
label: "设置校对语言",
|
|
15492
|
+
displayLabel: true,
|
|
15493
|
+
onClick: ()=>openProofingDialog(editor),
|
|
15494
|
+
children: /*#__PURE__*/ jsx(Languages, {
|
|
15495
|
+
size: 19
|
|
15496
|
+
})
|
|
14727
15497
|
})
|
|
14728
|
-
|
|
15498
|
+
]
|
|
14729
15499
|
}),
|
|
14730
15500
|
!suggestionOnly && /*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14731
15501
|
label: "批注",
|
|
@@ -14956,6 +15726,7 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14956
15726
|
onEditingPartChange: onPageChromeEditingPartChange,
|
|
14957
15727
|
onTogglePageNumber: onTogglePageChromePageNumber,
|
|
14958
15728
|
onOpenFontDialog: ()=>openFontDialog(pageChromeEditor),
|
|
15729
|
+
onOpenProofingDialog: ()=>openProofingDialog(pageChromeEditor),
|
|
14959
15730
|
onClose: onClosePageChrome
|
|
14960
15731
|
}) : null
|
|
14961
15732
|
}
|
|
@@ -14976,6 +15747,21 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14976
15747
|
});
|
|
14977
15748
|
}
|
|
14978
15749
|
}),
|
|
15750
|
+
proofingDialogRequest && /*#__PURE__*/ jsx(DocumentProofingDialog, {
|
|
15751
|
+
source: proofingDialogRequest.source,
|
|
15752
|
+
restoreFocusTarget: ()=>proofingDialogRequest.editor.isDestroyed ? null : proofingDialogRequest.editor.view.dom,
|
|
15753
|
+
onApply: (patch)=>applyDocumentProofingDialogPatch(proofingDialogRequest.editor, proofingDialogRequest.selection, patch),
|
|
15754
|
+
onClose: ()=>{
|
|
15755
|
+
const { editor: dialogEditor, selection } = proofingDialogRequest;
|
|
15756
|
+
setProofingDialogRequest(null);
|
|
15757
|
+
requestAnimationFrame(()=>{
|
|
15758
|
+
if (dialogEditor.isDestroyed) return;
|
|
15759
|
+
dialogEditor.chain().setTextSelection(selection).focus(null, {
|
|
15760
|
+
scrollIntoView: false
|
|
15761
|
+
}).run();
|
|
15762
|
+
});
|
|
15763
|
+
}
|
|
15764
|
+
}),
|
|
14979
15765
|
officeDialog.dialog
|
|
14980
15766
|
]
|
|
14981
15767
|
});
|
|
@@ -15360,6 +16146,182 @@ function commentActor(actor) {
|
|
|
15360
16146
|
author: CURRENT_COMMENT_AUTHOR
|
|
15361
16147
|
};
|
|
15362
16148
|
}
|
|
16149
|
+
function DocumentTableOfContentsDialog({ editing, options, restoreFocusTarget, onCancel, onOptionsChange, onSubmit }) {
|
|
16150
|
+
const updateOptions = (update)=>onOptionsChange({
|
|
16151
|
+
...options,
|
|
16152
|
+
...update
|
|
16153
|
+
});
|
|
16154
|
+
return /*#__PURE__*/ jsxs(Dialog, {
|
|
16155
|
+
title: editing ? '自定义目录' : '插入目录',
|
|
16156
|
+
description: "从文档标题生成可更新目录,并保留原生 DOCX 目录域。",
|
|
16157
|
+
className: "work-document-table-of-contents-dialog",
|
|
16158
|
+
restoreFocusTarget: restoreFocusTarget,
|
|
16159
|
+
onClose: onCancel,
|
|
16160
|
+
footer: /*#__PURE__*/ jsxs(Fragment, {
|
|
16161
|
+
children: [
|
|
16162
|
+
/*#__PURE__*/ jsx(button_Button, {
|
|
16163
|
+
tone: "quiet",
|
|
16164
|
+
onClick: onCancel,
|
|
16165
|
+
children: "取消"
|
|
16166
|
+
}),
|
|
16167
|
+
/*#__PURE__*/ jsx(button_Button, {
|
|
16168
|
+
tone: "primary",
|
|
16169
|
+
onClick: onSubmit,
|
|
16170
|
+
children: editing ? '应用' : '插入目录'
|
|
16171
|
+
})
|
|
16172
|
+
]
|
|
16173
|
+
}),
|
|
16174
|
+
children: [
|
|
16175
|
+
/*#__PURE__*/ jsxs("div", {
|
|
16176
|
+
className: "work-document-table-of-contents-dialog-grid",
|
|
16177
|
+
children: [
|
|
16178
|
+
/*#__PURE__*/ jsxs("div", {
|
|
16179
|
+
className: "work-document-table-of-contents-dialog-field",
|
|
16180
|
+
children: [
|
|
16181
|
+
/*#__PURE__*/ jsx("span", {
|
|
16182
|
+
children: "起始标题级别"
|
|
16183
|
+
}),
|
|
16184
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
16185
|
+
initialFocus: true,
|
|
16186
|
+
ariaLabel: "起始标题级别",
|
|
16187
|
+
value: String(options.minLevel),
|
|
16188
|
+
options: tableOfContentsLevelOptions,
|
|
16189
|
+
onValueChange: (value)=>{
|
|
16190
|
+
const minLevel = Number(value);
|
|
16191
|
+
updateOptions({
|
|
16192
|
+
minLevel,
|
|
16193
|
+
maxLevel: Math.max(minLevel, options.maxLevel)
|
|
16194
|
+
});
|
|
16195
|
+
}
|
|
16196
|
+
})
|
|
16197
|
+
]
|
|
16198
|
+
}),
|
|
16199
|
+
/*#__PURE__*/ jsxs("div", {
|
|
16200
|
+
className: "work-document-table-of-contents-dialog-field",
|
|
16201
|
+
children: [
|
|
16202
|
+
/*#__PURE__*/ jsx("span", {
|
|
16203
|
+
children: "结束标题级别"
|
|
16204
|
+
}),
|
|
16205
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
16206
|
+
ariaLabel: "结束标题级别",
|
|
16207
|
+
value: String(options.maxLevel),
|
|
16208
|
+
options: tableOfContentsLevelOptions.map((option)=>({
|
|
16209
|
+
...option,
|
|
16210
|
+
disabled: Number(option.value) < options.minLevel
|
|
16211
|
+
})),
|
|
16212
|
+
onValueChange: (value)=>updateOptions({
|
|
16213
|
+
maxLevel: Number(value)
|
|
16214
|
+
})
|
|
16215
|
+
})
|
|
16216
|
+
]
|
|
16217
|
+
})
|
|
16218
|
+
]
|
|
16219
|
+
}),
|
|
16220
|
+
/*#__PURE__*/ jsxs("div", {
|
|
16221
|
+
className: "work-document-table-of-contents-dialog-options",
|
|
16222
|
+
children: [
|
|
16223
|
+
/*#__PURE__*/ jsx(OfficeCheckbox, {
|
|
16224
|
+
ariaLabel: "目录项使用超链接",
|
|
16225
|
+
checked: options.hyperlinks,
|
|
16226
|
+
onCheckedChange: (hyperlinks)=>updateOptions({
|
|
16227
|
+
hyperlinks
|
|
16228
|
+
}),
|
|
16229
|
+
children: "目录项使用超链接"
|
|
16230
|
+
}),
|
|
16231
|
+
/*#__PURE__*/ jsx(OfficeCheckbox, {
|
|
16232
|
+
ariaLabel: "显示页码",
|
|
16233
|
+
checked: options.showPageNumbers,
|
|
16234
|
+
onCheckedChange: (showPageNumbers)=>updateOptions({
|
|
16235
|
+
showPageNumbers,
|
|
16236
|
+
rightAlignPageNumbers: showPageNumbers && options.rightAlignPageNumbers
|
|
16237
|
+
}),
|
|
16238
|
+
children: "显示页码"
|
|
16239
|
+
}),
|
|
16240
|
+
/*#__PURE__*/ jsx(OfficeCheckbox, {
|
|
16241
|
+
ariaLabel: "页码右对齐",
|
|
16242
|
+
checked: options.rightAlignPageNumbers,
|
|
16243
|
+
disabled: !options.showPageNumbers,
|
|
16244
|
+
onCheckedChange: (rightAlignPageNumbers)=>updateOptions({
|
|
16245
|
+
rightAlignPageNumbers
|
|
16246
|
+
}),
|
|
16247
|
+
children: "页码右对齐"
|
|
16248
|
+
})
|
|
16249
|
+
]
|
|
16250
|
+
}),
|
|
16251
|
+
/*#__PURE__*/ jsxs("div", {
|
|
16252
|
+
className: "work-document-table-of-contents-dialog-leader",
|
|
16253
|
+
children: [
|
|
16254
|
+
/*#__PURE__*/ jsx("span", {
|
|
16255
|
+
children: "前导符"
|
|
16256
|
+
}),
|
|
16257
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
16258
|
+
ariaLabel: "目录前导符",
|
|
16259
|
+
value: options.leader,
|
|
16260
|
+
options: tableOfContentsLeaderOptions,
|
|
16261
|
+
disabled: !options.showPageNumbers || !options.rightAlignPageNumbers,
|
|
16262
|
+
onValueChange: (leader)=>updateOptions({
|
|
16263
|
+
leader
|
|
16264
|
+
})
|
|
16265
|
+
})
|
|
16266
|
+
]
|
|
16267
|
+
}),
|
|
16268
|
+
/*#__PURE__*/ jsxs("fieldset", {
|
|
16269
|
+
className: "work-document-table-of-contents-dialog-preview",
|
|
16270
|
+
"aria-label": "目录预览",
|
|
16271
|
+
"data-toc-leader": options.leader,
|
|
16272
|
+
"data-toc-right-align-page-numbers": String(options.rightAlignPageNumbers),
|
|
16273
|
+
children: [
|
|
16274
|
+
/*#__PURE__*/ jsx("legend", {
|
|
16275
|
+
children: "目录"
|
|
16276
|
+
}),
|
|
16277
|
+
/*#__PURE__*/ jsxs("span", {
|
|
16278
|
+
children: [
|
|
16279
|
+
"项目概述 ",
|
|
16280
|
+
/*#__PURE__*/ jsx("i", {
|
|
16281
|
+
"aria-hidden": "true"
|
|
16282
|
+
}),
|
|
16283
|
+
options.showPageNumbers ? '1' : ''
|
|
16284
|
+
]
|
|
16285
|
+
}),
|
|
16286
|
+
/*#__PURE__*/ jsxs("span", {
|
|
16287
|
+
className: "nested",
|
|
16288
|
+
children: [
|
|
16289
|
+
"实施计划 ",
|
|
16290
|
+
/*#__PURE__*/ jsx("i", {
|
|
16291
|
+
"aria-hidden": "true"
|
|
16292
|
+
}),
|
|
16293
|
+
options.showPageNumbers ? '3' : ''
|
|
16294
|
+
]
|
|
16295
|
+
})
|
|
16296
|
+
]
|
|
16297
|
+
})
|
|
16298
|
+
]
|
|
16299
|
+
});
|
|
16300
|
+
}
|
|
16301
|
+
const tableOfContentsLevelOptions = Array.from({
|
|
16302
|
+
length: 9
|
|
16303
|
+
}, (_, index)=>({
|
|
16304
|
+
value: String(index + 1),
|
|
16305
|
+
label: `标题 ${index + 1}`
|
|
16306
|
+
}));
|
|
16307
|
+
const tableOfContentsLeaderOptions = [
|
|
16308
|
+
{
|
|
16309
|
+
value: 'dot',
|
|
16310
|
+
label: '点线(……)'
|
|
16311
|
+
},
|
|
16312
|
+
{
|
|
16313
|
+
value: 'dash',
|
|
16314
|
+
label: '短横线(----)'
|
|
16315
|
+
},
|
|
16316
|
+
{
|
|
16317
|
+
value: 'underline',
|
|
16318
|
+
label: '下划线(____)'
|
|
16319
|
+
},
|
|
16320
|
+
{
|
|
16321
|
+
value: 'none',
|
|
16322
|
+
label: '无'
|
|
16323
|
+
}
|
|
16324
|
+
];
|
|
15363
16325
|
function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext }) {
|
|
15364
16326
|
const officeDialog = useOfficeDialog();
|
|
15365
16327
|
const [insertDialog, setInsertDialog] = useState(null);
|
|
@@ -15453,6 +16415,19 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15453
16415
|
editor,
|
|
15454
16416
|
resolveFieldContext
|
|
15455
16417
|
]);
|
|
16418
|
+
const openTableOfContents = useCallback(()=>{
|
|
16419
|
+
if (!editor) return;
|
|
16420
|
+
rememberInvoker();
|
|
16421
|
+
const selected = selectedDocumentTableOfContentsOptions(editor);
|
|
16422
|
+
setInsertDialog({
|
|
16423
|
+
kind: 'tableOfContents',
|
|
16424
|
+
editing: Boolean(selected),
|
|
16425
|
+
options: selected ?? DEFAULT_DOCUMENT_TABLE_OF_CONTENTS_OPTIONS
|
|
16426
|
+
});
|
|
16427
|
+
}, [
|
|
16428
|
+
editor,
|
|
16429
|
+
rememberInvoker
|
|
16430
|
+
]);
|
|
15456
16431
|
const refreshFields = useCallback(()=>editor?.commands.refreshDocumentFields(contentRef.current, {
|
|
15457
16432
|
resolveContext: resolveFieldContext ?? void 0
|
|
15458
16433
|
}) ?? false, [
|
|
@@ -15460,6 +16435,12 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15460
16435
|
editor,
|
|
15461
16436
|
resolveFieldContext
|
|
15462
16437
|
]);
|
|
16438
|
+
const refreshTableOfContents = useCallback(()=>editor?.commands.refreshDocumentTablesOfContents({
|
|
16439
|
+
resolveContext: resolveFieldContext ?? void 0
|
|
16440
|
+
}) ?? false, [
|
|
16441
|
+
editor,
|
|
16442
|
+
resolveFieldContext
|
|
16443
|
+
]);
|
|
15463
16444
|
const submitCaption = ()=>{
|
|
15464
16445
|
if (!editor || insertDialog?.kind !== 'caption') return;
|
|
15465
16446
|
const inserted = editor.chain().focus().insertDocumentCaption(insertDialog.captionKind, insertDialog.title.trim()).run();
|
|
@@ -15476,6 +16457,16 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15476
16457
|
invokerRef.current = editor.view.dom;
|
|
15477
16458
|
setInsertDialog(null);
|
|
15478
16459
|
};
|
|
16460
|
+
const submitTableOfContents = ()=>{
|
|
16461
|
+
if (!editor || insertDialog?.kind !== 'tableOfContents') return;
|
|
16462
|
+
const buildOptions = {
|
|
16463
|
+
resolveContext: resolveFieldContext ?? void 0
|
|
16464
|
+
};
|
|
16465
|
+
const applied = insertDialog.editing ? editor.commands.updateDocumentTableOfContents(insertDialog.options, buildOptions) : editor.commands.insertDocumentTableOfContents(insertDialog.options, buildOptions);
|
|
16466
|
+
if (!applied) return;
|
|
16467
|
+
invokerRef.current = editor.view.dom;
|
|
16468
|
+
setInsertDialog(null);
|
|
16469
|
+
};
|
|
15479
16470
|
const moveReferenceSelection = (event, currentIndex)=>{
|
|
15480
16471
|
if (insertDialog?.kind !== 'crossReference') return;
|
|
15481
16472
|
let nextIndex = currentIndex;
|
|
@@ -15606,6 +16597,17 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15606
16597
|
}, targetKey);
|
|
15607
16598
|
})
|
|
15608
16599
|
})
|
|
16600
|
+
}),
|
|
16601
|
+
insertDialog?.kind === 'tableOfContents' && /*#__PURE__*/ jsx(DocumentTableOfContentsDialog, {
|
|
16602
|
+
editing: insertDialog.editing,
|
|
16603
|
+
options: insertDialog.options,
|
|
16604
|
+
restoreFocusTarget: ()=>invokerRef.current,
|
|
16605
|
+
onCancel: ()=>setInsertDialog(null),
|
|
16606
|
+
onOptionsChange: (options)=>setInsertDialog({
|
|
16607
|
+
...insertDialog,
|
|
16608
|
+
options
|
|
16609
|
+
}),
|
|
16610
|
+
onSubmit: submitTableOfContents
|
|
15609
16611
|
})
|
|
15610
16612
|
]
|
|
15611
16613
|
});
|
|
@@ -15616,7 +16618,9 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15616
16618
|
insertField,
|
|
15617
16619
|
insertImage,
|
|
15618
16620
|
insertNote,
|
|
15619
|
-
|
|
16621
|
+
openTableOfContents,
|
|
16622
|
+
refreshFields,
|
|
16623
|
+
refreshTableOfContents
|
|
15620
16624
|
};
|
|
15621
16625
|
}
|
|
15622
16626
|
function referenceTargetKey(target) {
|
|
@@ -17681,6 +18685,10 @@ function DocumentEditorSurface({ artifactId, autoFocus = true, collaboration, co
|
|
|
17681
18685
|
documentInsert.refreshFields();
|
|
17682
18686
|
restoreDocumentBodyFocus();
|
|
17683
18687
|
};
|
|
18688
|
+
const refreshDocumentTableOfContents = ()=>{
|
|
18689
|
+
documentInsert.refreshTableOfContents();
|
|
18690
|
+
restoreDocumentBodyFocus();
|
|
18691
|
+
};
|
|
17684
18692
|
const openSelectionContextMenu = (event)=>{
|
|
17685
18693
|
if (!canEditDocument || !getSelectionMenuItems && !onAgentRequest) return false;
|
|
17686
18694
|
const snapshot = createWorkDocumentSelectionSnapshot(editor, contentRef.current);
|
|
@@ -17777,11 +18785,13 @@ function DocumentEditorSurface({ artifactId, autoFocus = true, collaboration, co
|
|
|
17777
18785
|
onInsertNote: documentInsert.insertNote,
|
|
17778
18786
|
onInsertCaption: documentInsert.insertCaption,
|
|
17779
18787
|
onInsertCrossReference: documentInsert.insertCrossReference,
|
|
18788
|
+
onOpenTableOfContents: documentInsert.openTableOfContents,
|
|
17780
18789
|
citationsOpen: citationsOpen,
|
|
17781
18790
|
citationSourceCount: currentContent.bibliography?.sources.length ?? 0,
|
|
17782
18791
|
onToggleCitations: ()=>void toggleTaskPane('citations'),
|
|
17783
18792
|
onInsertField: documentInsert.insertField,
|
|
17784
18793
|
onRefreshFields: refreshDocumentFields,
|
|
18794
|
+
onRefreshTableOfContents: refreshDocumentTableOfContents,
|
|
17785
18795
|
canInsertComment: documentComments.canInsert,
|
|
17786
18796
|
onInsertComment: ()=>void startCommentDraft(),
|
|
17787
18797
|
commentsOpen: documentComments.open,
|