@a3s-lab/office 0.28.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 +126 -3
- package/dist/0~1403.js +1 -1
- package/dist/0~4980.js +1 -1
- package/dist/0~7048.js +1 -1
- package/dist/{0~7043.js → 0~7231.js} +400 -242
- package/dist/{0~5093.js → 0~7360.js} +293 -53
- package/dist/0~7614.js +1 -1
- package/dist/0~document-editor.js +1535 -102
- package/dist/0~presentation-editor.js +1 -1
- package/dist/0~spreadsheet-editor.js +184 -36
- package/dist/0~work-docx-export.js +437 -11
- package/dist/0~work-docx-import.js +32 -7
- package/dist/0~work-office-diagnostics.js +170 -7
- package/dist/0~work-pptx-export.js +1 -1
- package/dist/0~work-pptx-import.js +1 -1
- package/dist/0~work-presentation-charts.js +1 -1
- package/dist/1544.js +14 -2
- package/dist/4104.js +31 -8
- package/dist/4121.js +3448 -0
- package/dist/6282.js +558 -1688
- package/dist/8715.js +1 -1
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +27 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +8 -2
- package/dist/internal/features/work/editors/document-font-dialog-run-border-model.d.ts +24 -0
- package/dist/internal/features/work/editors/document-font-dialog-run-border-section.d.ts +10 -0
- 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 +12 -0
- package/dist/internal/features/work/work-document-format-changes.d.ts +7 -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-border.d.ts +11 -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 +4 -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-border-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-border-export.d.ts +17 -0
- package/dist/internal/features/work/work-docx-run-border.d.ts +20 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +9 -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 +339 -1
- package/docs/latest/en/browser-editor-architecture.md +72 -1
- package/package.json +15 -2
- package/dist/5184.js +0 -662
- package/dist/9424.js +0 -16
|
@@ -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, 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 { createOfficeId as createWorkId } from "./
|
|
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) {
|
|
@@ -7222,6 +7166,15 @@ const documentCommandCatalog = {
|
|
|
7222
7166
|
]
|
|
7223
7167
|
}
|
|
7224
7168
|
},
|
|
7169
|
+
runBorder: {
|
|
7170
|
+
id: 'font.runBorder',
|
|
7171
|
+
label: '字符边框',
|
|
7172
|
+
location: {
|
|
7173
|
+
area: 'ribbon',
|
|
7174
|
+
tab: 'home',
|
|
7175
|
+
group: 'font'
|
|
7176
|
+
}
|
|
7177
|
+
},
|
|
7225
7178
|
clearFormatting: {
|
|
7226
7179
|
id: 'font.clearFormatting',
|
|
7227
7180
|
label: '清除格式',
|
|
@@ -7512,6 +7465,24 @@ const documentCommandCatalog = {
|
|
|
7512
7465
|
]
|
|
7513
7466
|
}
|
|
7514
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
|
+
},
|
|
7515
7486
|
refreshFields: {
|
|
7516
7487
|
id: 'references.refreshFields',
|
|
7517
7488
|
label: '更新域',
|
|
@@ -8098,6 +8069,428 @@ function DocumentStatusBar({ bibliographyCount, citationCount, currentPage, page
|
|
|
8098
8069
|
]
|
|
8099
8070
|
});
|
|
8100
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
|
+
}
|
|
8101
8494
|
function DocumentFormatTools({ editor }) {
|
|
8102
8495
|
const hasFormat = useSyncExternalStore(subscribeDocumentFormatClipboard, hasDocumentFormatClipboard, hasDocumentFormatClipboard);
|
|
8103
8496
|
const [formatPainterActive, setFormatPainterActive] = useState(false);
|
|
@@ -8949,6 +9342,14 @@ function DocumentHomeRibbon({ editor, findReplaceMode, layoutFonts = [], onFindT
|
|
|
8949
9342
|
size: 16
|
|
8950
9343
|
})
|
|
8951
9344
|
}),
|
|
9345
|
+
/*#__PURE__*/ jsx(ToolbarButton, {
|
|
9346
|
+
label: "字符边框",
|
|
9347
|
+
active: documentRunBorderIsVisible(parseDocumentRunBorder(editor.getAttributes('textStyle').runBorder)),
|
|
9348
|
+
onClick: ()=>editor.commands.toggleDocumentRunBorder(),
|
|
9349
|
+
children: /*#__PURE__*/ jsx(Square, {
|
|
9350
|
+
size: 16
|
|
9351
|
+
})
|
|
9352
|
+
}),
|
|
8952
9353
|
/*#__PURE__*/ jsx(ToolbarButton, {
|
|
8953
9354
|
label: "清除格式",
|
|
8954
9355
|
onClick: ()=>editor.commands.clearDocumentFormatting(),
|
|
@@ -9177,7 +9578,7 @@ function applyDocumentScriptFontPatch(editor, selection, scalarPatch, scriptFont
|
|
|
9177
9578
|
const current = marks.find((mark)=>mark.type === textStyle);
|
|
9178
9579
|
const attributes = patchedTextStyleAttributes(current, scalarPatch, scriptFontPatch, normalizeDocumentScriptFontSlot(current?.attrs.scriptFontSlot) ?? documentScriptFontSlotFromHint(parseDocumentScriptFonts(current?.attrs.scriptFonts)?.hint));
|
|
9179
9580
|
const retained = marks.filter((mark)=>mark.type !== textStyle);
|
|
9180
|
-
if (
|
|
9581
|
+
if (document_font_dialog_script_font_model_textStyleAttributesHaveValue(attributes)) retained.push(textStyle.create(attributes));
|
|
9181
9582
|
transaction.setStoredMarks(retained);
|
|
9182
9583
|
transaction.scrollIntoView();
|
|
9183
9584
|
editor.view.dispatch(transaction);
|
|
@@ -9204,7 +9605,7 @@ function applyDocumentScriptFontPatch(editor, selection, scalarPatch, scriptFont
|
|
|
9204
9605
|
});
|
|
9205
9606
|
for (const update of updates){
|
|
9206
9607
|
if (update.current) transaction.removeMark(update.from, update.to, update.current);
|
|
9207
|
-
if (
|
|
9608
|
+
if (document_font_dialog_script_font_model_textStyleAttributesHaveValue(update.attributes)) transaction.addMark(update.from, update.to, textStyle.create(update.attributes));
|
|
9208
9609
|
}
|
|
9209
9610
|
if (!transaction.docChanged) return false;
|
|
9210
9611
|
editor.view.dispatch(transaction.scrollIntoView());
|
|
@@ -9233,7 +9634,7 @@ function patchedTextStyleAttributes(current, scalarPatch, scriptFontPatch, slot,
|
|
|
9233
9634
|
attributes.wordLineHeightFactor = family ? documentWordLineHeightFactor(family) : null;
|
|
9234
9635
|
return attributes;
|
|
9235
9636
|
}
|
|
9236
|
-
function
|
|
9637
|
+
function document_font_dialog_script_font_model_textStyleAttributesHaveValue(attributes) {
|
|
9237
9638
|
return Object.values(attributes).some((value)=>null != value && '' !== value);
|
|
9238
9639
|
}
|
|
9239
9640
|
function validScriptFontPatch(patch) {
|
|
@@ -9243,6 +9644,170 @@ function addFontValue(values, value) {
|
|
|
9243
9644
|
const normalized = value?.trim() || null;
|
|
9244
9645
|
values.set(normalized?.toLocaleLowerCase() ?? 'inherited', normalized);
|
|
9245
9646
|
}
|
|
9647
|
+
function addDocumentFontDialogRunBorderValue(values, source) {
|
|
9648
|
+
const border = parseDocumentRunBorder(source);
|
|
9649
|
+
const serialized = serializeDocumentRunBorder(border);
|
|
9650
|
+
values.set(serialized ?? 'inherited', border);
|
|
9651
|
+
}
|
|
9652
|
+
function selectedDocumentFontDialogRunBorderValue(values) {
|
|
9653
|
+
return 1 === values.size ? {
|
|
9654
|
+
mixed: false,
|
|
9655
|
+
value: values.values().next().value ?? null
|
|
9656
|
+
} : {
|
|
9657
|
+
mixed: true,
|
|
9658
|
+
value: null
|
|
9659
|
+
};
|
|
9660
|
+
}
|
|
9661
|
+
function createDocumentFontDialogRunBorderDraft(source) {
|
|
9662
|
+
const border = source.value;
|
|
9663
|
+
const visible = border && 'nil' !== border.style && 'none' !== border.style;
|
|
9664
|
+
return {
|
|
9665
|
+
runBorderMode: source.mixed ? 'mixed' : border ? visible ? 'value' : 'none' : 'inherit',
|
|
9666
|
+
runBorderStyle: visible ? border.style : 'single',
|
|
9667
|
+
runBorderColor: border?.color?.value ?? 'auto',
|
|
9668
|
+
runBorderWidthPoints: formatPoints((border?.size ?? 4) / 8),
|
|
9669
|
+
runBorderSpacingPoints: String(border?.space ?? 1),
|
|
9670
|
+
runBorderShadow: border?.shadow ?? false,
|
|
9671
|
+
runBorderFrame: border?.frame ?? false
|
|
9672
|
+
};
|
|
9673
|
+
}
|
|
9674
|
+
function documentFontDialogRunBorderDraftError(draft) {
|
|
9675
|
+
if ('value' !== draft.runBorderMode) return null;
|
|
9676
|
+
if (!DOCUMENT_RUN_BORDER_STYLES.includes(draft.runBorderStyle) || 'nil' === draft.runBorderStyle || 'none' === draft.runBorderStyle) return '请选择有效的字符边框线型。';
|
|
9677
|
+
if ('auto' !== draft.runBorderColor && !/^#[0-9a-f]{6}$/i.test(draft.runBorderColor)) return '请选择有效的字符边框颜色。';
|
|
9678
|
+
if (null === runBorderSizeFromDraft(draft)) return '请输入 0.25 至 12 磅、以 0.125 磅递增的字符边框宽度。';
|
|
9679
|
+
if (null === runBorderSpaceFromDraft(draft)) return '请输入 0 至 31 磅的整数字符边框间距。';
|
|
9680
|
+
return null;
|
|
9681
|
+
}
|
|
9682
|
+
function documentFontDialogRunBorderPatch(source, draft, touched) {
|
|
9683
|
+
if (!touched || 'mixed' === draft.runBorderMode) return {};
|
|
9684
|
+
if ('inherit' === draft.runBorderMode) return source.mixed || source.value ? {
|
|
9685
|
+
runBorder: null
|
|
9686
|
+
} : {};
|
|
9687
|
+
const border = 'none' === draft.runBorderMode ? {
|
|
9688
|
+
style: 'nil'
|
|
9689
|
+
} : documentFontDialogRunBorderFromDraft(source, draft);
|
|
9690
|
+
if (!border) return {};
|
|
9691
|
+
return serializeDocumentRunBorder(source.value) === serializeDocumentRunBorder(border) ? {} : {
|
|
9692
|
+
runBorder: border
|
|
9693
|
+
};
|
|
9694
|
+
}
|
|
9695
|
+
function documentFontDialogRunBorderFromDraft(source, draft) {
|
|
9696
|
+
if ('none' === draft.runBorderMode) return {
|
|
9697
|
+
style: 'nil'
|
|
9698
|
+
};
|
|
9699
|
+
if ('value' !== draft.runBorderMode) return source.value;
|
|
9700
|
+
const size = runBorderSizeFromDraft(draft);
|
|
9701
|
+
const space = runBorderSpaceFromDraft(draft);
|
|
9702
|
+
if (null === size || null === space) return null;
|
|
9703
|
+
const sourceColor = source.value?.color;
|
|
9704
|
+
return normalizeDocumentRunBorder({
|
|
9705
|
+
style: draft.runBorderStyle,
|
|
9706
|
+
color: {
|
|
9707
|
+
value: draft.runBorderColor,
|
|
9708
|
+
...sourceColor?.theme && sourceColor.value === draft.runBorderColor ? {
|
|
9709
|
+
theme: sourceColor.theme
|
|
9710
|
+
} : {}
|
|
9711
|
+
},
|
|
9712
|
+
size,
|
|
9713
|
+
space,
|
|
9714
|
+
shadow: draft.runBorderShadow,
|
|
9715
|
+
frame: draft.runBorderFrame
|
|
9716
|
+
});
|
|
9717
|
+
}
|
|
9718
|
+
function runBorderSizeFromDraft(draft) {
|
|
9719
|
+
const points = Number(draft.runBorderWidthPoints);
|
|
9720
|
+
const size = Math.round(8 * points);
|
|
9721
|
+
return Number.isFinite(points) && size >= 2 && size <= 96 && 8 * points === size ? size : null;
|
|
9722
|
+
}
|
|
9723
|
+
function runBorderSpaceFromDraft(draft) {
|
|
9724
|
+
const space = Number(draft.runBorderSpacingPoints);
|
|
9725
|
+
return Number.isSafeInteger(space) && space >= 0 && space <= 31 ? space : null;
|
|
9726
|
+
}
|
|
9727
|
+
function formatPoints(value) {
|
|
9728
|
+
return Number(value.toFixed(3)).toString();
|
|
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
|
+
}
|
|
9246
9811
|
function documentFontDialogSource(editor) {
|
|
9247
9812
|
const { doc, selection } = editor.state;
|
|
9248
9813
|
const scaleValues = new Map();
|
|
@@ -9255,6 +9820,8 @@ function documentFontDialogSource(editor) {
|
|
|
9255
9820
|
const legacyTextShadowValues = new Map();
|
|
9256
9821
|
const legacyTextEmbossValues = new Map();
|
|
9257
9822
|
const legacyTextImprintValues = new Map();
|
|
9823
|
+
const runBorderValues = new Map();
|
|
9824
|
+
const runShadingValues = new Map();
|
|
9258
9825
|
const latinFontValues = new Map();
|
|
9259
9826
|
const eastAsiaFontValues = new Map();
|
|
9260
9827
|
const complexScriptFontValues = new Map();
|
|
@@ -9269,6 +9836,8 @@ function documentFontDialogSource(editor) {
|
|
|
9269
9836
|
addLegacyTextEffectValue(legacyTextShadowValues, attributes.legacyTextShadow);
|
|
9270
9837
|
addLegacyTextEffectValue(legacyTextEmbossValues, attributes.legacyTextEmboss);
|
|
9271
9838
|
addLegacyTextEffectValue(legacyTextImprintValues, attributes.legacyTextImprint);
|
|
9839
|
+
addDocumentFontDialogRunBorderValue(runBorderValues, attributes.runBorder);
|
|
9840
|
+
addDocumentFontDialogRunShadingValue(runShadingValues, attributes.runShading);
|
|
9272
9841
|
addDocumentScriptFontValues(latinFontValues, eastAsiaFontValues, complexScriptFontValues, attributes);
|
|
9273
9842
|
};
|
|
9274
9843
|
if (selection.empty) addValues(editor.getAttributes('textStyle'));
|
|
@@ -9277,20 +9846,22 @@ function documentFontDialogSource(editor) {
|
|
|
9277
9846
|
const textStyle = node.marks.find((mark)=>'textStyle' === mark.type.name);
|
|
9278
9847
|
addValues(textStyle?.attrs ?? {});
|
|
9279
9848
|
});
|
|
9280
|
-
if (!scaleValues.size || !spacingValues.size || !positionValues.size || !kerningValues.size || !emphasisValues.size || !hiddenTextValues.size || !legacyTextOutlineValues.size || !legacyTextShadowValues.size || !legacyTextEmbossValues.size || !legacyTextImprintValues.size || !latinFontValues.size || !eastAsiaFontValues.size || !complexScriptFontValues.size) addValues(editor.getAttributes('textStyle'));
|
|
9281
|
-
const characterScale =
|
|
9282
|
-
const characterPosition =
|
|
9283
|
-
const characterSpacing =
|
|
9284
|
-
const kerningThreshold =
|
|
9285
|
-
const emphasisMark =
|
|
9286
|
-
const hiddenText =
|
|
9287
|
-
const legacyTextOutline =
|
|
9288
|
-
const legacyTextShadow =
|
|
9289
|
-
const legacyTextEmboss =
|
|
9290
|
-
const legacyTextImprint =
|
|
9291
|
-
const
|
|
9292
|
-
const
|
|
9293
|
-
const
|
|
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);
|
|
9860
|
+
const runBorder = selectedDocumentFontDialogRunBorderValue(runBorderValues);
|
|
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);
|
|
9294
9865
|
const textStyle = editor.getAttributes('textStyle');
|
|
9295
9866
|
const selectedText = selection.empty ? '' : doc.textBetween(selection.from, selection.to, ' ', ' ').replace(/\s+/g, ' ').trim();
|
|
9296
9867
|
return {
|
|
@@ -9304,6 +9875,8 @@ function documentFontDialogSource(editor) {
|
|
|
9304
9875
|
legacyTextShadow,
|
|
9305
9876
|
legacyTextEmboss,
|
|
9306
9877
|
legacyTextImprint,
|
|
9878
|
+
runBorder,
|
|
9879
|
+
runShading,
|
|
9307
9880
|
latinFont,
|
|
9308
9881
|
eastAsiaFont,
|
|
9309
9882
|
complexScriptFont,
|
|
@@ -9324,23 +9897,29 @@ function createDocumentFontDialogDraft(source) {
|
|
|
9324
9897
|
characterScaleMode: source.characterScale.mixed ? 'mixed' : 'value',
|
|
9325
9898
|
characterScalePercent: source.characterScale.mixed ? '' : String(scale ?? 100),
|
|
9326
9899
|
characterPositionMode: source.characterPosition.mixed ? 'mixed' : null !== position && position < 0 ? 'lowered' : null !== position && position > 0 ? 'raised' : 'normal',
|
|
9327
|
-
characterPositionPoints:
|
|
9900
|
+
characterPositionPoints: document_font_dialog_model_formatPoints(positionPoints || 1),
|
|
9328
9901
|
characterSpacingMode: source.characterSpacing.mixed ? 'mixed' : null !== spacing && spacing < 0 ? 'condensed' : null !== spacing && spacing > 0 ? 'expanded' : 'normal',
|
|
9329
|
-
characterSpacingPoints:
|
|
9902
|
+
characterSpacingPoints: document_font_dialog_model_formatPoints(spacingPoints || 1),
|
|
9330
9903
|
kerningEnabled: !source.kerningThreshold.mixed && null !== kerningThreshold,
|
|
9331
|
-
kerningThresholdPoints:
|
|
9904
|
+
kerningThresholdPoints: document_font_dialog_model_formatPoints(documentKerningThresholdPoints(kerningThreshold) ?? 12),
|
|
9332
9905
|
emphasisMark: source.emphasisMark.mixed ? 'mixed' : source.emphasisMark.value ?? 'inherit',
|
|
9333
9906
|
hiddenText: source.hiddenText.value ?? false,
|
|
9334
9907
|
legacyTextOutline: source.legacyTextOutline.value ?? false,
|
|
9335
9908
|
legacyTextShadow: source.legacyTextShadow.value ?? false,
|
|
9336
9909
|
legacyTextEmboss: source.legacyTextEmboss.value ?? false,
|
|
9337
9910
|
legacyTextImprint: source.legacyTextImprint.value ?? false,
|
|
9911
|
+
...createDocumentFontDialogRunBorderDraft(source.runBorder),
|
|
9912
|
+
...createDocumentFontDialogRunShadingDraft(source.runShading),
|
|
9338
9913
|
latinFont: documentFontFamilyDraftValue(source.latinFont),
|
|
9339
9914
|
eastAsiaFont: documentFontFamilyDraftValue(source.eastAsiaFont),
|
|
9340
9915
|
complexScriptFont: documentFontFamilyDraftValue(source.complexScriptFont)
|
|
9341
9916
|
};
|
|
9342
9917
|
}
|
|
9343
9918
|
function documentFontDialogDraftError(draft) {
|
|
9919
|
+
const runBorderError = documentFontDialogRunBorderDraftError(draft);
|
|
9920
|
+
if (runBorderError) return runBorderError;
|
|
9921
|
+
const runShadingError = documentFontDialogRunShadingDraftError(draft);
|
|
9922
|
+
if (runShadingError) return runShadingError;
|
|
9344
9923
|
if ('mixed' !== draft.characterScaleMode && null === characterScalePercentFromDraft(draft)) return "请输入 1 至 600 的整数缩放比例。";
|
|
9345
9924
|
if ('mixed' !== draft.characterSpacingMode && 'normal' !== draft.characterSpacingMode && null === characterSpacingTwipsFromDraft(draft)) return "请输入 0.05 至 1584 磅的间距。";
|
|
9346
9925
|
if ('mixed' !== draft.characterPositionMode && 'normal' !== draft.characterPositionMode && null === characterPositionHalfPointsFromDraft(draft)) return "请输入 0.5 至 1584 磅、以 0.5 磅递增的位置值。";
|
|
@@ -9375,6 +9954,8 @@ function documentFontDialogPatch(source, draft, touched) {
|
|
|
9375
9954
|
}
|
|
9376
9955
|
if (touched.hiddenText && (source.hiddenText.mixed || source.hiddenText.value !== draft.hiddenText)) patch.hiddenText = draft.hiddenText;
|
|
9377
9956
|
appendLegacyTextEffectPatch(patch, 'legacyTextOutline', source.legacyTextOutline, draft.legacyTextOutline, touched.legacyTextOutline);
|
|
9957
|
+
Object.assign(patch, documentFontDialogRunBorderPatch(source.runBorder, draft, touched.runBorder));
|
|
9958
|
+
Object.assign(patch, documentFontDialogRunShadingPatch(source.runShading, draft, touched.runShading));
|
|
9378
9959
|
appendLegacyTextEffectPatch(patch, 'legacyTextShadow', source.legacyTextShadow, draft.legacyTextShadow, touched.legacyTextShadow);
|
|
9379
9960
|
appendLegacyTextEffectPatch(patch, 'legacyTextEmboss', source.legacyTextEmboss, draft.legacyTextEmboss, touched.legacyTextEmboss);
|
|
9380
9961
|
appendLegacyTextEffectPatch(patch, 'legacyTextImprint', source.legacyTextImprint, draft.legacyTextImprint, touched.legacyTextImprint);
|
|
@@ -9394,6 +9975,8 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9394
9975
|
const hasLegacyTextShadow = void 0 !== patch.legacyTextShadow;
|
|
9395
9976
|
const hasLegacyTextEmboss = void 0 !== patch.legacyTextEmboss;
|
|
9396
9977
|
const hasLegacyTextImprint = void 0 !== patch.legacyTextImprint;
|
|
9978
|
+
const hasRunBorder = void 0 !== patch.runBorder;
|
|
9979
|
+
const hasRunShading = void 0 !== patch.runShading;
|
|
9397
9980
|
const hasLegacyTextEffects = hasLegacyTextOutline || hasLegacyTextShadow || hasLegacyTextEmboss || hasLegacyTextImprint;
|
|
9398
9981
|
const scriptFontPatch = {
|
|
9399
9982
|
...void 0 !== patch.latinFont ? {
|
|
@@ -9412,8 +9995,10 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9412
9995
|
const spacing = hasSpacing ? normalizeDocumentCharacterSpacingTwips(patch.characterSpacingTwips) : null;
|
|
9413
9996
|
const kerningThreshold = hasKerning && null !== patch.kerningThresholdHalfPoints ? normalizeDocumentKerningThresholdHalfPoints(patch.kerningThresholdHalfPoints) : null;
|
|
9414
9997
|
const emphasisMark = hasEmphasis && null !== patch.emphasisMark ? normalizeDocumentEmphasisMark(patch.emphasisMark) : null;
|
|
9998
|
+
const runBorder = hasRunBorder && null !== patch.runBorder ? normalizeDocumentRunBorder(patch.runBorder) : null;
|
|
9999
|
+
const runShading = hasRunShading && null !== patch.runShading ? normalizeDocumentRunShading(patch.runShading) : null;
|
|
9415
10000
|
const maximum = editor.state.doc.content.size;
|
|
9416
|
-
if (editor.isDestroyed || !hasScale && !hasPosition && !hasSpacing && !hasKerning && !hasEmphasis && !hasHiddenText && !hasLegacyTextEffects && !hasScriptFonts || hasScale && null === scale || hasPosition && null === position || hasSpacing && null === spacing || hasKerning && null !== patch.kerningThresholdHalfPoints && null === kerningThreshold || hasEmphasis && null !== patch.emphasisMark && null === emphasisMark || 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;
|
|
9417
10002
|
const attributes = {};
|
|
9418
10003
|
if (null !== scale) attributes.characterScalePercent = scale;
|
|
9419
10004
|
if (null !== position) attributes.characterPositionHalfPoints = position;
|
|
@@ -9425,6 +10010,8 @@ function applyDocumentFontDialogPatch(editor, selection, patch) {
|
|
|
9425
10010
|
if (hasLegacyTextShadow) attributes.legacyTextShadow = patch.legacyTextShadow ?? false;
|
|
9426
10011
|
if (hasLegacyTextEmboss) attributes.legacyTextEmboss = patch.legacyTextEmboss ?? false;
|
|
9427
10012
|
if (hasLegacyTextImprint) attributes.legacyTextImprint = patch.legacyTextImprint ?? false;
|
|
10013
|
+
if (hasRunBorder) attributes.runBorder = null === patch.runBorder ? null : serializeDocumentRunBorder(runBorder) ?? null;
|
|
10014
|
+
if (hasRunShading) attributes.runShading = null === patch.runShading ? null : serializeDocumentRunShading(runShading) ?? null;
|
|
9428
10015
|
if (hasScriptFonts) return applyDocumentScriptFontPatch(editor, selection, attributes, scriptFontPatch);
|
|
9429
10016
|
return editor.chain().setTextSelection(selection).setMark('textStyle', attributes).removeEmptyTextStyle().focus().scrollIntoView().run();
|
|
9430
10017
|
}
|
|
@@ -9522,15 +10109,538 @@ function kerningThresholdHalfPointsFromDraft(draft) {
|
|
|
9522
10109
|
if (!Number.isFinite(points) || points < 0 || points > 1638.5 || !Number.isSafeInteger(halfPoints)) return null;
|
|
9523
10110
|
return normalizeDocumentKerningThresholdHalfPoints(halfPoints);
|
|
9524
10111
|
}
|
|
9525
|
-
function
|
|
10112
|
+
function document_font_dialog_model_selectedValue(values) {
|
|
9526
10113
|
const mixed = values.size > 1;
|
|
9527
10114
|
return {
|
|
9528
10115
|
mixed,
|
|
9529
10116
|
value: mixed ? null : values.values().next().value ?? null
|
|
9530
10117
|
};
|
|
9531
|
-
}
|
|
9532
|
-
function
|
|
9533
|
-
return String(Number(value.toFixed(2)));
|
|
10118
|
+
}
|
|
10119
|
+
function document_font_dialog_model_formatPoints(value) {
|
|
10120
|
+
return String(Number(value.toFixed(2)));
|
|
10121
|
+
}
|
|
10122
|
+
const runBorderModes = [
|
|
10123
|
+
{
|
|
10124
|
+
value: 'mixed',
|
|
10125
|
+
label: '混合(保持不变)',
|
|
10126
|
+
disabled: true
|
|
10127
|
+
},
|
|
10128
|
+
{
|
|
10129
|
+
value: 'inherit',
|
|
10130
|
+
label: '跟随样式'
|
|
10131
|
+
},
|
|
10132
|
+
{
|
|
10133
|
+
value: 'none',
|
|
10134
|
+
label: '无(显式重置)'
|
|
10135
|
+
},
|
|
10136
|
+
{
|
|
10137
|
+
value: 'value',
|
|
10138
|
+
label: '边框'
|
|
10139
|
+
}
|
|
10140
|
+
];
|
|
10141
|
+
const runBorderStyles = [
|
|
10142
|
+
{
|
|
10143
|
+
value: 'single',
|
|
10144
|
+
label: '单实线'
|
|
10145
|
+
},
|
|
10146
|
+
{
|
|
10147
|
+
value: 'thick',
|
|
10148
|
+
label: '粗实线'
|
|
10149
|
+
},
|
|
10150
|
+
{
|
|
10151
|
+
value: 'double',
|
|
10152
|
+
label: '双线'
|
|
10153
|
+
},
|
|
10154
|
+
{
|
|
10155
|
+
value: 'dotted',
|
|
10156
|
+
label: '点线'
|
|
10157
|
+
},
|
|
10158
|
+
{
|
|
10159
|
+
value: 'dashed',
|
|
10160
|
+
label: '虚线'
|
|
10161
|
+
},
|
|
10162
|
+
{
|
|
10163
|
+
value: 'dotDash',
|
|
10164
|
+
label: '点划线'
|
|
10165
|
+
},
|
|
10166
|
+
{
|
|
10167
|
+
value: 'dotDotDash',
|
|
10168
|
+
label: '双点划线'
|
|
10169
|
+
},
|
|
10170
|
+
{
|
|
10171
|
+
value: 'triple',
|
|
10172
|
+
label: '三线'
|
|
10173
|
+
},
|
|
10174
|
+
{
|
|
10175
|
+
value: 'thinThickSmallGap',
|
|
10176
|
+
label: '细粗线(小间距)'
|
|
10177
|
+
},
|
|
10178
|
+
{
|
|
10179
|
+
value: 'thickThinSmallGap',
|
|
10180
|
+
label: '粗细线(小间距)'
|
|
10181
|
+
},
|
|
10182
|
+
{
|
|
10183
|
+
value: 'thinThickThinSmallGap',
|
|
10184
|
+
label: '细粗细线(小间距)'
|
|
10185
|
+
},
|
|
10186
|
+
{
|
|
10187
|
+
value: 'thinThickMediumGap',
|
|
10188
|
+
label: '细粗线(中间距)'
|
|
10189
|
+
},
|
|
10190
|
+
{
|
|
10191
|
+
value: 'thickThinMediumGap',
|
|
10192
|
+
label: '粗细线(中间距)'
|
|
10193
|
+
},
|
|
10194
|
+
{
|
|
10195
|
+
value: 'thinThickThinMediumGap',
|
|
10196
|
+
label: '细粗细线(中间距)'
|
|
10197
|
+
},
|
|
10198
|
+
{
|
|
10199
|
+
value: 'thinThickLargeGap',
|
|
10200
|
+
label: '细粗线(大间距)'
|
|
10201
|
+
},
|
|
10202
|
+
{
|
|
10203
|
+
value: 'thickThinLargeGap',
|
|
10204
|
+
label: '粗细线(大间距)'
|
|
10205
|
+
},
|
|
10206
|
+
{
|
|
10207
|
+
value: 'thinThickThinLargeGap',
|
|
10208
|
+
label: '细粗细线(大间距)'
|
|
10209
|
+
},
|
|
10210
|
+
{
|
|
10211
|
+
value: 'wave',
|
|
10212
|
+
label: '波浪线'
|
|
10213
|
+
},
|
|
10214
|
+
{
|
|
10215
|
+
value: 'doubleWave',
|
|
10216
|
+
label: '双波浪线'
|
|
10217
|
+
},
|
|
10218
|
+
{
|
|
10219
|
+
value: 'dashSmallGap',
|
|
10220
|
+
label: '短划线'
|
|
10221
|
+
},
|
|
10222
|
+
{
|
|
10223
|
+
value: 'dashDotStroked',
|
|
10224
|
+
label: '粗点划线'
|
|
10225
|
+
},
|
|
10226
|
+
{
|
|
10227
|
+
value: 'threeDEmboss',
|
|
10228
|
+
label: '三维浮雕'
|
|
10229
|
+
},
|
|
10230
|
+
{
|
|
10231
|
+
value: 'threeDEngrave',
|
|
10232
|
+
label: '三维凹刻'
|
|
10233
|
+
},
|
|
10234
|
+
{
|
|
10235
|
+
value: 'outset',
|
|
10236
|
+
label: '外凸'
|
|
10237
|
+
},
|
|
10238
|
+
{
|
|
10239
|
+
value: 'inset',
|
|
10240
|
+
label: '内凹'
|
|
10241
|
+
}
|
|
10242
|
+
];
|
|
10243
|
+
function DocumentFontDialogRunBorderSection({ source, draft, touched, onDraftChange, onTouched }) {
|
|
10244
|
+
const enabled = 'value' === draft.runBorderMode;
|
|
10245
|
+
const update = (patch)=>{
|
|
10246
|
+
onDraftChange(patch);
|
|
10247
|
+
onTouched();
|
|
10248
|
+
};
|
|
10249
|
+
return /*#__PURE__*/ jsxs("fieldset", {
|
|
10250
|
+
className: "work-document-font-dialog-run-border",
|
|
10251
|
+
"aria-label": "字符边框设置",
|
|
10252
|
+
children: [
|
|
10253
|
+
/*#__PURE__*/ jsx("legend", {
|
|
10254
|
+
children: "字符边框"
|
|
10255
|
+
}),
|
|
10256
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10257
|
+
className: "work-document-font-dialog-field",
|
|
10258
|
+
children: [
|
|
10259
|
+
/*#__PURE__*/ jsx("span", {
|
|
10260
|
+
children: "应用方式"
|
|
10261
|
+
}),
|
|
10262
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
10263
|
+
ariaLabel: "字符边框",
|
|
10264
|
+
value: draft.runBorderMode,
|
|
10265
|
+
options: runBorderModes,
|
|
10266
|
+
onValueChange: (runBorderMode)=>update({
|
|
10267
|
+
runBorderMode
|
|
10268
|
+
})
|
|
10269
|
+
})
|
|
10270
|
+
]
|
|
10271
|
+
}),
|
|
10272
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10273
|
+
className: "work-document-font-dialog-field",
|
|
10274
|
+
children: [
|
|
10275
|
+
/*#__PURE__*/ jsx("span", {
|
|
10276
|
+
children: "线型"
|
|
10277
|
+
}),
|
|
10278
|
+
/*#__PURE__*/ jsx(OfficeSelect, {
|
|
10279
|
+
ariaLabel: "字符边框线型",
|
|
10280
|
+
value: draft.runBorderStyle,
|
|
10281
|
+
options: runBorderStyles,
|
|
10282
|
+
disabled: !enabled,
|
|
10283
|
+
onValueChange: (runBorderStyle)=>update({
|
|
10284
|
+
runBorderMode: 'value',
|
|
10285
|
+
runBorderStyle
|
|
10286
|
+
})
|
|
10287
|
+
})
|
|
10288
|
+
]
|
|
10289
|
+
}),
|
|
10290
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10291
|
+
className: "work-document-font-dialog-field",
|
|
10292
|
+
children: [
|
|
10293
|
+
/*#__PURE__*/ jsx("span", {
|
|
10294
|
+
children: "颜色"
|
|
10295
|
+
}),
|
|
10296
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
10297
|
+
ariaLabel: "字符边框颜色",
|
|
10298
|
+
value: 'auto' === draft.runBorderColor ? '#000000' : draft.runBorderColor,
|
|
10299
|
+
disabled: !enabled,
|
|
10300
|
+
resetAction: {
|
|
10301
|
+
kind: 'automatic',
|
|
10302
|
+
label: '自动颜色',
|
|
10303
|
+
onSelect: ()=>update({
|
|
10304
|
+
runBorderMode: 'value',
|
|
10305
|
+
runBorderColor: 'auto'
|
|
10306
|
+
})
|
|
10307
|
+
},
|
|
10308
|
+
onValueChange: (runBorderColor)=>update({
|
|
10309
|
+
runBorderMode: 'value',
|
|
10310
|
+
runBorderColor: runBorderColor
|
|
10311
|
+
})
|
|
10312
|
+
})
|
|
10313
|
+
]
|
|
10314
|
+
}),
|
|
10315
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10316
|
+
className: "work-document-font-dialog-field",
|
|
10317
|
+
children: [
|
|
10318
|
+
/*#__PURE__*/ jsx("span", {
|
|
10319
|
+
children: "宽度"
|
|
10320
|
+
}),
|
|
10321
|
+
/*#__PURE__*/ jsxs("span", {
|
|
10322
|
+
className: "work-document-font-dialog-measure",
|
|
10323
|
+
children: [
|
|
10324
|
+
/*#__PURE__*/ jsx(OfficeNumberField, {
|
|
10325
|
+
ariaLabel: "字符边框宽度(磅)",
|
|
10326
|
+
value: draft.runBorderWidthPoints,
|
|
10327
|
+
min: 0.25,
|
|
10328
|
+
max: 12,
|
|
10329
|
+
step: 0.125,
|
|
10330
|
+
disabled: !enabled,
|
|
10331
|
+
onValueChange: (runBorderWidthPoints)=>update({
|
|
10332
|
+
runBorderMode: 'value',
|
|
10333
|
+
runBorderWidthPoints
|
|
10334
|
+
})
|
|
10335
|
+
}),
|
|
10336
|
+
/*#__PURE__*/ jsx("span", {
|
|
10337
|
+
"aria-hidden": "true",
|
|
10338
|
+
children: "磅"
|
|
10339
|
+
})
|
|
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
|
+
})
|
|
10566
|
+
})
|
|
10567
|
+
]
|
|
10568
|
+
}),
|
|
10569
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10570
|
+
className: "work-document-font-dialog-field",
|
|
10571
|
+
children: [
|
|
10572
|
+
/*#__PURE__*/ jsx("span", {
|
|
10573
|
+
children: "图案"
|
|
10574
|
+
}),
|
|
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
|
|
10583
|
+
})
|
|
10584
|
+
})
|
|
10585
|
+
]
|
|
10586
|
+
}),
|
|
10587
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10588
|
+
className: "work-document-font-dialog-field",
|
|
10589
|
+
children: [
|
|
10590
|
+
/*#__PURE__*/ jsx("span", {
|
|
10591
|
+
children: "前景色"
|
|
10592
|
+
}),
|
|
10593
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
10594
|
+
ariaLabel: "字符底纹前景色",
|
|
10595
|
+
value: 'auto' === draft.runShadingColor ? '#000000' : draft.runShadingColor,
|
|
10596
|
+
disabled: !enabled,
|
|
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: "背景色"
|
|
10617
|
+
}),
|
|
10618
|
+
/*#__PURE__*/ jsx(OfficeColorPicker, {
|
|
10619
|
+
ariaLabel: "字符底纹背景色",
|
|
10620
|
+
value: 'auto' === draft.runShadingFill ? '#ffffff' : draft.runShadingFill,
|
|
10621
|
+
disabled: !enabled,
|
|
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
|
+
})
|
|
10634
|
+
})
|
|
10635
|
+
]
|
|
10636
|
+
}),
|
|
10637
|
+
source.mixed && !touched ? /*#__PURE__*/ jsx("p", {
|
|
10638
|
+
className: "work-document-font-dialog-mixed",
|
|
10639
|
+
role: "status",
|
|
10640
|
+
children: "当前选区包含不同的字符底纹。选择一种应用方式后才会统一修改。"
|
|
10641
|
+
}) : null
|
|
10642
|
+
]
|
|
10643
|
+
});
|
|
9534
10644
|
}
|
|
9535
10645
|
const characterSpacingModes = [
|
|
9536
10646
|
{
|
|
@@ -9613,6 +10723,8 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
9613
10723
|
const [legacyTextShadowTouched, setLegacyTextShadowTouched] = useState(false);
|
|
9614
10724
|
const [legacyTextEmbossTouched, setLegacyTextEmbossTouched] = useState(false);
|
|
9615
10725
|
const [legacyTextImprintTouched, setLegacyTextImprintTouched] = useState(false);
|
|
10726
|
+
const [runBorderTouched, setRunBorderTouched] = useState(false);
|
|
10727
|
+
const [runShadingTouched, setRunShadingTouched] = useState(false);
|
|
9616
10728
|
const [latinFontTouched, setLatinFontTouched] = useState(false);
|
|
9617
10729
|
const [eastAsiaFontTouched, setEastAsiaFontTouched] = useState(false);
|
|
9618
10730
|
const [complexScriptFontTouched, setComplexScriptFontTouched] = useState(false);
|
|
@@ -9630,6 +10742,8 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
9630
10742
|
legacyTextShadow: legacyTextShadowTouched,
|
|
9631
10743
|
legacyTextEmboss: legacyTextEmbossTouched,
|
|
9632
10744
|
legacyTextImprint: legacyTextImprintTouched,
|
|
10745
|
+
runBorder: runBorderTouched,
|
|
10746
|
+
runShading: runShadingTouched,
|
|
9633
10747
|
kerning: kerningTouched,
|
|
9634
10748
|
latinFont: latinFontTouched
|
|
9635
10749
|
});
|
|
@@ -9645,6 +10759,8 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
9645
10759
|
emboss: draft.legacyTextEmboss,
|
|
9646
10760
|
imprint: draft.legacyTextImprint
|
|
9647
10761
|
});
|
|
10762
|
+
const previewRunBorder = documentFontDialogRunBorderPreviewStyle(source.runBorder, draft);
|
|
10763
|
+
const previewRunShading = documentFontDialogRunShadingPreviewStyle(source.runShading, draft);
|
|
9648
10764
|
const submit = (event)=>{
|
|
9649
10765
|
event?.preventDefault();
|
|
9650
10766
|
if (!hasChanges || error) return;
|
|
@@ -10084,6 +11200,26 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10084
11200
|
})
|
|
10085
11201
|
]
|
|
10086
11202
|
}),
|
|
11203
|
+
/*#__PURE__*/ jsx(DocumentFontDialogRunBorderSection, {
|
|
11204
|
+
source: source.runBorder,
|
|
11205
|
+
draft: draft,
|
|
11206
|
+
touched: runBorderTouched,
|
|
11207
|
+
onDraftChange: (runBorderDraft)=>setDraft((current)=>({
|
|
11208
|
+
...current,
|
|
11209
|
+
...runBorderDraft
|
|
11210
|
+
})),
|
|
11211
|
+
onTouched: ()=>setRunBorderTouched(true)
|
|
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
|
+
}),
|
|
10087
11223
|
source.characterScale.mixed && !characterScaleTouched && /*#__PURE__*/ jsx("p", {
|
|
10088
11224
|
className: "work-document-font-dialog-mixed",
|
|
10089
11225
|
role: "status",
|
|
@@ -10119,7 +11255,7 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10119
11255
|
role: "status",
|
|
10120
11256
|
children: "当前选区包含不同的空心、阴影、阳文或阴文设置。勾选或取消对应选项后才会统一修改。"
|
|
10121
11257
|
}),
|
|
10122
|
-
(characterScaleTouched || characterSpacingTouched || characterPositionTouched || kerningTouched || emphasisTouched || hiddenTextTouched || legacyTextOutlineTouched || legacyTextShadowTouched || legacyTextEmbossTouched || legacyTextImprintTouched) && error && /*#__PURE__*/ jsx("p", {
|
|
11258
|
+
(characterScaleTouched || characterSpacingTouched || characterPositionTouched || kerningTouched || emphasisTouched || hiddenTextTouched || legacyTextOutlineTouched || legacyTextShadowTouched || legacyTextEmbossTouched || legacyTextImprintTouched || runBorderTouched || runShadingTouched) && error && /*#__PURE__*/ jsx("p", {
|
|
10123
11259
|
className: "work-document-font-dialog-error",
|
|
10124
11260
|
role: "alert",
|
|
10125
11261
|
children: error
|
|
@@ -10146,6 +11282,8 @@ function DocumentFontDialog({ source, layoutFonts = [], restoreFocusTarget, onAp
|
|
|
10146
11282
|
verticalAlign: `${previewPosition}pt`,
|
|
10147
11283
|
...previewEmphasis,
|
|
10148
11284
|
...previewLegacyTextEffects,
|
|
11285
|
+
...previewRunShading,
|
|
11286
|
+
...previewRunBorder,
|
|
10149
11287
|
...draft.hiddenText ? {
|
|
10150
11288
|
textDecorationColor: 'currentColor',
|
|
10151
11289
|
textDecorationLine: 'underline',
|
|
@@ -10225,7 +11363,7 @@ function previewScriptFontFamily(value, fallback) {
|
|
|
10225
11363
|
function fontDialogDescription(source) {
|
|
10226
11364
|
return source.selectedCharacters ? `分别设置当前选中内容的拉丁、东亚和复杂文字字体,以及原生字符缩放、间距、字距调整阈值、位置、着重号、隐藏文字、空心、阴影、阳文和阴文(${source.selectedCharacters} 个字符)。` : '分别设置当前位置后续输入文字的拉丁、东亚和复杂文字字体,以及原生字符缩放、间距、字距调整阈值、位置、着重号、隐藏文字、空心、阴影、阳文和阴文。';
|
|
10227
11365
|
}
|
|
10228
|
-
function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditingPartChange, onTogglePageNumber, onOpenFontDialog, onClose }) {
|
|
11366
|
+
function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditingPartChange, onTogglePageNumber, onOpenFontDialog, onOpenProofingDialog, onClose }) {
|
|
10229
11367
|
const imageInputRef = useRef(null);
|
|
10230
11368
|
const [, setRevision] = useState(0);
|
|
10231
11369
|
const officeDialog = useOfficeDialog();
|
|
@@ -10383,6 +11521,13 @@ function DocumentPageChromeRibbon({ editor, editingPart, showPageNumber, onEditi
|
|
|
10383
11521
|
ariaLabel: "页眉页脚文字颜色",
|
|
10384
11522
|
value: pickerColor(state.color),
|
|
10385
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
|
+
})
|
|
10386
11531
|
})
|
|
10387
11532
|
]
|
|
10388
11533
|
}),
|
|
@@ -13797,15 +14942,17 @@ function headingLevelForShortcut(code, key) {
|
|
|
13797
14942
|
if ('3' === value) return 3;
|
|
13798
14943
|
return null;
|
|
13799
14944
|
}
|
|
13800
|
-
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 }) {
|
|
13801
14946
|
const [activeTab, setActiveTab] = useState(reviewOnly ? 'review' : 'home');
|
|
13802
14947
|
const [fontDialogRequest, setFontDialogRequest] = useState(null);
|
|
14948
|
+
const [proofingDialogRequest, setProofingDialogRequest] = useState(null);
|
|
13803
14949
|
const officeDialog = useOfficeDialog();
|
|
13804
14950
|
const prompt = officeDialog.prompt;
|
|
13805
14951
|
const imageSelected = editor.isActive('image');
|
|
13806
14952
|
const tableSelected = editor.isActive('table');
|
|
13807
14953
|
const activeBookmark = activeDocumentBookmark(editor);
|
|
13808
14954
|
const hasRefreshableFields = documentHasRefreshableFields(editor);
|
|
14955
|
+
const hasTableOfContents = documentHasTableOfContents(editor);
|
|
13809
14956
|
const documentChanges = collectDocumentChanges(editor.state.doc);
|
|
13810
14957
|
const previousChangeIndex = adjacentDocumentChangeIndex(documentChanges, editor.state.selection, -1);
|
|
13811
14958
|
const nextChangeIndex = adjacentDocumentChangeIndex(documentChanges, editor.state.selection, 1);
|
|
@@ -13828,6 +14975,18 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
13828
14975
|
source: documentFontDialogSource(target)
|
|
13829
14976
|
});
|
|
13830
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
|
+
}, []);
|
|
13831
14990
|
const ribbonTabs = reviewOnly ? documentRibbonTabs.filter(({ id })=>'review' === id || 'view' === id) : pageChromeEditor ? [
|
|
13832
14991
|
...documentRibbonTabs,
|
|
13833
14992
|
documentPageChromeRibbonTab
|
|
@@ -14203,6 +15362,30 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14203
15362
|
}),
|
|
14204
15363
|
references: reviewOnly ? null : /*#__PURE__*/ jsxs(Fragment, {
|
|
14205
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
|
+
}),
|
|
14206
15389
|
/*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14207
15390
|
label: "脚注",
|
|
14208
15391
|
priority: "high",
|
|
@@ -14289,20 +15472,30 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14289
15472
|
}),
|
|
14290
15473
|
review: /*#__PURE__*/ jsxs(Fragment, {
|
|
14291
15474
|
children: [
|
|
14292
|
-
!reviewOnly && /*#__PURE__*/
|
|
15475
|
+
!reviewOnly && /*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14293
15476
|
label: "校对",
|
|
14294
15477
|
priority: "high",
|
|
14295
|
-
children:
|
|
14296
|
-
|
|
14297
|
-
|
|
14298
|
-
|
|
14299
|
-
|
|
14300
|
-
|
|
14301
|
-
|
|
14302
|
-
|
|
14303
|
-
|
|
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
|
+
})
|
|
14304
15497
|
})
|
|
14305
|
-
|
|
15498
|
+
]
|
|
14306
15499
|
}),
|
|
14307
15500
|
!suggestionOnly && /*#__PURE__*/ jsxs(document_toolbar_RibbonGroup, {
|
|
14308
15501
|
label: "批注",
|
|
@@ -14533,6 +15726,7 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14533
15726
|
onEditingPartChange: onPageChromeEditingPartChange,
|
|
14534
15727
|
onTogglePageNumber: onTogglePageChromePageNumber,
|
|
14535
15728
|
onOpenFontDialog: ()=>openFontDialog(pageChromeEditor),
|
|
15729
|
+
onOpenProofingDialog: ()=>openProofingDialog(pageChromeEditor),
|
|
14536
15730
|
onClose: onClosePageChrome
|
|
14537
15731
|
}) : null
|
|
14538
15732
|
}
|
|
@@ -14553,6 +15747,21 @@ function DocumentToolbar({ editor, defaultRibbonCollapsed = false, reviewOnly =
|
|
|
14553
15747
|
});
|
|
14554
15748
|
}
|
|
14555
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
|
+
}),
|
|
14556
15765
|
officeDialog.dialog
|
|
14557
15766
|
]
|
|
14558
15767
|
});
|
|
@@ -14937,6 +16146,182 @@ function commentActor(actor) {
|
|
|
14937
16146
|
author: CURRENT_COMMENT_AUTHOR
|
|
14938
16147
|
};
|
|
14939
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
|
+
];
|
|
14940
16325
|
function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext }) {
|
|
14941
16326
|
const officeDialog = useOfficeDialog();
|
|
14942
16327
|
const [insertDialog, setInsertDialog] = useState(null);
|
|
@@ -15030,6 +16415,19 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15030
16415
|
editor,
|
|
15031
16416
|
resolveFieldContext
|
|
15032
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
|
+
]);
|
|
15033
16431
|
const refreshFields = useCallback(()=>editor?.commands.refreshDocumentFields(contentRef.current, {
|
|
15034
16432
|
resolveContext: resolveFieldContext ?? void 0
|
|
15035
16433
|
}) ?? false, [
|
|
@@ -15037,6 +16435,12 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15037
16435
|
editor,
|
|
15038
16436
|
resolveFieldContext
|
|
15039
16437
|
]);
|
|
16438
|
+
const refreshTableOfContents = useCallback(()=>editor?.commands.refreshDocumentTablesOfContents({
|
|
16439
|
+
resolveContext: resolveFieldContext ?? void 0
|
|
16440
|
+
}) ?? false, [
|
|
16441
|
+
editor,
|
|
16442
|
+
resolveFieldContext
|
|
16443
|
+
]);
|
|
15040
16444
|
const submitCaption = ()=>{
|
|
15041
16445
|
if (!editor || insertDialog?.kind !== 'caption') return;
|
|
15042
16446
|
const inserted = editor.chain().focus().insertDocumentCaption(insertDialog.captionKind, insertDialog.title.trim()).run();
|
|
@@ -15053,6 +16457,16 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15053
16457
|
invokerRef.current = editor.view.dom;
|
|
15054
16458
|
setInsertDialog(null);
|
|
15055
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
|
+
};
|
|
15056
16470
|
const moveReferenceSelection = (event, currentIndex)=>{
|
|
15057
16471
|
if (insertDialog?.kind !== 'crossReference') return;
|
|
15058
16472
|
let nextIndex = currentIndex;
|
|
@@ -15183,6 +16597,17 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15183
16597
|
}, targetKey);
|
|
15184
16598
|
})
|
|
15185
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
|
|
15186
16611
|
})
|
|
15187
16612
|
]
|
|
15188
16613
|
});
|
|
@@ -15193,7 +16618,9 @@ function useDocumentInsertCommands({ contentRef, editor, resolveFieldContext })
|
|
|
15193
16618
|
insertField,
|
|
15194
16619
|
insertImage,
|
|
15195
16620
|
insertNote,
|
|
15196
|
-
|
|
16621
|
+
openTableOfContents,
|
|
16622
|
+
refreshFields,
|
|
16623
|
+
refreshTableOfContents
|
|
15197
16624
|
};
|
|
15198
16625
|
}
|
|
15199
16626
|
function referenceTargetKey(target) {
|
|
@@ -17258,6 +18685,10 @@ function DocumentEditorSurface({ artifactId, autoFocus = true, collaboration, co
|
|
|
17258
18685
|
documentInsert.refreshFields();
|
|
17259
18686
|
restoreDocumentBodyFocus();
|
|
17260
18687
|
};
|
|
18688
|
+
const refreshDocumentTableOfContents = ()=>{
|
|
18689
|
+
documentInsert.refreshTableOfContents();
|
|
18690
|
+
restoreDocumentBodyFocus();
|
|
18691
|
+
};
|
|
17261
18692
|
const openSelectionContextMenu = (event)=>{
|
|
17262
18693
|
if (!canEditDocument || !getSelectionMenuItems && !onAgentRequest) return false;
|
|
17263
18694
|
const snapshot = createWorkDocumentSelectionSnapshot(editor, contentRef.current);
|
|
@@ -17354,11 +18785,13 @@ function DocumentEditorSurface({ artifactId, autoFocus = true, collaboration, co
|
|
|
17354
18785
|
onInsertNote: documentInsert.insertNote,
|
|
17355
18786
|
onInsertCaption: documentInsert.insertCaption,
|
|
17356
18787
|
onInsertCrossReference: documentInsert.insertCrossReference,
|
|
18788
|
+
onOpenTableOfContents: documentInsert.openTableOfContents,
|
|
17357
18789
|
citationsOpen: citationsOpen,
|
|
17358
18790
|
citationSourceCount: currentContent.bibliography?.sources.length ?? 0,
|
|
17359
18791
|
onToggleCitations: ()=>void toggleTaskPane('citations'),
|
|
17360
18792
|
onInsertField: documentInsert.insertField,
|
|
17361
18793
|
onRefreshFields: refreshDocumentFields,
|
|
18794
|
+
onRefreshTableOfContents: refreshDocumentTableOfContents,
|
|
17362
18795
|
canInsertComment: documentComments.canInsert,
|
|
17363
18796
|
onInsertComment: ()=>void startCommentDraft(),
|
|
17364
18797
|
commentsOpen: documentComments.open,
|