@a3s-lab/office 0.29.0 → 0.31.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 +117 -3
- package/dist/{0~7043.js → 0~4808.js} +347 -2
- package/dist/0~5050.js +10 -1
- package/dist/{0~5093.js → 0~7240.js} +465 -55
- package/dist/0~document-editor.js +1694 -187
- package/dist/0~spreadsheet-editor.js +183 -34
- package/dist/0~work-docx-export.js +507 -31
- package/dist/0~work-docx-import.js +41 -7
- package/dist/0~work-office-diagnostics.js +146 -5
- package/dist/1544.js +13 -1
- package/dist/4104.js +29 -6
- package/dist/4121.js +2340 -1
- package/dist/6282.js +1072 -1148
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +45 -0
- package/dist/internal/features/work/editors/document-dom-selection.d.ts +7 -0
- package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +5 -2
- package/dist/internal/features/work/editors/document-font-dialog-run-shading-model.d.ts +23 -0
- package/dist/internal/features/work/editors/document-font-dialog-run-shading-section.d.ts +8 -0
- package/dist/internal/features/work/editors/document-index-dialog.d.ts +10 -0
- package/dist/internal/features/work/editors/document-index-entry-dialog.d.ts +10 -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-references-ribbon.d.ts +19 -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 +6 -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 +5 -0
- package/dist/internal/features/work/work-document-character-formatting.d.ts +8 -0
- package/dist/internal/features/work/work-document-format-changes.d.ts +6 -0
- package/dist/internal/features/work/work-document-highlight.d.ts +9 -0
- package/dist/internal/features/work/work-document-index-fields.d.ts +19 -0
- package/dist/internal/features/work/work-document-index-nodes.d.ts +32 -0
- package/dist/internal/features/work/work-document-index.d.ts +63 -0
- package/dist/internal/features/work/work-document-outline.d.ts +1 -0
- package/dist/internal/features/work/work-document-paragraph-shading.d.ts +6 -0
- package/dist/internal/features/work/work-document-proofing.d.ts +19 -0
- package/dist/internal/features/work/work-document-run-shading.d.ts +12 -0
- package/dist/internal/features/work/work-document-table-of-contents-node.d.ts +18 -0
- package/dist/internal/features/work/work-document-table-of-contents.d.ts +51 -0
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-field-instructions.d.ts +1 -1
- package/dist/internal/features/work/work-docx-import.d.ts +5 -1
- package/dist/internal/features/work/work-docx-index-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-index-import.d.ts +23 -0
- package/dist/internal/features/work/work-docx-proofing-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-proofing.d.ts +38 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +7 -0
- package/dist/internal/features/work/work-docx-run-shading-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-shading-export.d.ts +17 -0
- package/dist/internal/features/work/work-docx-run-shading.d.ts +20 -0
- package/dist/internal/features/work/work-docx-table-of-contents-export.d.ts +11 -0
- package/dist/internal/features/work/work-docx-table-of-contents-import.d.ts +15 -0
- package/dist/internal/features/work/work-spreadsheet-data-validation.d.ts +7 -0
- package/dist/internal/features/work/work-types.d.ts +9 -0
- package/dist/internal/kernel/office-kernel-protocol.d.ts +1 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +607 -4
- package/docs/latest/en/browser-editor-architecture.md +64 -1
- package/package.json +15 -2
|
@@ -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 { normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES,
|
|
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, normalizeDocumentIndexesHtml, parseXml, parseDocumentRunShading, applyDocumentParagraphIdentityToElement, DOCUMENT_RUN_SHADING_ATTRIBUTE, documentScriptFontSlotFromElement, DOCUMENT_HIGHLIGHT_ATTRIBUTE, parseDocxThemeReference, 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, documentIndexValueFromElement, descendants, resolvePartTarget, documentProofingLanguagesFromElement, documentScriptFontFamily, parseDocumentRunShadingElement, parseDocumentProofingLanguages, documentHighlightFromElement, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, parseDocumentRunBorderElement, xmlNamespacePrefix, documentScriptFontSlotFromHint, documentNoProofFromElement, documentScriptFontsFromElement, normalizeDocumentRunShading, documentIndexEntryFromElement, directChild, normalizeDocumentScriptFontSlot, patchDocxThemeReferences, parseDocumentParagraphShadingElement, documentFontNameFromCssFamily } from "./4121.js";
|
|
4
4
|
import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.js";
|
|
5
|
-
import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue,
|
|
5
|
+
import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue, documentIndexInstruction, docxCharacterScaleValue, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, xmlNamespaceUri, paragraphSpacingOptions, docxEmphasisMarkRunOptions, documentIndexEntryInstruction, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, xmlDeclaredPrefix, assertXmlRoot, DOCX_WORDPROCESSING_NAMESPACES, paragraphIndent, domDirection, xmlAttributeNamespace, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, mergeDocxIgnorableExtensions, DocxParagraphDefaultCollapsedPatchCollector, dataBoolean, patchDocxParagraphDefaultCollapsed, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, documentProofingLanguageDocxOptions, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~4808.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,292 @@ 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_index_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2378
|
+
const work_docx_index_export_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
2379
|
+
class DocxIndexPatchCollector {
|
|
2380
|
+
patches = [];
|
|
2381
|
+
add(element) {
|
|
2382
|
+
const value = documentIndexValueFromElement(element);
|
|
2383
|
+
const patch = {
|
|
2384
|
+
marker: `__A3S_WORK_DOCUMENT_INDEX_${this.patches.length + 1}__`,
|
|
2385
|
+
options: value.options,
|
|
2386
|
+
entries: value.entries
|
|
2387
|
+
};
|
|
2388
|
+
this.patches.push(patch);
|
|
2389
|
+
return patch;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
function docxDocumentIndex(element, docx, collector) {
|
|
2393
|
+
const patch = collector.add(element);
|
|
2394
|
+
return [
|
|
2395
|
+
new docx.Paragraph({
|
|
2396
|
+
children: [
|
|
2397
|
+
new docx.TextRun(patch.marker)
|
|
2398
|
+
]
|
|
2399
|
+
})
|
|
2400
|
+
];
|
|
2401
|
+
}
|
|
2402
|
+
function docxIndexEntryRun(element, docx) {
|
|
2403
|
+
const value = documentIndexEntryFromElement(element);
|
|
2404
|
+
return value ? new docx.SimpleField(documentIndexEntryInstruction(value)) : null;
|
|
2405
|
+
}
|
|
2406
|
+
async function patchDocxIndexes(buffer, patches) {
|
|
2407
|
+
if (!patches.length) return buffer;
|
|
2408
|
+
const archive = await jszip.loadAsync(buffer);
|
|
2409
|
+
const entry = archive.file('word/document.xml');
|
|
2410
|
+
if (!entry) return buffer;
|
|
2411
|
+
const document = parseXml(await entry.async('text'), 'generated DOCX word/document.xml');
|
|
2412
|
+
const paragraphs = descendants(document, 'p');
|
|
2413
|
+
for (const patch of patches){
|
|
2414
|
+
const paragraph = paragraphs.find((candidate)=>descendants(candidate, 't').some((text)=>(text.textContent ?? '').includes(patch.marker)));
|
|
2415
|
+
if (!paragraph) throw new Error(`Generated DOCX did not emit the marker for document index ${patch.marker}.`);
|
|
2416
|
+
paragraph.replaceWith(createIndexContentControl(document, patch));
|
|
2417
|
+
}
|
|
2418
|
+
archive.file('word/document.xml', new XMLSerializer().serializeToString(document));
|
|
2419
|
+
return archive.generateAsync({
|
|
2420
|
+
type: 'arraybuffer'
|
|
2421
|
+
});
|
|
2422
|
+
}
|
|
2423
|
+
function createIndexContentControl(document, patch) {
|
|
2424
|
+
const control = wordElement(document, 'sdt');
|
|
2425
|
+
const properties = wordElement(document, 'sdtPr');
|
|
2426
|
+
const documentPart = wordElement(document, 'docPartObj');
|
|
2427
|
+
const gallery = wordElement(document, 'docPartGallery');
|
|
2428
|
+
work_docx_index_export_setWordAttribute(document, gallery, 'val', 'Indexes');
|
|
2429
|
+
documentPart.append(gallery, wordElement(document, 'docPartUnique'));
|
|
2430
|
+
properties.append(documentPart);
|
|
2431
|
+
const content = wordElement(document, 'sdtContent');
|
|
2432
|
+
const fieldStart = indexFieldStartParagraph(document, patch.options);
|
|
2433
|
+
content.append(fieldStart);
|
|
2434
|
+
const cached = cachedIndexParagraphs(document, patch);
|
|
2435
|
+
if (!cached.length) cached.push(emptyIndexParagraph(document));
|
|
2436
|
+
const last = cached.at(-1);
|
|
2437
|
+
last?.append(fieldCharacterRun(document, 'end'));
|
|
2438
|
+
content.append(...cached);
|
|
2439
|
+
control.append(properties, content);
|
|
2440
|
+
return control;
|
|
2441
|
+
}
|
|
2442
|
+
function indexFieldStartParagraph(document, options) {
|
|
2443
|
+
const paragraph = wordElement(document, 'p');
|
|
2444
|
+
paragraph.append(fieldCharacterRun(document, 'begin'));
|
|
2445
|
+
const instructionRun = wordElement(document, 'r');
|
|
2446
|
+
const instruction = wordElement(document, 'instrText');
|
|
2447
|
+
instruction.setAttributeNS(work_docx_index_export_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
2448
|
+
instruction.textContent = ` ${documentIndexInstruction(options)} `;
|
|
2449
|
+
instructionRun.append(instruction);
|
|
2450
|
+
paragraph.append(instructionRun, fieldCharacterRun(document, 'separate'));
|
|
2451
|
+
return paragraph;
|
|
2452
|
+
}
|
|
2453
|
+
function cachedIndexParagraphs(document, patch) {
|
|
2454
|
+
const paragraphs = [];
|
|
2455
|
+
let currentMain = '';
|
|
2456
|
+
for (const entry of patch.entries){
|
|
2457
|
+
if (entry.subEntry && entry.mainEntry !== currentMain) paragraphs.push(cachedIndexParagraph(document, patch.options, {
|
|
2458
|
+
style: 'Index1',
|
|
2459
|
+
term: entry.mainEntry,
|
|
2460
|
+
crossReference: '',
|
|
2461
|
+
pages: []
|
|
2462
|
+
}));
|
|
2463
|
+
paragraphs.push(cachedIndexParagraph(document, patch.options, {
|
|
2464
|
+
style: entry.subEntry ? 'Index2' : 'Index1',
|
|
2465
|
+
term: entry.subEntry || entry.mainEntry,
|
|
2466
|
+
crossReference: entry.crossReference,
|
|
2467
|
+
pages: entry.pages
|
|
2468
|
+
}));
|
|
2469
|
+
currentMain = entry.mainEntry;
|
|
2470
|
+
}
|
|
2471
|
+
return paragraphs;
|
|
2472
|
+
}
|
|
2473
|
+
function cachedIndexParagraph(document, options, source) {
|
|
2474
|
+
const paragraph = wordElement(document, 'p');
|
|
2475
|
+
const properties = wordElement(document, 'pPr');
|
|
2476
|
+
const style = wordElement(document, 'pStyle');
|
|
2477
|
+
work_docx_index_export_setWordAttribute(document, style, 'val', source.style);
|
|
2478
|
+
properties.append(style);
|
|
2479
|
+
if (source.pages.length && options.rightAlignPageNumbers) {
|
|
2480
|
+
const tabs = wordElement(document, 'tabs');
|
|
2481
|
+
const tab = wordElement(document, 'tab');
|
|
2482
|
+
work_docx_index_export_setWordAttribute(document, tab, 'val', 'right');
|
|
2483
|
+
const leader = docxIndexLeader(options.leader);
|
|
2484
|
+
if (leader) work_docx_index_export_setWordAttribute(document, tab, 'leader', leader);
|
|
2485
|
+
work_docx_index_export_setWordAttribute(document, tab, 'pos', '9360');
|
|
2486
|
+
tabs.append(tab);
|
|
2487
|
+
properties.append(tabs);
|
|
2488
|
+
}
|
|
2489
|
+
paragraph.append(properties, textRun(document, source.term));
|
|
2490
|
+
if (source.crossReference) {
|
|
2491
|
+
paragraph.append(textRun(document, `, See ${source.crossReference}`));
|
|
2492
|
+
return paragraph;
|
|
2493
|
+
}
|
|
2494
|
+
if (!source.pages.length) return paragraph;
|
|
2495
|
+
paragraph.append(options.rightAlignPageNumbers ? tabRun(document) : textRun(document, ', '));
|
|
2496
|
+
for (const [index, page] of source.pages.entries()){
|
|
2497
|
+
if (index > 0) paragraph.append(textRun(document, ', '));
|
|
2498
|
+
paragraph.append(textRun(document, String(page.pageNumber), {
|
|
2499
|
+
bold: page.pageBold,
|
|
2500
|
+
italic: page.pageItalic
|
|
2501
|
+
}));
|
|
2502
|
+
}
|
|
2503
|
+
return paragraph;
|
|
2504
|
+
}
|
|
2505
|
+
function emptyIndexParagraph(document) {
|
|
2506
|
+
const paragraph = wordElement(document, 'p');
|
|
2507
|
+
const properties = wordElement(document, 'pPr');
|
|
2508
|
+
const style = wordElement(document, 'pStyle');
|
|
2509
|
+
work_docx_index_export_setWordAttribute(document, style, 'val', 'Index1');
|
|
2510
|
+
properties.append(style);
|
|
2511
|
+
paragraph.append(properties);
|
|
2512
|
+
return paragraph;
|
|
2513
|
+
}
|
|
2514
|
+
function textRun(document, value, style = {}) {
|
|
2515
|
+
const run = wordElement(document, 'r');
|
|
2516
|
+
if (style.bold || style.italic) {
|
|
2517
|
+
const properties = wordElement(document, 'rPr');
|
|
2518
|
+
if (style.bold) properties.append(wordElement(document, 'b'));
|
|
2519
|
+
if (style.italic) properties.append(wordElement(document, 'i'));
|
|
2520
|
+
run.append(properties);
|
|
2521
|
+
}
|
|
2522
|
+
const text = wordElement(document, 't');
|
|
2523
|
+
if (/^\s|\s$/.test(value)) text.setAttributeNS(work_docx_index_export_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
2524
|
+
text.textContent = value;
|
|
2525
|
+
run.append(text);
|
|
2526
|
+
return run;
|
|
2527
|
+
}
|
|
2528
|
+
function tabRun(document) {
|
|
2529
|
+
const run = wordElement(document, 'r');
|
|
2530
|
+
run.append(wordElement(document, 'tab'));
|
|
2531
|
+
return run;
|
|
2532
|
+
}
|
|
2533
|
+
function fieldCharacterRun(document, type) {
|
|
2534
|
+
const run = wordElement(document, 'r');
|
|
2535
|
+
const character = wordElement(document, 'fldChar');
|
|
2536
|
+
work_docx_index_export_setWordAttribute(document, character, 'fldCharType', type);
|
|
2537
|
+
run.append(character);
|
|
2538
|
+
return run;
|
|
2539
|
+
}
|
|
2540
|
+
function docxIndexLeader(value) {
|
|
2541
|
+
if ('dash' === value) return 'hyphen';
|
|
2542
|
+
if ('underline' === value) return 'underscore';
|
|
2543
|
+
if ('dot' === value) return 'dot';
|
|
2544
|
+
return null;
|
|
2545
|
+
}
|
|
2546
|
+
function wordElement(document, localName) {
|
|
2547
|
+
return document.createElementNS(work_docx_index_export_WORD_NAMESPACE, wordQualifiedName(document.documentElement, localName));
|
|
2548
|
+
}
|
|
2549
|
+
function work_docx_index_export_setWordAttribute(document, element, localName, value) {
|
|
2550
|
+
for (const candidate of Array.from(element.attributes))if (candidate.localName === localName && (candidate.namespaceURI === work_docx_index_export_WORD_NAMESPACE || !candidate.namespaceURI)) element.removeAttributeNode(candidate);
|
|
2551
|
+
element.setAttributeNS(work_docx_index_export_WORD_NAMESPACE, wordQualifiedName(document.documentElement, localName), value);
|
|
2552
|
+
}
|
|
2553
|
+
function wordQualifiedName(root, localName) {
|
|
2554
|
+
return `${xmlNamespacePrefix(root, work_docx_index_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
|
|
2555
|
+
}
|
|
2556
|
+
const work_docx_run_shading_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
2557
|
+
class DocxRunShadingPatchCollector {
|
|
2558
|
+
patches = [];
|
|
2559
|
+
nextMarker = 1;
|
|
2560
|
+
usedColors;
|
|
2561
|
+
constructor(sourceHtml){
|
|
2562
|
+
this.usedColors = work_docx_run_shading_export_sourceColors(sourceHtml);
|
|
2563
|
+
}
|
|
2564
|
+
marker(source) {
|
|
2565
|
+
const shading = normalizeDocumentRunShading(source);
|
|
2566
|
+
if (!shading) return null;
|
|
2567
|
+
let marker = '';
|
|
2568
|
+
do {
|
|
2569
|
+
const value = 0xd00000 + this.nextMarker;
|
|
2570
|
+
if (value > 0xdfffff) throw new Error('DOCX character shading marker space is exhausted.');
|
|
2571
|
+
marker = value.toString(16).padStart(6, '0').toUpperCase();
|
|
2572
|
+
this.nextMarker += 1;
|
|
2573
|
+
}while (this.usedColors.has(marker))
|
|
2574
|
+
this.usedColors.add(marker);
|
|
2575
|
+
this.patches.push({
|
|
2576
|
+
marker,
|
|
2577
|
+
shading
|
|
2578
|
+
});
|
|
2579
|
+
return marker;
|
|
2580
|
+
}
|
|
2581
|
+
hasMarker(value) {
|
|
2582
|
+
const marker = value?.toUpperCase();
|
|
2583
|
+
return Boolean(marker && this.patches.some((patch)=>patch.marker === marker));
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
function documentRunShadingDocxOptions(source, collector) {
|
|
2587
|
+
const marker = collector.marker(source);
|
|
2588
|
+
return marker ? {
|
|
2589
|
+
shading: {
|
|
2590
|
+
type: 'clear',
|
|
2591
|
+
color: 'auto',
|
|
2592
|
+
fill: marker
|
|
2593
|
+
}
|
|
2594
|
+
} : {};
|
|
2595
|
+
}
|
|
2596
|
+
async function patchDocxRunShading(buffer, patches) {
|
|
2597
|
+
if (!patches.length) return buffer;
|
|
2598
|
+
const archive = await jszip.loadAsync(buffer);
|
|
2599
|
+
const byMarker = new Map(patches.map((patch)=>[
|
|
2600
|
+
patch.marker,
|
|
2601
|
+
patch
|
|
2602
|
+
]));
|
|
2603
|
+
const applied = new Set();
|
|
2604
|
+
for (const entry of Object.values(archive.files)){
|
|
2605
|
+
if (entry.dir || !/^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/i.test(entry.name)) continue;
|
|
2606
|
+
const document = parseXml(await entry.async('text'), entry.name);
|
|
2607
|
+
let changed = false;
|
|
2608
|
+
for (const element of Array.from(document.getElementsByTagName('*'))){
|
|
2609
|
+
if ('shd' !== element.localName || element.namespaceURI !== work_docx_run_shading_export_WORD_NAMESPACE || element.parentElement?.localName !== 'rPr') continue;
|
|
2610
|
+
const marker = work_docx_run_shading_export_wordAttribute(element, 'fill')?.toUpperCase();
|
|
2611
|
+
const patch = marker ? byMarker.get(marker) : void 0;
|
|
2612
|
+
if (marker && patch) {
|
|
2613
|
+
replaceRunShadingAttributes(document, element, patch.shading);
|
|
2614
|
+
applied.add(marker);
|
|
2615
|
+
changed = true;
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
if (changed) archive.file(entry.name, serializeUtf8Xml(document));
|
|
2619
|
+
}
|
|
2620
|
+
const missing = patches.filter((patch)=>!applied.has(patch.marker));
|
|
2621
|
+
if (missing.length) throw new Error(`Generated DOCX is missing ${missing.length} character shading marker(s).`);
|
|
2622
|
+
return archive.generateAsync({
|
|
2623
|
+
type: 'arraybuffer'
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
function setDocxRunShadingAttributes(document, element, source) {
|
|
2627
|
+
const shading = normalizeDocumentRunShading(source);
|
|
2628
|
+
if (!shading) return false;
|
|
2629
|
+
work_docx_run_shading_export_setWordAttribute(document, element, 'val', shading.pattern);
|
|
2630
|
+
setShadingColorAttributes(document, element, shading.color, 'color');
|
|
2631
|
+
setShadingColorAttributes(document, element, shading.fill, 'fill');
|
|
2632
|
+
return true;
|
|
2633
|
+
}
|
|
2634
|
+
function replaceRunShadingAttributes(document, element, shading) {
|
|
2635
|
+
for (const attribute of Array.from(element.attributes))if ('xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:')) element.removeAttributeNode(attribute);
|
|
2636
|
+
element.replaceChildren();
|
|
2637
|
+
setDocxRunShadingAttributes(document, element, shading);
|
|
2638
|
+
}
|
|
2639
|
+
function setShadingColorAttributes(document, element, color, kind) {
|
|
2640
|
+
if (!color) return;
|
|
2641
|
+
work_docx_run_shading_export_setWordAttribute(document, element, kind, 'auto' === color.value ? 'auto' : color.value.slice(1).toUpperCase());
|
|
2642
|
+
if (!color.theme) return;
|
|
2643
|
+
const themeName = 'color' === kind ? 'themeColor' : 'themeFill';
|
|
2644
|
+
const tintName = 'color' === kind ? 'themeTint' : 'themeFillTint';
|
|
2645
|
+
const shadeName = 'color' === kind ? 'themeShade' : 'themeFillShade';
|
|
2646
|
+
work_docx_run_shading_export_setWordAttribute(document, element, themeName, color.theme.theme);
|
|
2647
|
+
if (color.theme.tint) work_docx_run_shading_export_setWordAttribute(document, element, tintName, color.theme.tint);
|
|
2648
|
+
if (color.theme.shade) work_docx_run_shading_export_setWordAttribute(document, element, shadeName, color.theme.shade);
|
|
2649
|
+
}
|
|
2650
|
+
function work_docx_run_shading_export_sourceColors(source) {
|
|
2651
|
+
const colors = new Set();
|
|
2652
|
+
for (const match of source.matchAll(/#([0-9a-f]{6})\b/gi))if (match[1]) colors.add(match[1].toUpperCase());
|
|
2653
|
+
return colors;
|
|
2654
|
+
}
|
|
2655
|
+
function work_docx_run_shading_export_wordAttribute(element, name) {
|
|
2656
|
+
return element.getAttributeNS(element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE, name) ?? element.getAttribute(`${element.prefix ?? 'w'}:${name}`);
|
|
2657
|
+
}
|
|
2658
|
+
function work_docx_run_shading_export_setWordAttribute(document, element, name, value) {
|
|
2659
|
+
const namespace = element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE;
|
|
2660
|
+
const prefix = element.prefix ?? xmlNamespacePrefix(document.documentElement, namespace) ?? 'w';
|
|
2661
|
+
element.setAttributeNS(namespace, `${prefix}:${name}`, value);
|
|
2662
|
+
}
|
|
2377
2663
|
const MAX_RUN_FORMATTING_CHANGE_PATCHES = 65536;
|
|
2378
2664
|
const RUN_FORMATTING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
|
|
2379
2665
|
class DocxRunFormattingChangePatchCollector {
|
|
@@ -2474,17 +2760,17 @@ function setRunFormattingChange(document, run, patch) {
|
|
|
2474
2760
|
if (existing.length > 1) throw new Error('Generated DOCX run contains duplicate properties.');
|
|
2475
2761
|
const properties = existing[0] ?? insertRunProperties(document, run, wordNamespace, prefix);
|
|
2476
2762
|
if (directChildren(properties, 'rPrChange').some((element)=>element.namespaceURI === wordNamespace)) throw new Error('Generated DOCX run already contains a formatting revision.');
|
|
2477
|
-
const change =
|
|
2763
|
+
const change = work_docx_format_change_export_wordElement(document, wordNamespace, prefix, 'rPrChange');
|
|
2478
2764
|
work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'id', String(patch.id));
|
|
2479
2765
|
work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'author', patch.author);
|
|
2480
2766
|
work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'date', patch.date);
|
|
2481
|
-
const before =
|
|
2767
|
+
const before = work_docx_format_change_export_wordElement(document, wordNamespace, prefix, 'rPr');
|
|
2482
2768
|
appendFormattingProperties(document, before, wordNamespace, prefix, patch.before);
|
|
2483
2769
|
change.append(before);
|
|
2484
2770
|
properties.append(change);
|
|
2485
2771
|
}
|
|
2486
2772
|
function insertRunProperties(document, run, namespace, prefix) {
|
|
2487
|
-
const properties =
|
|
2773
|
+
const properties = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rPr');
|
|
2488
2774
|
run.insertBefore(properties, run.firstChild);
|
|
2489
2775
|
return properties;
|
|
2490
2776
|
}
|
|
@@ -2503,6 +2789,7 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
|
|
|
2503
2789
|
appendTextCaseProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2504
2790
|
appendStrikeProperties(document, properties, namespace, prefix, byType.get('strike'));
|
|
2505
2791
|
appendLegacyTextEffectsProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2792
|
+
appendNoProofProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2506
2793
|
appendSnapToGridProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2507
2794
|
appendHiddenTextProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2508
2795
|
appendColorProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
@@ -2511,16 +2798,33 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
|
|
|
2511
2798
|
appendKerningThresholdProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2512
2799
|
appendCharacterPositionProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2513
2800
|
appendFontSizeProperties(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2514
|
-
appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'));
|
|
2801
|
+
appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'), !parseDocumentRunShading(byType.get('textStyle')?.attrs?.runShading));
|
|
2515
2802
|
appendUnderlineProperty(document, properties, namespace, prefix, byType.get('underline'));
|
|
2516
2803
|
appendRunBorderProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2804
|
+
appendRunShadingProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2517
2805
|
appendVerticalAlignProperty(document, properties, namespace, prefix, byType);
|
|
2518
2806
|
appendEmphasisMarkProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2807
|
+
appendProofingLanguagesProperty(document, properties, namespace, prefix, byType.get('textStyle'));
|
|
2808
|
+
}
|
|
2809
|
+
function appendNoProofProperty(document, properties, namespace, prefix, mark) {
|
|
2810
|
+
const noProof = normalizeDocumentNoProof(mark?.attrs?.noProof);
|
|
2811
|
+
if (null === noProof) return;
|
|
2812
|
+
if (noProof) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'noProof'));
|
|
2813
|
+
else appendValuedProperty(document, properties, namespace, prefix, 'noProof', '0');
|
|
2814
|
+
}
|
|
2815
|
+
function appendProofingLanguagesProperty(document, properties, namespace, prefix, mark) {
|
|
2816
|
+
const languages = parseDocumentProofingLanguages(mark?.attrs?.proofingLanguages);
|
|
2817
|
+
if (!languages) return;
|
|
2818
|
+
const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'lang');
|
|
2819
|
+
if (languages.latin) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', languages.latin);
|
|
2820
|
+
if (languages.eastAsia) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'eastAsia', languages.eastAsia);
|
|
2821
|
+
if (languages.bidi) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'bidi', languages.bidi);
|
|
2822
|
+
properties.append(element);
|
|
2519
2823
|
}
|
|
2520
2824
|
function appendRunBorderProperty(document, properties, namespace, prefix, mark) {
|
|
2521
2825
|
const border = parseDocumentRunBorder(mark?.attrs?.runBorder);
|
|
2522
2826
|
if (!border) return;
|
|
2523
|
-
const element =
|
|
2827
|
+
const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'bdr');
|
|
2524
2828
|
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', border.style);
|
|
2525
2829
|
if (border.color) {
|
|
2526
2830
|
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'color', 'auto' === border.color.value ? 'auto' : border.color.value.slice(1).toUpperCase());
|
|
@@ -2536,6 +2840,13 @@ function appendRunBorderProperty(document, properties, namespace, prefix, mark)
|
|
|
2536
2840
|
if (void 0 !== border.frame) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'frame', border.frame ? '1' : '0');
|
|
2537
2841
|
properties.append(element);
|
|
2538
2842
|
}
|
|
2843
|
+
function appendRunShadingProperty(document, properties, namespace, prefix, mark) {
|
|
2844
|
+
const shading = parseDocumentRunShading(mark?.attrs?.runShading);
|
|
2845
|
+
if (!shading) return;
|
|
2846
|
+
const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'shd');
|
|
2847
|
+
if (!setDocxRunShadingAttributes(document, element, shading)) return;
|
|
2848
|
+
properties.append(element);
|
|
2849
|
+
}
|
|
2539
2850
|
function appendLegacyTextEffectsProperties(document, properties, namespace, prefix, mark) {
|
|
2540
2851
|
const effects = {};
|
|
2541
2852
|
const attributes = [
|
|
@@ -2563,14 +2874,14 @@ function appendLegacyTextEffectsProperties(document, properties, namespace, pref
|
|
|
2563
2874
|
if (documentLegacyTextEffectsConflict(effects)) throw new Error('Document contains conflicting legacy text effects.');
|
|
2564
2875
|
for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES){
|
|
2565
2876
|
const value = effects[name];
|
|
2566
|
-
if (void 0 !== value) if (value) properties.append(
|
|
2877
|
+
if (void 0 !== value) if (value) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, name));
|
|
2567
2878
|
else appendValuedProperty(document, properties, namespace, prefix, name, '0');
|
|
2568
2879
|
}
|
|
2569
2880
|
}
|
|
2570
2881
|
function appendHiddenTextProperty(document, properties, namespace, prefix, mark) {
|
|
2571
2882
|
const hiddenText = normalizeDocumentHiddenText(mark?.attrs?.hiddenText);
|
|
2572
2883
|
if (null === hiddenText) return;
|
|
2573
|
-
if (hiddenText) properties.append(
|
|
2884
|
+
if (hiddenText) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'vanish'));
|
|
2574
2885
|
else appendValuedProperty(document, properties, namespace, prefix, 'vanish', '0');
|
|
2575
2886
|
}
|
|
2576
2887
|
function appendEmphasisMarkProperty(document, properties, namespace, prefix, mark) {
|
|
@@ -2601,7 +2912,7 @@ function appendCharacterSpacingProperty(document, properties, namespace, prefix,
|
|
|
2601
2912
|
function appendFontProperties(document, properties, namespace, prefix, mark) {
|
|
2602
2913
|
const scriptFonts = parseDocumentScriptFonts('string' == typeof mark?.attrs?.scriptFonts ? mark.attrs.scriptFonts : void 0);
|
|
2603
2914
|
if (scriptFonts) {
|
|
2604
|
-
const fonts =
|
|
2915
|
+
const fonts = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rFonts');
|
|
2605
2916
|
for (const [name, value] of [
|
|
2606
2917
|
[
|
|
2607
2918
|
'ascii',
|
|
@@ -2645,7 +2956,7 @@ function appendFontProperties(document, properties, namespace, prefix, mark) {
|
|
|
2645
2956
|
}
|
|
2646
2957
|
const family = firstFontFamily(mark?.attrs?.fontFamily);
|
|
2647
2958
|
if (!family) return;
|
|
2648
|
-
const fonts =
|
|
2959
|
+
const fonts = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rFonts');
|
|
2649
2960
|
for (const name of [
|
|
2650
2961
|
'ascii',
|
|
2651
2962
|
'hAnsi',
|
|
@@ -2659,7 +2970,7 @@ function appendUnderlineProperty(document, properties, namespace, prefix, mark)
|
|
|
2659
2970
|
const style = normalizeDocumentUnderlineStyle(mark.attrs?.underlineStyle) ?? 'single';
|
|
2660
2971
|
const color = normalizedHex(mark.attrs?.underlineColor);
|
|
2661
2972
|
const theme = themeReference(mark.attrs?.underlineThemeColor);
|
|
2662
|
-
const underline =
|
|
2973
|
+
const underline = work_docx_format_change_export_wordElement(document, namespace, prefix, 'u');
|
|
2663
2974
|
work_docx_format_change_export_setWordAttribute(underline, namespace, prefix, 'val', style);
|
|
2664
2975
|
const resolved = color ?? normalizedHex(theme?.resolved);
|
|
2665
2976
|
if (resolved) work_docx_format_change_export_setWordAttribute(underline, namespace, prefix, 'color', resolved);
|
|
@@ -2667,7 +2978,7 @@ function appendUnderlineProperty(document, properties, namespace, prefix, mark)
|
|
|
2667
2978
|
properties.append(underline);
|
|
2668
2979
|
}
|
|
2669
2980
|
function appendBooleanProperty(document, properties, namespace, prefix, marks, mark, property) {
|
|
2670
|
-
if (marks.has(mark)) properties.append(
|
|
2981
|
+
if (marks.has(mark)) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, property));
|
|
2671
2982
|
}
|
|
2672
2983
|
function appendStrikeProperties(document, properties, namespace, prefix, mark) {
|
|
2673
2984
|
if (!mark) return;
|
|
@@ -2676,14 +2987,14 @@ function appendStrikeProperties(document, properties, namespace, prefix, mark) {
|
|
|
2676
2987
|
appendValuedProperty(document, properties, namespace, prefix, 'dstrike', 'double' === style ? '1' : '0');
|
|
2677
2988
|
}
|
|
2678
2989
|
function appendValuedProperty(document, properties, namespace, prefix, property, value) {
|
|
2679
|
-
const element =
|
|
2990
|
+
const element = work_docx_format_change_export_wordElement(document, namespace, prefix, property);
|
|
2680
2991
|
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', value);
|
|
2681
2992
|
properties.append(element);
|
|
2682
2993
|
}
|
|
2683
2994
|
function appendTextCaseProperties(document, properties, namespace, prefix, mark) {
|
|
2684
2995
|
const textCase = mark?.attrs?.textCase;
|
|
2685
|
-
if ('all-caps' === textCase) properties.append(
|
|
2686
|
-
else if ('small-caps' === textCase) properties.append(
|
|
2996
|
+
if ('all-caps' === textCase) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'caps'));
|
|
2997
|
+
else if ('small-caps' === textCase) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'smallCaps'));
|
|
2687
2998
|
else if ('none' === textCase) {
|
|
2688
2999
|
appendValuedProperty(document, properties, namespace, prefix, 'caps', '0');
|
|
2689
3000
|
appendValuedProperty(document, properties, namespace, prefix, 'smallCaps', '0');
|
|
@@ -2693,7 +3004,7 @@ function appendColorProperty(document, properties, namespace, prefix, mark) {
|
|
|
2693
3004
|
const color = normalizedHex(mark?.attrs?.color);
|
|
2694
3005
|
const theme = themeReference(mark?.attrs?.themeColor);
|
|
2695
3006
|
if (!color && !theme) return;
|
|
2696
|
-
const element =
|
|
3007
|
+
const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'color');
|
|
2697
3008
|
work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', color ?? normalizedHex(theme?.resolved) ?? '000000');
|
|
2698
3009
|
if (theme) setThemeAttributes(element, namespace, prefix, theme, 'themeColor');
|
|
2699
3010
|
properties.append(element);
|
|
@@ -2704,11 +3015,14 @@ function appendFontSizeProperties(document, properties, namespace, prefix, mark)
|
|
|
2704
3015
|
appendValuedProperty(document, properties, namespace, prefix, 'sz', String(halfPoints));
|
|
2705
3016
|
appendValuedProperty(document, properties, namespace, prefix, 'szCs', String(halfPoints));
|
|
2706
3017
|
}
|
|
2707
|
-
function appendHighlightProperty(document, properties, namespace, prefix, mark) {
|
|
3018
|
+
function appendHighlightProperty(document, properties, namespace, prefix, mark, allowFallbackShading) {
|
|
3019
|
+
const nativeHighlight = normalizeDocumentHighlight(mark?.attrs?.nativeHighlight) ?? documentHighlightForCssColor(mark?.attrs?.color);
|
|
3020
|
+
if (nativeHighlight) return void appendValuedProperty(document, properties, namespace, prefix, 'highlight', nativeHighlight);
|
|
3021
|
+
if (!allowFallbackShading) return;
|
|
2708
3022
|
const fill = normalizedHex(mark?.attrs?.color);
|
|
2709
3023
|
const theme = themeReference(mark?.attrs?.themeFill);
|
|
2710
3024
|
if (!fill && !theme) return;
|
|
2711
|
-
const shading =
|
|
3025
|
+
const shading = work_docx_format_change_export_wordElement(document, namespace, prefix, 'shd');
|
|
2712
3026
|
work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'val', 'clear');
|
|
2713
3027
|
work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'color', 'auto');
|
|
2714
3028
|
work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'fill', fill ?? normalizedHex(theme?.resolved) ?? 'FFFFFF');
|
|
@@ -2756,7 +3070,7 @@ function normalizedHex(value) {
|
|
|
2756
3070
|
const match = /^#?([0-9a-f]{6})$/i.exec(value.trim());
|
|
2757
3071
|
return match?.[1]?.toUpperCase() ?? null;
|
|
2758
3072
|
}
|
|
2759
|
-
function
|
|
3073
|
+
function work_docx_format_change_export_wordElement(document, namespace, prefix, name) {
|
|
2760
3074
|
return document.createElementNS(namespace, `${prefix}:${name}`);
|
|
2761
3075
|
}
|
|
2762
3076
|
function work_docx_format_change_export_setWordAttribute(element, namespace, prefix, name, value) {
|
|
@@ -3530,10 +3844,10 @@ async function patchDocxNumberingRestartRules(buffer, rules) {
|
|
|
3530
3844
|
if (!definition) continue;
|
|
3531
3845
|
let restart = directChild(definition, 'lvlRestart');
|
|
3532
3846
|
if (!restart) {
|
|
3533
|
-
restart = document.createElementNS(work_docx_numbering_WORD_NAMESPACE,
|
|
3847
|
+
restart = document.createElementNS(work_docx_numbering_WORD_NAMESPACE, work_docx_numbering_wordQualifiedName(document.documentElement, 'lvlRestart'));
|
|
3534
3848
|
definition.insertBefore(restart, directChild(definition, 'pPr') ?? null);
|
|
3535
3849
|
}
|
|
3536
|
-
restart.setAttributeNS(work_docx_numbering_WORD_NAMESPACE,
|
|
3850
|
+
restart.setAttributeNS(work_docx_numbering_WORD_NAMESPACE, work_docx_numbering_wordQualifiedName(document.documentElement, 'val'), String(restartAfterLevel));
|
|
3537
3851
|
}
|
|
3538
3852
|
}
|
|
3539
3853
|
archive.file('word/numbering.xml', new XMLSerializer().serializeToString(document));
|
|
@@ -3541,7 +3855,7 @@ async function patchDocxNumberingRestartRules(buffer, rules) {
|
|
|
3541
3855
|
type: 'arraybuffer'
|
|
3542
3856
|
});
|
|
3543
3857
|
}
|
|
3544
|
-
function
|
|
3858
|
+
function work_docx_numbering_wordQualifiedName(root, localName) {
|
|
3545
3859
|
return `${xmlNamespacePrefix(root, work_docx_numbering_WORD_NAMESPACE) ?? root.prefix ?? 'w'}:${localName}`;
|
|
3546
3860
|
}
|
|
3547
3861
|
const work_docx_paragraph_format_change_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
@@ -3971,6 +4285,127 @@ function docxBorderStyle(style, docx) {
|
|
|
3971
4285
|
function docxColor(color) {
|
|
3972
4286
|
return color.replace(/^#/, '').toUpperCase();
|
|
3973
4287
|
}
|
|
4288
|
+
const work_docx_table_of_contents_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
|
|
4289
|
+
const work_docx_table_of_contents_export_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
|
|
4290
|
+
class DocxTableOfContentsPatchCollector {
|
|
4291
|
+
patches = [];
|
|
4292
|
+
add(element) {
|
|
4293
|
+
const value = documentTableOfContentsValueFromElement(element);
|
|
4294
|
+
const patch = {
|
|
4295
|
+
options: value.options,
|
|
4296
|
+
entries: value.entries
|
|
4297
|
+
};
|
|
4298
|
+
this.patches.push(patch);
|
|
4299
|
+
return patch;
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
function docxTableOfContents(element, docx, collector) {
|
|
4303
|
+
const patch = collector.add(element);
|
|
4304
|
+
const options = patch.options;
|
|
4305
|
+
return new docx.TableOfContents('Table of Contents', {
|
|
4306
|
+
hyperlink: options.hyperlinks,
|
|
4307
|
+
headingStyleRange: `${options.minLevel}-${options.maxLevel}`,
|
|
4308
|
+
pageNumbersEntryLevelsRange: options.showPageNumbers ? void 0 : `${options.minLevel}-${options.maxLevel}`,
|
|
4309
|
+
entryAndPageNumberSeparator: options.showPageNumbers && !options.rightAlignPageNumbers ? ' ' : void 0,
|
|
4310
|
+
useAppliedParagraphOutlineLevel: true,
|
|
4311
|
+
hideTabAndPageNumbersInWebView: true,
|
|
4312
|
+
cachedEntries: patch.entries.map((entry)=>({
|
|
4313
|
+
title: entry.title,
|
|
4314
|
+
level: entry.level,
|
|
4315
|
+
page: options.showPageNumbers ? entry.pageNumber : void 0,
|
|
4316
|
+
href: options.hyperlinks ? entry.targetId : void 0
|
|
4317
|
+
}))
|
|
4318
|
+
});
|
|
4319
|
+
}
|
|
4320
|
+
async function patchDocxTableOfContents(buffer, patches) {
|
|
4321
|
+
if (!patches.length) return buffer;
|
|
4322
|
+
const archive = await jszip.loadAsync(buffer);
|
|
4323
|
+
const entry = archive.file('word/document.xml');
|
|
4324
|
+
if (!entry) return buffer;
|
|
4325
|
+
const document = parseXml(await entry.async('text'), 'generated DOCX word/document.xml');
|
|
4326
|
+
const tables = descendants(document, 'sdt').filter((element)=>descendants(element, 'instrText').some((instruction)=>/^\s*TOC\b/i.test(instruction.textContent ?? '')));
|
|
4327
|
+
if (tables.length !== patches.length) throw new Error(`Generated DOCX emitted ${tables.length} table(s) of contents for ${patches.length} source block(s).`);
|
|
4328
|
+
for (const [index, table] of tables.entries()){
|
|
4329
|
+
const patch = patches[index];
|
|
4330
|
+
if (patch) patchTableOfContents(document, table, patch.options);
|
|
4331
|
+
}
|
|
4332
|
+
addTableOfContentsBookmarks(document, patches);
|
|
4333
|
+
archive.file('word/document.xml', new XMLSerializer().serializeToString(document));
|
|
4334
|
+
return archive.generateAsync({
|
|
4335
|
+
type: 'arraybuffer'
|
|
4336
|
+
});
|
|
4337
|
+
}
|
|
4338
|
+
function patchTableOfContents(document, table, options) {
|
|
4339
|
+
for (const tabStop of descendants(table, 'tab')){
|
|
4340
|
+
if (tabStop.parentElement?.localName !== 'tabs') continue;
|
|
4341
|
+
const value = work_ooxml_package_attribute(tabStop, 'val');
|
|
4342
|
+
if ('right' !== value) continue;
|
|
4343
|
+
if (!options.showPageNumbers || !options.rightAlignPageNumbers) {
|
|
4344
|
+
const parent = tabStop.parentElement;
|
|
4345
|
+
tabStop.remove();
|
|
4346
|
+
if (parent && !directChildren(parent, 'tab').length) parent.remove();
|
|
4347
|
+
continue;
|
|
4348
|
+
}
|
|
4349
|
+
const leader = docxTableOfContentsLeader(options.leader);
|
|
4350
|
+
if (leader) work_docx_table_of_contents_export_setWordAttribute(document, tabStop, 'leader', leader);
|
|
4351
|
+
else removeWordAttribute(tabStop, 'leader');
|
|
4352
|
+
}
|
|
4353
|
+
if (options.showPageNumbers && options.rightAlignPageNumbers) return;
|
|
4354
|
+
for (const tab of descendants(table, 'tab')){
|
|
4355
|
+
if (tab.parentElement?.localName === 'tabs') continue;
|
|
4356
|
+
if (!options.showPageNumbers) {
|
|
4357
|
+
tab.remove();
|
|
4358
|
+
continue;
|
|
4359
|
+
}
|
|
4360
|
+
const text = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 't'));
|
|
4361
|
+
text.setAttributeNS(work_docx_table_of_contents_export_XML_NAMESPACE, 'xml:space', 'preserve');
|
|
4362
|
+
text.textContent = ' ';
|
|
4363
|
+
tab.replaceWith(text);
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
function addTableOfContentsBookmarks(document, patches) {
|
|
4367
|
+
const names = new Set(descendants(document, 'bookmarkStart').flatMap((bookmark)=>{
|
|
4368
|
+
const name = work_ooxml_package_attribute(bookmark, 'name')?.trim();
|
|
4369
|
+
return name ? [
|
|
4370
|
+
name
|
|
4371
|
+
] : [];
|
|
4372
|
+
}));
|
|
4373
|
+
let nextId = Math.max(0, ...descendants(document, 'bookmarkStart').map((bookmark)=>Number(work_ooxml_package_attribute(bookmark, 'id') ?? 0))) + 1;
|
|
4374
|
+
const targets = new Set(patches.flatMap((patch)=>patch.options.hyperlinks ? patch.entries.map((candidate)=>candidate.targetId) : []));
|
|
4375
|
+
for (const target of targets){
|
|
4376
|
+
if (names.has(target)) continue;
|
|
4377
|
+
const paragraphId = /^heading-([0-9a-f]{8})$/i.exec(target)?.[1];
|
|
4378
|
+
if (!paragraphId) continue;
|
|
4379
|
+
const paragraph = descendants(document, 'p').find((candidate)=>work_ooxml_package_attribute(candidate, 'paraId')?.toLowerCase() === paragraphId.toLowerCase());
|
|
4380
|
+
if (!paragraph) continue;
|
|
4381
|
+
const start = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkStart'));
|
|
4382
|
+
const end = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkEnd'));
|
|
4383
|
+
work_docx_table_of_contents_export_setWordAttribute(document, start, 'id', String(nextId));
|
|
4384
|
+
work_docx_table_of_contents_export_setWordAttribute(document, start, 'name', target);
|
|
4385
|
+
work_docx_table_of_contents_export_setWordAttribute(document, end, 'id', String(nextId));
|
|
4386
|
+
nextId += 1;
|
|
4387
|
+
const properties = directChild(paragraph, 'pPr');
|
|
4388
|
+
paragraph.insertBefore(start, properties?.nextSibling ?? paragraph.firstChild);
|
|
4389
|
+
paragraph.append(end);
|
|
4390
|
+
names.add(target);
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
function docxTableOfContentsLeader(value) {
|
|
4394
|
+
if ('dash' === value) return 'hyphen';
|
|
4395
|
+
if ('underline' === value) return 'underscore';
|
|
4396
|
+
if ('dot' === value) return 'dot';
|
|
4397
|
+
return null;
|
|
4398
|
+
}
|
|
4399
|
+
function work_docx_table_of_contents_export_setWordAttribute(document, element, localName, value) {
|
|
4400
|
+
removeWordAttribute(element, localName);
|
|
4401
|
+
element.setAttributeNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, localName), value);
|
|
4402
|
+
}
|
|
4403
|
+
function removeWordAttribute(element, localName) {
|
|
4404
|
+
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);
|
|
4405
|
+
}
|
|
4406
|
+
function work_docx_table_of_contents_export_wordQualifiedName(root, localName) {
|
|
4407
|
+
return `${xmlNamespacePrefix(root, work_docx_table_of_contents_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
|
|
4408
|
+
}
|
|
3974
4409
|
const work_docx_table_sizing_export_TWIPS_PER_PIXEL = 15;
|
|
3975
4410
|
function documentTableSizingDocxOptions(table, docx) {
|
|
3976
4411
|
const geometry = documentTableGeometryFromElement(table);
|
|
@@ -7956,7 +8391,7 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
7956
8391
|
const docx = await import("docx");
|
|
7957
8392
|
const normalizedContent = {
|
|
7958
8393
|
...content,
|
|
7959
|
-
html: normalizeDocumentBookmarkReferencesHtml(normalizeDocumentBookmarksHtml(content.html))
|
|
8394
|
+
html: normalizeDocumentIndexesHtml(normalizeDocumentBookmarkReferencesHtml(normalizeDocumentBookmarksHtml(content.html)))
|
|
7960
8395
|
};
|
|
7961
8396
|
const noteCollection = collectDocumentNotes(normalizedContent.html);
|
|
7962
8397
|
const comments = anchoredDocumentComments(normalizedContent);
|
|
@@ -7991,8 +8426,12 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
7991
8426
|
legacyTextEffectsPatches: new DocxLegacyTextEffectsPatchCollector(JSON.stringify(normalizedContent)),
|
|
7992
8427
|
runBorderPatches: new DocxRunBorderPatchCollector(JSON.stringify(normalizedContent)),
|
|
7993
8428
|
usedRunBorderMarkers: new Set(),
|
|
8429
|
+
runShadingPatches: new DocxRunShadingPatchCollector(JSON.stringify(normalizedContent)),
|
|
8430
|
+
usedRunShadingMarkers: new Set(),
|
|
7994
8431
|
usedNativeTextEffectMarkers: new Set(),
|
|
7995
8432
|
paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
|
|
8433
|
+
tableOfContentsPatches: new DocxTableOfContentsPatchCollector(),
|
|
8434
|
+
indexPatches: new DocxIndexPatchCollector(),
|
|
7996
8435
|
hasExplicitZeroCharacterSpacing: false,
|
|
7997
8436
|
hasExplicitZeroKerningThreshold: false
|
|
7998
8437
|
};
|
|
@@ -8047,7 +8486,8 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
8047
8486
|
const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
|
|
8048
8487
|
const legacyTextEffectsPatched = await patchDocxLegacyTextEffects(hiddenTextPatched, noteContext.legacyTextEffectsPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
|
|
8049
8488
|
const runBordersPatched = await patchDocxRunBorders(legacyTextEffectsPatched, noteContext.runBorderPatches.patches.filter((patch)=>noteContext.usedRunBorderMarkers.has(patch.marker)));
|
|
8050
|
-
const
|
|
8489
|
+
const runShadingPatched = await patchDocxRunShading(runBordersPatched, noteContext.runShadingPatches.patches.filter((patch)=>noteContext.usedRunShadingMarkers.has(patch.marker)));
|
|
8490
|
+
const formattingChangesPatched = await patchDocxRunFormattingChanges(runShadingPatched, noteContext.formattingChangePatches.patches);
|
|
8051
8491
|
const noteImageRelationshipsPatched = await patchDocxNoteImageRelationships(formattingChangesPatched);
|
|
8052
8492
|
const commentMetadataPatched = await patchDocxCommentMetadata(noteImageRelationshipsPatched, commentThreads);
|
|
8053
8493
|
const numberingPatched = await patchDocxNumberingRestartRules(commentMetadataPatched, noteContext.numberingRestartRules);
|
|
@@ -8062,7 +8502,9 @@ async function createDocxBlob(content, sourcePackage) {
|
|
|
8062
8502
|
const bookmarkPatched = await patchDocxBookmarks(imageIdentityPatched, noteContext.bookmarkPatches.patches);
|
|
8063
8503
|
const paragraphDefaultCollapsedPatched = await patchDocxParagraphDefaultCollapsed(bookmarkPatched, noteContext.paragraphDefaultCollapsedPatches.patches);
|
|
8064
8504
|
const paragraphIdentityPatched = await patchDocxParagraphIdentities(paragraphDefaultCollapsedPatched, noteContext.paragraphIdentityPatches.patches);
|
|
8065
|
-
const
|
|
8505
|
+
const tableOfContentsPatched = await patchDocxTableOfContents(paragraphIdentityPatched, noteContext.tableOfContentsPatches.patches);
|
|
8506
|
+
const indexPatched = await patchDocxIndexes(tableOfContentsPatched, noteContext.indexPatches.patches);
|
|
8507
|
+
const paragraphFormattingChangesPatched = await patchDocxParagraphFormattingChanges(indexPatched, noteContext.paragraphFormattingChangePatches.patches);
|
|
8066
8508
|
const equationPatched = await patchDocxEquations(paragraphFormattingChangesPatched, noteContext.equationPatches.patches);
|
|
8067
8509
|
const patched = await patchDocxPageColor(equationPatched, normalizedContent.pageColor);
|
|
8068
8510
|
const preserved = sourcePackage ? await preserveDocxSourcePackage(patched, sourcePackage, {
|
|
@@ -8132,6 +8574,10 @@ function markDocxRunBorderUsed(border, context) {
|
|
|
8132
8574
|
const marker = border?.color?.toUpperCase();
|
|
8133
8575
|
if (context.runBorderPatches.hasMarker(marker)) context.usedRunBorderMarkers.add(marker);
|
|
8134
8576
|
}
|
|
8577
|
+
function markDocxRunShadingUsed(shading, context) {
|
|
8578
|
+
const marker = shading?.fill?.toUpperCase();
|
|
8579
|
+
if (context.runShadingPatches.hasMarker(marker)) context.usedRunShadingMarkers.add(marker);
|
|
8580
|
+
}
|
|
8135
8581
|
function work_docx_export_sectionProperties(layout, docx) {
|
|
8136
8582
|
const landscape = 'landscape' === layout.orientation;
|
|
8137
8583
|
const dimensions = documentPageGeometryForLayout(layout);
|
|
@@ -8229,6 +8675,10 @@ async function blockToFileChildren(element, docx, noteContext) {
|
|
|
8229
8675
|
if (element.hasAttribute('data-document-bibliography')) return [
|
|
8230
8676
|
docxBibliographyParagraph(element, docx, paragraphBidirectional(element))
|
|
8231
8677
|
];
|
|
8678
|
+
if (element.hasAttribute('data-document-table-of-contents')) return [
|
|
8679
|
+
docxTableOfContents(element, docx, noteContext.tableOfContentsPatches)
|
|
8680
|
+
];
|
|
8681
|
+
if (element.hasAttribute('data-document-index')) return docxDocumentIndex(element, docx, noteContext.indexPatches);
|
|
8232
8682
|
if (element.hasAttribute('data-document-caption')) return [
|
|
8233
8683
|
docxCaptionParagraph(element, await paragraphRuns(element, docx, noteContext), docx, paragraphBidirectional(element))
|
|
8234
8684
|
];
|
|
@@ -8303,6 +8753,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8303
8753
|
if (!node.textContent) return [];
|
|
8304
8754
|
markDocxNativeTextEffectStyleUsed(inherited.style, noteContext);
|
|
8305
8755
|
markDocxRunBorderUsed(inherited.border, noteContext);
|
|
8756
|
+
markDocxRunShadingUsed(inherited.shading, noteContext);
|
|
8306
8757
|
if (revision?.kind === 'insertion') return [
|
|
8307
8758
|
new docx.InsertedTextRun({
|
|
8308
8759
|
...inherited,
|
|
@@ -8339,6 +8790,12 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8339
8790
|
if (node.hasAttribute('data-document-field')) return [
|
|
8340
8791
|
docxDocumentFieldRun(node, docx)
|
|
8341
8792
|
];
|
|
8793
|
+
if (node.hasAttribute('data-document-index-entry')) {
|
|
8794
|
+
const entry = docxIndexEntryRun(node, docx);
|
|
8795
|
+
return entry ? [
|
|
8796
|
+
entry
|
|
8797
|
+
] : [];
|
|
8798
|
+
}
|
|
8342
8799
|
if (node.hasAttribute('data-document-equation')) {
|
|
8343
8800
|
const equation = noteContext.equationPatches.marker(node);
|
|
8344
8801
|
return [
|
|
@@ -8360,19 +8817,32 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8360
8817
|
const formattingChange = node.hasAttribute('data-document-change') && 'formatting' === node.dataset.changeKind ? noteContext.formattingChangePatches.register(node, docxRevisionId(node, noteContext)) : null;
|
|
8361
8818
|
const commentBoundary = node.hasAttribute('data-document-comment') ? nextDocxCommentBoundary(node.dataset.commentId, noteContext) : null;
|
|
8362
8819
|
const backgroundColor = cssColorToHex(node.style.backgroundColor);
|
|
8820
|
+
const hasExplicitRunShading = 'span' === tag && node.hasAttribute(DOCUMENT_RUN_SHADING_ATTRIBUTE);
|
|
8821
|
+
const explicitRunShading = hasExplicitRunShading ? parseDocumentRunShadingElement(node) : null;
|
|
8822
|
+
if (hasExplicitRunShading && !explicitRunShading) throw new Error('Document contains invalid character shading.');
|
|
8823
|
+
const hasHighlightSemantics = node.hasAttribute(DOCUMENT_HIGHLIGHT_ATTRIBUTE) || node.hasAttribute('data-color') || 'mark' === tag || Boolean(backgroundColor) && !hasExplicitRunShading;
|
|
8824
|
+
const explicitHighlight = hasHighlightSemantics ? documentHighlightFromElement(node) : null;
|
|
8363
8825
|
const direction = domDirection(node);
|
|
8364
8826
|
const resolvedColor = cssColorToHex(node.style.color) ?? inherited.color;
|
|
8365
8827
|
const themeColorMarker = noteContext.themePatches.marker('color', parseDocxThemeReference(node.dataset.officeThemeColor), resolvedColor ? `#${resolvedColor}` : null);
|
|
8366
|
-
const
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8828
|
+
const runShading = explicitRunShading ? documentRunShadingDocxOptions(explicitRunShading, noteContext.runShadingPatches).shading : void 0;
|
|
8829
|
+
const customHighlightFill = hasHighlightSemantics && !explicitHighlight ? backgroundColor : null;
|
|
8830
|
+
const resolvedShading = runShading ?? (customHighlightFill ? {
|
|
8831
|
+
fill: customHighlightFill
|
|
8832
|
+
} : inherited.shading);
|
|
8833
|
+
const themeFillMarker = !runShading && customHighlightFill ? noteContext.themePatches.marker('fill', parseDocxThemeReference(node.dataset.officeThemeFill), `#${customHighlightFill}`) : null;
|
|
8370
8834
|
const explicitTextCase = normalizeDocumentTextCase(node.dataset.officeTextCase);
|
|
8371
8835
|
const explicitCharacterSpacing = documentCharacterSpacingTwipsFromElement(node);
|
|
8372
8836
|
const explicitCharacterScale = documentCharacterScalePercentFromElement(node);
|
|
8373
8837
|
const explicitKerningThreshold = documentKerningThresholdHalfPointsFromElement(node);
|
|
8374
8838
|
const explicitEmphasisMark = documentEmphasisMarkFromElement(node);
|
|
8375
8839
|
const explicitHiddenText = documentHiddenTextFromElement(node);
|
|
8840
|
+
const hasExplicitProofingLanguages = 'span' === tag && node.hasAttribute(DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE);
|
|
8841
|
+
const explicitProofingLanguages = hasExplicitProofingLanguages ? documentProofingLanguagesFromElement(node) : null;
|
|
8842
|
+
if (hasExplicitProofingLanguages && !explicitProofingLanguages) throw new Error('Document contains invalid proofing languages.');
|
|
8843
|
+
const hasExplicitNoProof = 'span' === tag && node.hasAttribute(DOCUMENT_NO_PROOF_ATTRIBUTE);
|
|
8844
|
+
const explicitNoProof = hasExplicitNoProof ? documentNoProofFromElement(node) : null;
|
|
8845
|
+
if (hasExplicitNoProof && null === explicitNoProof) throw new Error('Document contains invalid proofing state.');
|
|
8376
8846
|
const hasExplicitLegacyTextEffects = 'span' === tag && [
|
|
8377
8847
|
DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE,
|
|
8378
8848
|
DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE,
|
|
@@ -8410,6 +8880,8 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8410
8880
|
const strike = docxStrikeRunOptions(node, inherited);
|
|
8411
8881
|
const scriptFontMarker = noteContext.runFontPatches.marker(documentScriptFontsFromElement(node), documentScriptFontSlotFromElement(node), node.style.fontFamily);
|
|
8412
8882
|
const runBorder = explicitRunBorder ? documentRunBorderDocxOptions(explicitRunBorder, noteContext.runBorderPatches).border : inherited.border;
|
|
8883
|
+
const language = hasExplicitProofingLanguages ? documentProofingLanguageDocxOptions(explicitProofingLanguages) : inherited.language;
|
|
8884
|
+
const noProof = hasExplicitNoProof ? explicitNoProof ?? false : inherited.noProof;
|
|
8413
8885
|
const style = {
|
|
8414
8886
|
...inherited,
|
|
8415
8887
|
style: nativeTextEffectStyle,
|
|
@@ -8429,10 +8901,13 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8429
8901
|
kern,
|
|
8430
8902
|
position,
|
|
8431
8903
|
emphasisMark,
|
|
8904
|
+
language,
|
|
8905
|
+
noProof,
|
|
8432
8906
|
border: runBorder,
|
|
8433
8907
|
shading: themeFillMarker ? {
|
|
8434
8908
|
fill: themeFillMarker
|
|
8435
8909
|
} : resolvedShading,
|
|
8910
|
+
highlight: hasHighlightSemantics ? explicitHighlight ?? (customHighlightFill ? 'none' : void 0) : inherited.highlight,
|
|
8436
8911
|
snapToGrid: dataBoolean(node.dataset.officeWordSnapToGrid) ?? inherited.snapToGrid,
|
|
8437
8912
|
rightToLeft: void 0 === direction ? inherited.rightToLeft : 'rtl' === direction,
|
|
8438
8913
|
...textCaseOptions
|
|
@@ -8440,6 +8915,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
|
|
|
8440
8915
|
if ('br' === tag) {
|
|
8441
8916
|
markDocxNativeTextEffectStyleUsed(style.style, noteContext);
|
|
8442
8917
|
markDocxRunBorderUsed(style.border, noteContext);
|
|
8918
|
+
markDocxRunShadingUsed(style.shading, noteContext);
|
|
8443
8919
|
return [
|
|
8444
8920
|
new docx.TextRun({
|
|
8445
8921
|
...style,
|