@a3s-lab/office 0.27.0 → 0.28.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.
@@ -1,5 +1,5 @@
1
1
  import jszip from "jszip";
2
- import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, documentScriptFontSlotFromElement, normalizeDocumentColumns, createDocumentImageIdentityRegistry, serializeDocumentScriptFonts, documentCharacterSpacingTwipsFromElement, uniqueDocumentParagraphIdentity, documentCharacterPositionHalfPointsFromElement, normalizeDocumentTableVerticalAlign, documentTableColumnPercentagesFromElement, normalizeDocumentTextCase, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, normalizeDocumentScriptFonts, documentNoteKey, normalizeDocumentHiddenText, normalizeDocumentParagraphBorders, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, normalizeDocumentParagraphId, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, parseDocumentParagraphBordersElement, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, documentScriptFontsFromElement, normalizeDocumentUnderlineStyle, documentPageMarginsForLayout, normalizeDocumentPageChrome, normalizeDocumentImageLayer, documentFontNameFromCssFamily, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, parseDocumentScriptFonts, documentCaptionLabel, documentCaptionKind, applyDocumentParagraphIdentityToElement, isContourImageLayout, parseDocxThemeReference, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, createDocumentParagraphIdentityRegistry, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, DocxThemePatchCollector, defaultDocumentImageWrapContour, normalizeDocumentParagraphIdentity, normalizeDocumentPaperSource, documentEquationFromElement, DOCUMENT_PARAGRAPH_BORDER_EDGES, parseDocumentCharacterFormatting, documentScriptFontFamily, documentUnderlineFormattingFromElement, documentParagraphIdentityFromElement, normalizeDocumentEquation, patchDocxThemeReferences, parseDocumentParagraphShadingElement, normalizeDocumentBookmarkNativeId, parseDocumentParagraphFormatting, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, documentTableRowIdentityFromElement, documentImageLayoutFromElement, documentScriptFontSlotFromHint, collectDocumentNotes, documentPageHorizontalMarginTwips, documentPageGeometryForLayout, normalizeDocumentScriptFontSlot, normalizeDocumentPageMargins, documentCharacterScalePercentFromElement, documentNoteKind } from "./6282.js";
2
+ import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, documentScriptFontSlotFromElement, normalizeDocumentColumns, createDocumentImageIdentityRegistry, serializeDocumentScriptFonts, documentCharacterSpacingTwipsFromElement, uniqueDocumentParagraphIdentity, documentCharacterPositionHalfPointsFromElement, normalizeDocumentTableVerticalAlign, documentTableColumnPercentagesFromElement, normalizeDocumentTextCase, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, normalizeDocumentScriptFonts, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, normalizeDocumentParagraphBorders, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, normalizeDocumentParagraphId, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, parseDocumentParagraphBordersElement, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, documentScriptFontsFromElement, normalizeDocumentUnderlineStyle, documentPageMarginsForLayout, normalizeDocumentPageChrome, normalizeDocumentImageLayer, documentFontNameFromCssFamily, documentBookmarkReferenceInstruction, documentImageCropFromElement, documentKerningThresholdHalfPointsFromElement, normalizeDocumentPageBorders, documentImageLayerFromElement, normalizeDocumentLegacyTextEffects, documentCaptionLabel, documentCaptionKind, applyDocumentParagraphIdentityToElement, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, isContourImageLayout, parseDocumentScriptFonts, normalizeDocumentStrikeStyle, parseDocxThemeReference, createDocumentParagraphIdentityRegistry, documentCitationTags, docxDocumentFieldKind, normalizeDocumentImageIdentity, normalizeTableColor, documentTableBordersFromElement, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, DocxThemePatchCollector, defaultDocumentImageWrapContour, documentSections, normalizeDocumentParagraphIdentity, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, DOCUMENT_PARAGRAPH_BORDER_EDGES, documentLegacyTextEffectsFromElement, parseDocumentCharacterFormatting, documentScriptFontFamily, documentParagraphIdentityFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, documentUnderlineFormattingFromElement, normalizeDocumentBookmarkNativeId, patchDocxThemeReferences, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, parseDocumentParagraphShadingElement, documentImageLayoutFromElement, documentScriptFontSlotFromHint, parseDocumentParagraphFormatting, documentPageHorizontalMarginTwips, documentTableRowIdentityFromElement, collectDocumentNotes, documentPageGeometryForLayout, normalizeDocumentScriptFontSlot, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./6282.js";
3
3
  import { serializeUtf8Xml, directChildren, xmlNamespacePrefix, parseXml, decodeXmlBytes, descendants, resolvePartTarget, directChild, attribute as work_ooxml_package_attribute } from "./5184.js";
4
4
  import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.js";
5
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~7043.js";
@@ -757,8 +757,7 @@ function hasAncestor(element, localName) {
757
757
  }
758
758
  return false;
759
759
  }
760
- const HIDDEN_TEXT_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
761
- const WORD_RUN_PROPERTY_ORDER = [
760
+ const DOCX_RUN_PROPERTY_ORDER = [
762
761
  'rStyle',
763
762
  'rFonts',
764
763
  'b',
@@ -799,11 +798,12 @@ const WORD_RUN_PROPERTY_ORDER = [
799
798
  'specVanish',
800
799
  'rPrChange'
801
800
  ];
802
- const WORD_RUN_PROPERTY_RANK = new Map(WORD_RUN_PROPERTY_ORDER.map((name, index)=>[
801
+ const DOCX_RUN_PROPERTY_RANK = new Map(DOCX_RUN_PROPERTY_ORDER.map((name, index)=>[
803
802
  name,
804
803
  index
805
804
  ]));
806
- const VANISH_RANK = WORD_RUN_PROPERTY_RANK.get('vanish') ?? 0;
805
+ const HIDDEN_TEXT_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
806
+ const VANISH_RANK = DOCX_RUN_PROPERTY_RANK.get('vanish') ?? 0;
807
807
  class DocxHiddenTextPatchCollector {
808
808
  patches = [];
809
809
  nextMarker = 1;
@@ -838,6 +838,9 @@ class DocxHiddenTextPatchCollector {
838
838
  this.markersByValueAndStyle.set(key, marker);
839
839
  return marker;
840
840
  }
841
+ lookup(marker) {
842
+ return marker ? this.patchesByMarker.get(marker) : void 0;
843
+ }
841
844
  originalStyle(style) {
842
845
  let current = style;
843
846
  const seen = new Set();
@@ -897,7 +900,7 @@ function insertHiddenTextProperty(document, properties, value) {
897
900
  if (!value) vanish.setAttributeNS(namespace, `${prefix}:val`, '0');
898
901
  const next = directChildren(properties).find((child)=>{
899
902
  if (!DOCX_WORDPROCESSING_NAMESPACES.has(child.namespaceURI ?? '')) return true;
900
- return (WORD_RUN_PROPERTY_RANK.get(child.localName) ?? 1 / 0) > VANISH_RANK;
903
+ return (DOCX_RUN_PROPERTY_RANK.get(child.localName) ?? 1 / 0) > VANISH_RANK;
901
904
  });
902
905
  properties.insertBefore(vanish, next ?? null);
903
906
  }
@@ -911,6 +914,128 @@ function setWordValue(element, value) {
911
914
  for (const attribute of Array.from(element.attributes))if ('val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? '')) element.removeAttributeNode(attribute);
912
915
  element.setAttributeNS(namespace, `${prefix}:val`, value);
913
916
  }
917
+ const LEGACY_TEXT_EFFECTS_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
918
+ class DocxLegacyTextEffectsPatchCollector {
919
+ patches = [];
920
+ nextMarker = 1;
921
+ occupied;
922
+ patchesByMarker = new Map();
923
+ markersByEffectsAndStyle = new Map();
924
+ constructor(source){
925
+ this.occupied = source;
926
+ }
927
+ marker(value, inheritedStyle) {
928
+ const effects = normalizeDocumentLegacyTextEffects(value);
929
+ if (!effects || !Object.keys(effects).length) throw new Error('Document contains invalid legacy text effects.');
930
+ const style = this.originalStyle(inheritedStyle);
931
+ const key = JSON.stringify([
932
+ DOCUMENT_LEGACY_TEXT_EFFECT_NAMES.map((name)=>effects[name] ?? null),
933
+ style ?? null
934
+ ]);
935
+ const existing = this.markersByEffectsAndStyle.get(key);
936
+ if (existing) return existing;
937
+ let marker = '';
938
+ do {
939
+ marker = `A3SOfficeLegacyTextEffects${String(this.nextMarker).padStart(8, '0')}`;
940
+ this.nextMarker += 1;
941
+ }while (this.occupied.includes(marker) || this.patches.some((patch)=>patch.marker === marker))
942
+ const patch = {
943
+ marker,
944
+ effects,
945
+ ...style ? {
946
+ style
947
+ } : {}
948
+ };
949
+ this.patches.push(patch);
950
+ this.patchesByMarker.set(marker, patch);
951
+ this.markersByEffectsAndStyle.set(key, marker);
952
+ return marker;
953
+ }
954
+ lookup(marker) {
955
+ return marker ? this.patchesByMarker.get(marker) : void 0;
956
+ }
957
+ originalStyle(style) {
958
+ let current = style;
959
+ const seen = new Set();
960
+ while(current && !seen.has(current)){
961
+ seen.add(current);
962
+ const patch = this.patchesByMarker.get(current);
963
+ if (!patch) break;
964
+ current = patch.style;
965
+ }
966
+ return current;
967
+ }
968
+ }
969
+ async function patchDocxLegacyTextEffects(buffer, patches) {
970
+ if (!patches.length) return buffer;
971
+ const byMarker = new Map();
972
+ for (const patch of patches){
973
+ const effects = normalizeDocumentLegacyTextEffects(patch.effects);
974
+ if (!patch.marker || !effects || !Object.keys(effects).length || byMarker.has(patch.marker)) throw new Error('Document contains invalid legacy text-effect patches.');
975
+ byMarker.set(patch.marker, {
976
+ ...patch,
977
+ effects
978
+ });
979
+ }
980
+ const archive = await jszip.loadAsync(buffer);
981
+ const applied = new Set();
982
+ for (const entry of Object.values(archive.files)){
983
+ if (entry.dir || !LEGACY_TEXT_EFFECTS_PART_PATTERN.test(entry.name)) continue;
984
+ const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `generated DOCX ${entry.name}`), `generated DOCX ${entry.name}`);
985
+ let changed = false;
986
+ for (const properties of descendants(document, 'rPr')){
987
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(properties.namespaceURI ?? '')) continue;
988
+ const markerStyles = directChildren(properties, 'rStyle').filter((style)=>{
989
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(style.namespaceURI ?? '')) return false;
990
+ const marker = work_docx_legacy_text_effects_export_wordValue(style);
991
+ return null !== marker && byMarker.has(marker);
992
+ });
993
+ if (!markerStyles.length) continue;
994
+ if (1 !== markerStyles.length) throw new Error('Generated DOCX legacy text-effect marker is duplicated in one run.');
995
+ const marker = work_docx_legacy_text_effects_export_wordValue(markerStyles[0]);
996
+ const patch = marker ? byMarker.get(marker) : void 0;
997
+ if (marker && patch) {
998
+ if (DOCUMENT_LEGACY_TEXT_EFFECT_NAMES.some((name)=>directChildren(properties, name).length > 0)) throw new Error('Generated DOCX legacy text-effect marker unexpectedly has a native value.');
999
+ if (patch.style) work_docx_legacy_text_effects_export_setWordValue(markerStyles[0], patch.style);
1000
+ else markerStyles[0].remove();
1001
+ for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES){
1002
+ const value = patch.effects[name];
1003
+ if (void 0 !== value) insertLegacyTextEffectProperty(document, properties, name, value);
1004
+ }
1005
+ applied.add(marker);
1006
+ changed = true;
1007
+ }
1008
+ }
1009
+ if (changed) archive.file(entry.name, serializeUtf8Xml(document));
1010
+ }
1011
+ const missing = patches.filter((patch)=>!applied.has(patch.marker));
1012
+ if (missing.length) throw new Error(`DOCX legacy text-effect markers were not emitted: ${missing.map((patch)=>patch.marker).join(', ')}.`);
1013
+ return archive.generateAsync({
1014
+ type: 'arraybuffer'
1015
+ });
1016
+ }
1017
+ function insertLegacyTextEffectProperty(document, properties, name, value) {
1018
+ const namespace = properties.namespaceURI ?? '';
1019
+ const prefix = properties.prefix || 'w';
1020
+ const effect = document.createElementNS(namespace, `${prefix}:${name}`);
1021
+ if (!value) effect.setAttributeNS(namespace, `${prefix}:val`, '0');
1022
+ const rank = DOCX_RUN_PROPERTY_RANK.get(name) ?? 0;
1023
+ const next = directChildren(properties).find((child)=>{
1024
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(child.namespaceURI ?? '')) return true;
1025
+ return (DOCX_RUN_PROPERTY_RANK.get(child.localName) ?? 1 / 0) > rank;
1026
+ });
1027
+ properties.insertBefore(effect, next ?? null);
1028
+ }
1029
+ function work_docx_legacy_text_effects_export_wordValue(element) {
1030
+ const values = Array.from(element.attributes).filter((attribute)=>'val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? ''));
1031
+ return 1 === values.length ? values[0].value : null;
1032
+ }
1033
+ function work_docx_legacy_text_effects_export_setWordValue(element, value) {
1034
+ const namespace = element.namespaceURI ?? '';
1035
+ const prefix = element.prefix || 'w';
1036
+ for (const attribute of Array.from(element.attributes))if ('val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? '')) element.removeAttributeNode(attribute);
1037
+ element.setAttributeNS(namespace, `${prefix}:val`, value);
1038
+ }
914
1039
  const MATH_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/math';
915
1040
  const work_docx_equation_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
916
1041
  const WORD_DATE_UTC_NAMESPACE = 'http://schemas.microsoft.com/office/word/2023/wordml/word16du';
@@ -2375,9 +2500,10 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
2375
2500
  appendBooleanProperty(document, properties, namespace, prefix, byType, 'bold', 'bCs');
2376
2501
  appendBooleanProperty(document, properties, namespace, prefix, byType, 'italic', 'i');
2377
2502
  appendBooleanProperty(document, properties, namespace, prefix, byType, 'italic', 'iCs');
2378
- appendUnderlineProperty(document, properties, namespace, prefix, byType.get('underline'));
2379
- appendStrikeProperties(document, properties, namespace, prefix, byType.get('strike'));
2380
2503
  appendTextCaseProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2504
+ appendStrikeProperties(document, properties, namespace, prefix, byType.get('strike'));
2505
+ appendLegacyTextEffectsProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2506
+ appendSnapToGridProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2381
2507
  appendHiddenTextProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2382
2508
  appendColorProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2383
2509
  appendCharacterSpacingProperty(document, properties, namespace, prefix, byType.get('textStyle'));
@@ -2386,10 +2512,41 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
2386
2512
  appendCharacterPositionProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2387
2513
  appendFontSizeProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2388
2514
  appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'));
2389
- appendSnapToGridProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2515
+ appendUnderlineProperty(document, properties, namespace, prefix, byType.get('underline'));
2390
2516
  appendVerticalAlignProperty(document, properties, namespace, prefix, byType);
2391
2517
  appendEmphasisMarkProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2392
2518
  }
2519
+ function appendLegacyTextEffectsProperties(document, properties, namespace, prefix, mark) {
2520
+ const effects = {};
2521
+ const attributes = [
2522
+ [
2523
+ 'outline',
2524
+ 'legacyTextOutline'
2525
+ ],
2526
+ [
2527
+ 'shadow',
2528
+ 'legacyTextShadow'
2529
+ ],
2530
+ [
2531
+ 'emboss',
2532
+ 'legacyTextEmboss'
2533
+ ],
2534
+ [
2535
+ 'imprint',
2536
+ 'legacyTextImprint'
2537
+ ]
2538
+ ];
2539
+ for (const [effect, attribute] of attributes){
2540
+ const value = normalizeDocumentLegacyTextEffect(mark?.attrs?.[attribute]);
2541
+ if (null !== value) effects[effect] = value;
2542
+ }
2543
+ if (documentLegacyTextEffectsConflict(effects)) throw new Error('Document contains conflicting legacy text effects.');
2544
+ for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES){
2545
+ const value = effects[name];
2546
+ if (void 0 !== value) if (value) properties.append(wordElement(document, namespace, prefix, name));
2547
+ else appendValuedProperty(document, properties, namespace, prefix, name, '0');
2548
+ }
2549
+ }
2393
2550
  function appendHiddenTextProperty(document, properties, namespace, prefix, mark) {
2394
2551
  const hiddenText = normalizeDocumentHiddenText(mark?.attrs?.hiddenText);
2395
2552
  if (null === hiddenText) return;
@@ -7707,6 +7864,8 @@ async function createDocxBlob(content, sourcePackage) {
7707
7864
  formattingChangePatches: new DocxRunFormattingChangePatchCollector(),
7708
7865
  runFontPatches: new DocxRunFontsPatchCollector(JSON.stringify(normalizedContent)),
7709
7866
  hiddenTextPatches: new DocxHiddenTextPatchCollector(JSON.stringify(normalizedContent)),
7867
+ legacyTextEffectsPatches: new DocxLegacyTextEffectsPatchCollector(JSON.stringify(normalizedContent)),
7868
+ usedNativeTextEffectMarkers: new Set(),
7710
7869
  paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
7711
7870
  hasExplicitZeroCharacterSpacing: false,
7712
7871
  hasExplicitZeroKerningThreshold: false
@@ -7759,8 +7918,9 @@ async function createDocxBlob(content, sourcePackage) {
7759
7918
  const characterSpacingPatched = noteContext.hasExplicitZeroCharacterSpacing ? await patchDocxExplicitZeroCharacterSpacing(await packed.arrayBuffer()) : await packed.arrayBuffer();
7760
7919
  const kerningPatched = noteContext.hasExplicitZeroKerningThreshold ? await patchDocxExplicitZeroKerningThresholds(characterSpacingPatched) : characterSpacingPatched;
7761
7920
  const runFontsPatched = await patchDocxRunFonts(kerningPatched, noteContext.runFontPatches.patches);
7762
- const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches);
7763
- const formattingChangesPatched = await patchDocxRunFormattingChanges(hiddenTextPatched, noteContext.formattingChangePatches.patches);
7921
+ const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
7922
+ const legacyTextEffectsPatched = await patchDocxLegacyTextEffects(hiddenTextPatched, noteContext.legacyTextEffectsPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
7923
+ const formattingChangesPatched = await patchDocxRunFormattingChanges(legacyTextEffectsPatched, noteContext.formattingChangePatches.patches);
7764
7924
  const noteImageRelationshipsPatched = await patchDocxNoteImageRelationships(formattingChangesPatched);
7765
7925
  const commentMetadataPatched = await patchDocxCommentMetadata(noteImageRelationshipsPatched, commentThreads);
7766
7926
  const numberingPatched = await patchDocxNumberingRestartRules(commentMetadataPatched, noteContext.numberingRestartRules);
@@ -7787,6 +7947,60 @@ async function createDocxBlob(content, sourcePackage) {
7787
7947
  type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
7788
7948
  });
7789
7949
  }
7950
+ function docxNativeTextEffectState(style, context) {
7951
+ let current = style;
7952
+ let hiddenText;
7953
+ const legacyTextEffects = {};
7954
+ const seen = new Set();
7955
+ while(current && !seen.has(current)){
7956
+ seen.add(current);
7957
+ const hiddenPatch = context.hiddenTextPatches.lookup(current);
7958
+ if (hiddenPatch) {
7959
+ hiddenText ??= hiddenPatch.value;
7960
+ current = hiddenPatch.style;
7961
+ continue;
7962
+ }
7963
+ const legacyPatch = context.legacyTextEffectsPatches.lookup(current);
7964
+ if (legacyPatch) {
7965
+ for (const [name, value] of Object.entries(legacyPatch.effects)){
7966
+ const effect = name;
7967
+ if (void 0 === legacyTextEffects[effect]) legacyTextEffects[effect] = value;
7968
+ }
7969
+ current = legacyPatch.style;
7970
+ continue;
7971
+ }
7972
+ break;
7973
+ }
7974
+ return {
7975
+ ...current ? {
7976
+ baseStyle: current
7977
+ } : {},
7978
+ ...void 0 !== hiddenText ? {
7979
+ hiddenText
7980
+ } : {},
7981
+ legacyTextEffects
7982
+ };
7983
+ }
7984
+ function markDocxNativeTextEffectStyleUsed(style, context) {
7985
+ let current = style;
7986
+ const seen = new Set();
7987
+ while(current && !seen.has(current)){
7988
+ seen.add(current);
7989
+ const hiddenPatch = context.hiddenTextPatches.lookup(current);
7990
+ if (hiddenPatch) {
7991
+ context.usedNativeTextEffectMarkers.add(current);
7992
+ current = hiddenPatch.style;
7993
+ continue;
7994
+ }
7995
+ const legacyPatch = context.legacyTextEffectsPatches.lookup(current);
7996
+ if (legacyPatch) {
7997
+ context.usedNativeTextEffectMarkers.add(current);
7998
+ current = legacyPatch.style;
7999
+ continue;
8000
+ }
8001
+ break;
8002
+ }
8003
+ }
7790
8004
  function work_docx_export_sectionProperties(layout, docx) {
7791
8005
  const landscape = 'landscape' === layout.orientation;
7792
8006
  const dimensions = documentPageGeometryForLayout(layout);
@@ -7956,6 +8170,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
7956
8170
  const visit = async (node, inherited = {}, revision)=>{
7957
8171
  if (node.nodeType === Node.TEXT_NODE) {
7958
8172
  if (!node.textContent) return [];
8173
+ markDocxNativeTextEffectStyleUsed(inherited.style, noteContext);
7959
8174
  if (revision?.kind === 'insertion') return [
7960
8175
  new docx.InsertedTextRun({
7961
8176
  ...inherited,
@@ -8026,6 +8241,14 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8026
8241
  const explicitKerningThreshold = documentKerningThresholdHalfPointsFromElement(node);
8027
8242
  const explicitEmphasisMark = documentEmphasisMarkFromElement(node);
8028
8243
  const explicitHiddenText = documentHiddenTextFromElement(node);
8244
+ const hasExplicitLegacyTextEffects = 'span' === tag && [
8245
+ DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE,
8246
+ DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE,
8247
+ DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE,
8248
+ DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE
8249
+ ].some((attribute)=>node.hasAttribute(attribute));
8250
+ const explicitLegacyTextEffects = hasExplicitLegacyTextEffects ? documentLegacyTextEffectsFromElement(node) : {};
8251
+ if (hasExplicitLegacyTextEffects && !explicitLegacyTextEffects) throw new Error('Document contains invalid legacy text effects.');
8029
8252
  const explicitCharacterPosition = documentCharacterPositionHalfPointsFromElement(node);
8030
8253
  if (0 === explicitCharacterSpacing) noteContext.hasExplicitZeroCharacterSpacing = true;
8031
8254
  if (0 === explicitKerningThreshold) noteContext.hasExplicitZeroKerningThreshold = true;
@@ -8035,13 +8258,25 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8035
8258
  const position = null === explicitCharacterPosition ? inherited.position : docxCharacterPositionValue(explicitCharacterPosition);
8036
8259
  const emphasisMark = null === explicitEmphasisMark ? inherited.emphasisMark : docxEmphasisMarkRunOptions(explicitEmphasisMark);
8037
8260
  const textCaseOptions = docxTextCaseRunOptions(explicitTextCase, inherited);
8038
- const hiddenTextStyle = null === explicitHiddenText ? inherited.style : noteContext.hiddenTextPatches.marker(explicitHiddenText, inherited.style);
8261
+ const inheritedNativeTextEffects = docxNativeTextEffectState(inherited.style, noteContext);
8262
+ const legacyTextEffects = {
8263
+ ...inheritedNativeTextEffects.legacyTextEffects,
8264
+ ...explicitLegacyTextEffects ?? {}
8265
+ };
8266
+ if (documentLegacyTextEffectsConflict(legacyTextEffects)) throw new Error('Document contains conflicting legacy text effects.');
8267
+ const hiddenText = null === explicitHiddenText ? inheritedNativeTextEffects.hiddenText : explicitHiddenText;
8268
+ let nativeTextEffectStyle = inherited.style;
8269
+ if (hasExplicitLegacyTextEffects || null !== explicitHiddenText) {
8270
+ nativeTextEffectStyle = inheritedNativeTextEffects.baseStyle;
8271
+ if (Object.keys(legacyTextEffects).length) nativeTextEffectStyle = noteContext.legacyTextEffectsPatches.marker(legacyTextEffects, nativeTextEffectStyle);
8272
+ if (void 0 !== hiddenText) nativeTextEffectStyle = noteContext.hiddenTextPatches.marker(hiddenText, nativeTextEffectStyle);
8273
+ }
8039
8274
  const underline = docxUnderlineRunOptions(node, inherited.underline, noteContext.themePatches);
8040
8275
  const strike = docxStrikeRunOptions(node, inherited);
8041
8276
  const scriptFontMarker = noteContext.runFontPatches.marker(documentScriptFontsFromElement(node), documentScriptFontSlotFromElement(node), node.style.fontFamily);
8042
8277
  const style = {
8043
8278
  ...inherited,
8044
- style: hiddenTextStyle,
8279
+ style: nativeTextEffectStyle,
8045
8280
  bold: inherited.bold || 'strong' === tag || 'b' === tag,
8046
8281
  italics: inherited.italics || 'em' === tag || 'i' === tag,
8047
8282
  underline,
@@ -8065,12 +8300,15 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8065
8300
  rightToLeft: void 0 === direction ? inherited.rightToLeft : 'rtl' === direction,
8066
8301
  ...textCaseOptions
8067
8302
  };
8068
- if ('br' === tag) return [
8069
- new docx.TextRun({
8070
- ...style,
8071
- break: 1
8072
- })
8073
- ];
8303
+ if ('br' === tag) {
8304
+ markDocxNativeTextEffectStyleUsed(style.style, noteContext);
8305
+ return [
8306
+ new docx.TextRun({
8307
+ ...style,
8308
+ break: 1
8309
+ })
8310
+ ];
8311
+ }
8074
8312
  if ('img' === tag) return [
8075
8313
  await imageToDocx(node, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches)
8076
8314
  ];
@@ -1,7 +1,7 @@
1
1
  import jszip from "jszip";
2
2
  import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild, attribute as work_ooxml_package_attribute } from "./5184.js";
3
- import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, normalizeDocumentParagraphId, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, documentUnderlineDomAttributes, documentHiddenTextDomAttributes, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, applyDocumentPageGeometry, createDocumentNoteElement, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, applyDocumentParagraphIdentityToElement, documentKerningDomAttributes, docxDocumentFieldKind, serializeDocxThemeReference, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentParagraphShadingDomAttributes, documentCharacterScaleDomAttributes, documentParagraphBordersDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, normalizeDocumentParagraphIdentity, documentPageMarginBody, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./6282.js";
4
- import { markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, createDocxParagraphStyleResolver, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, hasImportedDocxParagraphSpacingMarkers, docxTablePropertySources, parseDocxPageMargins, parseDirectDocxParagraphShading, markDocxPackageEquations, parseDocxPageGeometry, markDocxParagraphIndents, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphTabStopMarkers, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphAlignmentMarkers, markDocxParagraphPagination, importedDocxUnderline, markDocxParagraphBorders, applyImportedDocxParagraphTabStopMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphPaginationMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~5093.js";
3
+ import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, normalizeDocumentParagraphId, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, documentUnderlineDomAttributes, documentHiddenTextDomAttributes, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, applyDocumentPageGeometry, createDocumentNoteElement, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, applyDocumentParagraphIdentityToElement, documentKerningDomAttributes, docxDocumentFieldKind, serializeDocxThemeReference, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentParagraphShadingDomAttributes, documentCharacterScaleDomAttributes, documentParagraphBordersDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, normalizeDocumentParagraphIdentity, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./6282.js";
4
+ import { markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, createDocxParagraphStyleResolver, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, resolveDocxLegacyTextEffects, hasImportedDocxParagraphSpacingMarkers, docxTablePropertySources, parseDocxPageMargins, parseDirectDocxParagraphShading, markDocxPackageEquations, parseDocxPageGeometry, markDocxParagraphIndents, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphTabStopMarkers, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphAlignmentMarkers, importedDocxUnderline, markDocxParagraphBorders, markDocxParagraphPagination, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphPaginationMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~5093.js";
5
5
  import { readDocxBibliography, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~7043.js";
6
6
  import { importDocxPageColor, importedDocumentNoteId } from "./0~4980.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
@@ -1824,6 +1824,8 @@ async function runHtml(run, field, context) {
1824
1824
  if (void 0 !== emphasisMark) content = `<span${htmlAttributes(documentEmphasisMarkDomAttributes(emphasisMark))}>${content}</span>`;
1825
1825
  const hiddenText = resolveDocxHiddenText(propertySources);
1826
1826
  if (void 0 !== hiddenText) content = `<span${htmlAttributes(documentHiddenTextDomAttributes(hiddenText))}>${content}</span>`;
1827
+ const legacyTextEffects = resolveDocxLegacyTextEffects(propertySources);
1828
+ if (legacyTextEffects) content = `<span${htmlAttributes(documentLegacyTextEffectsDomAttributes(legacyTextEffects))}>${content}</span>`;
1827
1829
  const characterSpacing = docxCharacterSpacingTwipsFromProperties(properties ?? run);
1828
1830
  if (void 0 !== characterSpacing) content = `<span${htmlAttributes(documentCharacterSpacingDomAttributes(characterSpacing))}>${content}</span>`;
1829
1831
  const color = work_ooxml_package_attribute(directChild(properties ?? run, 'color') ?? run, 'val');
@@ -1,7 +1,7 @@
1
1
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
2
  import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescendant, descendants, directChild, xmlContainsAnyElement, attribute } from "./5184.js";
3
- import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, normalizeDocumentBookmarkNativeId, isDocumentParagraphArtBorderStyle, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./6282.js";
4
- import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, createDocxTableStyleResolver, inspectDocxRunFonts, docxFieldOccurrences, inspectDocxEquation, inspectDocxPageMarginSettings, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, docxCaptionSequenceKind, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~5093.js";
3
+ import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, isDocumentParagraphArtBorderStyle, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, normalizeDocumentBookmarkNativeId, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./6282.js";
4
+ import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, createDocxTableStyleResolver, docxFieldOccurrences, inspectDocxRunFonts, inspectDocxEquation, inspectDocxPageMarginSettings, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, docxCaptionSequenceKind, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~5093.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
6
  import { xmlAttributeLocalName, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~7043.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, isSupportedXlsxWorksheetImageContentType, MAX_XLSX_WORKSHEET_IMAGE_BYTES, xlsxChartSeriesFormattingShapeProperties, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4104.js";
@@ -400,6 +400,56 @@ async function diagnoseDocxKerning(archive, document) {
400
400
  });
401
401
  return issues;
402
402
  }
403
+ const LEGACY_TEXT_EFFECTS_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
404
+ async function diagnoseDocxLegacyTextEffects(archive, document) {
405
+ const parts = [
406
+ document
407
+ ];
408
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && LEGACY_TEXT_EFFECTS_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push(await archive.xml(path));
409
+ const enabled = {
410
+ outline: 0,
411
+ shadow: 0,
412
+ emboss: 0,
413
+ imprint: 0
414
+ };
415
+ let validCount = 0;
416
+ let explicitFalseCount = 0;
417
+ let invalidCount = 0;
418
+ for (const part of parts){
419
+ const propertySets = descendants(part, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
420
+ for (const properties of propertySets){
421
+ if (!DOCUMENT_LEGACY_TEXT_EFFECT_NAMES.some((name)=>directChildren(properties, name).length > 0)) continue;
422
+ const inspection = inspectDocxLegacyTextEffects(properties);
423
+ if ('valid' === inspection.status) for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES){
424
+ const value = inspection.value[name];
425
+ if (void 0 !== value) {
426
+ validCount += 1;
427
+ if (value) enabled[name] += 1;
428
+ else explicitFalseCount += 1;
429
+ }
430
+ }
431
+ else if ('invalid' === inspection.status) invalidCount += 1;
432
+ }
433
+ for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES)invalidCount += descendants(part, name).filter((element)=>{
434
+ const parent = element.parentElement;
435
+ return !parent || 'rPr' !== parent.localName || !DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? '');
436
+ }).length;
437
+ }
438
+ const issues = [];
439
+ if (validCount) issues.push({
440
+ code: 'docx.legacy-text-effects',
441
+ severity: 'info',
442
+ feature: 'Legacy text effects',
443
+ message: `${validCount} native legacy text-effect value(s), including ${explicitFalseCount} explicit false reset(s), ${enabled.outline} enabled outline value(s), ${enabled.shadow} enabled shadow value(s), ${enabled.emboss} enabled emboss value(s), and ${enabled.imprint} enabled imprint value(s), were detected across document defaults, styles, body, page chrome, notes, comments, and formatting revisions. Editable Writer stories preserve w:outline, w:shadow, w:emboss, and w:imprint through independently mixed Font-dialog controls, conflict-aware one-step Undo, Format Painter, bounded CSS paint projections, and exact DOCX export. Outline plus shadow remains valid; emboss and imprint stay mutually exclusive with the other enabled legacy effects. The browser and PDF projections are bounded visual approximations rather than a claim of desktop-engine pixel identity, and no non-standard shortcut is invented.`
444
+ });
445
+ if (invalidCount) issues.push({
446
+ code: 'docx.legacy-text-effects.invalid',
447
+ severity: 'warning',
448
+ feature: 'Legacy text effects',
449
+ message: `${invalidCount} malformed, duplicated, misplaced, namespace-spoofed, text-bearing, child-bearing, extra-attribute, unknown, or conflicting legacy text-effect property set(s) are ignored instead of enabling contradictory or untrusted paint effects.`
450
+ });
451
+ return issues;
452
+ }
403
453
  const WORDPROCESSINGML_NAMESPACES = new Set([
404
454
  'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
405
455
  'http://purl.oclc.org/ooxml/wordprocessingml/main'
@@ -1879,6 +1929,7 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
1879
1929
  issues.push(...await diagnoseDocxKerning(archive, document));
1880
1930
  issues.push(...await diagnoseDocxEmphasisMarks(archive, document));
1881
1931
  issues.push(...await diagnoseDocxHiddenText(archive, document));
1932
+ issues.push(...await diagnoseDocxLegacyTextEffects(archive, document));
1882
1933
  issues.push(...await diagnoseDocxRunFonts(archive, document));
1883
1934
  }
1884
1935
  issues.push(...await diagnoseDocxPageChrome(archive));
@@ -1910,7 +1961,7 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
1910
1961
  const supportedRunFormattingRevisionCount = runFormattingRevisions.filter(isSupportedDocxRunFormattingChange).length;
1911
1962
  const supportedParagraphFormattingRevisionCount = paragraphFormattingRevisions.filter(isSupportedDocxParagraphFormattingChange).length;
1912
1963
  if (textRevisions.some((revision)=>descendants(revision, 't').length || descendants(revision, 'delText').length)) issues.push(work_office_diagnostics_issue('docx.revisions', 'Tracked changes', 'Body-text insertions and deletions preserve their author and date, remain reviewable in Work, and round-trip as native DOCX revisions.', 'info'));
1913
- if (supportedRunFormattingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.formatting', 'Character-formatting revisions', `${supportedRunFormattingRevisionCount} bounded character-formatting revision(s) preserve author, date, current formatting, and prior bold, italic, underline, strike, subscript, superscript, font, size, color, highlight, character scale, spacing, kerning threshold, emphasis mark, baseline position, and grid state. They remain reviewable in Work and round-trip as native w:rPrChange records.`, 'info'));
1964
+ if (supportedRunFormattingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.formatting', 'Character-formatting revisions', `${supportedRunFormattingRevisionCount} bounded character-formatting revision(s) preserve author, date, current formatting, and prior bold, italic, underline, strike, text case, hidden text, outline, shadow, emboss, imprint, subscript, superscript, font, size, color, highlight, character scale, spacing, kerning threshold, emphasis mark, baseline position, and grid state. They remain reviewable in Work and round-trip as native w:rPrChange records.`, 'info'));
1914
1965
  if (supportedParagraphFormattingRevisionCount) issues.push(work_office_diagnostics_issue('docx.revisions.paragraph-formatting', 'Paragraph-formatting revisions', `${supportedParagraphFormattingRevisionCount} bounded paragraph-formatting revision(s) preserve author, date, current formatting, and prior alignment, direction, indentation, spacing, pagination, outline, tab-stop, border, shading, and collapsed state. They remain reviewable in Work and round-trip as native w:pPrChange records.`, 'info'));
1915
1966
  if (textRevisions.some((revision)=>!descendants(revision, 't').length && !descendants(revision, 'delText').length) || supportedRunFormattingRevisionCount !== runFormattingRevisions.length || supportedParagraphFormattingRevisionCount !== paragraphFormattingRevisions.length || [
1916
1967
  'moveFrom',
package/dist/5184.js CHANGED
@@ -14,6 +14,13 @@ const WORK_TEMPLATES = [
14
14
  description: '目标、范围、里程碑与风险',
15
15
  accent: '#536de2'
16
16
  },
17
+ {
18
+ id: 'text-effects',
19
+ kind: 'document',
20
+ name: '文字效果',
21
+ description: '空心、阴影、阳文与阴文',
22
+ accent: '#6b5bd2'
23
+ },
17
24
  {
18
25
  id: 'blank-markdown',
19
26
  kind: 'markdown',
@@ -72,6 +79,7 @@ function createWorkId(prefix) {
72
79
  function initialTitle(templateId, kind) {
73
80
  const titles = {
74
81
  'project-brief': '新项目方案',
82
+ 'text-effects': '文字效果示例',
75
83
  'quarterly-plan': '季度执行计划',
76
84
  'strategy-deck': '业务策略汇报'
77
85
  };
@@ -87,6 +95,11 @@ function contentForTemplate(templateId) {
87
95
  pageSize: 'a4',
88
96
  html: "<h1>新项目方案</h1><p><strong>负责人:</strong>项目团队  <strong>更新日期:</strong>今天</p><blockquote><p>用一句话说明这项工作的目标,以及完成后会带来什么变化。</p></blockquote><h2>背景与目标</h2><p>描述当前情况、核心问题和可衡量的成功标准。</p><h2>工作范围</h2><ul><li><p>需要完成的关键交付物</p></li><li><p>明确不在本期范围内的事项</p></li></ul><h2>里程碑</h2><ol><li><p>方案确认</p></li><li><p>执行与评审</p></li><li><p>交付与复盘</p></li></ol><h2>风险与决策</h2><p>记录尚未解决的问题、依赖和决策负责人。</p>"
89
97
  };
98
+ if ('text-effects' === templateId) return {
99
+ type: 'document',
100
+ pageSize: 'a4',
101
+ html: '<h1>原生文字效果</h1><p>选择下面任一示例并打开字体高级设置,可以组合空心与阴影,或在互斥的阳文和阴文之间切换。</p><h2>可组合效果</h2><p><span data-office-legacy-text-outline="true" data-office-legacy-text-shadow="true">空心 + 阴影</span></p><p><span data-office-legacy-text-outline="true">空心</span></p><p><span data-office-legacy-text-shadow="true">阴影</span></p><h2>互斥效果</h2><p><span data-office-legacy-text-emboss="true">阳文</span></p><p><span data-office-legacy-text-imprint="true">阴文</span></p>'
102
+ };
90
103
  if ('quarterly-plan' === templateId) return {
91
104
  type: 'spreadsheet',
92
105
  sheets: quarterlyPlanSheets()