@stll/folio-core 0.54.1 → 0.55.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 (251) hide show
  1. package/dist/ai-edits/apply.d.ts +1 -1
  2. package/dist/ai-edits/apply.js +40 -32
  3. package/dist/ai-edits/headless.d.ts +1 -2
  4. package/dist/ai-edits/headless.js +13 -27
  5. package/dist/ai-edits/read.d.ts +1 -0
  6. package/dist/ai-edits/read.js +7 -2
  7. package/dist/ai-edits/table-mutation-plan.d.ts +2 -1
  8. package/dist/ai-edits/table-mutation-plan.js +39 -1
  9. package/dist/ai-suggestions/apply.d.ts +1 -1
  10. package/dist/ai-suggestions/apply.js +3 -2
  11. package/dist/compare/compare.js +2 -1
  12. package/dist/compare/content-types.d.ts +3 -15
  13. package/dist/controller/canonicalComposition.d.ts +36 -0
  14. package/dist/controller/canonicalComposition.js +168 -0
  15. package/dist/controller/canonicalInput.d.ts +45 -0
  16. package/dist/controller/canonicalInput.js +338 -0
  17. package/dist/controller/canonicalOperations.d.ts +22 -0
  18. package/dist/controller/canonicalOperations.js +85 -0
  19. package/dist/controller/canonicalReview.d.ts +12 -0
  20. package/dist/controller/canonicalReview.js +19 -0
  21. package/dist/controller/canonicalSession.d.ts +149 -0
  22. package/dist/controller/canonicalSession.js +1038 -0
  23. package/dist/controller/canonicalStoryEditor.d.ts +34 -0
  24. package/dist/controller/canonicalStoryEditor.js +82 -0
  25. package/dist/controller/canonicalStructure.d.ts +16 -0
  26. package/dist/controller/canonicalStructure.js +269 -0
  27. package/dist/controller/folioEditor.d.ts +1 -1
  28. package/dist/controller/folioEditor.js +9 -0
  29. package/dist/controller/headerFooterEditorManager.d.ts +4 -0
  30. package/dist/controller/headerFooterEditorManager.js +71 -3
  31. package/dist/controller/hiddenEditorApi.d.ts +35 -0
  32. package/dist/controller/hiddenEditorApi.js +25 -8
  33. package/dist/controller/hiddenEditorManager.d.ts +11 -2
  34. package/dist/controller/hiddenEditorManager.js +456 -30
  35. package/dist/controller/layoutPipeline.d.ts +1 -1
  36. package/dist/controller/layoutPipeline.js +2 -0
  37. package/dist/controller/noteEditorManager.d.ts +4 -0
  38. package/dist/controller/noteEditorManager.js +113 -15
  39. package/dist/docx/attributeRemainder.js +1 -0
  40. package/dist/docx/bookmarkIds.d.ts +11 -0
  41. package/dist/docx/bookmarkIds.js +33 -0
  42. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  43. package/dist/docx/canonicalSessionInput.js +27 -0
  44. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  45. package/dist/docx/canonicalStoryRepack.js +41 -0
  46. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  47. package/dist/docx/contentTypeRegistry.js +64 -0
  48. package/dist/docx/documentParser.d.ts +14 -1
  49. package/dist/docx/documentParser.js +17 -4
  50. package/dist/docx/drawingIdNormalization.js +23 -8
  51. package/dist/docx/ensureParaIds.d.ts +12 -1
  52. package/dist/docx/ensureParaIds.js +173 -213
  53. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  54. package/dist/docx/foldedListNumberFields.js +267 -0
  55. package/dist/docx/headerFooterVerbatim.d.ts +14 -1
  56. package/dist/docx/headerFooterVerbatim.js +95 -2
  57. package/dist/docx/listNumberingInstances.js +11 -9
  58. package/dist/docx/noteIds.d.ts +9 -0
  59. package/dist/docx/noteIds.js +17 -0
  60. package/dist/docx/noteReferenceMark.d.ts +3 -1
  61. package/dist/docx/noteReferenceMark.js +15 -14
  62. package/dist/docx/numberingIds.d.ts +14 -0
  63. package/dist/docx/numberingIds.js +16 -0
  64. package/dist/docx/numberingParser.d.ts +3 -1
  65. package/dist/docx/numberingParser.js +17 -3
  66. package/dist/docx/numericIdAllocator.d.ts +12 -0
  67. package/dist/docx/numericIdAllocator.js +33 -0
  68. package/dist/docx/numericIdNormalization.d.ts +16 -0
  69. package/dist/docx/numericIdNormalization.js +174 -0
  70. package/dist/docx/packageParts.d.ts +3 -1
  71. package/dist/docx/packageParts.js +65 -16
  72. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  73. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  74. package/dist/docx/paragraphParser.js +101 -53
  75. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  76. package/dist/docx/paragraphPropertySource.js +76 -22
  77. package/dist/docx/paragraphTextBoxEnrichment.js +2 -1
  78. package/dist/docx/parser.js +19 -6
  79. package/dist/docx/rasterMime.d.ts +64 -0
  80. package/dist/docx/rasterMime.js +116 -0
  81. package/dist/docx/replyToComment.js +13 -6
  82. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  83. package/dist/docx/reviewHistoryNamespace.js +4 -0
  84. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  85. package/dist/docx/reviewResolutionProvenance.js +153 -0
  86. package/dist/docx/rezip.d.ts +7 -3
  87. package/dist/docx/rezip.js +121 -52
  88. package/dist/docx/runConsolidator.d.ts +2 -58
  89. package/dist/docx/runConsolidator.js +3 -175
  90. package/dist/docx/runParser.d.ts +2 -1
  91. package/dist/docx/runParser.js +156 -116
  92. package/dist/docx/saveDiagnostics.d.ts +11 -0
  93. package/dist/docx/saveDiagnostics.js +0 -0
  94. package/dist/docx/selectiveSave.d.ts +2 -1
  95. package/dist/docx/selectiveSave.js +14 -1
  96. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  97. package/dist/docx/selectiveXmlPatch.js +74 -2
  98. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  99. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  100. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  101. package/dist/docx/serializer/noteSerializer.js +24 -8
  102. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  103. package/dist/docx/serializer/partNamespaces.js +6 -3
  104. package/dist/docx/serializer/runSerializer.js +8 -5
  105. package/dist/docx/serializer/trackedChangeAttributes.js +7 -1
  106. package/dist/docx/server/build.js +14 -3
  107. package/dist/docx/server/createBilingualDocument.js +10 -9
  108. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  109. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  110. package/dist/docx/settingsParser.d.ts +1 -2
  111. package/dist/docx/settingsParser.js +5 -6
  112. package/dist/docx/storyBlockReplay.d.ts +11 -0
  113. package/dist/docx/storyBlockReplay.js +367 -0
  114. package/dist/docx/streamingXmlParser.d.ts +31 -1
  115. package/dist/docx/streamingXmlParser.js +136 -21
  116. package/dist/docx/structuralXmlPatch.js +8 -1
  117. package/dist/docx/unzip.d.ts +3 -1
  118. package/dist/docx/unzip.js +36 -16
  119. package/dist/docx/verbatimCapture.d.ts +3 -1
  120. package/dist/docx/verbatimCapture.js +49 -6
  121. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  122. package/dist/i18n/messages/ar.gen.js +656 -0
  123. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  124. package/dist/i18n/messages/cs.gen.js +656 -0
  125. package/dist/i18n/messages/de.gen.d.ts +5 -0
  126. package/dist/i18n/messages/de.gen.js +656 -0
  127. package/dist/i18n/messages/en.gen.d.ts +5 -0
  128. package/dist/i18n/messages/en.gen.js +656 -0
  129. package/dist/i18n/messages/es.gen.d.ts +5 -0
  130. package/dist/i18n/messages/es.gen.js +656 -0
  131. package/dist/i18n/messages/et.gen.d.ts +5 -0
  132. package/dist/i18n/messages/et.gen.js +656 -0
  133. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  134. package/dist/i18n/messages/fr.gen.js +656 -0
  135. package/dist/i18n/messages/he.gen.d.ts +5 -0
  136. package/dist/i18n/messages/he.gen.js +656 -0
  137. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  138. package/dist/i18n/messages/hi.gen.js +656 -0
  139. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  140. package/dist/i18n/messages/hu.gen.js +656 -0
  141. package/dist/i18n/messages/locales.d.ts +5 -0
  142. package/dist/i18n/messages/locales.js +22 -0
  143. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  144. package/dist/i18n/messages/lt.gen.js +656 -0
  145. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  146. package/dist/i18n/messages/lv.gen.js +656 -0
  147. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  148. package/dist/i18n/messages/pl.gen.js +656 -0
  149. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  150. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  151. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  152. package/dist/i18n/messages/sk.gen.js +656 -0
  153. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  154. package/dist/i18n/messages/tr.gen.js +656 -0
  155. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  156. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  157. package/dist/i18n/messages.d.ts +2 -3
  158. package/dist/i18n/messages.js +1 -19
  159. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  160. package/dist/internal/noteMarkerAttrs.js +16 -0
  161. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  162. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  163. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  164. package/dist/layout-bridge/convert/fixedTableColumnWidths.d.ts +6 -0
  165. package/dist/layout-bridge/convert/fixedTableColumnWidths.js +23 -0
  166. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  167. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  168. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  169. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  170. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  171. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  172. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  173. package/dist/layout-bridge/convert/tableConversion.js +4 -1
  174. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  175. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  176. package/dist/layout-painter/index.js +2 -5
  177. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  178. package/dist/managers/DocumentLoaderManager.js +8 -1
  179. package/dist/markdown/renderBlock.js +15 -1
  180. package/dist/markdown/renderParagraph.js +9 -13
  181. package/dist/markdown/renderRuns.js +3 -2
  182. package/dist/markdown/renderTable.js +2 -0
  183. package/dist/markdown/types.d.ts +3 -9
  184. package/dist/paged-layout/editorScrollRoot.d.ts +15 -0
  185. package/dist/paged-layout/editorScrollRoot.js +72 -0
  186. package/dist/paged-layout/scrollToPmPosition.js +8 -22
  187. package/dist/prosemirror/attrs/index.d.ts +2 -12
  188. package/dist/prosemirror/attrs/index.js +22 -48
  189. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  190. package/dist/prosemirror/canonicalCommands.d.ts +97 -0
  191. package/dist/prosemirror/canonicalCommands.js +28 -0
  192. package/dist/prosemirror/commands/clearParagraphIndent.d.ts +6 -0
  193. package/dist/prosemirror/commands/clearParagraphIndent.js +25 -0
  194. package/dist/prosemirror/commands/pageBreak.js +15 -1
  195. package/dist/prosemirror/commentIdAllocator.d.ts +15 -22
  196. package/dist/prosemirror/commentIdAllocator.js +50 -25
  197. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  198. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  199. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  200. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  201. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -3
  202. package/dist/prosemirror/conversion/toProseDoc.js +51 -11
  203. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  204. package/dist/prosemirror/executeEditorCommand.js +26 -0
  205. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  206. package/dist/prosemirror/extensions/core/HistoryExtension.js +97 -5
  207. package/dist/prosemirror/extensions/core/ParagraphExtension.js +53 -20
  208. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +22 -28
  209. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  210. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  211. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  212. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  213. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  214. package/dist/prosemirror/extensions/marks/markUtils.js +70 -8
  215. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  216. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -6
  219. package/dist/prosemirror/listMarker.d.ts +1 -0
  220. package/dist/prosemirror/listMarker.js +16 -7
  221. package/dist/prosemirror/listNumbering.js +26 -5
  222. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  223. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  224. package/dist/prosemirror/markupViewNotes.js +3 -2
  225. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  226. package/dist/prosemirror/noteReferenceReview.js +5 -3
  227. package/dist/prosemirror/plugins/revisionIds.d.ts +23 -19
  228. package/dist/prosemirror/plugins/revisionIds.js +110 -29
  229. package/dist/prosemirror/plugins/suggestionMode.d.ts +2 -2
  230. package/dist/prosemirror/plugins/suggestionMode.js +246 -42
  231. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  232. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  233. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  234. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  235. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  236. package/dist/prosemirror/schema/marks.d.ts +2 -0
  237. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  238. package/dist/prosemirror/storyListNumbering.js +11 -9
  239. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  240. package/dist/prosemirror/textInput.d.ts +6 -1
  241. package/dist/prosemirror/textInput.js +14 -3
  242. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  243. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  244. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  245. package/dist/prosemirror/utils/visualLineNavigation.js +6 -8
  246. package/dist/prosemirror/validation.js +4 -0
  247. package/dist/types/content.d.ts +2 -2
  248. package/dist/utils/createDocument.js +2 -2
  249. package/dist/utils/mergeDocumentContent.d.ts +2 -2
  250. package/dist/utils/mergeDocumentContent.js +11 -8
  251. package/package.json +14 -2
@@ -1,7 +1,7 @@
1
1
  import { canonicalJson } from "../utils/canonicalJson.js";
2
2
  import { parseDocumentBody } from "./documentParser.js";
3
3
  import { paraIdAttribute } from "./paraIdAttribute.js";
4
- import { spliceXml } from "./selectiveXmlPatch.js";
4
+ import { spliceSupportsRootNamespaces, spliceXml } from "./selectiveXmlPatch.js";
5
5
  import { readRootNamespaceBindings, serializePartElement } from "./serializer/partNamespaces.js";
6
6
  import { NAMESPACES, WORDPROCESSINGML_NAMESPACE_URIS, getChildElements, getLocalName, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
7
7
  //#region src/docx/structuralXmlPatch.ts
@@ -203,6 +203,13 @@ const buildStructuralDocumentPatch = ({ originalXml, serializedXml, changedIds }
203
203
  end: source.bodyEnd,
204
204
  newXml: pending.join("")
205
205
  });
206
+ if (!spliceSupportsRootNamespaces({
207
+ originalXml,
208
+ serializedXml,
209
+ fragments: splices.map(({ newXml }) => newXml).filter(Boolean),
210
+ originalRoot: source.root,
211
+ serializedRoot: current.root
212
+ })) return null;
206
213
  return spliceXml(originalXml, splices);
207
214
  };
208
215
  //#endregion
@@ -99,6 +99,8 @@ type UnzipDocxBehavior = {
99
99
  * @returns Promise resolving to extracted content
100
100
  */
101
101
  declare function unzipDocx(buffer: ArrayBuffer, options?: DocxUnzipOptions, { verifyUnreadEntries }?: UnzipDocxBehavior): Promise<RawDocxContent>;
102
+ /** Keep extracted projections and the source ZIP aligned after parser normalization. */
103
+ declare const replaceRawDocxXmlParts: (content: RawDocxContent, parts: ReadonlyMap<string, string>) => Promise<void>;
102
104
  declare function getEntryUncompressedSize(file: JSZip.JSZipObject): number | null;
103
105
  /**
104
106
  * Get a list of all files in the DOCX
@@ -160,4 +162,4 @@ declare function getContentSummary(content: RawDocxContent): {
160
162
  totalFiles: number;
161
163
  };
162
164
  //#endregion
163
- export { DocxSecurityError, DocxUnzipLimits, DocxUnzipOptions, RawDocxContent, UnzipDocxBehavior, extractFile, getContentSummary, getEntryUncompressedSize, getFileList, getMediaMimeType, hasFile, mediaToDataUrl, unzipDocx };
165
+ export { DocxSecurityError, DocxUnzipLimits, DocxUnzipOptions, RawDocxContent, UnzipDocxBehavior, extractFile, getContentSummary, getEntryUncompressedSize, getFileList, getMediaMimeType, hasFile, mediaToDataUrl, replaceRawDocxXmlParts, unzipDocx };
@@ -2,6 +2,7 @@ import { bytesToDataUrl } from "../utils/base64.js";
2
2
  import { compressionRatioLimitFor, countCentralDirectoryRecords, createInflationBudget, exceedsCompressionRatio, getZipEntrySizes, inflateEntryWithinLimits, isStoredZipEntry } from "./archiveInflation.js";
3
3
  import { DOCX_CONTAINER_TYPES, detectDocxContainerType } from "./encryption/containerFormat.js";
4
4
  import { openDocxBuffer } from "./encryption/openEncryptedDocx.js";
5
+ import { RASTER_MIME_TYPES, detectRasterMimeType } from "./rasterMime.js";
5
6
  import { decodeXmlBytes } from "./xmlEncoding.js";
6
7
  import { FOLIO_XML_RESOURCE_LIMITS, assertXmlResourceLimits, createXmlPackageBudget } from "./xmlResourceLimits.js";
7
8
  import JSZip from "jszip";
@@ -38,12 +39,7 @@ var DocxSecurityError = class extends Error {
38
39
  }
39
40
  };
40
41
  const DEFAULT_ALLOWED_MEDIA_MIME_TYPES = /* @__PURE__ */ new Set([
41
- "image/png",
42
- "image/jpeg",
43
- "image/gif",
44
- "image/bmp",
45
- "image/tiff",
46
- "image/webp",
42
+ ...RASTER_MIME_TYPES,
47
43
  "image/x-emf",
48
44
  "image/x-wmf"
49
45
  ]);
@@ -227,11 +223,12 @@ async function unzipDocx(buffer, options = {}, { verifyUnreadEntries = true } =
227
223
  return null;
228
224
  }
229
225
  const binaryContent = result.bytes.buffer;
230
- if (!isMediaContentAllowed(binaryContent, mimeType)) return null;
226
+ const effectiveMimeType = RASTER_MIME_TYPES.has(mimeType) ? detectRasterMimeType(binaryContent) : mimeType;
227
+ if (!effectiveMimeType || !limits.allowedMediaMimeTypes.has(effectiveMimeType) || !isMediaContentAllowed(binaryContent, effectiveMimeType)) return null;
231
228
  return {
232
229
  type: "media",
233
230
  path,
234
- mimeType,
231
+ mimeType: effectiveMimeType,
235
232
  content: binaryContent
236
233
  };
237
234
  });
@@ -274,6 +271,26 @@ async function unzipDocx(buffer, options = {}, { verifyUnreadEntries = true } =
274
271
  }
275
272
  return content;
276
273
  }
274
+ /** Keep extracted projections and the source ZIP aligned after parser normalization. */
275
+ const replaceRawDocxXmlParts = async (content, parts) => {
276
+ let identitiesChanged = false;
277
+ for (const [path, xmlContent] of parts) {
278
+ if (content.allXml.get(path) === xmlContent) continue;
279
+ indexXmlContent(content, {
280
+ type: "xml",
281
+ path,
282
+ lowerPath: path.toLowerCase(),
283
+ content: xmlContent
284
+ });
285
+ content.originalZip.file(path, xmlContent);
286
+ identitiesChanged = true;
287
+ }
288
+ if (identitiesChanged) content.originalBuffer = await content.originalZip.generateAsync({
289
+ type: "arraybuffer",
290
+ compression: "DEFLATE",
291
+ compressionOptions: { level: 1 }
292
+ });
293
+ };
277
294
  /**
278
295
  * Preflight every XML part the unzip retains, not a named few.
279
296
  *
@@ -291,6 +308,14 @@ function assignXmlContent(content, { path, lowerPath, content: xmlContent }, lim
291
308
  partPath: path,
292
309
  budget
293
310
  });
311
+ indexXmlContent(content, {
312
+ type: "xml",
313
+ path,
314
+ lowerPath,
315
+ content: xmlContent
316
+ });
317
+ }
318
+ const indexXmlContent = (content, { path, lowerPath, content: xmlContent }) => {
294
319
  content.allXml.set(path, xmlContent);
295
320
  if (lowerPath === "word/document.xml") content.documentXml = xmlContent;
296
321
  else if (lowerPath === "word/styles.xml") content.stylesXml = xmlContent;
@@ -317,7 +342,7 @@ function assignXmlContent(content, { path, lowerPath, content: xmlContent }, lim
317
342
  const filename = path.split("/").pop() || path;
318
343
  content.footers.set(filename, xmlContent);
319
344
  }
320
- }
345
+ };
321
346
  function inflationLimitError(limit, path) {
322
347
  switch (limit) {
323
348
  case "declared-size": return new DocxSecurityError(`DOCX entry inflates past its declared size: ${path}`);
@@ -499,14 +524,9 @@ function isEntryTooLarge(declaredSize, maxBytes) {
499
524
  return declaredSize !== null && declaredSize > maxBytes;
500
525
  }
501
526
  function isMediaContentAllowed(data, mimeType) {
527
+ if (RASTER_MIME_TYPES.has(mimeType)) return detectRasterMimeType(data) === mimeType;
502
528
  const bytes = new Uint8Array(data);
503
529
  switch (mimeType) {
504
- case "image/png": return bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71;
505
- case "image/jpeg": return bytes[0] === 255 && bytes[1] === 216;
506
- case "image/gif": return bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 56;
507
- case "image/bmp": return bytes[0] === 66 && bytes[1] === 77;
508
- case "image/webp": return bytes[0] === 82 && bytes[1] === 73 && bytes[2] === 70 && bytes[3] === 70 && bytes[8] === 87 && bytes[9] === 69 && bytes[10] === 66 && bytes[11] === 80;
509
- case "image/tiff": return bytes[0] === 73 && bytes[1] === 73 || bytes[0] === 77 && bytes[1] === 77;
510
530
  case "image/x-emf":
511
531
  case "image/emf": return bytes.length >= 44 && bytes[0] === 1 && bytes[40] === 32 && bytes[41] === 69 && bytes[42] === 77 && bytes[43] === 70;
512
532
  case "image/x-wmf":
@@ -605,4 +625,4 @@ function getContentSummary(content) {
605
625
  };
606
626
  }
607
627
  //#endregion
608
- export { DocxSecurityError, extractFile, getContentSummary, getEntryUncompressedSize, getFileList, getMediaMimeType, hasFile, mediaToDataUrl, unzipDocx };
628
+ export { DocxSecurityError, extractFile, getContentSummary, getEntryUncompressedSize, getFileList, getMediaMimeType, hasFile, mediaToDataUrl, replaceRawDocxXmlParts, unzipDocx };
@@ -1,3 +1,4 @@
1
+ import { document_d_exports } from "../types/document.js";
1
2
  import { XmlElement, XmlNamespaceScope } from "./xmlParser.js";
2
3
  //#region src/docx/verbatimCapture.d.ts
3
4
  declare const UntranslatableStrictNamespaceError_base: import("better-result").TaggedErrorClass<"UntranslatableStrictNamespaceError">;
@@ -29,5 +30,6 @@ declare const isSafeCapturedXmlDocument: (xml: string) => boolean;
29
30
  * must therefore depend on nothing but the element they are given.
30
31
  */
31
32
  declare const createCapturedXmlSanitizer: (options: SanitizeCapturedXmlOptions) => ((xml: string | undefined) => string | null);
33
+ declare const captureSourceProfileXml: (element: XmlElement, conformance: document_d_exports.DocxConformanceClass | undefined) => string;
32
34
  //#endregion
33
- export { UntranslatableStrictNamespaceError, captureVerbatimXml, createCapturedXmlSanitizer, isSafeCapturedXmlDocument };
35
+ export { UntranslatableStrictNamespaceError, captureSourceProfileXml, captureVerbatimXml, createCapturedXmlSanitizer, isSafeCapturedXmlDocument };
@@ -1,10 +1,11 @@
1
1
  import { TRANSITIONAL_NAMESPACE_BY_STRICT_URI } from "./strictValueEncodings.gen.js";
2
2
  import { NUMBERS_PER_PERCENT, isStrictNamespaceUri, percentageSpelling, toTransitionalNamespaceUri, transitionalSlotEncoding } from "./transitionalSpelling.js";
3
3
  import { roundHalfAwayFromZero, universalMeasureAs } from "./universalMeasure.js";
4
- import { NAMESPACES, OOXML_NAMESPACE_SCOPE, cloneElement, elementToXml, getChildElements, getLocalName, getNamespacePrefix, parseXml } from "./xmlParser.js";
4
+ import { NAMESPACES, OOXML_NAMESPACE_SCOPE, WORDPROCESSINGML_NAMESPACE_URIS, cloneElement, elementToXml, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespacePrefix, parseXml, resolveAttributeNamespaceUri } from "./xmlParser.js";
5
5
  import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
6
6
  import { getDocxXmlSafetyIssue } from "./xmlSafety.js";
7
- import { TaggedError } from "better-result";
7
+ import { TaggedError, panic } from "better-result";
8
+ import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
8
9
  //#region src/docx/verbatimCapture.ts
9
10
  /**
10
11
  * The one way to turn parsed markup into a string a rebuilt part replays.
@@ -75,14 +76,22 @@ const originOf = (element, inherited) => {
75
76
  });
76
77
  return TRANSITIONAL_URIS.has(uri) ? "transitional" : inherited;
77
78
  };
78
- const convertAttributes = (element, namespaceUri, localName, convertValues) => {
79
+ /** A same-local-name extension attribute is not a slot in the element's vocabulary. */
80
+ const attributeSlotEncoding = (element, name) => {
81
+ if (getNamespacePrefix(name) !== null) {
82
+ const attributeUri = resolveAttributeNamespaceUri(element, name);
83
+ if (attributeUri === void 0 || element.namespaceUri === void 0 || toTransitionalNamespaceUri(attributeUri) !== toTransitionalNamespaceUri(element.namespaceUri)) return void 0;
84
+ }
85
+ return transitionalSlotEncoding(element.namespaceUri, getLocalName(element.name), getLocalName(name));
86
+ };
87
+ const convertAttributes = (element, namespaceUri, convertValues) => {
79
88
  const attributes = element.attributes ?? {};
80
89
  let converted;
81
90
  for (const [name, raw] of Object.entries(attributes)) {
82
91
  if (typeof raw !== "string") continue;
83
92
  let next = raw;
84
93
  if (name === "xmlns" || name.startsWith("xmlns:")) next = toTransitionalNamespaceUri(raw);
85
- else if (convertValues) next = transitionalValue(raw, namespaceUri, transitionalSlotEncoding(element.namespaceUri, localName, getLocalName(name)));
94
+ else if (convertValues) next = transitionalValue(raw, namespaceUri, attributeSlotEncoding(element, name));
86
95
  if (next === raw) continue;
87
96
  converted ??= { ...attributes };
88
97
  converted[name] = next;
@@ -99,7 +108,7 @@ const toTransitional = (element, inherited) => {
99
108
  const namespaceUri = element.namespaceUri === void 0 ? "" : toTransitionalNamespaceUri(element.namespaceUri);
100
109
  const localName = getLocalName(element.name);
101
110
  const textEncoding = transitionalSlotEncoding(element.namespaceUri, localName);
102
- const attributes = element.attributes ? convertAttributes(element, namespaceUri, localName, origin === "strict") : void 0;
111
+ const attributes = element.attributes ? convertAttributes(element, namespaceUri, origin === "strict") : void 0;
103
112
  let elements;
104
113
  for (const [index, child] of (element.elements ?? []).entries()) {
105
114
  const next = origin === "strict" && child.type === "text" && typeof child.text === "string" ? childWithValue(child, transitionalValue(child.text, namespaceUri, textEncoding)) : toTransitional(child, origin);
@@ -363,5 +372,39 @@ const createCapturedXmlSanitizer = (options) => {
363
372
  return sanitized;
364
373
  };
365
374
  };
375
+ const STRICT_BY_TRANSITIONAL = new Map([...TRANSITIONAL_NAMESPACE_BY_STRICT_URI].map(([strict, transitional]) => [transitional, strict]));
376
+ const strictPercentage = (value, unit) => /^-?\d+(?:\.\d+)?$/u.test(value) ? `${Number(value) / NUMBERS_PER_PERCENT[unit]}%` : value;
377
+ /** Translate generated markup by namespace/slot, never by a user-text replacement. */
378
+ const strictElement = (element) => {
379
+ const localName = getLocalName(element.name);
380
+ for (const [name, value] of Object.entries(element.attributes ?? {})) {
381
+ if (typeof value !== "string") continue;
382
+ if (name === "xmlns" || name.startsWith("xmlns:")) {
383
+ element.attributes[name] = STRICT_BY_TRANSITIONAL.get(value) ?? value;
384
+ continue;
385
+ }
386
+ if (localName === "graphicData" && toTransitionalNamespaceUri(element.namespaceUri ?? "") === NAMESPACES.a && name === "uri") {
387
+ element.attributes[name] = STRICT_BY_TRANSITIONAL.get(value) ?? value;
388
+ continue;
389
+ }
390
+ const encoding = attributeSlotEncoding(element, name);
391
+ if (encoding?.percent && (!encoding.measure || getAttributeByNamespaceUri(element, WORDPROCESSINGML_NAMESPACE_URIS, "type") === "pct")) element.attributes[name] = strictPercentage(value, encoding.percent);
392
+ }
393
+ const encoding = transitionalSlotEncoding(element.namespaceUri, localName);
394
+ for (const child of element.elements ?? []) if (child.type === "element") strictElement(child);
395
+ else if (child.type === "text" && typeof child.text === "string" && encoding?.percent) child.text = strictPercentage(child.text, encoding.percent);
396
+ };
397
+ /** Serialize a generated, scope-bound block in the source part's profile. */
398
+ const cloneSourceProfileTree = (element) => cloneElement(element, {
399
+ ...element.attributes === void 0 ? {} : { attributes: { ...element.attributes } },
400
+ ...element.elements === void 0 ? {} : { elements: element.elements.map(cloneSourceProfileTree) }
401
+ });
402
+ const captureSourceProfileXml = (element, conformance) => {
403
+ const owned = cloneSourceProfileTree(element);
404
+ if (conformance === DOCX_CONFORMANCE_CLASSES.STRICT) strictElement(owned);
405
+ const xml = elementToXml(owned);
406
+ if (!isSafeCapturedXmlDocument(xml)) panic("Generated source-profile markup is unsafe.");
407
+ return xml;
408
+ };
366
409
  //#endregion
367
- export { UntranslatableStrictNamespaceError, captureVerbatimXml, createCapturedXmlSanitizer, isSafeCapturedXmlDocument };
410
+ export { UntranslatableStrictNamespaceError, captureSourceProfileXml, captureVerbatimXml, createCapturedXmlSanitizer, isSafeCapturedXmlDocument };
@@ -0,0 +1,5 @@
1
+ import { FolioMessages } from "../messages.js";
2
+ //#region src/i18n/messages/ar.gen.d.ts
3
+ declare const messages: FolioMessages;
4
+ //#endregion
5
+ export { messages as default, messages };