@a3s-lab/office 0.44.0 → 0.46.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.
Files changed (25) hide show
  1. package/README.md +24 -0
  2. package/dist/{0~2330.js → 0~2133.js} +325 -19
  3. package/dist/{0~5024.js → 0~4042.js} +110 -2
  4. package/dist/0~document-editor.js +562 -9
  5. package/dist/0~work-docx-export.js +206 -8
  6. package/dist/0~work-docx-import.js +22 -7
  7. package/dist/0~work-office-diagnostics.js +19 -3
  8. package/dist/4174.js +508 -3
  9. package/dist/internal/features/work/editors/document-command-catalog.d.ts +15 -1
  10. package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +4 -1
  11. package/dist/internal/features/work/editors/document-text-box-ribbon.d.ts +4 -0
  12. package/dist/internal/features/work/editors/document-toolbar.d.ts +2 -1
  13. package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +1 -0
  14. package/dist/internal/features/work/work-document-image-layout.d.ts +14 -0
  15. package/dist/internal/features/work/work-document-text-box.d.ts +64 -0
  16. package/dist/internal/features/work/work-docx-export-image.d.ts +2 -1
  17. package/dist/internal/features/work/work-docx-image-layout-import.d.ts +2 -1
  18. package/dist/internal/features/work/work-docx-image-transform.d.ts +17 -0
  19. package/dist/internal/features/work/work-docx-import.d.ts +3 -1
  20. package/dist/internal/features/work/work-docx-text-box-export.d.ts +25 -0
  21. package/dist/internal/features/work/work-docx-text-box-import.d.ts +26 -0
  22. package/dist/office-kernel.wasm +0 -0
  23. package/dist/styles.css +101 -2
  24. package/docs/latest/en/browser-editor-architecture.md +7 -3
  25. package/package.json +6 -3
@@ -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, parseDocumentNumberingChange, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, serializeDocumentOpenTypeFeatures, documentCaptionLabel, documentCaptionKind, isContourImageLayout, normalizeDocumentLegacyTextEffects, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, normalizeDocumentOpenTypeFeatures, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, parseDocumentOpenTypeFeatures, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, parseDocumentCharacterFormatting, documentLegacyTextEffectsFromElement, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentOpenTypeFeaturesFromElement, normalizeDocumentBookmarkNativeId, documentTableRowIdentityFromElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, collectDocumentNotes, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, DOCUMENT_OPEN_TYPE_ATTRIBUTE, MAX_DOCUMENT_NUMBERING_START, 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, parseDocumentNumberingChange, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, serializeDocumentOpenTypeFeatures, documentCaptionLabel, documentCaptionKind, isContourImageLayout, normalizeDocumentLegacyTextEffects, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, normalizeDocumentOpenTypeFeatures, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, documentTextBoxPropertiesFromElement, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, parseDocumentOpenTypeFeatures, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentImageTransformFromElement, parseDocumentCharacterFormatting, documentLegacyTextEffectsFromElement, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentOpenTypeFeaturesFromElement, normalizeDocumentBookmarkNativeId, documentTableRowIdentityFromElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, collectDocumentNotes, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, DOCUMENT_OPEN_TYPE_ATTRIBUTE, MAX_DOCUMENT_NUMBERING_START, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./4174.js";
3
3
  import { normalizeDocumentRunBorder, parseDocumentScriptFonts, parseDocxThemeReference, parseXml, parseDocumentRunShading, applyDocumentParagraphIdentityToElement, DOCUMENT_RUN_SHADING_ATTRIBUTE, documentScriptFontSlotFromElement, DOCUMENT_HIGHLIGHT_ATTRIBUTE, normalizeDocumentIndexesHtml, serializeDocumentScriptFonts, attribute as work_ooxml_package_attribute, createDocumentParagraphIdentityRegistry, uniqueDocumentParagraphIdentity, DOCUMENT_NO_PROOF_ATTRIBUTE, documentHighlightForCssColor, directChildren, documentTableOfContentsValueFromElement, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DocxThemePatchCollector, normalizeDocumentScriptFonts, normalizeDocumentParagraphIdentity, normalizeDocumentHighlight, normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES, parseDocumentRunBorder, normalizeDocumentNoProof, decodeXmlBytes, documentParagraphIdentityFromElement, normalizeDocumentParagraphId, documentScriptFontFamily, descendants, resolvePartTarget, documentProofingLanguagesFromElement, documentHighlightFromElement, parseDocumentRunShadingElement, parseDocumentProofingLanguages, patchDocxThemeReferences, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, parseDocumentRunBorderElement, xmlNamespacePrefix, documentScriptFontSlotFromHint, documentNoProofFromElement, documentScriptFontsFromElement, normalizeDocumentRunShading, normalizeDocumentScriptFontSlot, directChild, documentIndexEntryFromElement, documentIndexValueFromElement, parseDocumentParagraphShadingElement, documentFontNameFromCssFamily } from "./6968.js";
4
4
  import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.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";
5
+ import { DocxImageTransformPatchCollector, paragraphTabStops, patchDocxImageTransforms, 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~4042.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 {
@@ -1959,7 +1959,7 @@ function supportedPartRoot(root, path) {
1959
1959
  const expected = /^word\/header\d*\.xml$/i.test(path) ? 'hdr' : /^word\/footer\d*\.xml$/i.test(path) ? 'ftr' : /^word\/footnotes\.xml$/i.test(path) ? 'footnotes' : /^word\/endnotes\.xml$/i.test(path) ? 'endnotes' : 'document';
1960
1960
  return root.localName === expected && DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '');
1961
1961
  }
1962
- async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches, identityPatches) {
1962
+ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches, identityPatches, transformPatches) {
1963
1963
  const source = element.getAttribute('src');
1964
1964
  const alt = element.getAttribute('alt') || element.getAttribute('title') || 'Image';
1965
1965
  if (!source) return new docx.TextRun(`[${alt}]`);
@@ -1982,6 +1982,7 @@ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches
1982
1982
  const wrapMarker = wrapPatches?.marker(imageLayout, documentImageWrapContourFromElement(element));
1983
1983
  const layer = documentImageLayerFromElement(element);
1984
1984
  const layerMarker = layerPatches?.marker(imageLayout.layout, layer);
1985
+ const transformMarker = transformPatches?.marker(documentImageTransformFromElement(element));
1985
1986
  return new docx.ImageRun({
1986
1987
  type,
1987
1988
  data: await blob.arrayBuffer(),
@@ -1990,7 +1991,7 @@ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches
1990
1991
  height: Math.max(24, Math.round(dimensions.height * scale))
1991
1992
  },
1992
1993
  altText: {
1993
- name: `${alt}${cropMarker ?? ''}${wrapMarker ?? ''}${layerMarker ?? ''}${identity?.marker ?? ''}`,
1994
+ name: `${alt}${cropMarker ?? ''}${wrapMarker ?? ''}${layerMarker ?? ''}${identity?.marker ?? ''}${transformMarker ?? ''}`,
1994
1995
  description: alt,
1995
1996
  title: alt,
1996
1997
  id: identity ? String(identity.docPropertiesId) : void 0
@@ -4905,6 +4906,84 @@ function removeWordAttribute(element, localName) {
4905
4906
  function work_docx_table_of_contents_export_wordQualifiedName(root, localName) {
4906
4907
  return `${xmlNamespacePrefix(root, work_docx_table_of_contents_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
4907
4908
  }
4909
+ const DOC_PROPERTIES_ID_MAX = 0xffffffff;
4910
+ const TEXT_BOX_ID_MARKER_PATTERN = /__A3S_TEXT_BOX_ID_\d+__/g;
4911
+ class DocxTextBoxIdentityPatchCollector {
4912
+ patches = [];
4913
+ nextMarker = 1;
4914
+ register(properties) {
4915
+ const marker = `__A3S_TEXT_BOX_ID_${this.nextMarker}__`;
4916
+ this.nextMarker += 1;
4917
+ this.patches.push({
4918
+ marker,
4919
+ preferredId: properties.docPropertiesId
4920
+ });
4921
+ return {
4922
+ marker,
4923
+ docPropertiesId: properties.docPropertiesId
4924
+ };
4925
+ }
4926
+ }
4927
+ async function patchDocxTextBoxIdentities(buffer, patches) {
4928
+ if (!patches.length) return buffer;
4929
+ const archive = await jszip.loadAsync(buffer);
4930
+ const byMarker = new Map(patches.map((patch)=>[
4931
+ patch.marker,
4932
+ patch
4933
+ ]));
4934
+ const entries = Object.values(archive.files).filter((entry)=>!entry.dir && /^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/.test(entry.name));
4935
+ const documents = await Promise.all(entries.map(async (entry)=>({
4936
+ entry,
4937
+ document: parseXml(await entry.async('text'), entry.name)
4938
+ })));
4939
+ const properties = documents.flatMap(({ document })=>descendants(document, 'docPr'));
4940
+ const marked = properties.map((property)=>({
4941
+ property,
4942
+ patch: textBoxIdentityPatch(property, byMarker)
4943
+ })).filter((value)=>Boolean(value.patch));
4944
+ if (!marked.length) return buffer;
4945
+ const used = new Set();
4946
+ for (const property of properties){
4947
+ if (marked.some((value)=>value.property === property)) continue;
4948
+ const id = parseDocPropertiesId(property.getAttribute('id'));
4949
+ if (null !== id) used.add(id);
4950
+ }
4951
+ let nextId = 1;
4952
+ const changedDocuments = new Set();
4953
+ for (const { property, patch } of marked){
4954
+ removeTextBoxIdentityMarker(property, patch.marker);
4955
+ const preferred = null === patch.preferredId || used.has(patch.preferredId) ? nextAvailableDocPropertiesId(used, nextId) : patch.preferredId;
4956
+ used.add(preferred);
4957
+ nextId = preferred + 1;
4958
+ property.setAttribute('id', String(preferred));
4959
+ changedDocuments.add(property.ownerDocument);
4960
+ }
4961
+ for (const { entry, document } of documents)if (changedDocuments.has(document)) archive.file(entry.name, new XMLSerializer().serializeToString(document));
4962
+ return archive.generateAsync({
4963
+ type: 'arraybuffer'
4964
+ });
4965
+ }
4966
+ function textBoxIdentityPatch(property, byMarker) {
4967
+ for (const attribute of Array.from(property.attributes)){
4968
+ const marker = attribute.value.match(TEXT_BOX_ID_MARKER_PATTERN)?.find((value)=>byMarker.has(value));
4969
+ if (marker) return byMarker.get(marker) ?? null;
4970
+ }
4971
+ return null;
4972
+ }
4973
+ function removeTextBoxIdentityMarker(property, marker) {
4974
+ for (const attribute of Array.from(property.attributes))if (attribute.value.includes(marker)) attribute.value = attribute.value.replace(marker, '').replace(/\s{2,}/g, ' ').trim();
4975
+ }
4976
+ function parseDocPropertiesId(value) {
4977
+ if (null === value || !/^\d+$/.test(value)) return null;
4978
+ const id = Number(value);
4979
+ return Number.isSafeInteger(id) && id <= DOC_PROPERTIES_ID_MAX ? id : null;
4980
+ }
4981
+ function nextAvailableDocPropertiesId(used, start) {
4982
+ let candidate = Math.max(1, start);
4983
+ while(candidate <= DOC_PROPERTIES_ID_MAX && used.has(candidate))candidate += 1;
4984
+ if (candidate > DOC_PROPERTIES_ID_MAX) throw new Error('DOCX drawing-property IDs are exhausted.');
4985
+ return candidate;
4986
+ }
4908
4987
  const work_docx_table_sizing_export_TWIPS_PER_PIXEL = 15;
4909
4988
  function documentTableSizingDocxOptions(table, docx) {
4910
4989
  const geometry = documentTableGeometryFromElement(table);
@@ -8686,6 +8765,8 @@ async function createDocxBlob(content, sourcePackage) {
8686
8765
  imageIdentityPatches: new DocxImageIdentityPatchCollector(),
8687
8766
  imageLayerPatches: new DocxImageLayerPatchCollector(),
8688
8767
  imageWrapPatches: new DocxImageWrapPatchCollector(),
8768
+ imageTransformPatches: new DocxImageTransformPatchCollector(),
8769
+ textBoxIdentityPatches: new DocxTextBoxIdentityPatchCollector(),
8689
8770
  paragraphBorderPatches: new DocxParagraphBorderPatchCollector(JSON.stringify(normalizedContent)),
8690
8771
  paragraphDefaultCollapsedPatches: new DocxParagraphDefaultCollapsedPatchCollector(),
8691
8772
  paragraphIdentityPatches: new DocxParagraphIdentityPatchCollector(JSON.stringify(normalizedContent)),
@@ -8773,8 +8854,10 @@ async function createDocxBlob(content, sourcePackage) {
8773
8854
  const imageCropPatched = await patchDocxImageCrops(themePatched, noteContext.imageCropPatches.patches);
8774
8855
  const imageWrapPatched = await patchDocxImageWraps(imageCropPatched, noteContext.imageWrapPatches.patches);
8775
8856
  const imageLayerPatched = await patchDocxImageLayers(imageWrapPatched, noteContext.imageLayerPatches.patches);
8776
- const imageIdentityPatched = await patchDocxImageIdentities(imageLayerPatched, noteContext.imageIdentityPatches.patches);
8777
- const bookmarkPatched = await patchDocxBookmarks(imageIdentityPatched, noteContext.bookmarkPatches.patches);
8857
+ const imageTransformPatched = await patchDocxImageTransforms(imageLayerPatched, noteContext.imageTransformPatches.patches);
8858
+ const imageIdentityPatched = await patchDocxImageIdentities(imageTransformPatched, noteContext.imageIdentityPatches.patches);
8859
+ const textBoxIdentityPatched = await patchDocxTextBoxIdentities(imageIdentityPatched, noteContext.textBoxIdentityPatches.patches);
8860
+ const bookmarkPatched = await patchDocxBookmarks(textBoxIdentityPatched, noteContext.bookmarkPatches.patches);
8778
8861
  const paragraphDefaultCollapsedPatched = await patchDocxParagraphDefaultCollapsed(bookmarkPatched, noteContext.paragraphDefaultCollapsedPatches.patches);
8779
8862
  const paragraphIdentityPatched = await patchDocxParagraphIdentities(paragraphDefaultCollapsedPatched, noteContext.paragraphIdentityPatches.patches);
8780
8863
  const tableOfContentsPatched = await patchDocxTableOfContents(paragraphIdentityPatched, noteContext.tableOfContentsPatches.patches);
@@ -8974,13 +9057,20 @@ async function blockToFileChildren(element, docx, noteContext) {
8974
9057
  if (element.hasAttribute('data-document-caption')) return [
8975
9058
  docxCaptionParagraph(element, await paragraphRuns(element, docx, noteContext), docx, paragraphBidirectional(element))
8976
9059
  ];
9060
+ if (element.hasAttribute('data-document-text-box')) return [
9061
+ new docx.Paragraph({
9062
+ children: [
9063
+ await textBoxToDocx(element, docx, noteContext)
9064
+ ]
9065
+ })
9066
+ ];
8977
9067
  if ('table' === tag) return [
8978
9068
  await tableToDocx(element, docx, noteContext)
8979
9069
  ];
8980
9070
  if ('img' === tag) return [
8981
9071
  new docx.Paragraph({
8982
9072
  children: [
8983
- await imageToDocx(element, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches)
9073
+ await imageToDocx(element, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches, noteContext.imageTransformPatches)
8984
9074
  ]
8985
9075
  })
8986
9076
  ];
@@ -9004,6 +9094,114 @@ async function blockToFileChildren(element, docx, noteContext) {
9004
9094
  })
9005
9095
  ];
9006
9096
  }
9097
+ async function textBoxToDocx(element, docx, noteContext) {
9098
+ const properties = documentTextBoxPropertiesFromElement(element);
9099
+ const identity = noteContext.textBoxIdentityPatches.register(properties);
9100
+ const runs = await paragraphRuns(element, docx, noteContext);
9101
+ const paragraph = new docx.Paragraph({
9102
+ children: runs.length ? runs : [
9103
+ new docx.TextRun('')
9104
+ ],
9105
+ alignment: paragraphAlignment(element, docx),
9106
+ ...paragraphDirectionOptions(element)
9107
+ });
9108
+ const shapeOptions = {
9109
+ type: 'wps',
9110
+ transformation: {
9111
+ width: millimetersToPixels(properties.width),
9112
+ height: millimetersToPixels(properties.height)
9113
+ },
9114
+ children: [
9115
+ paragraph
9116
+ ],
9117
+ nonVisualProperties: {
9118
+ txBox: '1'
9119
+ },
9120
+ bodyProperties: {
9121
+ verticalAnchor: textBoxVerticalAnchor(properties, docx),
9122
+ margins: {
9123
+ top: work_docx_export_millimetersToEmus(properties.padding),
9124
+ right: work_docx_export_millimetersToEmus(properties.padding),
9125
+ bottom: work_docx_export_millimetersToEmus(properties.padding),
9126
+ left: work_docx_export_millimetersToEmus(properties.padding)
9127
+ },
9128
+ noAutoFit: true
9129
+ },
9130
+ altText: {
9131
+ name: `A3S Text Box ${properties.id || 'text-box'} ${identity.marker}`,
9132
+ description: 'A3S editable text box',
9133
+ title: 'Text box',
9134
+ ...null === identity.docPropertiesId ? {} : {
9135
+ id: String(identity.docPropertiesId)
9136
+ }
9137
+ },
9138
+ ...'transparent' === properties.fill ? {} : {
9139
+ solidFill: {
9140
+ type: 'rgb',
9141
+ value: properties.fill.slice(1)
9142
+ }
9143
+ },
9144
+ outline: 'none' === properties.borderColor || properties.borderWidth <= 0 ? {
9145
+ type: 'noFill'
9146
+ } : {
9147
+ type: 'solidFill',
9148
+ solidFillType: 'rgb',
9149
+ value: properties.borderColor.slice(1),
9150
+ width: work_docx_export_millimetersToEmus(properties.borderWidth)
9151
+ },
9152
+ ...'floating' === properties.layout ? {
9153
+ floating: textBoxFloatingOptions(properties, docx)
9154
+ } : {}
9155
+ };
9156
+ return new docx.WpsShapeRun(shapeOptions);
9157
+ }
9158
+ function textBoxVerticalAnchor(properties, docx) {
9159
+ if ('center' === properties.verticalAlign) return docx.VerticalAnchor.CENTER;
9160
+ if ('bottom' === properties.verticalAlign) return docx.VerticalAnchor.BOTTOM;
9161
+ return docx.VerticalAnchor.TOP;
9162
+ }
9163
+ function textBoxFloatingOptions(properties, docx) {
9164
+ return {
9165
+ horizontalPosition: {
9166
+ relative: textBoxHorizontalReference(properties, docx),
9167
+ offset: work_docx_export_millimetersToEmus(properties.horizontalOffset ?? 0)
9168
+ },
9169
+ verticalPosition: {
9170
+ relative: textBoxVerticalReference(properties, docx),
9171
+ offset: work_docx_export_millimetersToEmus(properties.verticalOffset ?? 0)
9172
+ },
9173
+ allowOverlap: true,
9174
+ behindDocument: false,
9175
+ layoutInCell: true,
9176
+ lockAnchor: false,
9177
+ zIndex: 0,
9178
+ margins: {
9179
+ top: 0,
9180
+ right: 0,
9181
+ bottom: 0,
9182
+ left: 0
9183
+ },
9184
+ wrap: {
9185
+ type: docx.TextWrappingType.SQUARE
9186
+ }
9187
+ };
9188
+ }
9189
+ function textBoxHorizontalReference(properties, docx) {
9190
+ if ('margin' === properties.horizontalReference) return docx.HorizontalPositionRelativeFrom.MARGIN;
9191
+ if ('page' === properties.horizontalReference) return docx.HorizontalPositionRelativeFrom.PAGE;
9192
+ return docx.HorizontalPositionRelativeFrom.COLUMN;
9193
+ }
9194
+ function textBoxVerticalReference(properties, docx) {
9195
+ if ('margin' === properties.verticalReference) return docx.VerticalPositionRelativeFrom.MARGIN;
9196
+ if ('page' === properties.verticalReference) return docx.VerticalPositionRelativeFrom.PAGE;
9197
+ return docx.VerticalPositionRelativeFrom.PARAGRAPH;
9198
+ }
9199
+ function millimetersToPixels(value) {
9200
+ return 96 * value / 25.4;
9201
+ }
9202
+ function work_docx_export_millimetersToEmus(value) {
9203
+ return Math.round(36000 * value);
9204
+ }
9007
9205
  function paragraphHeadingLevel(tag, docx) {
9008
9206
  if ('h1' === tag) return docx.HeadingLevel.HEADING_1;
9009
9207
  if ('h2' === tag) return docx.HeadingLevel.HEADING_2;
@@ -9221,7 +9419,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
9221
9419
  ];
9222
9420
  }
9223
9421
  if ('img' === tag) return [
9224
- await imageToDocx(node, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches)
9422
+ await imageToDocx(node, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches, noteContext.imageTransformPatches)
9225
9423
  ];
9226
9424
  if ('span' === tag && 'true' === node.dataset.documentBookmarkBoundary) {
9227
9425
  const marker = noteContext.bookmarkPatches.register(node);
@@ -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 "./6968.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
- import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxNumberingChangeMarkers, 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, hasImportedDocxNumberingChangeMarkers, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphDirectionMarkers, markDocxNumberingChanges, applyImportedDocxParagraphAlignmentMarkers, importedDocxUnderline, markDocxParagraphBorders, markDocxParagraphPagination, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxParagraphPaginationMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~2330.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";
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, applyDocumentImageTransformToElement, 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
+ import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxTextBoxMarkers, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, markDocxTextBoxes, createDocxParagraphStyleResolver, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, resolveDocxLegacyTextEffects, markDocxTablesOfContents, hasImportedDocxParagraphSpacingMarkers, applyImportedDocxIndexMarkers, applyImportedDocxTableOfContentsMarkers, markDocxIndexes, docxTablePropertySources, parseDirectDocxParagraphShading, markDocxPackageEquations, markDocxParagraphIndents, parseDocxPageMargins, resolveDocxRunBorder, parseDocxPageGeometry, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, hasImportedDocxNumberingChangeMarkers, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, hasImportedDocxTextBoxMarkers, markDocxNumberingChanges, markDocxParagraphPagination, importedDocxUnderline, markDocxParagraphBorders, applyImportedDocxParagraphDirectionMarkers, applyImportedDocxParagraphAlignmentMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, applyImportedDocxParagraphPaginationMarkers, applyImportedDocxParagraphTabStopMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~2133.js";
5
+ import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, resolveDocxOpenTypeFeatures, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, readDocxImageTransform, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~4042.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';
@@ -1039,6 +1039,7 @@ function markDocxImageLayouts(document, state = createImportedDocxImageLayoutMar
1039
1039
  const run = closestAncestor(anchor, 'r');
1040
1040
  if (!run || markedRuns.has(run)) continue;
1041
1041
  const crop = anchorCrop(anchor);
1042
+ const transform = anchorTransform(anchor);
1042
1043
  const layout = 'inline' === anchor.localName ? 'inline' : anchorLayout(anchor);
1043
1044
  if (!layout) continue;
1044
1045
  if (state.nextMarker > MAX_IMPORTED_IMAGE_LAYOUTS) throw new Error('Imported DOCX exceeds the image-layout limit.');
@@ -1060,6 +1061,7 @@ function markDocxImageLayouts(document, state = createImportedDocxImageLayoutMar
1060
1061
  }),
1061
1062
  position: anchorPosition(anchor),
1062
1063
  crop,
1064
+ transform,
1063
1065
  contour: isContourImageLayout(layout) ? anchorWrapContour(anchor, layout) : null,
1064
1066
  layer: 'anchor' === anchor.localName ? anchorLayer(anchor) : null,
1065
1067
  identity: uniqueDocumentImageIdentity(drawingIdentitySource(anchor), state.identityRegistry)
@@ -1098,7 +1100,7 @@ function applyImportedDocxImageLayoutMarkers(document, markers) {
1098
1100
  continue;
1099
1101
  }
1100
1102
  if (!state.applied && state.active && node instanceof HTMLImageElement) {
1101
- applyImageLayout(node, state.active.options, state.active.position, state.active.crop, state.active.contour, state.active.layer, state.active.identity);
1103
+ applyImageLayout(node, state.active.options, state.active.position, state.active.crop, state.active.transform, state.active.contour, state.active.layer, state.active.identity);
1102
1104
  state.applied = true;
1103
1105
  }
1104
1106
  }
@@ -1185,6 +1187,9 @@ function anchorCrop(anchor) {
1185
1187
  cropLeft: cropPercentage(source, 'l')
1186
1188
  });
1187
1189
  }
1190
+ function anchorTransform(anchor) {
1191
+ return readDocxImageTransform(anchor).transform;
1192
+ }
1188
1193
  function anchorLayer(anchor) {
1189
1194
  return normalizeDocumentImageLayer({
1190
1195
  relativeHeight: work_ooxml_package_attribute(anchor, 'relativeHeight'),
@@ -1225,7 +1230,7 @@ function insertMarkerRun(document, run, marker, position) {
1225
1230
  if (!parent) return;
1226
1231
  parent.insertBefore(markerRun, 'before' === position ? run : run.nextSibling);
1227
1232
  }
1228
- function applyImageLayout(image, options, position, crop, contour, layer, identity) {
1233
+ function applyImageLayout(image, options, position, crop, transform, contour, layer, identity) {
1229
1234
  applyDocumentImageIdentityToElement(image, identity);
1230
1235
  image.dataset.officeImageLayout = options.layout;
1231
1236
  image.dataset.officeImageAlignment = options.alignment;
@@ -1246,6 +1251,7 @@ function applyImageLayout(image, options, position, crop, contour, layer, identi
1246
1251
  image.dataset.officeImageVerticalReference = position.verticalReference;
1247
1252
  }
1248
1253
  applyDocumentImageCropToElement(image, crop);
1254
+ applyDocumentImageTransformToElement(image, transform);
1249
1255
  applyDocumentImageWrapContourToElement(image, contour);
1250
1256
  if (layer) applyDocumentImageLayerToElement(image, layer);
1251
1257
  }
@@ -2904,6 +2910,9 @@ async function prepareDocxImport(buffer, sourcePackage) {
2904
2910
  imageLayoutMarkers: {
2905
2911
  images: []
2906
2912
  },
2913
+ textBoxMarkers: {
2914
+ textBoxes: []
2915
+ },
2907
2916
  paragraphIdentityMarkers: {
2908
2917
  paragraphs: []
2909
2918
  },
@@ -2958,6 +2967,7 @@ async function prepareDocxImport(buffer, sourcePackage) {
2958
2967
  const pageColor = importDocxPageColor(document);
2959
2968
  const tableOfContentsMarkers = markDocxTablesOfContents(document);
2960
2969
  const indexMarkers = markDocxIndexes(document);
2970
+ const textBoxMarkers = markDocxTextBoxes(document);
2961
2971
  const paragraphIdentityMarkers = markDocxParagraphIdentities(document);
2962
2972
  const numbering = archive.has('word/numbering.xml') ? await archive.xml('word/numbering.xml') : null;
2963
2973
  const commentMarkers = await markDocxComments(document, archive);
@@ -3003,7 +3013,7 @@ async function prepareDocxImport(buffer, sourcePackage) {
3003
3013
  const trackChanges = Boolean(settings && firstDescendant(settings, 'trackRevisions')) || changeMarkers.changes.length > 0 || numberingChangeMarkers.groups.length > 0 || paragraphFormattingChangeMarkers.paragraphs.length > 0 || runFormattingMarkers.runs.some((run)=>Boolean(run.change));
3004
3014
  const sectionElements = effectiveSectionProperties(document);
3005
3015
  if (!sectionElements.length) return {
3006
- conversionBuffer: hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxTableOfContentsMarkers(tableOfContentsMarkers) || hasImportedDocxIndexMarkers(indexMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxNumberingChangeMarkers(numberingChangeMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphFormattingChangeMarkers(paragraphFormattingChangeMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
3016
+ conversionBuffer: hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxTableOfContentsMarkers(tableOfContentsMarkers) || hasImportedDocxIndexMarkers(indexMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxNumberingChangeMarkers(numberingChangeMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxTextBoxMarkers(textBoxMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphFormattingChangeMarkers(paragraphFormattingChangeMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
3007
3017
  sections: [
3008
3018
  {
3009
3019
  id: 'document-section-1',
@@ -3023,6 +3033,7 @@ async function prepareDocxImport(buffer, sourcePackage) {
3023
3033
  listMarkers,
3024
3034
  numberingChangeMarkers,
3025
3035
  imageLayoutMarkers,
3036
+ textBoxMarkers,
3026
3037
  paragraphIdentityMarkers,
3027
3038
  paragraphFormattingChangeMarkers,
3028
3039
  paragraphAlignmentMarkers,
@@ -3054,7 +3065,7 @@ async function prepareDocxImport(buffer, sourcePackage) {
3054
3065
  }
3055
3066
  if (sections.length > 1) addSectionMarkers(document, sectionElements);
3056
3067
  return {
3057
- conversionBuffer: sections.length > 1 || hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxTableOfContentsMarkers(tableOfContentsMarkers) || hasImportedDocxIndexMarkers(indexMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxNumberingChangeMarkers(numberingChangeMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphFormattingChangeMarkers(paragraphFormattingChangeMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
3068
+ conversionBuffer: sections.length > 1 || hasImportedDocxCaptionMarkers(captionMarkers) || hasImportedDocxBookmarkMarkers(bookmarkMarkers) || hasImportedDocxChangeMarkers(changeMarkers) || hasImportedDocxCommentMarkers(commentMarkers) || hasImportedDocxCitationMarkers(citationMarkers) || hasImportedDocxFieldMarkers(fieldMarkers) || hasImportedDocxTableOfContentsMarkers(tableOfContentsMarkers) || hasImportedDocxIndexMarkers(indexMarkers) || equationMarkers.changed || hasImportedDocxListMarkers(listMarkers) || hasImportedDocxNumberingChangeMarkers(numberingChangeMarkers) || hasImportedDocxImageLayoutMarkers(imageLayoutMarkers) || hasImportedDocxTextBoxMarkers(textBoxMarkers) || hasImportedDocxParagraphIdentityMarkers(paragraphIdentityMarkers) || hasImportedDocxParagraphFormattingChangeMarkers(paragraphFormattingChangeMarkers) || hasImportedDocxParagraphAlignmentMarkers(paragraphAlignmentMarkers) || hasImportedDocxParagraphDirectionMarkers(paragraphDirectionMarkers) || hasImportedDocxParagraphIndentMarkers(paragraphIndentMarkers) || hasImportedDocxParagraphSpacingMarkers(paragraphSpacingMarkers) || hasImportedDocxParagraphBorderMarkers(paragraphBorderMarkers) || hasImportedDocxParagraphShadingMarkers(paragraphShadingMarkers) || hasImportedDocxParagraphPaginationMarkers(paragraphPaginationMarkers) || hasImportedDocxRunFormattingMarkers(runFormattingMarkers) || hasImportedDocxParagraphTabStopMarkers(tabStopMarkers) || hasImportedDocxTableCellMarkers(tableCellMarkers) || hasImportedDocxTableRowMarkers(tableRowMarkers) || hasImportedDocxTableSizingMarkers(tableSizingMarkers) ? await writeDocumentXml(buffer, document, equationMarkers.parts) : buffer,
3058
3069
  sections,
3059
3070
  pageColor,
3060
3071
  captionMarkers,
@@ -3069,6 +3080,7 @@ async function prepareDocxImport(buffer, sourcePackage) {
3069
3080
  listMarkers,
3070
3081
  numberingChangeMarkers,
3071
3082
  imageLayoutMarkers,
3083
+ textBoxMarkers,
3072
3084
  paragraphIdentityMarkers,
3073
3085
  paragraphFormattingChangeMarkers,
3074
3086
  paragraphAlignmentMarkers,
@@ -3149,6 +3161,8 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
3149
3161
  rows: []
3150
3162
  }, tableSizingMarkers = {
3151
3163
  tables: []
3164
+ }, textBoxMarkers = {
3165
+ textBoxes: []
3152
3166
  }) {
3153
3167
  const document = new DOMParser().parseFromString(html, 'text/html');
3154
3168
  applyImportedDocxRunFormattingMarkers(document, runFormattingMarkers);
@@ -3175,6 +3189,7 @@ function applyDocxSectionsToHtml(html, sections, captionMarkers = {
3175
3189
  applyImportedDocxChangeMarkers(document, changeMarkers);
3176
3190
  applyImportedDocxCommentMarkers(document, commentMarkers);
3177
3191
  applyImportedDocxParagraphIdentityMarkers(document, paragraphIdentityMarkers);
3192
+ applyImportedDocxTextBoxMarkers(document, textBoxMarkers);
3178
3193
  applyImportedDocxTableOfContentsMarkers(document, tableOfContentsMarkers);
3179
3194
  applyImportedDocxIndexMarkers(document, indexMarkers);
3180
3195
  const notes = extractMammothDocumentNotes(document);
@@ -1,9 +1,9 @@
1
1
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
2
  import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescendant, isDocumentParagraphArtBorderStyle, descendants, directChild, xmlContainsAnyElement, attribute, documentRunBorderIsVisible } from "./6968.js";
3
3
  import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, normalizeDocumentBookmarkNativeId, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./4174.js";
4
- import { markDocxParagraphShading, inspectDocxPageSize, isSupportedDocxNumberingChange, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, createDocxTableStyleResolver, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunBorder, inspectDocxRunFonts, inspectDocxRunShading, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxHiddenText, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~2330.js";
4
+ import { isSupportedDocxEquationPlacement, inspectDocxPageSize, hasInvalidDocxFieldStructure, createDocxTableStyleResolver, inspectDocxRunBorder, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunShading, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxPageBorders, docxCaptionBookmark, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, inspectDocxRunFonts, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, inspectDocxTextBoxes, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, inspectDocxHiddenText, isSupportedDocxRunFormattingChange, isSupportedDocxNumberingChange, markDocxParagraphShading, docxFieldInstructions } from "./0~2133.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
- import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~5024.js";
6
+ import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, readDocxImageTransform, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~4042.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";
@@ -2190,8 +2190,17 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
2190
2190
  issues.push(...await diagnoseDocxCitations(archive, document));
2191
2191
  const captionDiagnostics = diagnoseDocxCaptions(document);
2192
2192
  issues.push(...captionDiagnostics.issues);
2193
+ const textBoxInspection = inspectDocxTextBoxes(document);
2194
+ if (textBoxInspection.supported) issues.push(work_office_diagnostics_issue('docx.text-boxes', 'Text boxes', `${textBoxInspection.supported} isolated WPS text box(es) remain editable with native DrawingML geometry, inline or floating layout, safe page-relative offsets, fill, outline, padding, and vertical alignment. Mixed paragraphs are intentionally kept on the normal DOCX compatibility path.`, 'info'));
2195
+ if (textBoxInspection.unsupported) issues.push(work_office_diagnostics_issue('docx.text-boxes.unsupported', 'Text boxes', `${textBoxInspection.unsupported} WPS text box(es) mix a drawing with other paragraph content or have unsupported shape content. Only isolated text-box paragraphs are converted to editable text boxes; the rest may normalize during browser conversion.`));
2193
2196
  if (descendants(document, 'tbl').length) issues.push(work_office_diagnostics_issue('docx.tables', 'Tables', 'Table rows, non-splitting rows, repeated headers, cell shading, vertical alignment, per-edge borders, and paragraph-boundary row continuation remain editable. Native row identities survive body and page-chrome HTML; uniquely matched passive extensions on stable table, row, and cell scopes and their property nodes are retained, while duplicate, cross-kind, relationship-bound, or semantic branches fail closed. Layout algorithm, preferred auto, percentage, or pixel width, alignment, indent, percentage or pixel column widths, table-level cell margins, and cell-level margin overrides are preserved independently across edit, preview, and DOCX export. Percentage column preferences use pixel grid widths as responsive browser fallbacks and remain coherent through merged cells. Nested tables retain independent edit and DOCX geometry, and tall outer rows can paginate at nested-row boundaries. Row-spanning cells continue through every covered physical row with in-cell page breaks and contiguous content ranges; combined row and column spans retain native DOCX merge semantics. Common inherited Word table styles apply whole-table, banded row or column, first or last row or column, corner-cell, border, fill, text-emphasis, paragraph alignment, direction, indents, spacing, line, pagination, and tab-stop rules before direct table, cell, paragraph, and run formatting. Theme tint and shade values resolve to stable RGB for edit and preview, while untouched run colors, run shading, cell fills, and per-edge borders retain their semantic theme references on export; explicit color edits use direct RGB. Less-common conditional paragraph properties may be normalized.'));
2194
- if (descendants(document, 'drawing').length || descendants(document, 'pict').length) issues.push(work_office_diagnostics_issue('docx.images', 'Images', 'Inline images and supported square, tight, through, top-and-bottom, or no-wrap free-floating images remain embedded with editable size, alternative text, alignment, wrap side and distance where applicable, signed horizontal or vertical offsets relative to the column, paragraph, margin, or page, four-edge percentage cropping, and drawing-layer options. Aligned and precise DOCX anchors retain their distinct position semantics; inline and floating crop geometry round-trips as DrawingML source rectangles; tight or through anchors retain their ordered wrap polygons; no-wrap anchors remain outside the body text flow and use behind-text placement to choose their side of the text; and supported floating images preserve relative Z-order, overlap and cell-layout policy, and anchor locking. Inline and floating pictures retain unique drawing-property and anchor IDs together with their edit IDs. Copies receive independent identities while move, delete, undo, and relationship regeneration retain the original object identity. Unsupported drawing types may be normalized.'));
2197
+ const drawingCount = descendants(document, 'drawing').length;
2198
+ const textBoxDrawingCount = textBoxInspection.supported + textBoxInspection.unsupported;
2199
+ if (drawingCount > textBoxDrawingCount || descendants(document, 'pict').length) {
2200
+ const unsupportedImageTransforms = docxUnsupportedImageTransformCount(document);
2201
+ issues.push(work_office_diagnostics_issue('docx.images', 'Images', 'Inline images and supported square, tight, through, top-and-bottom, or no-wrap free-floating images remain embedded with editable size, alternative text, alignment, wrap side and distance where applicable, signed horizontal or vertical offsets relative to the column, paragraph, margin, or page, four-edge percentage cropping, 90-degree rotation, horizontal or vertical reflection, and drawing-layer options. Aligned and precise DOCX anchors retain their distinct position semantics; inline and floating crop geometry round-trips as DrawingML source rectangles; tight or through anchors retain their ordered wrap polygons; no-wrap anchors remain outside the body text flow and use behind-text placement to choose their side of the text; and supported floating images preserve relative Z-order, overlap and cell-layout policy, and anchor locking. Inline and floating pictures retain unique drawing-property and anchor IDs together with their edit IDs. Copies receive independent identities while move, delete, undo, and relationship regeneration retain the original object identity. Arbitrary-angle or malformed picture transforms and unsupported drawing types may be normalized.'));
2202
+ if (unsupportedImageTransforms) issues.push(work_office_diagnostics_issue('docx.images.transform', 'Image transforms', `${unsupportedImageTransforms} picture transform(s) use an arbitrary angle or malformed rotation/reflection value. Work imports the editable 90-degree/reflection subset and normalizes the unsupported transform instead of exposing an inexact control.`));
2203
+ }
2195
2204
  const textRevisions = [
2196
2205
  ...descendants(document, 'ins'),
2197
2206
  ...descendants(document, 'del')
@@ -2349,6 +2358,13 @@ async function inspectXlsxPackage(archive, issues, importedMetadata) {
2349
2358
  })) issues.push(work_office_diagnostics_issue('xlsx.manual-page-breaks', 'Manual page breaks', 'Manual row and column page breaks are preserved, editable, and honored by PDF pagination.', 'info'));
2350
2359
  }
2351
2360
  }
2361
+ function docxUnsupportedImageTransformCount(document) {
2362
+ const drawings = [
2363
+ ...descendants(document, 'anchor'),
2364
+ ...descendants(document, 'inline')
2365
+ ];
2366
+ return drawings.filter((drawing)=>descendants(drawing, 'pic').length > 0 && !readDocxImageTransform(drawing).supported).length;
2367
+ }
2352
2368
  function report(file, sourceFormat, issues) {
2353
2369
  return {
2354
2370
  sourceFormat,