@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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import jszip from "jszip";
|
|
2
|
-
import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE,
|
|
3
|
-
import {
|
|
2
|
+
import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, createDocumentImageIdentityRegistry, normalizeDocumentColumns, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, documentCharacterSpacingTwipsFromElement, documentCharacterPositionHalfPointsFromElement, documentTableColumnPercentagesFromElement, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, normalizeDocumentLegacyTextEffects, documentCaptionLabel, documentCaptionKind, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, isContourImageLayout, normalizeDocumentImageIdentity, normalizeTableColor, normalizeDocumentStrikeStyle, documentTableBordersFromElement, documentSections, documentCitationTags, docxDocumentFieldKind, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentLegacyTextEffectsFromElement, parseDocumentCharacterFormatting, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentTableRowIdentityFromElement, normalizeDocumentBookmarkNativeId, collectDocumentNotes, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./6282.js";
|
|
3
|
+
import { normalizeDocumentRunBorder, parseDocumentScriptFonts, parseDocxThemeReference, parseXml, parseDocumentRunShading, applyDocumentParagraphIdentityToElement, DOCUMENT_RUN_SHADING_ATTRIBUTE, documentScriptFontSlotFromElement, DOCUMENT_HIGHLIGHT_ATTRIBUTE, serializeDocumentScriptFonts, attribute as work_ooxml_package_attribute, createDocumentParagraphIdentityRegistry, uniqueDocumentParagraphIdentity, DOCUMENT_NO_PROOF_ATTRIBUTE, documentHighlightForCssColor, directChildren, documentTableOfContentsValueFromElement, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DocxThemePatchCollector, normalizeDocumentScriptFonts, normalizeDocumentParagraphIdentity, normalizeDocumentHighlight, normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES, parseDocumentRunBorder, normalizeDocumentNoProof, decodeXmlBytes, documentParagraphIdentityFromElement, normalizeDocumentParagraphId, documentScriptFontFamily, descendants, resolvePartTarget, documentProofingLanguagesFromElement, documentHighlightFromElement, parseDocumentRunShadingElement, parseDocumentProofingLanguages, patchDocxThemeReferences, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, parseDocumentRunBorderElement, xmlNamespacePrefix, documentScriptFontSlotFromHint, documentNoProofFromElement, documentScriptFontsFromElement, normalizeDocumentRunShading, normalizeDocumentScriptFontSlot, directChild, parseDocumentParagraphShadingElement, documentFontNameFromCssFamily } from "./4121.js";
|
|
4
4
|
import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.js";
|
|
5
|
-
import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue, docxCharacterScaleValue, docxEmphasisMarkRunOptions, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, paragraphSpacingOptions, xmlNamespaceUri, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, DocxParagraphDefaultCollapsedPatchCollector, assertXmlRoot, xmlDeclaredPrefix, paragraphIndent, domDirection, DOCX_WORDPROCESSING_NAMESPACES, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, patchDocxParagraphDefaultCollapsed, xmlAttributeNamespace, dataBoolean, mergeDocxIgnorableExtensions, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~
|
|
5
|
+
import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue, docxCharacterScaleValue, docxEmphasisMarkRunOptions, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, paragraphSpacingOptions, xmlNamespaceUri, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, DocxParagraphDefaultCollapsedPatchCollector, assertXmlRoot, xmlDeclaredPrefix, paragraphIndent, domDirection, DOCX_WORDPROCESSING_NAMESPACES, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, patchDocxParagraphDefaultCollapsed, xmlAttributeNamespace, dataBoolean, mergeDocxIgnorableExtensions, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, documentProofingLanguageDocxOptions, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~7231.js";
|
|
6
6
|
import { normalizeDocumentHref } from "./0~work-document-links.js";
|
|
7
7
|
const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
8
8
|
class DocxBookmarkPatchCollector {
|
|
@@ -2374,6 +2374,113 @@ function docxDocumentFieldRun(element, docx) {
|
|
|
2374
2374
|
if (!docxDocumentFieldKind(instruction)) return new docx.TextRun(display);
|
|
2375
2375
|
return new docx.SimpleField(instruction, display);
|
|
2376
2376
|
}
|
|
2377
|
+
const work_docx_run_shading_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2378
|
+
class DocxRunShadingPatchCollector {
|
|
2379
|
+
patches = [];
|
|
2380
|
+
nextMarker = 1;
|
|
2381
|
+
usedColors;
|
|
2382
|
+
constructor(sourceHtml){
|
|
2383
|
+
this.usedColors = work_docx_run_shading_export_sourceColors(sourceHtml);
|
|
2384
|
+
}
|
|
2385
|
+
marker(source) {
|
|
2386
|
+
const shading = normalizeDocumentRunShading(source);
|
|
2387
|
+
if (!shading) return null;
|
|
2388
|
+
let marker = '';
|
|
2389
|
+
do {
|
|
2390
|
+
const value = 0xd00000 + this.nextMarker;
|
|
2391
|
+
if (value > 0xdfffff) throw new Error('DOCX character shading marker space is exhausted.');
|
|
2392
|
+
marker = value.toString(16).padStart(6, '0').toUpperCase();
|
|
2393
|
+
this.nextMarker += 1;
|
|
2394
|
+
}while (this.usedColors.has(marker))
|
|
2395
|
+
this.usedColors.add(marker);
|
|
2396
|
+
this.patches.push({
|
|
2397
|
+
marker,
|
|
2398
|
+
shading
|
|
2399
|
+
});
|
|
2400
|
+
return marker;
|
|
2401
|
+
}
|
|
2402
|
+
hasMarker(value) {
|
|
2403
|
+
const marker = value?.toUpperCase();
|
|
2404
|
+
return Boolean(marker && this.patches.some((patch)=>patch.marker === marker));
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
function documentRunShadingDocxOptions(source, collector) {
|
|
2408
|
+
const marker = collector.marker(source);
|
|
2409
|
+
return marker ? {
|
|
2410
|
+
shading: {
|
|
2411
|
+
type: 'clear',
|
|
2412
|
+
color: 'auto',
|
|
2413
|
+
fill: marker
|
|
2414
|
+
}
|
|
2415
|
+
} : {};
|
|
2416
|
+
}
|
|
2417
|
+
async function patchDocxRunShading(buffer, patches) {
|
|
2418
|
+
if (!patches.length) return buffer;
|
|
2419
|
+
const archive = await jszip.loadAsync(buffer);
|
|
2420
|
+
const byMarker = new Map(patches.map((patch)=>[
|
|
2421
|
+
patch.marker,
|
|
2422
|
+
patch
|
|
2423
|
+
]));
|
|
2424
|
+
const applied = new Set();
|
|
2425
|
+
for (const entry of Object.values(archive.files)){
|
|
2426
|
+
if (entry.dir || !/^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/i.test(entry.name)) continue;
|
|
2427
|
+
const document = parseXml(await entry.async('text'), entry.name);
|
|
2428
|
+
let changed = false;
|
|
2429
|
+
for (const element of Array.from(document.getElementsByTagName('*'))){
|
|
2430
|
+
if ('shd' !== element.localName || element.namespaceURI !== work_docx_run_shading_export_WORD_NAMESPACE || element.parentElement?.localName !== 'rPr') continue;
|
|
2431
|
+
const marker = work_docx_run_shading_export_wordAttribute(element, 'fill')?.toUpperCase();
|
|
2432
|
+
const patch = marker ? byMarker.get(marker) : void 0;
|
|
2433
|
+
if (marker && patch) {
|
|
2434
|
+
replaceRunShadingAttributes(document, element, patch.shading);
|
|
2435
|
+
applied.add(marker);
|
|
2436
|
+
changed = true;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
if (changed) archive.file(entry.name, serializeUtf8Xml(document));
|
|
2440
|
+
}
|
|
2441
|
+
const missing = patches.filter((patch)=>!applied.has(patch.marker));
|
|
2442
|
+
if (missing.length) throw new Error(`Generated DOCX is missing ${missing.length} character shading marker(s).`);
|
|
2443
|
+
return archive.generateAsync({
|
|
2444
|
+
type: 'arraybuffer'
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
function setDocxRunShadingAttributes(document, element, source) {
|
|
2448
|
+
const shading = normalizeDocumentRunShading(source);
|
|
2449
|
+
if (!shading) return false;
|
|
2450
|
+
work_docx_run_shading_export_setWordAttribute(document, element, 'val', shading.pattern);
|
|
2451
|
+
setShadingColorAttributes(document, element, shading.color, 'color');
|
|
2452
|
+
setShadingColorAttributes(document, element, shading.fill, 'fill');
|
|
2453
|
+
return true;
|
|
2454
|
+
}
|
|
2455
|
+
function replaceRunShadingAttributes(document, element, shading) {
|
|
2456
|
+
for (const attribute of Array.from(element.attributes))if ('xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:')) element.removeAttributeNode(attribute);
|
|
2457
|
+
element.replaceChildren();
|
|
2458
|
+
setDocxRunShadingAttributes(document, element, shading);
|
|
2459
|
+
}
|
|
2460
|
+
function setShadingColorAttributes(document, element, color, kind) {
|
|
2461
|
+
if (!color) return;
|
|
2462
|
+
work_docx_run_shading_export_setWordAttribute(document, element, kind, 'auto' === color.value ? 'auto' : color.value.slice(1).toUpperCase());
|
|
2463
|
+
if (!color.theme) return;
|
|
2464
|
+
const themeName = 'color' === kind ? 'themeColor' : 'themeFill';
|
|
2465
|
+
const tintName = 'color' === kind ? 'themeTint' : 'themeFillTint';
|
|
2466
|
+
const shadeName = 'color' === kind ? 'themeShade' : 'themeFillShade';
|
|
2467
|
+
work_docx_run_shading_export_setWordAttribute(document, element, themeName, color.theme.theme);
|
|
2468
|
+
if (color.theme.tint) work_docx_run_shading_export_setWordAttribute(document, element, tintName, color.theme.tint);
|
|
2469
|
+
if (color.theme.shade) work_docx_run_shading_export_setWordAttribute(document, element, shadeName, color.theme.shade);
|
|
2470
|
+
}
|
|
2471
|
+
function work_docx_run_shading_export_sourceColors(source) {
|
|
2472
|
+
const colors = new Set();
|
|
2473
|
+
for (const match of source.matchAll(/#([0-9a-f]{6})\b/gi))if (match[1]) colors.add(match[1].toUpperCase());
|
|
2474
|
+
return colors;
|
|
2475
|
+
}
|
|
2476
|
+
function work_docx_run_shading_export_wordAttribute(element, name) {
|
|
2477
|
+
return element.getAttributeNS(element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE, name) ?? element.getAttribute(`${element.prefix ?? 'w'}:${name}`);
|
|
2478
|
+
}
|
|
2479
|
+
function work_docx_run_shading_export_setWordAttribute(document, element, name, value) {
|
|
2480
|
+
const namespace = element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE;
|
|
2481
|
+
const prefix = element.prefix ?? xmlNamespacePrefix(document.documentElement, namespace) ?? 'w';
|
|
2482
|
+
element.setAttributeNS(namespace, `${prefix}:${name}`, value);
|
|
2483
|
+
}
|
|
2377
2484
|
const MAX_RUN_FORMATTING_CHANGE_PATCHES = 65536;
|
|
2378
2485
|
const RUN_FORMATTING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
|
|
2379
2486
|
class DocxRunFormattingChangePatchCollector {
|
|
@@ -2503,6 +2610,7 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
|
|
|
2503
2610
|
appendTextCaseProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2504
2611
|
appendStrikeProperties(document, properties, namespace, prefix, byType.get('strike'));
|
|
2505
2612
|
appendLegacyTextEffectsProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2613
|
+
appendNoProofProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2506
2614
|
appendSnapToGridProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2507
2615
|
appendHiddenTextProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2508
2616
|
appendColorProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
@@ -2511,10 +2619,54 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
|
|
|
2511
2619
|
appendKerningThresholdProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2512
2620
|
appendCharacterPositionProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2513
2621
|
appendFontSizeProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2514
|
-
appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'));
|
|
2622
|
+
appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'), !parseDocumentRunShading(byType.get('textStyle')?.attrs?.runShading));
|
|
2515
2623
|
appendUnderlineProperty(document, properties, namespace, prefix, byType.get('underline'));
|
|
2624
|
+
appendRunBorderProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2625
|
+
appendRunShadingProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2516
2626
|
appendVerticalAlignProperty(document, properties, namespace, prefix, byType);
|
|
2517
2627
|
appendEmphasisMarkProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2628
|
+
appendProofingLanguagesProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2629
|
+
}
|
|
2630
|
+
function appendNoProofProperty(document, properties, namespace, prefix, mark) {
|
|
2631
|
+
const noProof = normalizeDocumentNoProof(mark?.attrs?.noProof);
|
|
2632
|
+
if (null === noProof) return;
|
|
2633
|
+
if (noProof) properties.append(wordElement(document, namespace, prefix, 'noProof'));
|
|
2634
|
+
else appendValuedProperty(document, properties, namespace, prefix, 'noProof', '0');
|
|
2635
|
+
}
|
|
2636
|
+
function appendProofingLanguagesProperty(document, properties, namespace, prefix, mark) {
|
|
2637
|
+
const languages = parseDocumentProofingLanguages(mark?.attrs?.proofingLanguages);
|
|
2638
|
+
if (!languages) return;
|
|
2639
|
+
const element = wordElement(document, namespace, prefix, 'lang');
|
|
2640
|
+
if (languages.latin) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', languages.latin);
|
|
2641
|
+
if (languages.eastAsia) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'eastAsia', languages.eastAsia);
|
|
2642
|
+
if (languages.bidi) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'bidi', languages.bidi);
|
|
2643
|
+
properties.append(element);
|
|
2644
|
+
}
|
|
2645
|
+
function appendRunBorderProperty(document, properties, namespace, prefix, mark) {
|
|
2646
|
+
const border = parseDocumentRunBorder(mark?.attrs?.runBorder);
|
|
2647
|
+
if (!border) return;
|
|
2648
|
+
const element = wordElement(document, namespace, prefix, 'bdr');
|
|
2649
|
+
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', border.style);
|
|
2650
|
+
if (border.color) {
|
|
2651
|
+
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'color', 'auto' === border.color.value ? 'auto' : border.color.value.slice(1).toUpperCase());
|
|
2652
|
+
if (border.color.theme) {
|
|
2653
|
+
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'themeColor', border.color.theme.theme);
|
|
2654
|
+
if (border.color.theme.tint) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'themeTint', border.color.theme.tint);
|
|
2655
|
+
if (border.color.theme.shade) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'themeShade', border.color.theme.shade);
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
if (void 0 !== border.size) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'sz', String(border.size));
|
|
2659
|
+
if (void 0 !== border.space) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'space', String(border.space));
|
|
2660
|
+
if (void 0 !== border.shadow) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'shadow', border.shadow ? '1' : '0');
|
|
2661
|
+
if (void 0 !== border.frame) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'frame', border.frame ? '1' : '0');
|
|
2662
|
+
properties.append(element);
|
|
2663
|
+
}
|
|
2664
|
+
function appendRunShadingProperty(document, properties, namespace, prefix, mark) {
|
|
2665
|
+
const shading = parseDocumentRunShading(mark?.attrs?.runShading);
|
|
2666
|
+
if (!shading) return;
|
|
2667
|
+
const element = wordElement(document, namespace, prefix, 'shd');
|
|
2668
|
+
if (!setDocxRunShadingAttributes(document, element, shading)) return;
|
|
2669
|
+
properties.append(element);
|
|
2518
2670
|
}
|
|
2519
2671
|
function appendLegacyTextEffectsProperties(document, properties, namespace, prefix, mark) {
|
|
2520
2672
|
const effects = {};
|
|
@@ -2684,7 +2836,10 @@ function appendFontSizeProperties(document, properties, namespace, prefix, mark)
|
|
|
2684
2836
|
appendValuedProperty(document, properties, namespace, prefix, 'sz', String(halfPoints));
|
|
2685
2837
|
appendValuedProperty(document, properties, namespace, prefix, 'szCs', String(halfPoints));
|
|
2686
2838
|
}
|
|
2687
|
-
function appendHighlightProperty(document, properties, namespace, prefix, mark) {
|
|
2839
|
+
function appendHighlightProperty(document, properties, namespace, prefix, mark, allowFallbackShading) {
|
|
2840
|
+
const nativeHighlight = normalizeDocumentHighlight(mark?.attrs?.nativeHighlight) ?? documentHighlightForCssColor(mark?.attrs?.color);
|
|
2841
|
+
if (nativeHighlight) return void appendValuedProperty(document, properties, namespace, prefix, 'highlight', nativeHighlight);
|
|
2842
|
+
if (!allowFallbackShading) return;
|
|
2688
2843
|
const fill = normalizedHex(mark?.attrs?.color);
|
|
2689
2844
|
const theme = themeReference(mark?.attrs?.themeFill);
|
|
2690
2845
|
if (!fill && !theme) return;
|
|
@@ -3951,6 +4106,127 @@ function docxBorderStyle(style, docx) {
|
|
|
3951
4106
|
function docxColor(color) {
|
|
3952
4107
|
return color.replace(/^#/, '').toUpperCase();
|
|
3953
4108
|
}
|
|
4109
|
+
const work_docx_table_of_contents_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
4110
|
+
const work_docx_table_of_contents_export_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
4111
|
+
class DocxTableOfContentsPatchCollector {
|
|
4112
|
+
patches = [];
|
|
4113
|
+
add(element) {
|
|
4114
|
+
const value = documentTableOfContentsValueFromElement(element);
|
|
4115
|
+
const patch = {
|
|
4116
|
+
options: value.options,
|
|
4117
|
+
entries: value.entries
|
|
4118
|
+
};
|
|
4119
|
+
this.patches.push(patch);
|
|
4120
|
+
return patch;
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
function docxTableOfContents(element, docx, collector) {
|
|
4124
|
+
const patch = collector.add(element);
|
|
4125
|
+
const options = patch.options;
|
|
4126
|
+
return new docx.TableOfContents('Table of Contents', {
|
|
4127
|
+
hyperlink: options.hyperlinks,
|
|
4128
|
+
headingStyleRange: `${options.minLevel}-${options.maxLevel}`,
|
|
4129
|
+
pageNumbersEntryLevelsRange: options.showPageNumbers ? void 0 : `${options.minLevel}-${options.maxLevel}`,
|
|
4130
|
+
entryAndPageNumberSeparator: options.showPageNumbers && !options.rightAlignPageNumbers ? ' ' : void 0,
|
|
4131
|
+
useAppliedParagraphOutlineLevel: true,
|
|
4132
|
+
hideTabAndPageNumbersInWebView: true,
|
|
4133
|
+
cachedEntries: patch.entries.map((entry)=>({
|
|
4134
|
+
title: entry.title,
|
|
4135
|
+
level: entry.level,
|
|
4136
|
+
page: options.showPageNumbers ? entry.pageNumber : void 0,
|
|
4137
|
+
href: options.hyperlinks ? entry.targetId : void 0
|
|
4138
|
+
}))
|
|
4139
|
+
});
|
|
4140
|
+
}
|
|
4141
|
+
async function patchDocxTableOfContents(buffer, patches) {
|
|
4142
|
+
if (!patches.length) return buffer;
|
|
4143
|
+
const archive = await jszip.loadAsync(buffer);
|
|
4144
|
+
const entry = archive.file('word/document.xml');
|
|
4145
|
+
if (!entry) return buffer;
|
|
4146
|
+
const document = parseXml(await entry.async('text'), 'generated DOCX word/document.xml');
|
|
4147
|
+
const tables = descendants(document, 'sdt').filter((element)=>descendants(element, 'instrText').some((instruction)=>/^\s*TOC\b/i.test(instruction.textContent ?? '')));
|
|
4148
|
+
if (tables.length !== patches.length) throw new Error(`Generated DOCX emitted ${tables.length} table(s) of contents for ${patches.length} source block(s).`);
|
|
4149
|
+
for (const [index, table] of tables.entries()){
|
|
4150
|
+
const patch = patches[index];
|
|
4151
|
+
if (patch) patchTableOfContents(document, table, patch.options);
|
|
4152
|
+
}
|
|
4153
|
+
addTableOfContentsBookmarks(document, patches);
|
|
4154
|
+
archive.file('word/document.xml', new XMLSerializer().serializeToString(document));
|
|
4155
|
+
return archive.generateAsync({
|
|
4156
|
+
type: 'arraybuffer'
|
|
4157
|
+
});
|
|
4158
|
+
}
|
|
4159
|
+
function patchTableOfContents(document, table, options) {
|
|
4160
|
+
for (const tabStop of descendants(table, 'tab')){
|
|
4161
|
+
if (tabStop.parentElement?.localName !== 'tabs') continue;
|
|
4162
|
+
const value = work_ooxml_package_attribute(tabStop, 'val');
|
|
4163
|
+
if ('right' !== value) continue;
|
|
4164
|
+
if (!options.showPageNumbers || !options.rightAlignPageNumbers) {
|
|
4165
|
+
const parent = tabStop.parentElement;
|
|
4166
|
+
tabStop.remove();
|
|
4167
|
+
if (parent && !directChildren(parent, 'tab').length) parent.remove();
|
|
4168
|
+
continue;
|
|
4169
|
+
}
|
|
4170
|
+
const leader = docxTableOfContentsLeader(options.leader);
|
|
4171
|
+
if (leader) work_docx_table_of_contents_export_setWordAttribute(document, tabStop, 'leader', leader);
|
|
4172
|
+
else removeWordAttribute(tabStop, 'leader');
|
|
4173
|
+
}
|
|
4174
|
+
if (options.showPageNumbers && options.rightAlignPageNumbers) return;
|
|
4175
|
+
for (const tab of descendants(table, 'tab')){
|
|
4176
|
+
if (tab.parentElement?.localName === 'tabs') continue;
|
|
4177
|
+
if (!options.showPageNumbers) {
|
|
4178
|
+
tab.remove();
|
|
4179
|
+
continue;
|
|
4180
|
+
}
|
|
4181
|
+
const text = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 't'));
|
|
4182
|
+
text.setAttributeNS(work_docx_table_of_contents_export_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
4183
|
+
text.textContent = ' ';
|
|
4184
|
+
tab.replaceWith(text);
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
function addTableOfContentsBookmarks(document, patches) {
|
|
4188
|
+
const names = new Set(descendants(document, 'bookmarkStart').flatMap((bookmark)=>{
|
|
4189
|
+
const name = work_ooxml_package_attribute(bookmark, 'name')?.trim();
|
|
4190
|
+
return name ? [
|
|
4191
|
+
name
|
|
4192
|
+
] : [];
|
|
4193
|
+
}));
|
|
4194
|
+
let nextId = Math.max(0, ...descendants(document, 'bookmarkStart').map((bookmark)=>Number(work_ooxml_package_attribute(bookmark, 'id') ?? 0))) + 1;
|
|
4195
|
+
const targets = new Set(patches.flatMap((patch)=>patch.options.hyperlinks ? patch.entries.map((candidate)=>candidate.targetId) : []));
|
|
4196
|
+
for (const target of targets){
|
|
4197
|
+
if (names.has(target)) continue;
|
|
4198
|
+
const paragraphId = /^heading-([0-9a-f]{8})$/i.exec(target)?.[1];
|
|
4199
|
+
if (!paragraphId) continue;
|
|
4200
|
+
const paragraph = descendants(document, 'p').find((candidate)=>work_ooxml_package_attribute(candidate, 'paraId')?.toLowerCase() === paragraphId.toLowerCase());
|
|
4201
|
+
if (!paragraph) continue;
|
|
4202
|
+
const start = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkStart'));
|
|
4203
|
+
const end = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkEnd'));
|
|
4204
|
+
work_docx_table_of_contents_export_setWordAttribute(document, start, 'id', String(nextId));
|
|
4205
|
+
work_docx_table_of_contents_export_setWordAttribute(document, start, 'name', target);
|
|
4206
|
+
work_docx_table_of_contents_export_setWordAttribute(document, end, 'id', String(nextId));
|
|
4207
|
+
nextId += 1;
|
|
4208
|
+
const properties = directChild(paragraph, 'pPr');
|
|
4209
|
+
paragraph.insertBefore(start, properties?.nextSibling ?? paragraph.firstChild);
|
|
4210
|
+
paragraph.append(end);
|
|
4211
|
+
names.add(target);
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
function docxTableOfContentsLeader(value) {
|
|
4215
|
+
if ('dash' === value) return 'hyphen';
|
|
4216
|
+
if ('underline' === value) return 'underscore';
|
|
4217
|
+
if ('dot' === value) return 'dot';
|
|
4218
|
+
return null;
|
|
4219
|
+
}
|
|
4220
|
+
function work_docx_table_of_contents_export_setWordAttribute(document, element, localName, value) {
|
|
4221
|
+
removeWordAttribute(element, localName);
|
|
4222
|
+
element.setAttributeNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, localName), value);
|
|
4223
|
+
}
|
|
4224
|
+
function removeWordAttribute(element, localName) {
|
|
4225
|
+
for (const candidate of Array.from(element.attributes))if (candidate.localName === localName && (candidate.namespaceURI === work_docx_table_of_contents_export_WORD_NAMESPACE || !candidate.namespaceURI)) element.removeAttributeNode(candidate);
|
|
4226
|
+
}
|
|
4227
|
+
function work_docx_table_of_contents_export_wordQualifiedName(root, localName) {
|
|
4228
|
+
return `${xmlNamespacePrefix(root, work_docx_table_of_contents_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
|
|
4229
|
+
}
|
|
3954
4230
|
const work_docx_table_sizing_export_TWIPS_PER_PIXEL = 15;
|
|
3955
4231
|
function documentTableSizingDocxOptions(table, docx) {
|
|
3956
4232
|
const geometry = documentTableGeometryFromElement(table);
|
|
@@ -7828,6 +8104,110 @@ function setWordFontAttribute(element, name, value) {
|
|
|
7828
8104
|
const prefix = element.prefix || 'w';
|
|
7829
8105
|
element.setAttributeNS(namespace, `${prefix}:${name}`, value);
|
|
7830
8106
|
}
|
|
8107
|
+
const work_docx_run_border_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
8108
|
+
class DocxRunBorderPatchCollector {
|
|
8109
|
+
patches = [];
|
|
8110
|
+
nextMarker = 1;
|
|
8111
|
+
usedColors;
|
|
8112
|
+
constructor(sourceHtml){
|
|
8113
|
+
this.usedColors = work_docx_run_border_export_sourceColors(sourceHtml);
|
|
8114
|
+
}
|
|
8115
|
+
marker(source) {
|
|
8116
|
+
const border = normalizeDocumentRunBorder(source);
|
|
8117
|
+
if (!border) return null;
|
|
8118
|
+
let marker = '';
|
|
8119
|
+
do {
|
|
8120
|
+
const value = 0xc00000 + this.nextMarker;
|
|
8121
|
+
if (value > 0xcfffff) throw new Error('DOCX character border marker space is exhausted.');
|
|
8122
|
+
marker = value.toString(16).padStart(6, '0').toUpperCase();
|
|
8123
|
+
this.nextMarker += 1;
|
|
8124
|
+
}while (this.usedColors.has(marker))
|
|
8125
|
+
this.usedColors.add(marker);
|
|
8126
|
+
this.patches.push({
|
|
8127
|
+
marker,
|
|
8128
|
+
border
|
|
8129
|
+
});
|
|
8130
|
+
return marker;
|
|
8131
|
+
}
|
|
8132
|
+
hasMarker(value) {
|
|
8133
|
+
const marker = value?.toUpperCase();
|
|
8134
|
+
return Boolean(marker && this.patches.some((patch)=>patch.marker === marker));
|
|
8135
|
+
}
|
|
8136
|
+
}
|
|
8137
|
+
function documentRunBorderDocxOptions(source, collector) {
|
|
8138
|
+
const marker = collector.marker(source);
|
|
8139
|
+
return marker ? {
|
|
8140
|
+
border: {
|
|
8141
|
+
style: 'single',
|
|
8142
|
+
color: marker,
|
|
8143
|
+
size: 2,
|
|
8144
|
+
space: 0
|
|
8145
|
+
}
|
|
8146
|
+
} : {};
|
|
8147
|
+
}
|
|
8148
|
+
async function patchDocxRunBorders(buffer, patches) {
|
|
8149
|
+
if (!patches.length) return buffer;
|
|
8150
|
+
const archive = await jszip.loadAsync(buffer);
|
|
8151
|
+
const byMarker = new Map(patches.map((patch)=>[
|
|
8152
|
+
patch.marker,
|
|
8153
|
+
patch
|
|
8154
|
+
]));
|
|
8155
|
+
const applied = new Set();
|
|
8156
|
+
for (const entry of Object.values(archive.files)){
|
|
8157
|
+
if (entry.dir || !/^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/i.test(entry.name)) continue;
|
|
8158
|
+
const document = parseXml(await entry.async('text'), entry.name);
|
|
8159
|
+
let changed = false;
|
|
8160
|
+
for (const element of Array.from(document.getElementsByTagName('*'))){
|
|
8161
|
+
if ('bdr' !== element.localName || element.namespaceURI !== work_docx_run_border_export_WORD_NAMESPACE || element.parentElement?.localName !== 'rPr') continue;
|
|
8162
|
+
const marker = work_docx_run_border_export_wordAttribute(element, 'color')?.toUpperCase();
|
|
8163
|
+
const patch = marker ? byMarker.get(marker) : void 0;
|
|
8164
|
+
if (marker && patch) {
|
|
8165
|
+
replaceRunBorderAttributes(document, element, patch.border);
|
|
8166
|
+
applied.add(marker);
|
|
8167
|
+
changed = true;
|
|
8168
|
+
}
|
|
8169
|
+
}
|
|
8170
|
+
if (changed) archive.file(entry.name, serializeUtf8Xml(document));
|
|
8171
|
+
}
|
|
8172
|
+
const missing = patches.filter((patch)=>!applied.has(patch.marker));
|
|
8173
|
+
if (missing.length) throw new Error(`Generated DOCX is missing ${missing.length} character border marker(s).`);
|
|
8174
|
+
return archive.generateAsync({
|
|
8175
|
+
type: 'arraybuffer'
|
|
8176
|
+
});
|
|
8177
|
+
}
|
|
8178
|
+
function setDocxRunBorderAttributes(document, element, border) {
|
|
8179
|
+
work_docx_run_border_export_setWordAttribute(document, element, 'val', border.style);
|
|
8180
|
+
const color = border.color;
|
|
8181
|
+
if (color) {
|
|
8182
|
+
work_docx_run_border_export_setWordAttribute(document, element, 'color', 'auto' === color.value ? 'auto' : color.value.slice(1).toUpperCase());
|
|
8183
|
+
if (color.theme) {
|
|
8184
|
+
work_docx_run_border_export_setWordAttribute(document, element, 'themeColor', color.theme.theme);
|
|
8185
|
+
if (color.theme.tint) work_docx_run_border_export_setWordAttribute(document, element, 'themeTint', color.theme.tint);
|
|
8186
|
+
if (color.theme.shade) work_docx_run_border_export_setWordAttribute(document, element, 'themeShade', color.theme.shade);
|
|
8187
|
+
}
|
|
8188
|
+
}
|
|
8189
|
+
if (void 0 !== border.size) work_docx_run_border_export_setWordAttribute(document, element, 'sz', String(border.size));
|
|
8190
|
+
if (void 0 !== border.space) work_docx_run_border_export_setWordAttribute(document, element, 'space', String(border.space));
|
|
8191
|
+
if (void 0 !== border.shadow) work_docx_run_border_export_setWordAttribute(document, element, 'shadow', border.shadow ? '1' : '0');
|
|
8192
|
+
if (void 0 !== border.frame) work_docx_run_border_export_setWordAttribute(document, element, 'frame', border.frame ? '1' : '0');
|
|
8193
|
+
}
|
|
8194
|
+
function replaceRunBorderAttributes(document, element, border) {
|
|
8195
|
+
for (const attribute of Array.from(element.attributes))if ('xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:')) element.removeAttributeNode(attribute);
|
|
8196
|
+
element.replaceChildren();
|
|
8197
|
+
setDocxRunBorderAttributes(document, element, border);
|
|
8198
|
+
}
|
|
8199
|
+
function work_docx_run_border_export_sourceColors(source) {
|
|
8200
|
+
const colors = new Set();
|
|
8201
|
+
for (const match of source.matchAll(/#([0-9a-f]{6})\b/gi))if (match[1]) colors.add(match[1].toUpperCase());
|
|
8202
|
+
return colors;
|
|
8203
|
+
}
|
|
8204
|
+
function work_docx_run_border_export_wordAttribute(element, name) {
|
|
8205
|
+
return element.getAttributeNS(work_docx_run_border_export_WORD_NAMESPACE, name) ?? element.getAttribute(`w:${name}`);
|
|
8206
|
+
}
|
|
8207
|
+
function work_docx_run_border_export_setWordAttribute(document, element, name, value) {
|
|
8208
|
+
const prefix = xmlNamespacePrefix(document.documentElement, work_docx_run_border_export_WORD_NAMESPACE) ?? 'w';
|
|
8209
|
+
element.setAttributeNS(work_docx_run_border_export_WORD_NAMESPACE, `${prefix}:${name}`, value);
|
|
8210
|
+
}
|
|
7831
8211
|
async function createDocxBlob(content, sourcePackage) {
|
|
7832
8212
|
const docx = await import("docx");
|
|
7833
8213
|
const normalizedContent = {
|
|
@@ -7865,8 +8245,13 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
7865
8245
|
runFontPatches: new DocxRunFontsPatchCollector(JSON.stringify(normalizedContent)),
|
|
7866
8246
|
hiddenTextPatches: new DocxHiddenTextPatchCollector(JSON.stringify(normalizedContent)),
|
|
7867
8247
|
legacyTextEffectsPatches: new DocxLegacyTextEffectsPatchCollector(JSON.stringify(normalizedContent)),
|
|
8248
|
+
runBorderPatches: new DocxRunBorderPatchCollector(JSON.stringify(normalizedContent)),
|
|
8249
|
+
usedRunBorderMarkers: new Set(),
|
|
8250
|
+
runShadingPatches: new DocxRunShadingPatchCollector(JSON.stringify(normalizedContent)),
|
|
8251
|
+
usedRunShadingMarkers: new Set(),
|
|
7868
8252
|
usedNativeTextEffectMarkers: new Set(),
|
|
7869
8253
|
paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
|
|
8254
|
+
tableOfContentsPatches: new DocxTableOfContentsPatchCollector(),
|
|
7870
8255
|
hasExplicitZeroCharacterSpacing: false,
|
|
7871
8256
|
hasExplicitZeroKerningThreshold: false
|
|
7872
8257
|
};
|
|
@@ -7920,7 +8305,9 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
7920
8305
|
const runFontsPatched = await patchDocxRunFonts(kerningPatched, noteContext.runFontPatches.patches);
|
|
7921
8306
|
const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
|
|
7922
8307
|
const legacyTextEffectsPatched = await patchDocxLegacyTextEffects(hiddenTextPatched, noteContext.legacyTextEffectsPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
|
|
7923
|
-
const
|
|
8308
|
+
const runBordersPatched = await patchDocxRunBorders(legacyTextEffectsPatched, noteContext.runBorderPatches.patches.filter((patch)=>noteContext.usedRunBorderMarkers.has(patch.marker)));
|
|
8309
|
+
const runShadingPatched = await patchDocxRunShading(runBordersPatched, noteContext.runShadingPatches.patches.filter((patch)=>noteContext.usedRunShadingMarkers.has(patch.marker)));
|
|
8310
|
+
const formattingChangesPatched = await patchDocxRunFormattingChanges(runShadingPatched, noteContext.formattingChangePatches.patches);
|
|
7924
8311
|
const noteImageRelationshipsPatched = await patchDocxNoteImageRelationships(formattingChangesPatched);
|
|
7925
8312
|
const commentMetadataPatched = await patchDocxCommentMetadata(noteImageRelationshipsPatched, commentThreads);
|
|
7926
8313
|
const numberingPatched = await patchDocxNumberingRestartRules(commentMetadataPatched, noteContext.numberingRestartRules);
|
|
@@ -7935,7 +8322,8 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
7935
8322
|
const bookmarkPatched = await patchDocxBookmarks(imageIdentityPatched, noteContext.bookmarkPatches.patches);
|
|
7936
8323
|
const paragraphDefaultCollapsedPatched = await patchDocxParagraphDefaultCollapsed(bookmarkPatched, noteContext.paragraphDefaultCollapsedPatches.patches);
|
|
7937
8324
|
const paragraphIdentityPatched = await patchDocxParagraphIdentities(paragraphDefaultCollapsedPatched, noteContext.paragraphIdentityPatches.patches);
|
|
7938
|
-
const
|
|
8325
|
+
const tableOfContentsPatched = await patchDocxTableOfContents(paragraphIdentityPatched, noteContext.tableOfContentsPatches.patches);
|
|
8326
|
+
const paragraphFormattingChangesPatched = await patchDocxParagraphFormattingChanges(tableOfContentsPatched, noteContext.paragraphFormattingChangePatches.patches);
|
|
7939
8327
|
const equationPatched = await patchDocxEquations(paragraphFormattingChangesPatched, noteContext.equationPatches.patches);
|
|
7940
8328
|
const patched = await patchDocxPageColor(equationPatched, normalizedContent.pageColor);
|
|
7941
8329
|
const preserved = sourcePackage ? await preserveDocxSourcePackage(patched, sourcePackage, {
|
|
@@ -8001,6 +8389,14 @@ function markDocxNativeTextEffectStyleUsed(style, context) {
|
|
|
8001
8389
|
break;
|
|
8002
8390
|
}
|
|
8003
8391
|
}
|
|
8392
|
+
function markDocxRunBorderUsed(border, context) {
|
|
8393
|
+
const marker = border?.color?.toUpperCase();
|
|
8394
|
+
if (context.runBorderPatches.hasMarker(marker)) context.usedRunBorderMarkers.add(marker);
|
|
8395
|
+
}
|
|
8396
|
+
function markDocxRunShadingUsed(shading, context) {
|
|
8397
|
+
const marker = shading?.fill?.toUpperCase();
|
|
8398
|
+
if (context.runShadingPatches.hasMarker(marker)) context.usedRunShadingMarkers.add(marker);
|
|
8399
|
+
}
|
|
8004
8400
|
function work_docx_export_sectionProperties(layout, docx) {
|
|
8005
8401
|
const landscape = 'landscape' === layout.orientation;
|
|
8006
8402
|
const dimensions = documentPageGeometryForLayout(layout);
|
|
@@ -8098,6 +8494,9 @@ async function blockToFileChildren(element, docx, noteContext) {
|
|
|
8098
8494
|
if (element.hasAttribute('data-document-bibliography')) return [
|
|
8099
8495
|
docxBibliographyParagraph(element, docx, paragraphBidirectional(element))
|
|
8100
8496
|
];
|
|
8497
|
+
if (element.hasAttribute('data-document-table-of-contents')) return [
|
|
8498
|
+
docxTableOfContents(element, docx, noteContext.tableOfContentsPatches)
|
|
8499
|
+
];
|
|
8101
8500
|
if (element.hasAttribute('data-document-caption')) return [
|
|
8102
8501
|
docxCaptionParagraph(element, await paragraphRuns(element, docx, noteContext), docx, paragraphBidirectional(element))
|
|
8103
8502
|
];
|
|
@@ -8171,6 +8570,8 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8171
8570
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
8172
8571
|
if (!node.textContent) return [];
|
|
8173
8572
|
markDocxNativeTextEffectStyleUsed(inherited.style, noteContext);
|
|
8573
|
+
markDocxRunBorderUsed(inherited.border, noteContext);
|
|
8574
|
+
markDocxRunShadingUsed(inherited.shading, noteContext);
|
|
8174
8575
|
if (revision?.kind === 'insertion') return [
|
|
8175
8576
|
new docx.InsertedTextRun({
|
|
8176
8577
|
...inherited,
|
|
@@ -8228,19 +8629,32 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8228
8629
|
const formattingChange = node.hasAttribute('data-document-change') && 'formatting' === node.dataset.changeKind ? noteContext.formattingChangePatches.register(node, docxRevisionId(node, noteContext)) : null;
|
|
8229
8630
|
const commentBoundary = node.hasAttribute('data-document-comment') ? nextDocxCommentBoundary(node.dataset.commentId, noteContext) : null;
|
|
8230
8631
|
const backgroundColor = cssColorToHex(node.style.backgroundColor);
|
|
8632
|
+
const hasExplicitRunShading = 'span' === tag && node.hasAttribute(DOCUMENT_RUN_SHADING_ATTRIBUTE);
|
|
8633
|
+
const explicitRunShading = hasExplicitRunShading ? parseDocumentRunShadingElement(node) : null;
|
|
8634
|
+
if (hasExplicitRunShading && !explicitRunShading) throw new Error('Document contains invalid character shading.');
|
|
8635
|
+
const hasHighlightSemantics = node.hasAttribute(DOCUMENT_HIGHLIGHT_ATTRIBUTE) || node.hasAttribute('data-color') || 'mark' === tag || Boolean(backgroundColor) && !hasExplicitRunShading;
|
|
8636
|
+
const explicitHighlight = hasHighlightSemantics ? documentHighlightFromElement(node) : null;
|
|
8231
8637
|
const direction = domDirection(node);
|
|
8232
8638
|
const resolvedColor = cssColorToHex(node.style.color) ?? inherited.color;
|
|
8233
8639
|
const themeColorMarker = noteContext.themePatches.marker('color', parseDocxThemeReference(node.dataset.officeThemeColor), resolvedColor ? `#${resolvedColor}` : null);
|
|
8234
|
-
const
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8640
|
+
const runShading = explicitRunShading ? documentRunShadingDocxOptions(explicitRunShading, noteContext.runShadingPatches).shading : void 0;
|
|
8641
|
+
const customHighlightFill = hasHighlightSemantics && !explicitHighlight ? backgroundColor : null;
|
|
8642
|
+
const resolvedShading = runShading ?? (customHighlightFill ? {
|
|
8643
|
+
fill: customHighlightFill
|
|
8644
|
+
} : inherited.shading);
|
|
8645
|
+
const themeFillMarker = !runShading && customHighlightFill ? noteContext.themePatches.marker('fill', parseDocxThemeReference(node.dataset.officeThemeFill), `#${customHighlightFill}`) : null;
|
|
8238
8646
|
const explicitTextCase = normalizeDocumentTextCase(node.dataset.officeTextCase);
|
|
8239
8647
|
const explicitCharacterSpacing = documentCharacterSpacingTwipsFromElement(node);
|
|
8240
8648
|
const explicitCharacterScale = documentCharacterScalePercentFromElement(node);
|
|
8241
8649
|
const explicitKerningThreshold = documentKerningThresholdHalfPointsFromElement(node);
|
|
8242
8650
|
const explicitEmphasisMark = documentEmphasisMarkFromElement(node);
|
|
8243
8651
|
const explicitHiddenText = documentHiddenTextFromElement(node);
|
|
8652
|
+
const hasExplicitProofingLanguages = 'span' === tag && node.hasAttribute(DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE);
|
|
8653
|
+
const explicitProofingLanguages = hasExplicitProofingLanguages ? documentProofingLanguagesFromElement(node) : null;
|
|
8654
|
+
if (hasExplicitProofingLanguages && !explicitProofingLanguages) throw new Error('Document contains invalid proofing languages.');
|
|
8655
|
+
const hasExplicitNoProof = 'span' === tag && node.hasAttribute(DOCUMENT_NO_PROOF_ATTRIBUTE);
|
|
8656
|
+
const explicitNoProof = hasExplicitNoProof ? documentNoProofFromElement(node) : null;
|
|
8657
|
+
if (hasExplicitNoProof && null === explicitNoProof) throw new Error('Document contains invalid proofing state.');
|
|
8244
8658
|
const hasExplicitLegacyTextEffects = 'span' === tag && [
|
|
8245
8659
|
DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE,
|
|
8246
8660
|
DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE,
|
|
@@ -8250,6 +8664,9 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8250
8664
|
const explicitLegacyTextEffects = hasExplicitLegacyTextEffects ? documentLegacyTextEffectsFromElement(node) : {};
|
|
8251
8665
|
if (hasExplicitLegacyTextEffects && !explicitLegacyTextEffects) throw new Error('Document contains invalid legacy text effects.');
|
|
8252
8666
|
const explicitCharacterPosition = documentCharacterPositionHalfPointsFromElement(node);
|
|
8667
|
+
const hasExplicitRunBorder = 'span' === tag && (node.hasAttribute(DOCUMENT_RUN_BORDER_ATTRIBUTE) || Boolean(node.style.borderStyle));
|
|
8668
|
+
const explicitRunBorder = hasExplicitRunBorder ? parseDocumentRunBorderElement(node) : null;
|
|
8669
|
+
if (hasExplicitRunBorder && !explicitRunBorder) throw new Error('Document contains an invalid character border.');
|
|
8253
8670
|
if (0 === explicitCharacterSpacing) noteContext.hasExplicitZeroCharacterSpacing = true;
|
|
8254
8671
|
if (0 === explicitKerningThreshold) noteContext.hasExplicitZeroKerningThreshold = true;
|
|
8255
8672
|
const characterSpacing = null === explicitCharacterSpacing ? inherited.characterSpacing : docxCharacterSpacingValue(explicitCharacterSpacing);
|
|
@@ -8274,6 +8691,9 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8274
8691
|
const underline = docxUnderlineRunOptions(node, inherited.underline, noteContext.themePatches);
|
|
8275
8692
|
const strike = docxStrikeRunOptions(node, inherited);
|
|
8276
8693
|
const scriptFontMarker = noteContext.runFontPatches.marker(documentScriptFontsFromElement(node), documentScriptFontSlotFromElement(node), node.style.fontFamily);
|
|
8694
|
+
const runBorder = explicitRunBorder ? documentRunBorderDocxOptions(explicitRunBorder, noteContext.runBorderPatches).border : inherited.border;
|
|
8695
|
+
const language = hasExplicitProofingLanguages ? documentProofingLanguageDocxOptions(explicitProofingLanguages) : inherited.language;
|
|
8696
|
+
const noProof = hasExplicitNoProof ? explicitNoProof ?? false : inherited.noProof;
|
|
8277
8697
|
const style = {
|
|
8278
8698
|
...inherited,
|
|
8279
8699
|
style: nativeTextEffectStyle,
|
|
@@ -8293,15 +8713,21 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8293
8713
|
kern,
|
|
8294
8714
|
position,
|
|
8295
8715
|
emphasisMark,
|
|
8716
|
+
language,
|
|
8717
|
+
noProof,
|
|
8718
|
+
border: runBorder,
|
|
8296
8719
|
shading: themeFillMarker ? {
|
|
8297
8720
|
fill: themeFillMarker
|
|
8298
8721
|
} : resolvedShading,
|
|
8722
|
+
highlight: hasHighlightSemantics ? explicitHighlight ?? (customHighlightFill ? 'none' : void 0) : inherited.highlight,
|
|
8299
8723
|
snapToGrid: dataBoolean(node.dataset.officeWordSnapToGrid) ?? inherited.snapToGrid,
|
|
8300
8724
|
rightToLeft: void 0 === direction ? inherited.rightToLeft : 'rtl' === direction,
|
|
8301
8725
|
...textCaseOptions
|
|
8302
8726
|
};
|
|
8303
8727
|
if ('br' === tag) {
|
|
8304
8728
|
markDocxNativeTextEffectStyleUsed(style.style, noteContext);
|
|
8729
|
+
markDocxRunBorderUsed(style.border, noteContext);
|
|
8730
|
+
markDocxRunShadingUsed(style.shading, noteContext);
|
|
8305
8731
|
return [
|
|
8306
8732
|
new docx.TextRun({
|
|
8307
8733
|
...style,
|