@stll/folio-core 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 (263) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.js +2 -2
  2. package/dist/ai-edits/apply.js +59 -19
  3. package/dist/ai-edits/headless.js +2 -1
  4. package/dist/compare/compare.js +2 -5
  5. package/dist/compare/content-alignment.js +78 -53
  6. package/dist/compare/inline-atoms.js +34 -20
  7. package/dist/compare/scenario.js +2 -5
  8. package/dist/compare/types.d.ts +9 -1
  9. package/dist/compare/types.js +12 -1
  10. package/dist/compat/eigenpal.d.ts +2 -1
  11. package/dist/compat/eigenpal.js +2 -1
  12. package/dist/content-controls/checkboxDisplay.d.ts +11 -0
  13. package/dist/content-controls/checkboxDisplay.js +40 -0
  14. package/dist/content-controls/findContentControls.js +3 -1
  15. package/dist/content-controls/mutateContentControls.js +21 -4
  16. package/dist/controller/contentControlWidgetController.d.ts +1 -0
  17. package/dist/controller/contentControlWidgetController.js +3 -0
  18. package/dist/controller/hiddenEditorApi.js +3 -1
  19. package/dist/controller/hiddenEditorManager.d.ts +1 -1
  20. package/dist/controller/hiddenEditorManager.js +6 -3
  21. package/dist/display-list/build/buildDisplayList.js +20 -1
  22. package/dist/display-list/build/imagePrimitives.d.ts +1 -1
  23. package/dist/display-list/build/imagePrimitives.js +3 -1
  24. package/dist/display-list/build/paragraphPrimitives.js +21 -2
  25. package/dist/display-list/dom/renderDisplayListToDom.js +18 -10
  26. package/dist/display-list/types.d.ts +17 -0
  27. package/dist/document-operations.js +14 -3
  28. package/dist/docx/attributeRemainder.d.ts +43 -0
  29. package/dist/docx/attributeRemainder.js +65 -0
  30. package/dist/docx/blockContentParser.d.ts +1 -1
  31. package/dist/docx/blockContentParser.js +87 -63
  32. package/dist/docx/blockPlainText.d.ts +3 -4
  33. package/dist/docx/blockPlainText.js +1 -0
  34. package/dist/docx/bookmarkPlacement.js +2 -0
  35. package/dist/docx/borderParser.js +5 -5
  36. package/dist/docx/commentAnchorIndex.d.ts +30 -0
  37. package/dist/docx/commentAnchorIndex.js +50 -0
  38. package/dist/docx/commentParser.d.ts +1 -1
  39. package/dist/docx/commentParser.js +78 -50
  40. package/dist/docx/commentRangeIntegrity.d.ts +16 -1
  41. package/dist/docx/commentRangeIntegrity.js +42 -1
  42. package/dist/docx/commentRangeJoin.d.ts +9 -0
  43. package/dist/docx/commentRangeJoin.js +33 -0
  44. package/dist/docx/commentReferenceCompletion.d.ts +9 -0
  45. package/dist/docx/commentReferenceCompletion.js +47 -0
  46. package/dist/docx/commentReferenceNormalization.js +1 -0
  47. package/dist/docx/commentReplyMarkers.js +11 -19
  48. package/dist/docx/commentThreadKey.d.ts +18 -0
  49. package/dist/docx/commentThreadKey.js +22 -0
  50. package/dist/docx/compatibility.js +1 -0
  51. package/dist/docx/containerChildren.d.ts +111 -0
  52. package/dist/docx/containerChildren.gen.d.ts +28 -0
  53. package/dist/docx/containerChildren.gen.js +246 -0
  54. package/dist/docx/containerChildren.js +103 -0
  55. package/dist/docx/diagramPreview.js +87 -27
  56. package/dist/docx/documentParser.d.ts +1 -1
  57. package/dist/docx/documentParser.js +3 -3
  58. package/dist/docx/ensureParaIds.js +17 -7
  59. package/dist/docx/fieldParser.d.ts +1 -1
  60. package/dist/docx/fieldParser.js +4 -4
  61. package/dist/docx/fieldState.d.ts +26 -0
  62. package/dist/docx/fieldState.js +53 -0
  63. package/dist/docx/footnoteParser.d.ts +1 -1
  64. package/dist/docx/graphicFrameLocks.d.ts +16 -4
  65. package/dist/docx/graphicFrameLocks.js +19 -6
  66. package/dist/docx/groupDrawingParser.js +3 -3
  67. package/dist/docx/headerFooterParser.js +1 -1
  68. package/dist/docx/headerFooterReferenceNormalization.js +1 -0
  69. package/dist/docx/hyperlinkParser.d.ts +27 -8
  70. package/dist/docx/hyperlinkParser.js +78 -20
  71. package/dist/docx/imageParser.d.ts +9 -1
  72. package/dist/docx/imageParser.js +91 -20
  73. package/dist/docx/imageRawXml.d.ts +14 -1
  74. package/dist/docx/imageRawXml.js +30 -6
  75. package/dist/docx/inlineWrapperContent.d.ts +85 -0
  76. package/dist/docx/inlineWrapperContent.js +84 -0
  77. package/dist/docx/mathToMathml.js +12 -14
  78. package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
  79. package/dist/docx/nonVisualDrawingProps.js +46 -0
  80. package/dist/docx/normalizeBaseDirection.js +10 -1
  81. package/dist/docx/paraIdAttribute.d.ts +21 -0
  82. package/dist/docx/paraIdAttribute.js +64 -0
  83. package/dist/docx/paragraphParser.d.ts +1 -1
  84. package/dist/docx/paragraphParser.js +277 -168
  85. package/dist/docx/paragraphPropertySource.js +5 -1
  86. package/dist/docx/paragraphTextBoxEnrichment.d.ts +1 -1
  87. package/dist/docx/paragraphTextBoxEnrichment.js +9 -52
  88. package/dist/docx/paragraphTraversal.js +7 -4
  89. package/dist/docx/parseWarningMessage.js +2 -1
  90. package/dist/docx/parser.js +2 -2
  91. package/dist/docx/preservedRunContent.d.ts +32 -0
  92. package/dist/docx/preservedRunContent.js +86 -0
  93. package/dist/docx/previewBudget.d.ts +64 -0
  94. package/dist/docx/previewBudget.js +88 -0
  95. package/dist/docx/renderedPageBreakNormalization.js +2 -4
  96. package/dist/docx/revisionIdNormalization.js +17 -5
  97. package/dist/docx/rezip.js +91 -36
  98. package/dist/docx/runParser.d.ts +1 -1
  99. package/dist/docx/runParser.js +16 -12
  100. package/dist/docx/sdtPropertiesPatch.js +24 -18
  101. package/dist/docx/sectionParser.js +8 -1
  102. package/dist/docx/sectionReferenceHistory.js +2 -2
  103. package/dist/docx/selectiveSave.js +6 -6
  104. package/dist/docx/selectiveXmlPatch.d.ts +46 -2
  105. package/dist/docx/selectiveXmlPatch.js +86 -39
  106. package/dist/docx/serializer/blockSdtSerializer.js +38 -26
  107. package/dist/docx/serializer/borderSerializer.d.ts +1 -1
  108. package/dist/docx/serializer/borderSerializer.js +15 -14
  109. package/dist/docx/serializer/commentSerializer.d.ts +41 -16
  110. package/dist/docx/serializer/commentSerializer.js +87 -92
  111. package/dist/docx/serializer/documentSerializer.js +8 -11
  112. package/dist/docx/serializer/fontTableSerializer.js +6 -6
  113. package/dist/docx/serializer/headerFooterSerializer.js +12 -14
  114. package/dist/docx/serializer/markupRangeAttributes.js +2 -2
  115. package/dist/docx/serializer/noteSerializer.js +8 -8
  116. package/dist/docx/serializer/numberingSerializer.js +7 -6
  117. package/dist/docx/serializer/paragraphSerializer.js +93 -72
  118. package/dist/docx/serializer/partNamespaces.js +2 -2
  119. package/dist/docx/serializer/runSerializer.js +73 -44
  120. package/dist/docx/serializer/sectionPropertiesSerializer.js +19 -14
  121. package/dist/docx/serializer/settingsSerializer.js +4 -3
  122. package/dist/docx/serializer/stylesSerializer.js +6 -6
  123. package/dist/docx/serializer/tableSerializer.js +28 -17
  124. package/dist/docx/serializer/textFormattingSerializer.js +29 -28
  125. package/dist/docx/serializer/themeSerializer.js +6 -6
  126. package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
  127. package/dist/docx/serializer/xmlUtils.d.ts +1 -2
  128. package/dist/docx/serializer/xmlUtils.js +1 -13
  129. package/dist/docx/server/boundedArchive.d.ts +12 -0
  130. package/dist/docx/server/boundedArchive.js +20 -1
  131. package/dist/docx/server/createBilingualDocument.js +3 -1
  132. package/dist/docx/server/materializeYjsDocx.d.ts +1 -1
  133. package/dist/docx/server/materializeYjsDocx.js +9 -1
  134. package/dist/docx/server/migrateYjsAttrSchema.d.ts +55 -0
  135. package/dist/docx/server/migrateYjsAttrSchema.js +95 -0
  136. package/dist/docx/server/validateDocxConformance.js +22 -1
  137. package/dist/docx/shapeParser.js +12 -10
  138. package/dist/docx/tableParser.d.ts +1 -1
  139. package/dist/docx/tableParser.js +206 -85
  140. package/dist/docx/textBoxParser.d.ts +25 -2
  141. package/dist/docx/textBoxParser.js +59 -4
  142. package/dist/docx/unzip.d.ts +23 -0
  143. package/dist/docx/unzip.js +37 -26
  144. package/dist/docx/verbatimCapture.js +1 -1
  145. package/dist/docx/vmlImageParser.d.ts +17 -1
  146. package/dist/docx/vmlImageParser.js +20 -3
  147. package/dist/docx/vmlPreview.d.ts +1 -3
  148. package/dist/docx/vmlPreview.js +2 -30
  149. package/dist/docx/xmlEncoding.d.ts +5 -0
  150. package/dist/docx/xmlEncoding.js +12 -0
  151. package/dist/docx/xmlParser.d.ts +26 -2
  152. package/dist/docx/xmlParser.js +70 -27
  153. package/dist/docx/xmlResourceLimits.d.ts +89 -9
  154. package/dist/docx/xmlResourceLimits.js +105 -24
  155. package/dist/headless-layout.js +10 -1
  156. package/dist/index.d.ts +2 -1
  157. package/dist/index.js +2 -1
  158. package/dist/internal/pageBreakRunSourceDescendantIndex.js +5 -2
  159. package/dist/internal/paragraphFormattingSerialization.js +3 -2
  160. package/dist/layout-bridge/convert/toFlowBlocks.js +102 -12
  161. package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
  162. package/dist/layout-engine/measure/tableCellFloating.js +2 -0
  163. package/dist/layout-engine/types.d.ts +23 -1
  164. package/dist/layout-painter/renderImage.d.ts +5 -1
  165. package/dist/layout-painter/renderImage.js +14 -6
  166. package/dist/layout-painter/renderPage.d.ts +2 -0
  167. package/dist/layout-painter/renderPage.js +4 -0
  168. package/dist/layout-painter/renderParagraph.d.ts +13 -1
  169. package/dist/layout-painter/renderParagraph.js +26 -6
  170. package/dist/managers/autoSaveCodec.d.ts +9 -1
  171. package/dist/managers/autoSaveCodec.js +14 -12
  172. package/dist/markdown/images.js +1 -4
  173. package/dist/markdown/renderBlock.js +1 -0
  174. package/dist/markdown/renderRuns.d.ts +1 -1
  175. package/dist/markdown/renderRuns.js +28 -5
  176. package/dist/markdown/renderTable.js +22 -5
  177. package/dist/markdown/trailers.js +4 -1
  178. package/dist/pdf/images.js +142 -6
  179. package/dist/prosemirror/attrs/index.d.ts +14 -3
  180. package/dist/prosemirror/attrs/index.js +224 -2
  181. package/dist/prosemirror/authoredTransformAttrs.d.ts +28 -0
  182. package/dist/prosemirror/authoredTransformAttrs.js +64 -0
  183. package/dist/prosemirror/commands/contentControls.js +10 -2
  184. package/dist/prosemirror/commands/image.d.ts +9 -2
  185. package/dist/prosemirror/commands/image.js +43 -28
  186. package/dist/prosemirror/commands/pageBreak.js +1 -1
  187. package/dist/prosemirror/commentReferenceAttrs.d.ts +8 -0
  188. package/dist/prosemirror/commentReferenceAttrs.js +33 -0
  189. package/dist/prosemirror/commentReferenceIntegrity.d.ts +47 -0
  190. package/dist/prosemirror/commentReferenceIntegrity.js +43 -0
  191. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -13
  192. package/dist/prosemirror/conversion/fromProseDoc.js +338 -99
  193. package/dist/prosemirror/conversion/index.d.ts +2 -2
  194. package/dist/prosemirror/conversion/toProseDoc.d.ts +7 -9
  195. package/dist/prosemirror/conversion/toProseDoc.js +551 -327
  196. package/dist/prosemirror/extensions/StarterKit.js +8 -58
  197. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  198. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -1
  199. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +45 -27
  200. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -1
  201. package/dist/prosemirror/extensions/features/ImagePasteExtension.js +5 -3
  202. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +1 -0
  203. package/dist/prosemirror/extensions/markRegistry.d.ts +41 -0
  204. package/dist/prosemirror/extensions/markRegistry.js +75 -0
  205. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
  206. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.d.ts +18 -0
  207. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +63 -0
  208. package/dist/prosemirror/extensions/marks/markUtils.d.ts +2 -1
  209. package/dist/prosemirror/extensions/marks/markUtils.js +47 -4
  210. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.d.ts +11 -0
  211. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +87 -0
  212. package/dist/prosemirror/extensions/nodes/FieldExtension.js +9 -7
  213. package/dist/prosemirror/extensions/nodes/ImageExtension.js +20 -0
  214. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.d.ts +32 -0
  215. package/dist/prosemirror/extensions/nodes/PreservedBlockExtension.js +67 -0
  216. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.d.ts +16 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +60 -0
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +10 -2
  219. package/dist/prosemirror/extensions/nodes/TableExtension.js +3 -2
  220. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +13 -5
  221. package/dist/prosemirror/inlineWrapperStack.d.ts +39 -0
  222. package/dist/prosemirror/inlineWrapperStack.js +75 -0
  223. package/dist/prosemirror/pageBreakRunProjection.d.ts +17 -7
  224. package/dist/prosemirror/pageBreakRunProjection.js +19 -9
  225. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +6 -3
  226. package/dist/prosemirror/paragraphFormattingProvenance.js +12 -3
  227. package/dist/prosemirror/replacedAnnotations.d.ts +59 -0
  228. package/dist/prosemirror/replacedAnnotations.js +165 -0
  229. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +3 -1
  230. package/dist/prosemirror/runFormattingInlineCarriers.js +5 -1
  231. package/dist/prosemirror/schema/index.d.ts +3 -3
  232. package/dist/prosemirror/schema/marks.d.ts +25 -1
  233. package/dist/prosemirror/schema/nodes.d.ts +139 -3
  234. package/dist/prosemirror/schema/nodes.js +16 -1
  235. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  236. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  237. package/dist/prosemirror/validation.js +16 -2
  238. package/dist/prosemirror/yjsDocumentMetadata.d.ts +73 -0
  239. package/dist/prosemirror/yjsDocumentMetadata.js +171 -0
  240. package/dist/prosemirror/zeroWidthAnchors.js +2 -0
  241. package/dist/render-dom/commentAnchorAttributes.d.ts +37 -0
  242. package/dist/render-dom/commentAnchorAttributes.js +54 -0
  243. package/dist/server.d.ts +3 -1
  244. package/dist/server.js +3 -1
  245. package/dist/types/content.d.ts +2 -2
  246. package/dist/utils/base64.d.ts +36 -0
  247. package/dist/utils/base64.js +40 -0
  248. package/dist/utils/clipboard.d.ts +9 -1
  249. package/dist/utils/clipboard.js +29 -2
  250. package/dist/utils/findReplace.js +1 -1
  251. package/dist/utils/imageLuminance.d.ts +15 -0
  252. package/dist/utils/imageLuminance.js +32 -0
  253. package/dist/utils/mergeDocumentContent.js +7 -17
  254. package/dist/utils/replaceText.js +1 -0
  255. package/dist/utils/units.d.ts +10 -1
  256. package/dist/utils/units.js +12 -1
  257. package/dist/utils/urlSecurity.d.ts +8 -2
  258. package/dist/utils/urlSecurity.js +21 -3
  259. package/package.json +2 -2
  260. package/dist/docx/blockRangeMarkers.d.ts +0 -36
  261. package/dist/docx/blockRangeMarkers.js +0 -59
  262. package/dist/prosemirror/yjsParagraphSourceContract.d.ts +0 -9
  263. package/dist/prosemirror/yjsParagraphSourceContract.js +0 -26
@@ -26,10 +26,29 @@ const EDITED_PREVIEW_FINGERPRINT = "editedPreview";
26
26
  const editableImageProjection = ({ id: _id, rId: _rId, src: _src, mimeType: _mimeType, filename: _filename, ...image }) => image;
27
27
  /** Fingerprints modeled image fields which make raw DrawingML stale when edited. */
28
28
  const imageRawXmlFingerprint = (image) => canonicalJson(editableImageProjection(image));
29
- /** Editable raw drawing XML can replay only while its modeled projection is unchanged. */
29
+ /** Whether the modeled image still says what the captured raw drawing says. */
30
+ const modelAgreesWithRawXml = (drawing) => drawing.rawImageFingerprint === void 0 || drawing.rawImageFingerprint === imageRawXmlFingerprint(drawing.image);
31
+ /**
32
+ * Whether the serializer writes the captured raw XML back.
33
+ *
34
+ * For an unclassified drawing the capture is a cache of the model, so it
35
+ * replays only while the two agree. For a classified one the capture *is* the
36
+ * drawing: a preserve-only drawing has a placeholder image, and a preview-only
37
+ * group has a raster render of shapes the model cannot hold. Regenerating
38
+ * either writes something the source never contained — for the group, at best
39
+ * the one child picture the rasterizer saw first under that child's
40
+ * relationship, in place of the whole group. So a classified capture is always
41
+ * written back; a stale fingerprint means the edit that made it stale is lost,
42
+ * which {@link classifyDrawingSafety} reports as `opaque`, and never that
43
+ * folio may build a replacement.
44
+ */
30
45
  const canReplayEditableImageRawXml = (drawing) => {
31
- if (drawing.rawXmlMode === DRAWING_RAW_XML_MODES.PRESERVE_ONLY) return true;
32
- return drawing.rawImageFingerprint === void 0 || drawing.rawImageFingerprint === imageRawXmlFingerprint(drawing.image);
46
+ switch (drawing.rawXmlMode) {
47
+ case DRAWING_RAW_XML_MODES.PRESERVE_ONLY:
48
+ case DRAWING_RAW_XML_MODES.PREVIEW_ONLY: return true;
49
+ case void 0: return modelAgreesWithRawXml(drawing);
50
+ default: return drawing;
51
+ }
33
52
  };
34
53
  /**
35
54
  * What a drawing costs the document when Folio writes it back.
@@ -60,9 +79,14 @@ const canRegenerateDrawing = (drawing) => drawing.image.rId !== void 0;
60
79
  */
61
80
  const classifyDrawingSafety = (drawing) => {
62
81
  if (drawing.rawXml === void 0) return DRAWING_SAFETY_CLASSES.NATIVE;
63
- if (canReplayEditableImageRawXml(drawing)) return DRAWING_SAFETY_CLASSES.REPLAYABLE;
64
- if (drawing.rawXmlMode === DRAWING_RAW_XML_MODES.PREVIEW_ONLY) return DRAWING_SAFETY_CLASSES.OPAQUE;
65
- return canRegenerateDrawing(drawing) ? DRAWING_SAFETY_CLASSES.NATIVE : DRAWING_SAFETY_CLASSES.OPAQUE;
82
+ switch (drawing.rawXmlMode) {
83
+ case DRAWING_RAW_XML_MODES.PRESERVE_ONLY: return DRAWING_SAFETY_CLASSES.REPLAYABLE;
84
+ case DRAWING_RAW_XML_MODES.PREVIEW_ONLY: return modelAgreesWithRawXml(drawing) ? DRAWING_SAFETY_CLASSES.REPLAYABLE : DRAWING_SAFETY_CLASSES.OPAQUE;
85
+ case void 0:
86
+ if (modelAgreesWithRawXml(drawing)) return DRAWING_SAFETY_CLASSES.REPLAYABLE;
87
+ return canRegenerateDrawing(drawing) ? DRAWING_SAFETY_CLASSES.NATIVE : DRAWING_SAFETY_CLASSES.OPAQUE;
88
+ default: return drawing;
89
+ }
66
90
  };
67
91
  //#endregion
68
92
  export { DRAWING_SAFETY_CLASSES, EDITED_PREVIEW_FINGERPRINT, allowsDirectDrawingEdit, canReplayEditableImageRawXml, classifyDrawingSafety, imageRawXmlFingerprint, isDrawingRawXmlMode };
@@ -0,0 +1,85 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/docx/inlineWrapperContent.d.ts
3
+ /**
4
+ * What a run-level tracked-change wrapper keeps inside itself (CT_RunTrackChange).
5
+ *
6
+ * Runs, links, fields, bookmark boundaries, equations, nested revisions and
7
+ * markup folio does not model.
8
+ *
9
+ * The transparent wrappers are admitted too: `w:bdo` / `w:dir` state how their
10
+ * content is laid out, and `w:sdt` states what the content is bound to.
11
+ * Neither says anything about the revision, so lifting one out of a revision
12
+ * takes its text out of the revision with it.
13
+ *
14
+ * The range markers are not: a `w:commentRangeStart` or `w:moveFromRangeStart`
15
+ * inside a revision is a marker the revision does not own, and the pairing
16
+ * passes read it as a paragraph-level sibling.
17
+ */
18
+ declare const TRACKED_CHANGE_WRAPPER_CONTENT: {
19
+ readonly inlineWrapper: true;
20
+ readonly bookmarkEnd: true;
21
+ readonly bookmarkStart: true;
22
+ readonly complexField: true;
23
+ readonly deletion: true;
24
+ readonly hyperlink: true;
25
+ readonly inlineSdt: true;
26
+ readonly insertion: true;
27
+ readonly mathEquation: true;
28
+ readonly moveFrom: true;
29
+ readonly moveTo: true;
30
+ readonly preservedInline: true;
31
+ readonly run: true;
32
+ readonly simpleField: true;
33
+ readonly commentRangeEnd: false;
34
+ readonly commentRangeStart: false;
35
+ readonly commentReference: false;
36
+ readonly moveFromRangeEnd: false;
37
+ readonly moveFromRangeStart: false;
38
+ readonly moveToRangeEnd: false;
39
+ readonly moveToRangeStart: false;
40
+ };
41
+ /**
42
+ * What an inline content control keeps inside `<w:sdtContent>`.
43
+ *
44
+ * Mirror of upstream eigenpal/docx-editor PR #482 (commit 29f95751d), plus
45
+ * the bidirectional wrapper: OOXML allows runs, hyperlinks, simple/complex
46
+ * fields, nested SDTs, tracked insertions/deletions/moves, math, markup folio
47
+ * does not model, and the bidirectional controls directly inside
48
+ * `<w:sdtContent>`. Bookmarks and range markers are lifted out as siblings of
49
+ * the SDT so the control itself stays valid.
50
+ */
51
+ declare const INLINE_SDT_CONTENT: {
52
+ readonly inlineWrapper: true;
53
+ readonly complexField: true;
54
+ readonly deletion: true;
55
+ readonly hyperlink: true;
56
+ readonly inlineSdt: true;
57
+ readonly insertion: true;
58
+ readonly mathEquation: true;
59
+ readonly moveFrom: true;
60
+ readonly moveTo: true;
61
+ readonly preservedInline: true;
62
+ readonly run: true;
63
+ readonly simpleField: true;
64
+ readonly bookmarkEnd: false;
65
+ readonly bookmarkStart: false;
66
+ readonly commentRangeEnd: false;
67
+ readonly commentRangeStart: false;
68
+ readonly commentReference: false;
69
+ readonly moveFromRangeEnd: false;
70
+ readonly moveFromRangeStart: false;
71
+ readonly moveToRangeEnd: false;
72
+ readonly moveToRangeStart: false;
73
+ };
74
+ /**
75
+ * Whether a revision wrapper keeps this content inside itself.
76
+ *
77
+ * Generic in the input so a caller that has already narrowed its content
78
+ * keeps that narrowing: filtering a list the bidirectional wrappers are
79
+ * already flattened out of must not put one back into the result type.
80
+ */
81
+ declare const isTrackedChangeWrapperChild: <Content extends document_d_exports.ParagraphContent>(content: Content) => content is Extract<Content, document_d_exports.TrackedRunContent>;
82
+ /** Whether an inline content control keeps this content inside `<w:sdtContent>`. */
83
+ declare const isInlineSdtContent: <Content extends document_d_exports.ParagraphContent>(content: Content) => content is Extract<Content, document_d_exports.InlineSdt["content"][number]>;
84
+ //#endregion
85
+ export { INLINE_SDT_CONTENT, TRACKED_CHANGE_WRAPPER_CONTENT, isInlineSdtContent, isTrackedChangeWrapperChild };
@@ -0,0 +1,84 @@
1
+ //#region src/docx/inlineWrapperContent.ts
2
+ /**
3
+ * What a run-level tracked-change wrapper keeps inside itself (CT_RunTrackChange).
4
+ *
5
+ * Runs, links, fields, bookmark boundaries, equations, nested revisions and
6
+ * markup folio does not model.
7
+ *
8
+ * The transparent wrappers are admitted too: `w:bdo` / `w:dir` state how their
9
+ * content is laid out, and `w:sdt` states what the content is bound to.
10
+ * Neither says anything about the revision, so lifting one out of a revision
11
+ * takes its text out of the revision with it.
12
+ *
13
+ * The range markers are not: a `w:commentRangeStart` or `w:moveFromRangeStart`
14
+ * inside a revision is a marker the revision does not own, and the pairing
15
+ * passes read it as a paragraph-level sibling.
16
+ */
17
+ const TRACKED_CHANGE_WRAPPER_CONTENT = {
18
+ inlineWrapper: true,
19
+ bookmarkEnd: true,
20
+ bookmarkStart: true,
21
+ complexField: true,
22
+ deletion: true,
23
+ hyperlink: true,
24
+ inlineSdt: true,
25
+ insertion: true,
26
+ mathEquation: true,
27
+ moveFrom: true,
28
+ moveTo: true,
29
+ preservedInline: true,
30
+ run: true,
31
+ simpleField: true,
32
+ commentRangeEnd: false,
33
+ commentRangeStart: false,
34
+ commentReference: false,
35
+ moveFromRangeEnd: false,
36
+ moveFromRangeStart: false,
37
+ moveToRangeEnd: false,
38
+ moveToRangeStart: false
39
+ };
40
+ /**
41
+ * What an inline content control keeps inside `<w:sdtContent>`.
42
+ *
43
+ * Mirror of upstream eigenpal/docx-editor PR #482 (commit 29f95751d), plus
44
+ * the bidirectional wrapper: OOXML allows runs, hyperlinks, simple/complex
45
+ * fields, nested SDTs, tracked insertions/deletions/moves, math, markup folio
46
+ * does not model, and the bidirectional controls directly inside
47
+ * `<w:sdtContent>`. Bookmarks and range markers are lifted out as siblings of
48
+ * the SDT so the control itself stays valid.
49
+ */
50
+ const INLINE_SDT_CONTENT = {
51
+ inlineWrapper: true,
52
+ complexField: true,
53
+ deletion: true,
54
+ hyperlink: true,
55
+ inlineSdt: true,
56
+ insertion: true,
57
+ mathEquation: true,
58
+ moveFrom: true,
59
+ moveTo: true,
60
+ preservedInline: true,
61
+ run: true,
62
+ simpleField: true,
63
+ bookmarkEnd: false,
64
+ bookmarkStart: false,
65
+ commentRangeEnd: false,
66
+ commentRangeStart: false,
67
+ commentReference: false,
68
+ moveFromRangeEnd: false,
69
+ moveFromRangeStart: false,
70
+ moveToRangeEnd: false,
71
+ moveToRangeStart: false
72
+ };
73
+ /**
74
+ * Whether a revision wrapper keeps this content inside itself.
75
+ *
76
+ * Generic in the input so a caller that has already narrowed its content
77
+ * keeps that narrowing: filtering a list the bidirectional wrappers are
78
+ * already flattened out of must not put one back into the result type.
79
+ */
80
+ const isTrackedChangeWrapperChild = (content) => TRACKED_CHANGE_WRAPPER_CONTENT[content.type];
81
+ /** Whether an inline content control keeps this content inside `<w:sdtContent>`. */
82
+ const isInlineSdtContent = (content) => INLINE_SDT_CONTENT[content.type];
83
+ //#endregion
84
+ export { INLINE_SDT_CONTENT, TRACKED_CHANGE_WRAPPER_CONTENT, isInlineSdtContent, isTrackedChangeWrapperChild };
@@ -1,4 +1,5 @@
1
1
  import { findChildByLocalName, getLocalName } from "./xmlParser.js";
2
+ import { escapeXmlText } from "@stll/docx-core";
2
3
  //#region src/docx/mathToMathml.ts
3
4
  /**
4
5
  * OMML → MathML conversion.
@@ -95,13 +96,13 @@ const MATH_OPERATOR_HINT = /* @__PURE__ */ new Set([
95
96
  "…"
96
97
  ]);
97
98
  function renderElement(el) {
98
- if (el.type === "text") return escapeXml(textValue(el));
99
+ if (el.type === "text") return escapeXmlText(textValue(el));
99
100
  if (el.type !== "element") return "";
100
101
  switch (el.name ? getLocalName(el.name) : "") {
101
102
  case "oMath":
102
103
  case "oMathPara": return renderChildren(el);
103
104
  case "r": return renderRun(el);
104
- case "t": return escapeXml(extractText(el));
105
+ case "t": return escapeXmlText(extractText(el));
105
106
  case "f": return renderFraction(el);
106
107
  case "num":
107
108
  case "den": return wrapMrow(renderChildren(el));
@@ -179,8 +180,8 @@ function tokenizeMathText(text) {
179
180
  let bufKind = null;
180
181
  const flush = () => {
181
182
  if (!buf) return;
182
- if (bufKind === "digit") out += `<mn>${escapeXml(buf)}</mn>`;
183
- else out += `<mi>${escapeXml(buf)}</mi>`;
183
+ if (bufKind === "digit") out += `<mn>${escapeXmlText(buf)}</mn>`;
184
+ else out += `<mi>${escapeXmlText(buf)}</mi>`;
184
185
  buf = "";
185
186
  bufKind = null;
186
187
  };
@@ -193,7 +194,7 @@ function tokenizeMathText(text) {
193
194
  const kind = classifyChar(ch);
194
195
  if (kind === "operator") {
195
196
  flush();
196
- out += `<mo>${escapeXml(ch)}</mo>`;
197
+ out += `<mo>${escapeXmlText(ch)}</mo>`;
197
198
  continue;
198
199
  }
199
200
  if (kind === "digit") {
@@ -202,7 +203,7 @@ function tokenizeMathText(text) {
202
203
  continue;
203
204
  }
204
205
  flush();
205
- out += `<mi>${escapeXml(ch)}</mi>`;
206
+ out += `<mi>${escapeXmlText(ch)}</mi>`;
206
207
  }
207
208
  flush();
208
209
  return out;
@@ -258,7 +259,7 @@ function renderNary(el) {
258
259
  const chr = (chrEl ? getAttrValue(chrEl, "val") : null) || "∫";
259
260
  const limLocEl = naryPr ? findChildByLocalName(naryPr, "limLoc") : null;
260
261
  const limLoc = (limLocEl ? getAttrValue(limLocEl, "val") : null) || "subSup";
261
- const opMml = `<mo>${escapeXml(chr)}</mo>`;
262
+ const opMml = `<mo>${escapeXmlText(chr)}</mo>`;
262
263
  const subMml = sub ? wrapMrow(renderChildren(sub)) : "";
263
264
  const supMml = sup ? wrapMrow(renderChildren(sup)) : "";
264
265
  const bodyMml = body ? wrapMrow(renderChildren(body)) : "<mrow/>";
@@ -277,8 +278,8 @@ function renderDelimiter(el) {
277
278
  const begChr = begChrEl ? getAttrValue(begChrEl, "val") ?? "(" : "(";
278
279
  const endChr = endChrEl ? getAttrValue(endChrEl, "val") ?? ")" : ")";
279
280
  const sepChr = sepChrEl ? getAttrValue(sepChrEl, "val") ?? "|" : "|";
280
- const inner = (el.elements ?? []).filter((c) => c.type === "element" && getLocalName(c.name ?? "") === "e").map((c) => wrapMrow(renderChildren(c))).join(`<mo>${escapeXml(sepChr)}</mo>`);
281
- return `<mrow><mo>${escapeXml(begChr)}</mo>${inner}<mo>${escapeXml(endChr)}</mo></mrow>`;
281
+ const inner = (el.elements ?? []).filter((c) => c.type === "element" && getLocalName(c.name ?? "") === "e").map((c) => wrapMrow(renderChildren(c))).join(`<mo>${escapeXmlText(sepChr)}</mo>`);
282
+ return `<mrow><mo>${escapeXmlText(begChr)}</mo>${inner}<mo>${escapeXmlText(endChr)}</mo></mrow>`;
282
283
  }
283
284
  function renderMatrix(el) {
284
285
  return `<mtable>${(el.elements ?? []).filter((c) => c.type === "element" && getLocalName(c.name ?? "") === "mr").map(renderMatrixRow).join("")}</mtable>`;
@@ -291,7 +292,7 @@ function renderAccent(el) {
291
292
  const chrEl = accPr ? findChildByLocalName(accPr, "chr") : null;
292
293
  const chr = chrEl ? getAttrValue(chrEl, "val") ?? "̂" : "̂";
293
294
  const base = findChildByLocalName(el, "e");
294
- return `<mover accent="true">${base ? wrapMrow(renderChildren(base)) : "<mrow/>"}<mo>${escapeXml(chr)}</mo></mover>`;
295
+ return `<mover accent="true">${base ? wrapMrow(renderChildren(base)) : "<mrow/>"}<mo>${escapeXmlText(chr)}</mo></mover>`;
295
296
  }
296
297
  function renderBar(el) {
297
298
  const barPr = findChildByLocalName(el, "barPr");
@@ -311,7 +312,7 @@ function renderGroupChr(el) {
311
312
  const chr = chrEl ? getAttrValue(chrEl, "val") ?? defaultChr : defaultChr;
312
313
  const base = findChildByLocalName(el, "e");
313
314
  const baseMml = base ? wrapMrow(renderChildren(base)) : "<mrow/>";
314
- const grouper = `<mo stretchy="true">${escapeXml(chr)}</mo>`;
315
+ const grouper = `<mo stretchy="true">${escapeXmlText(chr)}</mo>`;
315
316
  return pos === "top" ? `<mover>${baseMml}${grouper}</mover>` : `<munder>${baseMml}${grouper}</munder>`;
316
317
  }
317
318
  function renderLimLow(el) {
@@ -350,8 +351,5 @@ function getAttrValue(el, localAttr) {
350
351
  return String(v);
351
352
  }
352
353
  }
353
- function escapeXml(s) {
354
- return s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
355
- }
356
354
  //#endregion
357
355
  export { ommlToMathml };
@@ -0,0 +1,34 @@
1
+ import { XmlElement } from "./xmlParser.js";
2
+ //#region src/docx/nonVisualDrawingProps.d.ts
3
+ /** The authored name, alt text and title of a drawing object. */
4
+ type NonVisualDrawingNames = {
5
+ /** `@name`, schema-required, so `""` means the object was never named. */
6
+ name?: string;
7
+ /** `@descr`: alt text, accessibility content. */
8
+ alt?: string;
9
+ /** `@title`. */
10
+ title?: string;
11
+ };
12
+ /**
13
+ * Read `@name`, `@descr` and `@title` off a `CT_NonVisualDrawingProps` element.
14
+ *
15
+ * An attribute that is not there stays absent. `@name` is schema-required, so
16
+ * an unnamed object still writes one, and `name=""` is the marker the writer
17
+ * below mints for exactly that: reading it back as an authored name would make
18
+ * `absent → save → parse` land on `""` instead of absent, and no reader can
19
+ * tell the two apart. `@descr` and `@title` are optional and written only when
20
+ * authored, so `""` in either is a string someone wrote.
21
+ */
22
+ declare const parseNonVisualDrawingNames: (element: XmlElement | null | undefined) => NonVisualDrawingNames;
23
+ /**
24
+ * The `name`, `descr` and `title` attributes of a `CT_NonVisualDrawingProps`
25
+ * element, leading space included.
26
+ *
27
+ * `@name` is schema-required, so an object carrying none writes the empty
28
+ * string. folio does not name an object it did not author: a generated
29
+ * "Shape 3" would overwrite the author's own name for every drawing whose
30
+ * name did not survive the model, and read back as authored content.
31
+ */
32
+ declare const serializeNonVisualDrawingNames: (names: NonVisualDrawingNames) => string;
33
+ //#endregion
34
+ export { NonVisualDrawingNames, parseNonVisualDrawingNames, serializeNonVisualDrawingNames };
@@ -0,0 +1,46 @@
1
+ import { getAttribute } from "./xmlParser.js";
2
+ import { escapeXmlAttribute } from "@stll/docx-core";
3
+ //#region src/docx/nonVisualDrawingProps.ts
4
+ /**
5
+ * `CT_NonVisualDrawingProps` (`wp:docPr`, `wps:cNvPr`, `pic:cNvPr`) carries the
6
+ * three authored strings every drawing object has: its name, its alt text
7
+ * (`descr`) and its title. They are authored content, not folio's to mint, so
8
+ * one reader and one writer own them for every drawing kind.
9
+ */
10
+ /**
11
+ * Read `@name`, `@descr` and `@title` off a `CT_NonVisualDrawingProps` element.
12
+ *
13
+ * An attribute that is not there stays absent. `@name` is schema-required, so
14
+ * an unnamed object still writes one, and `name=""` is the marker the writer
15
+ * below mints for exactly that: reading it back as an authored name would make
16
+ * `absent → save → parse` land on `""` instead of absent, and no reader can
17
+ * tell the two apart. `@descr` and `@title` are optional and written only when
18
+ * authored, so `""` in either is a string someone wrote.
19
+ */
20
+ const parseNonVisualDrawingNames = (element) => {
21
+ if (!element) return {};
22
+ const name = getAttribute(element, null, "name");
23
+ const descr = getAttribute(element, null, "descr");
24
+ const title = getAttribute(element, null, "title");
25
+ return {
26
+ ...name !== null && name !== "" ? { name } : {},
27
+ ...descr !== null ? { alt: descr } : {},
28
+ ...title !== null ? { title } : {}
29
+ };
30
+ };
31
+ /**
32
+ * The `name`, `descr` and `title` attributes of a `CT_NonVisualDrawingProps`
33
+ * element, leading space included.
34
+ *
35
+ * `@name` is schema-required, so an object carrying none writes the empty
36
+ * string. folio does not name an object it did not author: a generated
37
+ * "Shape 3" would overwrite the author's own name for every drawing whose
38
+ * name did not survive the model, and read back as authored content.
39
+ */
40
+ const serializeNonVisualDrawingNames = (names) => {
41
+ const descr = names.alt === void 0 ? "" : ` descr="${escapeXmlAttribute(names.alt)}"`;
42
+ const title = names.title === void 0 ? "" : ` title="${escapeXmlAttribute(names.title)}"`;
43
+ return ` name="${escapeXmlAttribute(names.name ?? "")}"${descr}${title}`;
44
+ };
45
+ //#endregion
46
+ export { parseNonVisualDrawingNames, serializeNonVisualDrawingNames };
@@ -44,13 +44,22 @@ const normalizeTable = (table, styles) => ({
44
44
  ...row,
45
45
  cells: row.cells.map((cell) => ({
46
46
  ...cell,
47
- content: cell.content.map((block) => block.type === "paragraph" ? normalizeParagraph(block, styles) : normalizeTable(block, styles))
47
+ content: cell.content.map((block) => normalizeCellBlock(block, styles))
48
48
  }))
49
49
  }))
50
50
  });
51
+ const normalizeCellBlock = (block, styles) => {
52
+ switch (block.type) {
53
+ case "paragraph": return normalizeParagraph(block, styles);
54
+ case "table": return normalizeTable(block, styles);
55
+ case "preservedBlock": return block;
56
+ default: return block;
57
+ }
58
+ };
51
59
  const normalizeBlocks = (blocks, styles) => blocks.map((block) => {
52
60
  if (block.type === "paragraph") return normalizeParagraph(block, styles);
53
61
  if (block.type === "table") return normalizeTable(block, styles);
62
+ if (block.type === "preservedBlock") return block;
54
63
  return {
55
64
  ...block,
56
65
  content: normalizeBlocks(block.content, styles)
@@ -0,0 +1,21 @@
1
+ import { XmlElement } from "./xmlParser.js";
2
+ //#region src/docx/paraIdAttribute.d.ts
3
+ /**
4
+ * The namespaces a paraId-valued attribute may be written in: the Word 2010,
5
+ * 2012 and 2018 wordml extensions.
6
+ *
7
+ * The 2018 URI is read from the serializer's table rather than retyped, so the
8
+ * spelling folio writes and the spelling it accepts cannot drift.
9
+ */
10
+ declare const PARA_ID_NAMESPACE_URIS: ReadonlySet<string>;
11
+ /** The paraId this element carries, or `undefined` when it carries none. */
12
+ declare const paraIdAttribute: (element: XmlElement) => string | undefined;
13
+ /** The paraId of the parent this element names, by the same rule. */
14
+ declare const paraIdParentAttribute: (element: XmlElement) => string | undefined;
15
+ /**
16
+ * The textId this element carries: a paragraph identity written beside
17
+ * `paraId`, in the same namespaces and by the same rule.
18
+ */
19
+ declare const textIdAttribute: (element: XmlElement) => string | undefined;
20
+ //#endregion
21
+ export { PARA_ID_NAMESPACE_URIS, paraIdAttribute, paraIdParentAttribute, textIdAttribute };
@@ -0,0 +1,64 @@
1
+ import { OOXML_NAMESPACES } from "./serializer/partNamespaces.js";
2
+ import { NAMESPACES, WORDPROCESSINGML_NAMESPACE_URIS, getAttributeByNamespaceUri } from "./xmlParser.js";
3
+ //#region src/docx/paraIdAttribute.ts
4
+ /**
5
+ * The one reader for "the paraId written on this element".
6
+ *
7
+ * A `paraId` is a join key: `w15:commentEx/@w15:paraId`,
8
+ * `w16cex:comment/@w16cex:paraId` and `w15:paraIdParent` all name a paragraph
9
+ * through the `w14:paraId` it carries. Three Word generations write the same
10
+ * key under three prefixes, and a producer is free to bind any of those
11
+ * namespaces to a prefix of its own choosing, so the key must be resolved by
12
+ * namespace URI. Resolving it by local name alone is worse than missing it: an
13
+ * unrelated `vendor:paraId` would key a comment into another thread and carry
14
+ * that thread's date, parent and resolved state.
15
+ *
16
+ * Every reader of the key calls this, so no call site can come to disagree
17
+ * with another about which attribute is a paraId.
18
+ */
19
+ /**
20
+ * The namespaces a paraId-valued attribute may be written in: the Word 2010,
21
+ * 2012 and 2018 wordml extensions.
22
+ *
23
+ * The 2018 URI is read from the serializer's table rather than retyped, so the
24
+ * spelling folio writes and the spelling it accepts cannot drift.
25
+ */
26
+ const PARA_ID_NAMESPACE_URIS = /* @__PURE__ */ new Set([
27
+ NAMESPACES.w14,
28
+ NAMESPACES.w15,
29
+ OOXML_NAMESPACES.w16cex.uri
30
+ ]);
31
+ /**
32
+ * The conventional prefixes, read literally as a last resort.
33
+ *
34
+ * A part that writes `w14:paraId` without declaring `xmlns:w14` is malformed,
35
+ * and no URI lookup can resolve it; Word reads those files, so folio does too.
36
+ */
37
+ const CONVENTIONAL_PARA_ID_PREFIXES = [
38
+ "w14",
39
+ "w15",
40
+ "w16cex"
41
+ ];
42
+ const paraIdValuedAttribute = (element, localName) => {
43
+ const byUri = getAttributeByNamespaceUri(element, PARA_ID_NAMESPACE_URIS, localName);
44
+ if (byUri !== null) return byUri;
45
+ for (const prefix of CONVENTIONAL_PARA_ID_PREFIXES) {
46
+ const literal = element.attributes?.[`${prefix}:${localName}`];
47
+ if (literal !== void 0) return String(literal);
48
+ }
49
+ const inWordprocessingml = getAttributeByNamespaceUri(element, WORDPROCESSINGML_NAMESPACE_URIS, localName);
50
+ if (inWordprocessingml !== null) return inWordprocessingml;
51
+ const literalW = element.attributes?.[`w:${localName}`];
52
+ return literalW === void 0 ? void 0 : String(literalW);
53
+ };
54
+ /** The paraId this element carries, or `undefined` when it carries none. */
55
+ const paraIdAttribute = (element) => paraIdValuedAttribute(element, "paraId");
56
+ /** The paraId of the parent this element names, by the same rule. */
57
+ const paraIdParentAttribute = (element) => paraIdValuedAttribute(element, "paraIdParent");
58
+ /**
59
+ * The textId this element carries: a paragraph identity written beside
60
+ * `paraId`, in the same namespaces and by the same rule.
61
+ */
62
+ const textIdAttribute = (element) => paraIdValuedAttribute(element, "textId");
63
+ //#endregion
64
+ export { PARA_ID_NAMESPACE_URIS, paraIdAttribute, paraIdParentAttribute, textIdAttribute };
@@ -1,7 +1,7 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { NumberingMap } from "./numberingParser.js";
3
- import { StyleMap } from "./styleParser.js";
4
3
  import { XmlElement } from "./xmlParser.js";
4
+ import { StyleMap } from "./styleParser.js";
5
5
  //#region src/docx/paragraphParser.d.ts
6
6
  /**
7
7
  * Parse paragraph formatting properties (w:pPr)