@a3s-lab/office 0.37.5 → 0.38.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,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, 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 "./4174.js";
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, serializeDocumentOpenTypeFeatures, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, normalizeDocumentOpenTypeFeatures, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, parseDocumentOpenTypeFeatures, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentLegacyTextEffectsFromElement, parseDocumentCharacterFormatting, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentOpenTypeFeaturesFromElement, normalizeDocumentBookmarkNativeId, documentTableRowIdentityFromElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, collectDocumentNotes, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, DOCUMENT_OPEN_TYPE_ATTRIBUTE, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./4174.js";
3
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, 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";
5
+ import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, DOCX_WORD_2010_NAMESPACE, docxKerningThresholdValue, patchDocxBibliography, documentIndexInstruction, docxCharacterScaleValue, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, xmlNamespaceUri, paragraphSpacingOptions, docxCharacterPositionValue, documentIndexEntryInstruction, docxEmphasisMarkRunOptions, 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~5024.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 {
@@ -2660,6 +2660,174 @@ function work_docx_run_shading_export_setWordAttribute(document, element, name,
2660
2660
  const prefix = element.prefix ?? xmlNamespacePrefix(document.documentElement, namespace) ?? 'w';
2661
2661
  element.setAttributeNS(namespace, `${prefix}:${name}`, value);
2662
2662
  }
2663
+ const work_docx_opentype_export_MARKUP_COMPATIBILITY_NAMESPACE = 'http://schemas.openxmlformats.org/markup-compatibility/2006';
2664
+ const OPEN_TYPE_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
2665
+ const OPEN_TYPE_PROPERTY_ORDER = [
2666
+ 'ligatures',
2667
+ 'numForm',
2668
+ 'numSpacing',
2669
+ 'stylisticSets',
2670
+ 'cntxtAlts'
2671
+ ];
2672
+ class DocxOpenTypePatchCollector {
2673
+ patches = [];
2674
+ nextMarker = 1;
2675
+ occupied;
2676
+ patchesByMarker = new Map();
2677
+ markersByFeaturesAndStyle = new Map();
2678
+ constructor(source){
2679
+ this.occupied = source;
2680
+ }
2681
+ marker(value, inheritedStyle) {
2682
+ const features = normalizeDocumentOpenTypeFeatures(value);
2683
+ if (!features) throw new Error('Document contains invalid OpenType typography.');
2684
+ const style = this.originalStyle(inheritedStyle);
2685
+ const serialized = serializeDocumentOpenTypeFeatures(features);
2686
+ if (!serialized) throw new Error('Document contains invalid OpenType typography.');
2687
+ const key = JSON.stringify([
2688
+ serialized,
2689
+ style ?? null
2690
+ ]);
2691
+ const existing = this.markersByFeaturesAndStyle.get(key);
2692
+ if (existing) return existing;
2693
+ let marker = '';
2694
+ do {
2695
+ marker = `A3SOfficeOpenType${String(this.nextMarker).padStart(8, '0')}`;
2696
+ this.nextMarker += 1;
2697
+ }while (this.occupied.includes(marker) || this.patches.some((patch)=>patch.marker === marker))
2698
+ const patch = {
2699
+ marker,
2700
+ features,
2701
+ ...style ? {
2702
+ style
2703
+ } : {}
2704
+ };
2705
+ this.patches.push(patch);
2706
+ this.patchesByMarker.set(marker, patch);
2707
+ this.markersByFeaturesAndStyle.set(key, marker);
2708
+ return marker;
2709
+ }
2710
+ lookup(marker) {
2711
+ return marker ? this.patchesByMarker.get(marker) : void 0;
2712
+ }
2713
+ originalStyle(style) {
2714
+ let current = style;
2715
+ const seen = new Set();
2716
+ while(current && !seen.has(current)){
2717
+ seen.add(current);
2718
+ const patch = this.patchesByMarker.get(current);
2719
+ if (!patch) break;
2720
+ current = patch.style;
2721
+ }
2722
+ return current;
2723
+ }
2724
+ }
2725
+ async function patchDocxOpenTypeFeatures(buffer, patches) {
2726
+ if (!patches.length) return buffer;
2727
+ const byMarker = validatedPatches(patches);
2728
+ const archive = await jszip.loadAsync(buffer);
2729
+ const applied = new Set();
2730
+ for (const entry of Object.values(archive.files)){
2731
+ if (entry.dir || !OPEN_TYPE_PART_PATTERN.test(entry.name)) continue;
2732
+ const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `generated DOCX ${entry.name}`), `generated DOCX ${entry.name}`);
2733
+ let changed = false;
2734
+ for (const properties of descendants(document, 'rPr')){
2735
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(properties.namespaceURI ?? '')) continue;
2736
+ const markerStyles = directChildren(properties, 'rStyle').filter((style)=>{
2737
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(style.namespaceURI ?? '')) return false;
2738
+ const marker = work_docx_opentype_export_wordValue(style);
2739
+ return null !== marker && byMarker.has(marker);
2740
+ });
2741
+ if (!markerStyles.length) continue;
2742
+ if (1 !== markerStyles.length) throw new Error('Generated DOCX OpenType marker is duplicated in one run.');
2743
+ const marker = work_docx_opentype_export_wordValue(markerStyles[0]);
2744
+ const patch = marker ? byMarker.get(marker) : void 0;
2745
+ if (marker && patch) {
2746
+ if (directChildren(properties).some((child)=>child.namespaceURI === DOCX_WORD_2010_NAMESPACE && OPEN_TYPE_PROPERTY_ORDER.includes(child.localName))) throw new Error('Generated DOCX OpenType marker unexpectedly has a native value.');
2747
+ if (patch.style) work_docx_opentype_export_setWordValue(markerStyles[0], patch.style);
2748
+ else markerStyles[0].remove();
2749
+ appendDocxOpenTypeProperties(document, properties, patch.features);
2750
+ applied.add(marker);
2751
+ changed = true;
2752
+ }
2753
+ }
2754
+ if (changed) archive.file(entry.name, serializeUtf8Xml(document));
2755
+ }
2756
+ const missing = patches.filter((patch)=>!applied.has(patch.marker));
2757
+ if (missing.length) throw new Error(`DOCX OpenType markers were not emitted: ${missing.map((patch)=>patch.marker).join(', ')}.`);
2758
+ return archive.generateAsync({
2759
+ type: 'arraybuffer'
2760
+ });
2761
+ }
2762
+ function validatedPatches(patches) {
2763
+ const result = new Map();
2764
+ for (const patch of patches){
2765
+ const features = normalizeDocumentOpenTypeFeatures(patch.features);
2766
+ if (!patch.marker || !features || result.has(patch.marker)) throw new Error('Document contains invalid OpenType patches.');
2767
+ result.set(patch.marker, {
2768
+ ...patch,
2769
+ features
2770
+ });
2771
+ }
2772
+ return result;
2773
+ }
2774
+ function appendDocxOpenTypeProperties(document, properties, source) {
2775
+ const features = normalizeDocumentOpenTypeFeatures(source);
2776
+ if (!features) throw new Error('Document contains invalid OpenType typography.');
2777
+ const prefix = work_docx_opentype_export_ensureWord2010Prefix(document.documentElement);
2778
+ if (void 0 !== features.ligatures) properties.append(valuedElement(document, prefix, 'ligatures', features.ligatures));
2779
+ if (void 0 !== features.numberForm) properties.append(valuedElement(document, prefix, 'numForm', features.numberForm));
2780
+ if (void 0 !== features.numberSpacing) properties.append(valuedElement(document, prefix, 'numSpacing', features.numberSpacing));
2781
+ if (void 0 !== features.stylisticSets) {
2782
+ const stylisticSets = word2010Element(document, prefix, 'stylisticSets');
2783
+ for (const id of features.stylisticSets)stylisticSets.append(valuedElement(document, prefix, 'styleSet', String(id), 'id'));
2784
+ properties.append(stylisticSets);
2785
+ }
2786
+ if (void 0 !== features.contextualAlternates) properties.append(valuedElement(document, prefix, 'cntxtAlts', features.contextualAlternates ? '1' : '0'));
2787
+ }
2788
+ function valuedElement(document, prefix, name, value, attribute = 'val') {
2789
+ const element = word2010Element(document, prefix, name);
2790
+ element.setAttributeNS(DOCX_WORD_2010_NAMESPACE, `${prefix}:${attribute}`, value);
2791
+ return element;
2792
+ }
2793
+ function word2010Element(document, prefix, name) {
2794
+ return document.createElementNS(DOCX_WORD_2010_NAMESPACE, `${prefix}:${name}`);
2795
+ }
2796
+ function work_docx_opentype_export_ensureWord2010Prefix(root) {
2797
+ const existing = Array.from(root.attributes).find((attribute)=>attribute.namespaceURI === work_docx_settings_xml_XMLNS_NAMESPACE && attribute.value === DOCX_WORD_2010_NAMESPACE);
2798
+ const prefix = existing?.localName ?? availablePrefix(root, 'w14');
2799
+ if (!existing) root.setAttributeNS(work_docx_settings_xml_XMLNS_NAMESPACE, `xmlns:${prefix}`, DOCX_WORD_2010_NAMESPACE);
2800
+ ensureIgnorable(root, prefix);
2801
+ return prefix;
2802
+ }
2803
+ function availablePrefix(root, preferred) {
2804
+ let index = 0;
2805
+ while(true){
2806
+ const prefix = index ? `${preferred}${index}` : preferred;
2807
+ const occupied = Array.from(root.attributes).some((attribute)=>attribute.namespaceURI === work_docx_settings_xml_XMLNS_NAMESPACE && attribute.localName === prefix);
2808
+ if (!occupied) return prefix;
2809
+ index += 1;
2810
+ }
2811
+ }
2812
+ function ensureIgnorable(root, word2010Prefix) {
2813
+ const existingPrefix = Array.from(root.attributes).find((attribute)=>attribute.namespaceURI === work_docx_settings_xml_XMLNS_NAMESPACE && attribute.value === work_docx_opentype_export_MARKUP_COMPATIBILITY_NAMESPACE)?.localName;
2814
+ const prefix = existingPrefix ?? availablePrefix(root, 'mc');
2815
+ if (!existingPrefix) root.setAttributeNS(work_docx_settings_xml_XMLNS_NAMESPACE, `xmlns:${prefix}`, work_docx_opentype_export_MARKUP_COMPATIBILITY_NAMESPACE);
2816
+ const value = root.getAttributeNS(work_docx_opentype_export_MARKUP_COMPATIBILITY_NAMESPACE, 'Ignorable');
2817
+ const tokens = value?.trim().split(/\s+/).filter(Boolean) ?? [];
2818
+ if (!tokens.includes(word2010Prefix)) tokens.push(word2010Prefix);
2819
+ root.setAttributeNS(work_docx_opentype_export_MARKUP_COMPATIBILITY_NAMESPACE, `${prefix}:Ignorable`, tokens.join(' '));
2820
+ }
2821
+ function work_docx_opentype_export_wordValue(element) {
2822
+ const values = Array.from(element.attributes).filter((attribute)=>'val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? ''));
2823
+ return 1 === values.length ? values[0].value : null;
2824
+ }
2825
+ function work_docx_opentype_export_setWordValue(element, value) {
2826
+ const namespace = element.namespaceURI ?? '';
2827
+ const prefix = element.prefix || 'w';
2828
+ for (const attribute of Array.from(element.attributes))if ('val' === xmlAttributeLocalName(attribute) && DOCX_WORDPROCESSING_NAMESPACES.has(xmlAttributeNamespace(element, attribute) ?? '')) element.removeAttributeNode(attribute);
2829
+ element.setAttributeNS(namespace, `${prefix}:val`, value);
2830
+ }
2663
2831
  const MAX_RUN_FORMATTING_CHANGE_PATCHES = 65536;
2664
2832
  const RUN_FORMATTING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
2665
2833
  class DocxRunFormattingChangePatchCollector {
@@ -2805,6 +2973,11 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
2805
2973
  appendVerticalAlignProperty(document, properties, namespace, prefix, byType);
2806
2974
  appendEmphasisMarkProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2807
2975
  appendProofingLanguagesProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2976
+ appendOpenTypeProperties(document, properties, byType.get('textStyle'));
2977
+ }
2978
+ function appendOpenTypeProperties(document, properties, mark) {
2979
+ const features = parseDocumentOpenTypeFeatures(mark?.attrs?.openTypeFeatures);
2980
+ if (features) appendDocxOpenTypeProperties(document, properties, features);
2808
2981
  }
2809
2982
  function appendNoProofProperty(document, properties, namespace, prefix, mark) {
2810
2983
  const noProof = normalizeDocumentNoProof(mark?.attrs?.noProof);
@@ -5271,12 +5444,12 @@ function work_docx_note_comment_hyperlink_relationships_removeNamespacedAttribut
5271
5444
  function setNamespacedAttribute(element, root, namespace, preferredPrefix, localName, value) {
5272
5445
  let prefix = xmlDeclaredPrefix(element, namespace) ?? xmlDeclaredPrefix(root, namespace);
5273
5446
  if (!prefix) {
5274
- prefix = availablePrefix(root, preferredPrefix);
5447
+ prefix = work_docx_note_comment_hyperlink_relationships_availablePrefix(root, preferredPrefix);
5275
5448
  root.setAttributeNS(work_docx_settings_xml_XMLNS_NAMESPACE, `xmlns:${prefix}`, namespace);
5276
5449
  }
5277
5450
  element.setAttributeNS(namespace, `${prefix}:${localName}`, value);
5278
5451
  }
5279
- function availablePrefix(root, preferred) {
5452
+ function work_docx_note_comment_hyperlink_relationships_availablePrefix(root, preferred) {
5280
5453
  if (!xmlNamespaceUri(root, preferred)) return preferred;
5281
5454
  let index = 1;
5282
5455
  while(xmlNamespaceUri(root, `${preferred}${index}`))index += 1;
@@ -8424,11 +8597,13 @@ async function createDocxBlob(content, sourcePackage) {
8424
8597
  runFontPatches: new DocxRunFontsPatchCollector(JSON.stringify(normalizedContent)),
8425
8598
  hiddenTextPatches: new DocxHiddenTextPatchCollector(JSON.stringify(normalizedContent)),
8426
8599
  legacyTextEffectsPatches: new DocxLegacyTextEffectsPatchCollector(JSON.stringify(normalizedContent)),
8600
+ openTypePatches: new DocxOpenTypePatchCollector(JSON.stringify(normalizedContent)),
8427
8601
  runBorderPatches: new DocxRunBorderPatchCollector(JSON.stringify(normalizedContent)),
8428
8602
  usedRunBorderMarkers: new Set(),
8429
8603
  runShadingPatches: new DocxRunShadingPatchCollector(JSON.stringify(normalizedContent)),
8430
8604
  usedRunShadingMarkers: new Set(),
8431
8605
  usedNativeTextEffectMarkers: new Set(),
8606
+ usedOpenTypeMarkers: new Set(),
8432
8607
  paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
8433
8608
  tableOfContentsPatches: new DocxTableOfContentsPatchCollector(),
8434
8609
  indexPatches: new DocxIndexPatchCollector(),
@@ -8483,7 +8658,8 @@ async function createDocxBlob(content, sourcePackage) {
8483
8658
  const characterSpacingPatched = noteContext.hasExplicitZeroCharacterSpacing ? await patchDocxExplicitZeroCharacterSpacing(await packed.arrayBuffer()) : await packed.arrayBuffer();
8484
8659
  const kerningPatched = noteContext.hasExplicitZeroKerningThreshold ? await patchDocxExplicitZeroKerningThresholds(characterSpacingPatched) : characterSpacingPatched;
8485
8660
  const runFontsPatched = await patchDocxRunFonts(kerningPatched, noteContext.runFontPatches.patches);
8486
- const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
8661
+ const openTypePatched = await patchDocxOpenTypeFeatures(runFontsPatched, noteContext.openTypePatches.patches.filter((patch)=>noteContext.usedOpenTypeMarkers.has(patch.marker)));
8662
+ const hiddenTextPatched = await patchDocxHiddenText(openTypePatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
8487
8663
  const legacyTextEffectsPatched = await patchDocxLegacyTextEffects(hiddenTextPatched, noteContext.legacyTextEffectsPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
8488
8664
  const runBordersPatched = await patchDocxRunBorders(legacyTextEffectsPatched, noteContext.runBorderPatches.patches.filter((patch)=>noteContext.usedRunBorderMarkers.has(patch.marker)));
8489
8665
  const runShadingPatched = await patchDocxRunShading(runBordersPatched, noteContext.runShadingPatches.patches.filter((patch)=>noteContext.usedRunShadingMarkers.has(patch.marker)));
@@ -8516,13 +8692,20 @@ async function createDocxBlob(content, sourcePackage) {
8516
8692
  type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
8517
8693
  });
8518
8694
  }
8519
- function docxNativeTextEffectState(style, context) {
8695
+ function docxRunStyleState(style, context) {
8520
8696
  let current = style;
8521
8697
  let hiddenText;
8698
+ let openTypeFeatures;
8522
8699
  const legacyTextEffects = {};
8523
8700
  const seen = new Set();
8524
8701
  while(current && !seen.has(current)){
8525
8702
  seen.add(current);
8703
+ const openTypePatch = context.openTypePatches.lookup(current);
8704
+ if (openTypePatch) {
8705
+ openTypeFeatures ??= openTypePatch.features;
8706
+ current = openTypePatch.style;
8707
+ continue;
8708
+ }
8526
8709
  const hiddenPatch = context.hiddenTextPatches.lookup(current);
8527
8710
  if (hiddenPatch) {
8528
8711
  hiddenText ??= hiddenPatch.value;
@@ -8547,14 +8730,23 @@ function docxNativeTextEffectState(style, context) {
8547
8730
  ...void 0 !== hiddenText ? {
8548
8731
  hiddenText
8549
8732
  } : {},
8733
+ ...openTypeFeatures ? {
8734
+ openTypeFeatures
8735
+ } : {},
8550
8736
  legacyTextEffects
8551
8737
  };
8552
8738
  }
8553
- function markDocxNativeTextEffectStyleUsed(style, context) {
8739
+ function markDocxRunStyleMarkersUsed(style, context) {
8554
8740
  let current = style;
8555
8741
  const seen = new Set();
8556
8742
  while(current && !seen.has(current)){
8557
8743
  seen.add(current);
8744
+ const openTypePatch = context.openTypePatches.lookup(current);
8745
+ if (openTypePatch) {
8746
+ context.usedOpenTypeMarkers.add(current);
8747
+ current = openTypePatch.style;
8748
+ continue;
8749
+ }
8558
8750
  const hiddenPatch = context.hiddenTextPatches.lookup(current);
8559
8751
  if (hiddenPatch) {
8560
8752
  context.usedNativeTextEffectMarkers.add(current);
@@ -8751,7 +8943,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8751
8943
  const visit = async (node, inherited = {}, revision)=>{
8752
8944
  if (node.nodeType === Node.TEXT_NODE) {
8753
8945
  if (!node.textContent) return [];
8754
- markDocxNativeTextEffectStyleUsed(inherited.style, noteContext);
8946
+ markDocxRunStyleMarkersUsed(inherited.style, noteContext);
8755
8947
  markDocxRunBorderUsed(inherited.border, noteContext);
8756
8948
  markDocxRunShadingUsed(inherited.shading, noteContext);
8757
8949
  if (revision?.kind === 'insertion') return [
@@ -8843,6 +9035,9 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8843
9035
  const hasExplicitNoProof = 'span' === tag && node.hasAttribute(DOCUMENT_NO_PROOF_ATTRIBUTE);
8844
9036
  const explicitNoProof = hasExplicitNoProof ? documentNoProofFromElement(node) : null;
8845
9037
  if (hasExplicitNoProof && null === explicitNoProof) throw new Error('Document contains invalid proofing state.');
9038
+ const hasExplicitOpenType = 'span' === tag && node.hasAttribute(DOCUMENT_OPEN_TYPE_ATTRIBUTE);
9039
+ const explicitOpenType = hasExplicitOpenType ? documentOpenTypeFeaturesFromElement(node) : null;
9040
+ if (hasExplicitOpenType && !explicitOpenType) throw new Error('Document contains invalid OpenType typography.');
8846
9041
  const hasExplicitLegacyTextEffects = 'span' === tag && [
8847
9042
  DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE,
8848
9043
  DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE,
@@ -8863,18 +9058,20 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8863
9058
  const position = null === explicitCharacterPosition ? inherited.position : docxCharacterPositionValue(explicitCharacterPosition);
8864
9059
  const emphasisMark = null === explicitEmphasisMark ? inherited.emphasisMark : docxEmphasisMarkRunOptions(explicitEmphasisMark);
8865
9060
  const textCaseOptions = docxTextCaseRunOptions(explicitTextCase, inherited);
8866
- const inheritedNativeTextEffects = docxNativeTextEffectState(inherited.style, noteContext);
9061
+ const inheritedRunStyle = docxRunStyleState(inherited.style, noteContext);
8867
9062
  const legacyTextEffects = {
8868
- ...inheritedNativeTextEffects.legacyTextEffects,
9063
+ ...inheritedRunStyle.legacyTextEffects,
8869
9064
  ...explicitLegacyTextEffects ?? {}
8870
9065
  };
8871
9066
  if (documentLegacyTextEffectsConflict(legacyTextEffects)) throw new Error('Document contains conflicting legacy text effects.');
8872
- const hiddenText = null === explicitHiddenText ? inheritedNativeTextEffects.hiddenText : explicitHiddenText;
8873
- let nativeTextEffectStyle = inherited.style;
8874
- if (hasExplicitLegacyTextEffects || null !== explicitHiddenText) {
8875
- nativeTextEffectStyle = inheritedNativeTextEffects.baseStyle;
8876
- if (Object.keys(legacyTextEffects).length) nativeTextEffectStyle = noteContext.legacyTextEffectsPatches.marker(legacyTextEffects, nativeTextEffectStyle);
8877
- if (void 0 !== hiddenText) nativeTextEffectStyle = noteContext.hiddenTextPatches.marker(hiddenText, nativeTextEffectStyle);
9067
+ const hiddenText = null === explicitHiddenText ? inheritedRunStyle.hiddenText : explicitHiddenText;
9068
+ const openTypeFeatures = hasExplicitOpenType ? explicitOpenType ?? void 0 : inheritedRunStyle.openTypeFeatures;
9069
+ let runStyle = inherited.style;
9070
+ if (hasExplicitLegacyTextEffects || null !== explicitHiddenText || hasExplicitOpenType) {
9071
+ runStyle = inheritedRunStyle.baseStyle;
9072
+ if (Object.keys(legacyTextEffects).length) runStyle = noteContext.legacyTextEffectsPatches.marker(legacyTextEffects, runStyle);
9073
+ if (void 0 !== hiddenText) runStyle = noteContext.hiddenTextPatches.marker(hiddenText, runStyle);
9074
+ if (openTypeFeatures) runStyle = noteContext.openTypePatches.marker(openTypeFeatures, runStyle);
8878
9075
  }
8879
9076
  const underline = docxUnderlineRunOptions(node, inherited.underline, noteContext.themePatches);
8880
9077
  const strike = docxStrikeRunOptions(node, inherited);
@@ -8884,7 +9081,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8884
9081
  const noProof = hasExplicitNoProof ? explicitNoProof ?? false : inherited.noProof;
8885
9082
  const style = {
8886
9083
  ...inherited,
8887
- style: nativeTextEffectStyle,
9084
+ style: runStyle,
8888
9085
  bold: inherited.bold || 'strong' === tag || 'b' === tag,
8889
9086
  italics: inherited.italics || 'em' === tag || 'i' === tag,
8890
9087
  underline,
@@ -8913,7 +9110,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8913
9110
  ...textCaseOptions
8914
9111
  };
8915
9112
  if ('br' === tag) {
8916
- markDocxNativeTextEffectStyleUsed(style.style, noteContext);
9113
+ markDocxRunStyleMarkersUsed(style.style, noteContext);
8917
9114
  markDocxRunBorderUsed(style.border, noteContext);
8918
9115
  markDocxRunShadingUsed(style.shading, noteContext);
8919
9116
  return [
@@ -1,8 +1,8 @@
1
1
  import jszip from "jszip";
2
2
  import { documentRunBorderDomAttributes, contentTypeForPart, bytesToDataUrl, OoxmlPackage, normalizeDocumentIndexesHtml, firstDescendant, normalizeDocumentParagraphId, applyDocumentParagraphIdentityToElement, descendants, documentHighlightDomAttributes, attribute as work_ooxml_package_attribute, documentHighlightFromDocxValue, serializeDocxThemeReference, normalizeDocumentTableOfContentsHtml, directChildren, documentParagraphShadingDomAttributes, documentProofingDomAttributes, documentParagraphBordersDomAttributes, directChild, documentScriptFontSegments, normalizeDocumentParagraphIdentity, documentRunShadingDomAttributes } from "./4121.js";
3
- import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, 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, documentKerningDomAttributes, docxDocumentFieldKind, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentCharacterScaleDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./4174.js";
3
+ import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, 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, documentKerningDomAttributes, docxDocumentFieldKind, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentCharacterScaleDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, documentOpenTypeDomAttributes, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./4174.js";
4
4
  import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, createDocxParagraphStyleResolver, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, resolveDocxLegacyTextEffects, markDocxTablesOfContents, hasImportedDocxParagraphSpacingMarkers, applyImportedDocxIndexMarkers, applyImportedDocxTableOfContentsMarkers, markDocxIndexes, parseDocxPageMargins, docxTablePropertySources, parseDirectDocxParagraphShading, markDocxParagraphIndents, markDocxPackageEquations, resolveDocxRunBorder, parseDocxPageGeometry, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxTableOfContentsMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphAlignmentMarkers, markDocxParagraphPagination, importedDocxUnderline, markDocxParagraphBorders, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxParagraphPaginationMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~7240.js";
5
- import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~4808.js";
5
+ import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, resolveDocxOpenTypeFeatures, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~5024.js";
6
6
  import { importDocxPageColor, importedDocumentNoteId } from "./0~4980.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
8
8
  const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
@@ -1801,6 +1801,8 @@ async function runHtml(run, field, context) {
1801
1801
  } : {}
1802
1802
  })}>${content}</span>`;
1803
1803
  }
1804
+ const openTypeFeatures = resolveDocxOpenTypeFeatures(propertySources).features;
1805
+ if (openTypeFeatures) content = `<span${htmlAttributes(documentOpenTypeDomAttributes(openTypeFeatures))}>${content}</span>`;
1804
1806
  const characterPosition = docxCharacterPositionHalfPointsFromProperties(properties ?? run);
1805
1807
  if (void 0 !== characterPosition) content = `<span${htmlAttributes(documentCharacterPositionDomAttributes(characterPosition))}>${content}</span>`;
1806
1808
  const emphasisMark = resolveDocxEmphasisMark(propertySources);
@@ -3,7 +3,7 @@ import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescen
3
3
  import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, normalizeDocumentBookmarkNativeId, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./4174.js";
4
4
  import { markDocxParagraphShading, inspectDocxPageSize, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, createDocxTableStyleResolver, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunFonts, inspectDocxRunBorder, inspectDocxRunShading, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxHiddenText, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~7240.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
- import { xmlAttributeLocalName, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~4808.js";
6
+ import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~5024.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, isSupportedXlsxWorksheetImageContentType, MAX_XLSX_WORKSHEET_IMAGE_BYTES, xlsxChartSeriesFormattingShapeProperties, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4166.js";
8
8
  import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount, xlsxWorksheetCellEntries } from "./9333.js";
9
9
  import { formulaHasStructuredReference, formulaHasExternalReference, parseSpreadsheetPrintTitles, volatileSpreadsheetFormulaFunctions, stripSpreadsheetSheetQualifier } from "./8715.js";
@@ -606,6 +606,61 @@ function noteIssue(code, message, severity = 'warning') {
606
606
  severity
607
607
  };
608
608
  }
609
+ const OPEN_TYPE_DIAGNOSTIC_PART_PATTERN = /^word\/(?:document|styles|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i;
610
+ const OPEN_TYPE_PROPERTY_NAMES = new Set([
611
+ 'ligatures',
612
+ 'numForm',
613
+ 'numSpacing',
614
+ 'stylisticSets',
615
+ 'cntxtAlts'
616
+ ]);
617
+ async function diagnoseDocxOpenTypeTypography(archive, document) {
618
+ const parts = [
619
+ {
620
+ path: 'word/document.xml',
621
+ document
622
+ }
623
+ ];
624
+ for (const path of archive.paths('word/'))if ('word/document.xml' !== path.toLowerCase() && OPEN_TYPE_DIAGNOSTIC_PART_PATTERN.test(path)) parts.push({
625
+ path,
626
+ document: await archive.xml(path)
627
+ });
628
+ let validCount = 0;
629
+ let invalidCount = 0;
630
+ let spoofedCount = 0;
631
+ for (const part of parts){
632
+ const propertySets = descendants(part.document, 'rPr').filter((element)=>DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? ''));
633
+ for (const properties of propertySets){
634
+ const candidates = directChildren(properties).filter((child)=>OPEN_TYPE_PROPERTY_NAMES.has(child.localName));
635
+ if (!candidates.length) continue;
636
+ const inspection = resolveDocxOpenTypeFeatures([
637
+ properties
638
+ ]);
639
+ if (inspection.features) validCount += 1;
640
+ invalidCount += inspection.invalidCount;
641
+ spoofedCount += inspection.spoofedCount;
642
+ }
643
+ for (const name of OPEN_TYPE_PROPERTY_NAMES)for (const property of descendants(part.document, name)){
644
+ const parent = property.parentElement;
645
+ if (!(parent?.localName === 'rPr' && DOCX_WORDPROCESSING_NAMESPACES.has(parent.namespaceURI ?? ''))) if (property.namespaceURI === DOCX_WORD_2010_NAMESPACE) invalidCount += 1;
646
+ else spoofedCount += 1;
647
+ }
648
+ }
649
+ const issues = [];
650
+ if (validCount) issues.push({
651
+ code: 'docx.typography.opentype',
652
+ severity: 'info',
653
+ feature: 'OpenType typography',
654
+ message: `${validCount} native OpenType run-property set(s) preserve all 16 w14:ligatures combinations, default, lining, or old-style number forms, default, proportional, or tabular number spacing, style sets 1-20, and contextual alternates through inheritance, body and static-story editing, formatting revisions, CSS projection, and DOCX export.`
655
+ });
656
+ if (invalidCount || spoofedCount) issues.push({
657
+ code: 'docx.typography.opentype.invalid',
658
+ severity: 'warning',
659
+ feature: 'OpenType typography',
660
+ message: `${invalidCount + spoofedCount} malformed, duplicated, misplaced, namespace-spoofed, text-bearing, child-bearing, extra-attribute, unknown, or out-of-range OpenType run-property value(s) are ignored instead of enabling untrusted typography.`
661
+ });
662
+ return issues;
663
+ }
609
664
  async function diagnoseDocxPageBorders(archive, document) {
610
665
  const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
611
666
  const themeDocument = themePath ? await archive.xml(themePath) : null;
@@ -2108,6 +2163,7 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
2108
2163
  issues.push(...await diagnoseDocxEquations(archive, document));
2109
2164
  if (document) {
2110
2165
  issues.push(...await diagnoseDocxKerning(archive, document));
2166
+ issues.push(...await diagnoseDocxOpenTypeTypography(archive, document));
2111
2167
  issues.push(...await diagnoseDocxEmphasisMarks(archive, document));
2112
2168
  issues.push(...await diagnoseDocxHiddenText(archive, document));
2113
2169
  issues.push(...await diagnoseDocxLegacyTextEffects(archive, document));