@stll/folio-core 0.55.0 → 0.57.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 (225) hide show
  1. package/dist/ai-edits/apply.js +214 -52
  2. package/dist/ai-edits/batch-claims.d.ts +3 -1
  3. package/dist/ai-edits/batch-claims.js +25 -1
  4. package/dist/ai-edits/headless.js +2 -2
  5. package/dist/ai-edits/table-row-column-mutations.js +17 -3
  6. package/dist/ai-edits/types.d.ts +7 -1
  7. package/dist/ai-suggestions/apply.js +20 -1
  8. package/dist/compare/compare.js +1 -0
  9. package/dist/compare/inline-atoms.js +40 -16
  10. package/dist/compare/inline-provenance.js +12 -5
  11. package/dist/compare/reproducible-package.d.ts +0 -17
  12. package/dist/compare/reproducible-package.js +12 -18
  13. package/dist/compat/eigenpal.d.ts +2 -1
  14. package/dist/compat/eigenpal.js +2 -1
  15. package/dist/controller/canonicalClipboard.d.ts +23 -0
  16. package/dist/controller/canonicalClipboard.js +482 -0
  17. package/dist/controller/canonicalClipboardResources.d.ts +21 -0
  18. package/dist/controller/canonicalClipboardResources.js +382 -0
  19. package/dist/controller/canonicalComments.d.ts +41 -0
  20. package/dist/controller/canonicalComments.js +152 -0
  21. package/dist/controller/canonicalComposition.d.ts +24 -3
  22. package/dist/controller/canonicalComposition.js +208 -48
  23. package/dist/controller/canonicalInlineProjection.d.ts +118 -0
  24. package/dist/controller/canonicalInlineProjection.js +476 -0
  25. package/dist/controller/canonicalInput.d.ts +13 -4
  26. package/dist/controller/canonicalInput.js +62 -14
  27. package/dist/controller/canonicalInputTimer.d.ts +16 -0
  28. package/dist/controller/canonicalInputTimer.js +34 -0
  29. package/dist/controller/canonicalPublicOperations.d.ts +48 -0
  30. package/dist/controller/canonicalPublicOperations.js +648 -0
  31. package/dist/controller/canonicalSelection.d.ts +18 -0
  32. package/dist/controller/canonicalSelection.js +32 -0
  33. package/dist/controller/canonicalSession.d.ts +27 -6
  34. package/dist/controller/canonicalSession.js +298 -116
  35. package/dist/controller/canonicalStoryEditor.d.ts +7 -3
  36. package/dist/controller/canonicalStoryEditor.js +27 -2
  37. package/dist/controller/canonicalStructure.js +57 -4
  38. package/dist/controller/canonicalTocSelection.d.ts +11 -0
  39. package/dist/controller/canonicalTocSelection.js +43 -0
  40. package/dist/controller/folioEditor.d.ts +2 -9
  41. package/dist/controller/folioEditor.js +18 -4
  42. package/dist/controller/headerFooterEditorManager.d.ts +2 -1
  43. package/dist/controller/headerFooterEditorManager.js +26 -11
  44. package/dist/controller/hiddenEditorApi.d.ts +24 -3
  45. package/dist/controller/hiddenEditorApi.js +8 -0
  46. package/dist/controller/hiddenEditorManager.d.ts +5 -1
  47. package/dist/controller/hiddenEditorManager.js +378 -43
  48. package/dist/controller/noteEditorManager.d.ts +2 -1
  49. package/dist/controller/noteEditorManager.js +29 -13
  50. package/dist/document-operations.d.ts +8 -1
  51. package/dist/document-operations.js +6 -4
  52. package/dist/docx/blockPlainText.d.ts +1 -1
  53. package/dist/docx/blockPlainText.js +11 -3
  54. package/dist/docx/builtInStyles.js +13 -6
  55. package/dist/docx/canonicalResourceSave.d.ts +16 -0
  56. package/dist/docx/canonicalResourceSave.js +27 -0
  57. package/dist/docx/canonicalSave.d.ts +29 -0
  58. package/dist/docx/canonicalSave.js +101 -0
  59. package/dist/docx/canonicalStoryRepack.d.ts +1 -1
  60. package/dist/docx/canonicalStoryRepack.js +38 -5
  61. package/dist/docx/containerChildren.gen.d.ts +3 -1
  62. package/dist/docx/containerChildren.gen.js +33 -1
  63. package/dist/docx/documentParser.d.ts +1 -13
  64. package/dist/docx/documentParser.js +1 -47
  65. package/dist/docx/ensureParaIds.js +10 -4
  66. package/dist/docx/fieldParser.js +14 -2
  67. package/dist/docx/footnoteParser.d.ts +1 -11
  68. package/dist/docx/footnoteParser.js +1 -16
  69. package/dist/docx/headerFooterParser.d.ts +1 -9
  70. package/dist/docx/headerFooterParser.js +1 -12
  71. package/dist/docx/headerFooterVerbatim.d.ts +26 -1
  72. package/dist/docx/headerFooterVerbatim.js +81 -3
  73. package/dist/docx/hyperlinkParser.d.ts +1 -1
  74. package/dist/docx/hyperlinkParser.js +20 -1
  75. package/dist/docx/imageParser.d.ts +13 -1
  76. package/dist/docx/imageParser.js +20 -11
  77. package/dist/docx/inlineWrapperContent.d.ts +4 -4
  78. package/dist/docx/inlineWrapperContent.js +4 -4
  79. package/dist/docx/linkedSdtPreservation.d.ts +10 -0
  80. package/dist/docx/linkedSdtPreservation.js +37 -0
  81. package/dist/docx/metadataPrivacy.js +6 -1
  82. package/dist/docx/packageParts.js +9 -3
  83. package/dist/docx/paragraphParser.js +88 -67
  84. package/dist/docx/paragraphPropertySource.d.ts +22 -1
  85. package/dist/docx/paragraphPropertySource.js +109 -2
  86. package/dist/docx/parser.js +2 -1
  87. package/dist/docx/preservedRunContent.js +2 -1
  88. package/dist/docx/relsParser.js +26 -2
  89. package/dist/docx/removeHeaderFooterParts.js +17 -6
  90. package/dist/docx/rezip.d.ts +49 -5
  91. package/dist/docx/rezip.js +754 -235
  92. package/dist/docx/saveDiagnostics.d.ts +11 -0
  93. package/dist/docx/selectiveSave.d.ts +2 -1
  94. package/dist/docx/selectiveSave.js +42 -11
  95. package/dist/docx/selectiveXmlPatch.js +7 -5
  96. package/dist/docx/serializer/commentSerializer.d.ts +4 -1
  97. package/dist/docx/serializer/commentSerializer.js +7 -3
  98. package/dist/docx/serializer/documentSerializer.d.ts +9 -2
  99. package/dist/docx/serializer/documentSerializer.js +29 -10
  100. package/dist/docx/serializer/paragraphSerializer.js +207 -94
  101. package/dist/docx/server/applyDocxXmlPatchProposal.js +14 -9
  102. package/dist/docx/server/materializeYjsDocx.js +14 -6
  103. package/dist/docx/server/migrateYjsAttrSchema.js +17 -5
  104. package/dist/docx/storyBlockReplay.d.ts +21 -1
  105. package/dist/docx/storyBlockReplay.js +113 -9
  106. package/dist/docx/storyPlainText.d.ts +20 -0
  107. package/dist/docx/storyPlainText.js +23 -0
  108. package/dist/docx/structuralXmlPatch.js +10 -22
  109. package/dist/docx/styleParser.d.ts +5 -1
  110. package/dist/docx/styleParser.js +1 -1
  111. package/dist/docx/tableParser.d.ts +1 -8
  112. package/dist/docx/tableParser.js +1 -28
  113. package/dist/docx/textBoxParser.d.ts +1 -5
  114. package/dist/docx/textBoxParser.js +1 -20
  115. package/dist/docx/unzip.js +6 -1
  116. package/dist/i18n/messages/ar.gen.js +4 -0
  117. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  118. package/dist/i18n/messages/catalogs.gen.js +68 -0
  119. package/dist/i18n/messages/cs.gen.js +4 -0
  120. package/dist/i18n/messages/de.gen.js +4 -0
  121. package/dist/i18n/messages/en.gen.js +4 -0
  122. package/dist/i18n/messages/es.gen.js +4 -0
  123. package/dist/i18n/messages/et.gen.js +4 -0
  124. package/dist/i18n/messages/fr.gen.js +4 -0
  125. package/dist/i18n/messages/he.gen.js +4 -0
  126. package/dist/i18n/messages/hi.gen.js +4 -0
  127. package/dist/i18n/messages/hu.gen.js +4 -0
  128. package/dist/i18n/messages/lt.gen.js +4 -0
  129. package/dist/i18n/messages/lv.gen.js +4 -0
  130. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  131. package/dist/i18n/messages/pl.gen.js +4 -0
  132. package/dist/i18n/messages/pt-BR.gen.js +4 -0
  133. package/dist/i18n/messages/sk.gen.js +4 -0
  134. package/dist/i18n/messages/tr.gen.js +4 -0
  135. package/dist/i18n/messages/zh-CN.gen.js +4 -0
  136. package/dist/index.d.ts +2 -1
  137. package/dist/index.js +2 -1
  138. package/dist/internal/acceptedBlockProjection.d.ts +12 -0
  139. package/dist/internal/acceptedBlockProjection.js +45 -0
  140. package/dist/internal/revisionResolutionInline.js +25 -3
  141. package/dist/managers/DocumentLoaderManager.js +2 -1
  142. package/dist/markdown/escape.d.ts +3 -1
  143. package/dist/markdown/escape.js +9 -2
  144. package/dist/markdown/renderBlock.js +5 -120
  145. package/dist/markdown/renderParagraph.js +4 -2
  146. package/dist/markdown/renderRuns.d.ts +7 -1
  147. package/dist/markdown/renderRuns.js +33 -24
  148. package/dist/panel-layout.d.ts +11 -9
  149. package/dist/panel-layout.js +13 -9
  150. package/dist/prosemirror/addTrackedDeletionMark.d.ts +18 -0
  151. package/dist/prosemirror/addTrackedDeletionMark.js +87 -0
  152. package/dist/prosemirror/attrs/index.js +5 -0
  153. package/dist/prosemirror/canonicalCommands.d.ts +28 -4
  154. package/dist/prosemirror/canonicalCommands.js +11 -4
  155. package/dist/prosemirror/canonicalSelectionRange.d.ts +9 -0
  156. package/dist/prosemirror/canonicalSelectionRange.js +15 -0
  157. package/dist/prosemirror/clipboardIntent.d.ts +7 -0
  158. package/dist/prosemirror/clipboardIntent.js +9 -0
  159. package/dist/prosemirror/commands/comments.js +60 -35
  160. package/dist/prosemirror/commands/pageBreak.js +2 -2
  161. package/dist/prosemirror/commands/pastePlainText.js +2 -1
  162. package/dist/prosemirror/commands/propertyChangeScope.js +3 -6
  163. package/dist/prosemirror/commands/resolveParagraphProperties.js +22 -13
  164. package/dist/prosemirror/commentOps.js +15 -1
  165. package/dist/prosemirror/conversion/fromProseDoc.js +22 -3
  166. package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +8 -0
  167. package/dist/prosemirror/conversion/hyphenTextCarriers.js +8 -0
  168. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -1
  169. package/dist/prosemirror/conversion/toProseDoc.js +124 -22
  170. package/dist/prosemirror/extensions/core/ParagraphExtension.js +61 -35
  171. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +74 -25
  172. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +11 -0
  173. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +65 -29
  174. package/dist/prosemirror/extensions/marks/markUtils.js +11 -8
  175. package/dist/prosemirror/extensions/marks/noteReferenceDeletion.js +5 -2
  176. package/dist/prosemirror/fieldRepresentation.d.ts +8 -0
  177. package/dist/prosemirror/fieldRepresentation.js +18 -0
  178. package/dist/prosemirror/hyperlinkRemoval.d.ts +13 -1
  179. package/dist/prosemirror/hyperlinkRemoval.js +28 -9
  180. package/dist/prosemirror/insertOperations.js +2 -1
  181. package/dist/prosemirror/listNumbering.js +11 -5
  182. package/dist/prosemirror/noteReferenceOccurrenceId.d.ts +5 -0
  183. package/dist/prosemirror/noteReferenceOccurrenceId.js +5 -0
  184. package/dist/prosemirror/noteReferenceOccurrences.d.ts +21 -0
  185. package/dist/prosemirror/noteReferenceOccurrences.js +185 -0
  186. package/dist/prosemirror/noteReferenceReview.js +14 -1
  187. package/dist/prosemirror/paragraphPropertyCarry.d.ts +7 -1
  188. package/dist/prosemirror/paragraphPropertyCarry.js +8 -3
  189. package/dist/prosemirror/plugins/documentStyles.d.ts +4 -1
  190. package/dist/prosemirror/plugins/documentStyles.js +17 -10
  191. package/dist/prosemirror/plugins/suggestionMode.js +48 -48
  192. package/dist/prosemirror/preservedXmlReview.d.ts +6 -0
  193. package/dist/prosemirror/preservedXmlReview.js +35 -0
  194. package/dist/prosemirror/runFormattingFromMarks.js +2 -2
  195. package/dist/prosemirror/runFormattingReconciliation.js +5 -4
  196. package/dist/prosemirror/runPropertyChangeResolution.d.ts +8 -1
  197. package/dist/prosemirror/runPropertyChangeResolution.js +24 -2
  198. package/dist/prosemirror/runStyleFormatting.d.ts +3 -1
  199. package/dist/prosemirror/runStyleFormatting.js +3 -1
  200. package/dist/prosemirror/schema/marks.d.ts +1 -0
  201. package/dist/prosemirror/schema/nodes.d.ts +2 -0
  202. package/dist/prosemirror/styles/paragraphStyleCascade.js +4 -1
  203. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +15 -15
  204. package/dist/prosemirror/styles/resolvedStyleAttrs.js +69 -28
  205. package/dist/prosemirror/textInput.d.ts +5 -1
  206. package/dist/prosemirror/textInput.js +3 -3
  207. package/dist/prosemirror/trackedRevisionPath.d.ts +5 -1
  208. package/dist/prosemirror/trackedRevisionPath.js +39 -1
  209. package/dist/prosemirror/validation.js +3 -5
  210. package/dist/prosemirror/yjsDocumentMetadata.d.ts +9 -3
  211. package/dist/prosemirror/yjsDocumentMetadata.js +37 -8
  212. package/dist/types/canonicalCapabilities.d.ts +201 -0
  213. package/dist/types/canonicalCapabilities.js +198 -0
  214. package/dist/types/canonicalComments.d.ts +51 -0
  215. package/dist/types/canonicalComments.js +0 -0
  216. package/dist/types/canonicalSave.d.ts +11 -0
  217. package/dist/types/canonicalSave.js +0 -0
  218. package/dist/types/canonicalSections.d.ts +12 -0
  219. package/dist/types/canonicalSections.js +0 -0
  220. package/dist/types/docxSerialization.d.ts +14 -0
  221. package/dist/types/docxSerialization.js +7 -0
  222. package/dist/utils/headingCollector.js +45 -4
  223. package/dist/utils/outlineDepth.d.ts +9 -0
  224. package/dist/utils/outlineDepth.js +9 -0
  225. package/package.json +4 -4
@@ -239,58 +239,12 @@ function getNestedTables(table) {
239
239
  return tables;
240
240
  }
241
241
  /**
242
- * Get plain text from entire document body
243
- */
244
- function getDocumentText(body) {
245
- const lines = [];
246
- for (const block of body.content) if (block.type === "paragraph") lines.push(getParagraphText(block));
247
- else if (block.type === "table") lines.push(getTableText(block));
248
- else if (block.type === "blockSdt" || block.type === "blockCustomXml") lines.push(getTextFromBlocks(block.content));
249
- return lines.join("\n");
250
- }
251
- const getTextFromBlocks = (blocks) => blocks.flatMap((block) => {
252
- if (block.type === "paragraph") return [getParagraphText(block)];
253
- if (block.type === "table") return [getTableText(block)];
254
- return block.type === "blockSdt" || block.type === "blockCustomXml" ? [getTextFromBlocks(block.content)] : [];
255
- }).join("\n");
256
- /**
257
- * Get plain text from a table
258
- */
259
- function getTableText(table) {
260
- const lines = [];
261
- for (const row of table.rows) {
262
- const rowTexts = [];
263
- for (const cell of row.cells) {
264
- const cellTexts = [];
265
- for (const content of cell.content) if (content.type === "paragraph") cellTexts.push(getParagraphText(content));
266
- else if (content.type === "table") cellTexts.push(getTableText(content));
267
- else if (content.type === "blockSdt" || content.type === "blockCustomXml") cellTexts.push(getTextFromBlocks(content.content));
268
- rowTexts.push(cellTexts.join("\n"));
269
- }
270
- lines.push(rowTexts.join(" "));
271
- }
272
- return lines.join("\n");
273
- }
274
- /**
275
242
  * Count total paragraphs in document
276
243
  */
277
244
  function getParagraphCount(body) {
278
245
  return getAllParagraphs(body).length;
279
246
  }
280
247
  /**
281
- * Count total words in document (approximate)
282
- */
283
- function getWordCount(body) {
284
- const words = getDocumentText(body).trim().split(/\s+/u);
285
- return words.length > 0 && words[0] !== "" ? words.length : 0;
286
- }
287
- /**
288
- * Count total characters in document
289
- */
290
- function getCharacterCount(body) {
291
- return getDocumentText(body).length;
292
- }
293
- /**
294
248
  * Get section count
295
249
  */
296
250
  function getSectionCount(body) {
@@ -303,4 +257,4 @@ function hasTemplateVariables(body) {
303
257
  return extractAllTemplateVariables(body.content).length > 0;
304
258
  }
305
259
  //#endregion
306
- export { extractAllTemplateVariables, extractTemplateVariables, getAllParagraphs, getAllTables, getCharacterCount, getDocumentText, getParagraphCount, getSectionCount, getWordCount, hasTemplateVariables, parseDocumentBody, parseDocumentBodyTree };
260
+ export { extractAllTemplateVariables, extractTemplateVariables, getAllParagraphs, getAllTables, getParagraphCount, getSectionCount, hasTemplateVariables, parseDocumentBody, parseDocumentBodyTree };
@@ -6,6 +6,7 @@ import { scanStreamingXmlElements } from "./streamingXmlParser.js";
6
6
  import { resolveNamespaceUri } from "./xmlNamespaceContext.js";
7
7
  import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, WORDPROCESSINGML_NAMESPACE_URIS, getAttribute, getChildElements, getLocalName, getNamespaceUri, parseXmlDocument, resolveAttributeNamespaceUri } from "./xmlParser.js";
8
8
  import { TaggedError } from "better-result";
9
+ import { writeZipPart } from "@stll/docx-core/zip";
9
10
  import JSZip from "jszip";
10
11
  //#region src/docx/ensureParaIds.ts
11
12
  /**
@@ -386,10 +387,15 @@ const ensureParaIdsInternal = async (docx, options) => {
386
387
  for (const [partPath, content] of updates) {
387
388
  const sourceEntry = zip.file(partPath);
388
389
  if (sourceEntry === null) throw createEnsureParaIdsError(`Package part disappeared during normalization: ${partPath}`);
389
- zip.file(partPath, content, {
390
- compression: "DEFLATE",
391
- compressionOptions: { level: 6 },
392
- date: sourceEntry.date
390
+ writeZipPart({
391
+ zip,
392
+ path: partPath,
393
+ data: content,
394
+ options: {
395
+ compression: "DEFLATE",
396
+ compressionOptions: { level: 6 },
397
+ date: sourceEntry.date
398
+ }
393
399
  });
394
400
  }
395
401
  return {
@@ -231,8 +231,20 @@ function finalizeComplexField(ctx) {
231
231
  * @returns The display text
232
232
  */
233
233
  function getFieldDisplayValue(field) {
234
- if (field.type === "simpleField") return field.content.filter((c) => "content" in c).map((run) => getRunText(run)).join("");
235
- return field.fieldResult.map((run) => getRunText(run)).join("");
234
+ const displayText = (content) => content.map((child) => {
235
+ switch (child.type) {
236
+ case "run": return getRunText(child);
237
+ case "hyperlink": return displayText(child.children);
238
+ case "inlineWrapper":
239
+ case "insertion":
240
+ case "deletion":
241
+ case "moveFrom":
242
+ case "moveTo": return displayText(child.content);
243
+ case "preservedInline": return child.text;
244
+ default: return "";
245
+ }
246
+ }).join("");
247
+ return displayText(field.type === "simpleField" ? field.content : field.fieldResult);
236
248
  }
237
249
  /**
238
250
  * Helper to get text from a run (simplified)
@@ -67,16 +67,6 @@ declare function parseFootnotes(footnotesXml: string | null, styles?: StyleMap |
67
67
  * @returns EndnoteMap with all endnotes
68
68
  */
69
69
  declare function parseEndnotes(endnotesXml: string | null, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, context?: ParseContext, previews?: PreviewLedger): EndnoteMap;
70
- /**
71
- * Get plain text content of a footnote.
72
- *
73
- * Uses the accepted tracked-change view and recurses through every note block.
74
- */
75
- declare function getFootnoteText(footnote: document_d_exports.Footnote): string;
76
- /**
77
- * Get plain text content of an endnote.
78
- */
79
- declare function getEndnoteText(endnote: document_d_exports.Endnote): string;
80
70
  /**
81
71
  * Check if a footnote is a separator (not regular content)
82
72
  */
@@ -102,4 +92,4 @@ declare function mergeFootnoteMaps(...maps: FootnoteMap[]): FootnoteMap;
102
92
  */
103
93
  declare function mergeEndnoteMaps(...maps: EndnoteMap[]): EndnoteMap;
104
94
  //#endregion
105
- export { EndnoteMap, FootnoteMap, createEmptyEndnoteMap, createEmptyFootnoteMap, getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote, mergeEndnoteMaps, mergeFootnoteMaps, parseEndnoteProperties, parseEndnotes, parseFootnoteProperties, parseFootnotes };
95
+ export { EndnoteMap, FootnoteMap, createEmptyEndnoteMap, createEmptyFootnoteMap, isSeparatorEndnote, isSeparatorFootnote, mergeEndnoteMaps, mergeFootnoteMaps, parseEndnoteProperties, parseEndnotes, parseFootnoteProperties, parseFootnotes };
@@ -1,4 +1,3 @@
1
- import { blockPlainText } from "./blockPlainText.js";
2
1
  import { parseEndnoteProperties, parseFootnoteProperties } from "./notePropertiesParser.js";
3
2
  import { parseParagraph } from "./paragraphParser.js";
4
3
  import { standalonePreviewLedger } from "./previewBudget.js";
@@ -196,20 +195,6 @@ function createEndnoteMap(byId, endnotes) {
196
195
  };
197
196
  }
198
197
  /**
199
- * Get plain text content of a footnote.
200
- *
201
- * Uses the accepted tracked-change view and recurses through every note block.
202
- */
203
- function getFootnoteText(footnote) {
204
- return blockPlainText(footnote.content);
205
- }
206
- /**
207
- * Get plain text content of an endnote.
208
- */
209
- function getEndnoteText(endnote) {
210
- return blockPlainText(endnote.content);
211
- }
212
- /**
213
198
  * Check if a footnote is a separator (not regular content)
214
199
  */
215
200
  function isSeparatorFootnote(footnote) {
@@ -258,4 +243,4 @@ function mergeEndnoteMaps(...maps) {
258
243
  return createEndnoteMap(byId, endnotes);
259
244
  }
260
245
  //#endregion
261
- export { createEmptyEndnoteMap, createEmptyFootnoteMap, getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote, mergeEndnoteMaps, mergeFootnoteMaps, parseEndnoteProperties, parseEndnotes, parseFootnoteProperties, parseFootnotes };
246
+ export { createEmptyEndnoteMap, createEmptyFootnoteMap, isSeparatorEndnote, isSeparatorFootnote, mergeEndnoteMaps, mergeFootnoteMaps, parseEndnoteProperties, parseEndnotes, parseFootnoteProperties, parseFootnotes };
@@ -81,14 +81,6 @@ declare function createEmptyHeaderFooterMap(): HeaderFooterMap;
81
81
  * @returns HeaderFooterMap with all parsed headers/footers
82
82
  */
83
83
  declare function buildHeaderFooterMap(references: (document_d_exports.HeaderReference | document_d_exports.FooterReference)[], xmlContents: Map<string, string>, isHeader: boolean, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null): HeaderFooterMap;
84
- /**
85
- * Get plain text content of a header/footer.
86
- *
87
- * Shares one walk with the note stories: this used to read only text runs, so a
88
- * header's fields, hyperlinks, tabs and breaks were silently absent from its
89
- * text while the same paragraph in a footnote read in full.
90
- */
91
- declare function getHeaderFooterText(hf: document_d_exports.HeaderFooter): string;
92
84
  /**
93
85
  * Check if header/footer is empty (no content)
94
86
  */
@@ -129,4 +121,4 @@ declare function hasImages(hf: document_d_exports.HeaderFooter): boolean;
129
121
  */
130
122
  declare function hasTables(hf: document_d_exports.HeaderFooter): boolean;
131
123
  //#endregion
132
- export { HeaderFooterMap, buildHeaderFooterMap, createEmptyHeaderFooterMap, getFooterForPage, getHeaderFooterText, getHeaderForPage, hasImages, hasPageNumberField, hasTables, headerFooterMapToTypeMap, isEmptyHeaderFooter, parseFooter, parseFooterReference, parseFooterReferences, parseHeader, parseHeaderFooter, parseHeaderReference, parseHeaderReferences };
124
+ export { HeaderFooterMap, buildHeaderFooterMap, createEmptyHeaderFooterMap, getFooterForPage, getHeaderForPage, hasImages, hasPageNumberField, hasTables, headerFooterMapToTypeMap, isEmptyHeaderFooter, parseFooter, parseFooterReference, parseFooterReferences, parseHeader, parseHeaderFooter, parseHeaderReference, parseHeaderReferences };
@@ -1,5 +1,4 @@
1
1
  import { parseBlockContent } from "./blockContentParser.js";
2
- import { blockPlainText } from "./blockPlainText.js";
3
2
  import { parseFooterReference, parseFooterReferences, parseHeaderReference, parseHeaderReferences } from "./headerFooterRefParser.js";
4
3
  import { assignHeaderFooterVerbatimXml } from "./headerFooterVerbatim.js";
5
4
  import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
@@ -150,16 +149,6 @@ function buildHeaderFooterMap(references, xmlContents, isHeader, styles = null,
150
149
  return createHeaderFooterMap(byId);
151
150
  }
152
151
  /**
153
- * Get plain text content of a header/footer.
154
- *
155
- * Shares one walk with the note stories: this used to read only text runs, so a
156
- * header's fields, hyperlinks, tabs and breaks were silently absent from its
157
- * text while the same paragraph in a footnote read in full.
158
- */
159
- function getHeaderFooterText(hf) {
160
- return blockPlainText(hf.content);
161
- }
162
- /**
163
152
  * Check if header/footer is empty (no content)
164
153
  */
165
154
  function isEmptyHeaderFooter(hf) {
@@ -254,4 +243,4 @@ function hasTables(hf) {
254
243
  return false;
255
244
  }
256
245
  //#endregion
257
- export { buildHeaderFooterMap, createEmptyHeaderFooterMap, getFooterForPage, getHeaderFooterText, getHeaderForPage, hasImages, hasPageNumberField, hasTables, headerFooterMapToTypeMap, isEmptyHeaderFooter, parseFooter, parseFooterReference, parseFooterReferences, parseHeader, parseHeaderFooter, parseHeaderReference, parseHeaderReferences };
246
+ export { buildHeaderFooterMap, createEmptyHeaderFooterMap, getFooterForPage, getHeaderForPage, hasImages, hasPageNumberField, hasTables, headerFooterMapToTypeMap, isEmptyHeaderFooter, parseFooter, parseFooterReference, parseFooterReferences, parseHeader, parseHeaderFooter, parseHeaderReference, parseHeaderReferences };
@@ -9,6 +9,13 @@ type HeaderFooterSourceBaseline = {
9
9
  content: readonly document_d_exports.BlockContent[];
10
10
  };
11
11
  declare const captureHeaderFooterPackageBaselines: (document: document_d_exports.Document) => void;
12
+ /**
13
+ * Transfer body, header and footer capture handles across a trusted
14
+ * document graph clone. `structuredClone` drops symbol-keyed properties, so a
15
+ * clone would otherwise read an edited part as uncaptured ("missing") rather
16
+ * than as a mismatch against its source.
17
+ */
18
+ declare const copyHeaderFooterBaselineHandles: (target: document_d_exports.Document, source: document_d_exports.Document) => void;
12
19
  /** Transfer the parsed package registry only across a trusted document graph clone. */
13
20
  declare const copyHeaderFooterPackageBaselines: (target: document_d_exports.Document, source: document_d_exports.Document) => void;
14
21
  declare const getHeaderFooterSourceBaseline: (hf: document_d_exports.HeaderFooter, originalBuffer?: ArrayBuffer) => HeaderFooterSourceBaseline;
@@ -18,5 +25,23 @@ declare const canReplayHeaderFooterVerbatim: (hf: document_d_exports.HeaderFoote
18
25
  declare const assignHeaderFooterVerbatimXml: (hf: document_d_exports.HeaderFooter, xml: string) => void;
19
26
  declare const refreshHeaderFooterVerbatimFingerprint: (hf: document_d_exports.HeaderFooter) => void;
20
27
  declare const clearHeaderFooterVerbatimXml: (hf: document_d_exports.HeaderFooter) => void;
28
+ /** Capture the body in the same trusted package registry as secondary stories. */
29
+ declare const captureDocumentSourceBaseline: (document: document_d_exports.Document, xml: string) => void;
30
+ declare const getDocumentSourceBaseline: (document: document_d_exports.Document) => {
31
+ type: "missing";
32
+ } | {
33
+ type: "mismatch";
34
+ } | {
35
+ type: "captured";
36
+ body: document_d_exports.Document["package"]["document"];
37
+ xml: string;
38
+ fingerprint: string;
39
+ resourceStyles: document_d_exports.Document["package"]["styles"];
40
+ resourceRelationships: document_d_exports.Document["package"]["relationships"];
41
+ resourceMedia: ReadonlyMap<string, {
42
+ data: ArrayBuffer;
43
+ mimeType: string;
44
+ }>;
45
+ };
21
46
  //#endregion
22
- export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterPackageBaselines, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
47
+ export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureDocumentSourceBaseline, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterBaselineHandles, copyHeaderFooterPackageBaselines, getDocumentSourceBaseline, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
@@ -15,7 +15,7 @@ const readFingerprint = (hf) => {
15
15
  });
16
16
  return value;
17
17
  };
18
- const BASELINE_HANDLE = Symbol("header-footer-source-baseline");
18
+ const BASELINE_HANDLE = Symbol("package-source-baseline");
19
19
  const contentBaselines = /* @__PURE__ */ new WeakMap();
20
20
  const captureContentBaseline = (hf) => {
21
21
  const fingerprint = hf.verbatimFingerprint;
@@ -23,6 +23,7 @@ const captureContentBaseline = (hf) => {
23
23
  const handle = {};
24
24
  const content = structuredClone(hf.content);
25
25
  contentBaselines.set(handle, {
26
+ type: "headerFooter",
26
27
  fingerprint,
27
28
  xml: hf.verbatimXml,
28
29
  contentFingerprint: canonicalJson(content),
@@ -46,6 +47,33 @@ const captureHeaderFooterPackageBaselines = (document) => {
46
47
  }
47
48
  packageBaselines.set(document.originalBuffer, handles);
48
49
  };
50
+ /**
51
+ * Transfer body, header and footer capture handles across a trusted
52
+ * document graph clone. `structuredClone` drops symbol-keyed properties, so a
53
+ * clone would otherwise read an edited part as uncaptured ("missing") rather
54
+ * than as a mismatch against its source.
55
+ */
56
+ const copyHeaderFooterBaselineHandles = (target, source) => {
57
+ const sourceBody = source.package.document;
58
+ if (BASELINE_HANDLE in sourceBody) Object.defineProperty(target.package.document, BASELINE_HANDLE, {
59
+ value: sourceBody[BASELINE_HANDLE],
60
+ enumerable: true,
61
+ configurable: true
62
+ });
63
+ for (const kind of ["headers", "footers"]) {
64
+ const targets = target.package[kind];
65
+ for (const [rId, sourcePart] of source.package[kind] ?? []) {
66
+ if (!(BASELINE_HANDLE in sourcePart)) continue;
67
+ const targetPart = targets?.get(rId);
68
+ if (!targetPart) continue;
69
+ Object.defineProperty(targetPart, BASELINE_HANDLE, {
70
+ value: sourcePart[BASELINE_HANDLE],
71
+ enumerable: true,
72
+ configurable: true
73
+ });
74
+ }
75
+ }
76
+ };
49
77
  /** Transfer the parsed package registry only across a trusted document graph clone. */
50
78
  const copyHeaderFooterPackageBaselines = (target, source) => {
51
79
  if (!target.originalBuffer || !source.originalBuffer) return;
@@ -59,7 +87,7 @@ const getHeaderFooterSourceBaseline = (hf, originalBuffer) => {
59
87
  if (handle === void 0 && !(BASELINE_HANDLE in hf)) return { type: "missing" };
60
88
  if (typeof handle !== "object" || handle === null) return { type: "mismatch" };
61
89
  const baseline = contentBaselines.get(handle);
62
- if (!baseline || baseline.fingerprint !== hf.verbatimFingerprint || baseline.xml !== hf.verbatimXml || baseline.contentFingerprint !== canonicalJson(baseline.content)) return { type: "mismatch" };
90
+ if (!baseline || baseline.type !== "headerFooter" || baseline.fingerprint !== hf.verbatimFingerprint || baseline.xml !== hf.verbatimXml || baseline.contentFingerprint !== canonicalJson(baseline.content)) return { type: "mismatch" };
63
91
  return {
64
92
  type: "captured",
65
93
  content: baseline.content
@@ -119,5 +147,55 @@ const clearHeaderFooterVerbatimXml = (hf) => {
119
147
  delete ext.verbatimFingerprint;
120
148
  Reflect.deleteProperty(hf, BASELINE_HANDLE);
121
149
  };
150
+ /** Capture the body in the same trusted package registry as secondary stories. */
151
+ const captureDocumentSourceBaseline = (document, xml) => {
152
+ const body = structuredClone(document.package.document);
153
+ const handle = {};
154
+ contentBaselines.set(handle, {
155
+ type: "body",
156
+ fingerprint: { type: "pending" },
157
+ xml,
158
+ body,
159
+ resourceStyles: structuredClone(document.package.styles),
160
+ resourceRelationships: structuredClone(document.package.relationships),
161
+ resourceMedia: new Map([...document.package.media ?? []].map(([path, media]) => [path, {
162
+ data: media.data,
163
+ mimeType: media.mimeType
164
+ }]))
165
+ });
166
+ Object.defineProperty(document.package.document, BASELINE_HANDLE, {
167
+ value: handle,
168
+ enumerable: true,
169
+ configurable: true
170
+ });
171
+ if (document.originalBuffer) {
172
+ const registry = packageBaselines.get(document.originalBuffer) ?? /* @__PURE__ */ new Map();
173
+ registry.set("word/document.xml", /* @__PURE__ */ new Map([["body", handle]]));
174
+ packageBaselines.set(document.originalBuffer, registry);
175
+ }
176
+ };
177
+ const getDocumentSourceBaseline = (document) => {
178
+ const body = document.package.document;
179
+ const handle = BASELINE_HANDLE in body ? body[BASELINE_HANDLE] : document.originalBuffer && packageBaselines.get(document.originalBuffer)?.get("word/document.xml")?.get("body");
180
+ if (handle === void 0) return { type: "missing" };
181
+ if (typeof handle !== "object" || handle === null) return { type: "mismatch" };
182
+ const baseline = contentBaselines.get(handle);
183
+ if (!baseline || baseline.type !== "body") return { type: "mismatch" };
184
+ const fingerprint = JSON.stringify(baseline.body);
185
+ if (baseline.fingerprint.type === "pending") baseline.fingerprint = {
186
+ type: "captured",
187
+ value: fingerprint
188
+ };
189
+ if (baseline.fingerprint.value !== fingerprint) return { type: "mismatch" };
190
+ return {
191
+ type: "captured",
192
+ body: baseline.body,
193
+ xml: baseline.xml,
194
+ fingerprint,
195
+ resourceStyles: baseline.resourceStyles,
196
+ resourceRelationships: baseline.resourceRelationships,
197
+ resourceMedia: baseline.resourceMedia
198
+ };
199
+ };
122
200
  //#endregion
123
- export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterPackageBaselines, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
201
+ export { assignHeaderFooterVerbatimXml, canReplayHeaderFooterBlocks, canReplayHeaderFooterVerbatim, captureDocumentSourceBaseline, captureHeaderFooterPackageBaselines, clearHeaderFooterVerbatimXml, copyHeaderFooterBaselineHandles, copyHeaderFooterPackageBaselines, getDocumentSourceBaseline, getHeaderFooterSourceBaseline, getHeaderFooterVerbatimXml, refreshHeaderFooterVerbatimFingerprint };
@@ -86,7 +86,7 @@ declare const HYPERLINK_CHILD_HANDLERS: {
86
86
  readonly permEnd: "capture";
87
87
  readonly permStart: "capture";
88
88
  readonly proofErr: "capture";
89
- readonly sdt: "capture";
89
+ readonly sdt: (child: XmlElement, { push }: HyperlinkChildContext) => void;
90
90
  readonly subDoc: "capture";
91
91
  };
92
92
  /**
@@ -1,6 +1,7 @@
1
1
  import { sanitizeExternalUrl } from "../utils/urlSecurity.js";
2
2
  import { CAPTURE, dispatchChildrenWithContext, ownedElsewhere, withPreservedChildren } from "./containerChildren.js";
3
3
  import { inlineWrapperOf } from "./inlineWrapperParser.js";
4
+ import { preserveLinkedSdt } from "./linkedSdtPreservation.js";
4
5
  import { preserveInlineChild, preservedInlineCapture } from "./preservedRunContent.js";
5
6
  import { standalonePreviewLedger } from "./previewBudget.js";
6
7
  import { RELATIONSHIP_TYPES, resolveRelationshipIdOfType } from "./relsParser.js";
@@ -9,6 +10,22 @@ import { runHoldsPayload } from "./runPayload.js";
9
10
  import { getAttribute, mergeXmlnsDeclarations, parseNumericAttribute, parseOnOffAttribute } from "./xmlParser.js";
10
11
  //#region src/docx/hyperlinkParser.ts
11
12
  /**
13
+ * Hyperlink Parser - Parse hyperlinks (w:hyperlink) with URL resolution
14
+ *
15
+ * OOXML Reference:
16
+ * - Hyperlink element: w:hyperlink
17
+ * - Attributes:
18
+ * - r:id - Relationship ID for external link (resolves via .rels)
19
+ * - w:anchor - Internal bookmark name
20
+ * - w:tooltip - Tooltip/title text
21
+ * - w:tgtFrame - Target frame (_blank, _self, etc.)
22
+ * - w:history - Whether to add to history
23
+ * - w:docLocation - Location within a document
24
+ *
25
+ * External links use r:id to reference a relationship in document.xml.rels
26
+ * Internal links use w:anchor to reference a bookmark in the same document
27
+ */
28
+ /**
12
29
  * Parse bookmark start (w:bookmarkStart)
13
30
  *
14
31
  * Used for internal hyperlink targets within the document.
@@ -169,7 +186,9 @@ const HYPERLINK_CHILD_HANDLERS = {
169
186
  permEnd: CAPTURE,
170
187
  permStart: CAPTURE,
171
188
  proofErr: CAPTURE,
172
- sdt: CAPTURE,
189
+ sdt: (child, { push }) => {
190
+ push(preserveLinkedSdt(child));
191
+ },
173
192
  subDoc: CAPTURE
174
193
  };
175
194
  const LINKED_SMART_TAG_PROPERTIES_OWNER = ownedElsewhere({
@@ -22,6 +22,18 @@ declare function resolveImageData(rId: string | undefined, rels: document_d_expo
22
22
  mimeType?: string;
23
23
  filename?: string;
24
24
  };
25
+ type ImageDerivedFactsOptions = {
26
+ id: string | undefined;
27
+ pictureNames: NonNullable<document_d_exports.Image["pictureNames"]>;
28
+ imageData: ReturnType<typeof resolveImageData>;
29
+ };
30
+ /** Facts the parser obtains from exported drawing markup and image relationships. */
31
+ declare const imageDerivedFactsOf: ({ id, pictureNames, imageData }: ImageDerivedFactsOptions) => {
32
+ filename?: string;
33
+ mimeType?: string;
34
+ pictureNames?: import("@stll/docx-core/model").NonVisualDrawingNames;
35
+ id?: string;
36
+ };
25
37
  /**
26
38
  * Parse a w:drawing element
27
39
  *
@@ -97,4 +109,4 @@ declare function getWrapDistancesPx(image: document_d_exports.Image): {
97
109
  */
98
110
  declare function needsTextWrapping(image: document_d_exports.Image): boolean;
99
111
  //#endregion
100
- export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
112
+ export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, imageDerivedFactsOf, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
@@ -10,7 +10,7 @@ import { RELATIONSHIP_TYPES, resolveRelationshipIdOfType } from "./relsParser.js
10
10
  import { isTextBoxDrawing } from "./textBoxParser.js";
11
11
  import { percentageSpelling } from "./transitionalSpelling.js";
12
12
  import { captureVerbatimXml } from "./verbatimCapture.js";
13
- import { findByFullName, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getChildElements, getLocalName, getNamespaceUri, parseNumericAttribute, parseOnOffAttribute, parseOnOffValue } from "./xmlParser.js";
13
+ import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, findAttributeByNamespaceUri, findByFullName, findChildByNamespaceUri, findChildrenByNamespaceUri, getAttribute, getChildElements, getLocalName, getNamespaceUri, parseNumericAttribute, parseOnOffAttribute, parseOnOffValue } from "./xmlParser.js";
14
14
  import { relationshipIdOf } from "@stll/docx-core/model";
15
15
  //#region src/docx/imageParser.ts
16
16
  /**
@@ -129,7 +129,7 @@ const parseDocPropsExtensions = (docPr) => {
129
129
  const parseDocPrLink = (docPr, localName) => {
130
130
  const element = findChildByNamespaceUri(docPr, DRAWINGML_NAMESPACE_URIS, localName);
131
131
  if (!element) return;
132
- const rId = getAttribute(element, "r", "id");
132
+ const rId = findAttributeByNamespaceUri(element, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id")?.value;
133
133
  return {
134
134
  xml: captureVerbatimXml(element),
135
135
  ...rId == null ? {} : { rId }
@@ -382,6 +382,13 @@ function resolveImageData(rId, rels, media) {
382
382
  ...filename !== void 0 ? { filename } : {}
383
383
  };
384
384
  }
385
+ /** Facts the parser obtains from exported drawing markup and image relationships. */
386
+ const imageDerivedFactsOf = ({ id, pictureNames, imageData }) => ({
387
+ ...id ? { id } : {},
388
+ ...Object.keys(pictureNames).length > 0 ? { pictureNames } : {},
389
+ ...imageData.mimeType ? { mimeType: imageData.mimeType } : {},
390
+ ...imageData.filename ? { filename: imageData.filename } : {}
391
+ });
385
392
  /**
386
393
  * Parse a wp:inline element (inline image)
387
394
  *
@@ -411,18 +418,19 @@ function parseInline(inlineEl, rels, media) {
411
418
  size,
412
419
  wrap
413
420
  };
414
- if (props.id) image.id = props.id;
421
+ Object.assign(image, imageDerivedFactsOf({
422
+ id: props.id,
423
+ pictureNames,
424
+ imageData
425
+ }));
415
426
  if (props.name !== void 0) image.docPrName = props.name;
416
427
  if (props.alt !== void 0) image.alt = props.alt;
417
428
  if (props.title !== void 0) image.title = props.title;
418
- if (Object.keys(pictureNames).length > 0) image.pictureNames = pictureNames;
419
429
  if (props.decorative !== void 0) image.decorative = props.decorative;
420
430
  if (props.hidden !== void 0) image.hidden = props.hidden;
421
431
  if (props.docPrExtensions !== void 0) image.docPrExtensions = props.docPrExtensions;
422
432
  const safeSrc = sanitizeImageSrc(imageData.src);
423
433
  if (safeSrc) image.src = safeSrc;
424
- if (imageData.mimeType) image.mimeType = imageData.mimeType;
425
- if (imageData.filename) image.filename = imageData.filename;
426
434
  if (padding) image.padding = padding;
427
435
  if (transform) image.transform = transform;
428
436
  if (crop) image.crop = crop;
@@ -492,18 +500,19 @@ function parseAnchor(anchorEl, rels, media) {
492
500
  size,
493
501
  wrap
494
502
  };
495
- if (props.id) image.id = props.id;
503
+ Object.assign(image, imageDerivedFactsOf({
504
+ id: props.id,
505
+ pictureNames,
506
+ imageData
507
+ }));
496
508
  if (props.name !== void 0) image.docPrName = props.name;
497
509
  if (props.alt !== void 0) image.alt = props.alt;
498
510
  if (props.title !== void 0) image.title = props.title;
499
- if (Object.keys(pictureNames).length > 0) image.pictureNames = pictureNames;
500
511
  if (props.decorative !== void 0) image.decorative = props.decorative;
501
512
  if (props.hidden !== void 0) image.hidden = props.hidden;
502
513
  if (props.docPrExtensions !== void 0) image.docPrExtensions = props.docPrExtensions;
503
514
  const safeSrc = sanitizeImageSrc(imageData.src);
504
515
  if (safeSrc) image.src = safeSrc;
505
- if (imageData.mimeType) image.mimeType = imageData.mimeType;
506
- if (imageData.filename) image.filename = imageData.filename;
507
516
  if (position) image.position = position;
508
517
  if (padding) image.padding = padding;
509
518
  if (transform) image.transform = transform;
@@ -628,4 +637,4 @@ function needsTextWrapping(image) {
628
637
  ].includes(image.wrap.type);
629
638
  }
630
639
  //#endregion
631
- export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
640
+ export { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE, getImageDimensionsPx, getImageHeightPx, getImageWidthPx, getWrapDistancesPx, hasAltText, imageDerivedFactsOf, isBehindText, isDecorativeImage, isFloatingImage, isInFrontOfText, isInlineImage, needsTextWrapping, parseDrawing, parseImage, resolveImageData };
@@ -138,14 +138,14 @@ declare const SIMPLE_FIELD_CONTENT: {
138
138
  readonly commentRangeStart: false;
139
139
  readonly commentReference: false;
140
140
  readonly complexField: false;
141
- readonly deletion: false;
141
+ readonly deletion: true;
142
142
  readonly inlineSdt: false;
143
- readonly insertion: false;
143
+ readonly insertion: true;
144
144
  readonly mathEquation: false;
145
- readonly moveFrom: false;
145
+ readonly moveFrom: true;
146
146
  readonly moveFromRangeEnd: false;
147
147
  readonly moveFromRangeStart: false;
148
- readonly moveTo: false;
148
+ readonly moveTo: true;
149
149
  readonly moveToRangeEnd: false;
150
150
  readonly moveToRangeStart: false;
151
151
  readonly simpleField: false;
@@ -137,14 +137,14 @@ const SIMPLE_FIELD_CONTENT = {
137
137
  commentRangeStart: false,
138
138
  commentReference: false,
139
139
  complexField: false,
140
- deletion: false,
140
+ deletion: true,
141
141
  inlineSdt: false,
142
- insertion: false,
142
+ insertion: true,
143
143
  mathEquation: false,
144
- moveFrom: false,
144
+ moveFrom: true,
145
145
  moveFromRangeEnd: false,
146
146
  moveFromRangeStart: false,
147
- moveTo: false,
147
+ moveTo: true,
148
148
  moveToRangeEnd: false,
149
149
  moveToRangeStart: false,
150
150
  simpleField: false
@@ -0,0 +1,10 @@
1
+ import { XmlElement } from "./xmlParser.js";
2
+ //#region src/docx/linkedSdtPreservation.d.ts
3
+ declare const UnrepresentableLinkedSdtRevisionError_base: import("better-result").TaggedErrorClass<"UnrepresentableLinkedSdtRevisionError">;
4
+ declare class UnrepresentableLinkedSdtRevisionError extends UnrepresentableLinkedSdtRevisionError_base<{
5
+ message: string;
6
+ }> {}
7
+ /** Capture only the unsupported hyperlink child, never its enclosing revision. */
8
+ declare const preserveLinkedSdt: (root: XmlElement) => import("@stll/docx-core/model").PreservedInline;
9
+ //#endregion
10
+ export { UnrepresentableLinkedSdtRevisionError, preserveLinkedSdt };
@@ -0,0 +1,37 @@
1
+ import { preserveInlineChild } from "./preservedRunContent.js";
2
+ import { WORDPROCESSINGML_NAMESPACE_URIS, getChildElements, getLocalName } from "./xmlParser.js";
3
+ import { TaggedError } from "better-result";
4
+ //#region src/docx/linkedSdtPreservation.ts
5
+ var UnrepresentableLinkedSdtRevisionError = class extends TaggedError("UnrepresentableLinkedSdtRevisionError") {};
6
+ /** Capture only the unsupported hyperlink child, never its enclosing revision. */
7
+ const preserveLinkedSdt = (root) => {
8
+ const pending = getChildElements(root);
9
+ while (pending.length > 0) {
10
+ const node = pending.pop();
11
+ if (!node) continue;
12
+ const wordprocessing = WORDPROCESSINGML_NAMESPACE_URIS.has(node.namespaceUri ?? "");
13
+ const name = getLocalName(node.name);
14
+ if (wordprocessing && [
15
+ "ins",
16
+ "del",
17
+ "moveFrom",
18
+ "moveTo",
19
+ "rPrChange",
20
+ "pPrChange",
21
+ "sectPrChange",
22
+ "tblPrChange",
23
+ "tblGridChange",
24
+ "trPrChange",
25
+ "tblPrExChange",
26
+ "tcPrChange",
27
+ "cellIns",
28
+ "cellDel",
29
+ "cellMerge",
30
+ "numberingChange"
31
+ ].includes(name)) throw new UnrepresentableLinkedSdtRevisionError({ message: "A content control under a hyperlink cannot preserve nested revisions as opaque XML." });
32
+ pending.push(...getChildElements(node));
33
+ }
34
+ return preserveInlineChild(root);
35
+ };
36
+ //#endregion
37
+ export { UnrepresentableLinkedSdtRevisionError, preserveLinkedSdt };
@@ -1,6 +1,7 @@
1
1
  import { countCentralDirectoryRecords, createInflationBudget, inflateEntryWithinLimits } from "./archiveInflation.js";
2
2
  import { elementToXml, getLocalName, parseXmlDocument } from "./xmlParser.js";
3
3
  import { TaggedError } from "better-result";
4
+ import { writeZipPart } from "@stll/docx-core/zip";
4
5
  import JSZip from "jszip";
5
6
  //#region src/docx/metadataPrivacy.ts
6
7
  const FOLIO_DOCUMENT_METADATA_PROPERTIES = Object.freeze([
@@ -152,7 +153,11 @@ const rewriteDocxMetadataPrivacy = async (buffer, { transforms }) => {
152
153
  removedMetadataProperties: []
153
154
  }
154
155
  };
155
- zip.file(coreProperties.name, rewritten.xml);
156
+ writeZipPart({
157
+ zip,
158
+ path: coreProperties.name,
159
+ data: rewritten.xml
160
+ });
156
161
  return {
157
162
  buffer: await zip.generateAsync({
158
163
  type: "arraybuffer",